diff --git a/.github/workflows/build-container.yml b/.github/workflows/build-container.yml index 52d28ffbdb2..cc619909785 100644 --- a/.github/workflows/build-container.yml +++ b/.github/workflows/build-container.yml @@ -8,11 +8,11 @@ on: - '.github/workflows/build-container.yml' jobs: - xcsoar-docker-env: + opensoar-docker-env: runs-on: ubuntu-latest env: REGISTRY: ghcr.io - IMAGENAME: xcsoar-build + IMAGENAME: opensoar-build steps: - uses: actions/checkout@v4 with: @@ -33,8 +33,8 @@ jobs: push: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }} context: ./ide file: ./ide/docker/Dockerfile - tags: ghcr.io/${{ steps.lc_repository_name.outputs.lowercase }}/xcsoar-build:latest - cache-from: type=registry,ref=ghcr.io/${{ steps.string.outputs.lowercase }}/xcsoar-build:latest + tags: ghcr.io/${{ steps.lc_repository_name.outputs.lowercase }}/opensoar-build:latest + cache-from: type=registry,ref=ghcr.io/${{ steps.string.outputs.lowercase }}/opensoar-build:latest cache-to: type=inline secrets: | GIT_AUTH_TOKEN=${{ github.token }} diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index dbf2a71c1f0..afcca1c326b 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -7,18 +7,20 @@ on: - '.github/workflows/build-docs.yml' branches: - master + - dev-branch pull_request: paths: - 'doc/**' - '.github/workflows/build-docs.yml' branches: - master + - dev-branch env: TARGET: manual - TARGET_FINAL: XCSoar-docs + TARGET_FINAL: OpenSoar-docs TARGET_EXT: pdf jobs: - xcsoar-compile: + opensoar-compile: runs-on: ubuntu-latest steps: - id: checkout @@ -35,10 +37,10 @@ jobs: - name: XCSoar generate Docs uses: addnab/docker-run-action@v3 with: - image: ghcr.io/${{ steps.repository.outputs.lowercase }}/xcsoar-build:latest - options: -v ${{ github.workspace }}:/opt/xcsoar + image: ghcr.io/${{ steps.repository.outputs.lowercase }}/opensoar-build:latest + options: -v ${{ github.workspace }}:/opt/opensoar run: | - cd /opt/xcsoar + cd /opt/opensoar make manual V=2 - name: upload artifact uses: actions/upload-artifact@v4 diff --git a/.github/workflows/build-native.yml b/.github/workflows/build-native.yml index a442a0829b5..74d094df930 100644 --- a/.github/workflows/build-native.yml +++ b/.github/workflows/build-native.yml @@ -13,6 +13,7 @@ on: - '.github/workflows/build-unix.yml' branches: - master + - dev-branch pull_request: paths-ignore: @@ -26,6 +27,7 @@ on: - '.github/workflows/build-unix.yml' branches: - master + - dev-branch env: DEBUG: y @@ -37,8 +39,8 @@ jobs: env: TARGET: UNIX - TARGET_BIN: xcsoar - TARGET_FINAL: xcsoar-debug + TARGET_BIN: opensoar + TARGET_FINAL: opensoar-debug TARGET_EXT: '' steps: @@ -46,7 +48,7 @@ jobs: if: github.event_name == 'push' run: | echo "DEBUG=n" >> $GITHUB_ENV - echo "TARGET_FINAL=xcsoar" >> $GITHUB_ENV + echo "TARGET_FINAL=OpenSoar" >> $GITHUB_ENV - id: checkout uses: actions/checkout@v4 with: @@ -94,7 +96,7 @@ jobs: libasound2-dev \ libgles2-mesa-dev libegl1-mesa-dev - - name: Compile XCSoar + - name: Compile OpenSoar run: | make -j$(nproc) TARGET=${{env.TARGET }} DEBUG=${{ env.DEBUG }} USE_CCACHE=y V=2 everything check @@ -106,7 +108,7 @@ jobs: - name: Deploy to Staging server if: | - github.repository == 'XCSoar/XCSoar' && + github.repository == 'OpenSoaring/OpenSoar' && github.ref == 'ref/head/master' && github.event == 'push' uses: easingthemes/ssh-deploy@main @@ -173,7 +175,7 @@ jobs: libxml-parser-perl \ libasound2-dev - - name: Compile XCSoar + - name: Compile OpenSoar run: | make -j$(nproc) TARGET=${{env.TARGET }} DEBUG=${{ env.DEBUG }} VFB=y SANITIZE=y DEBUG_GLIBCXX=y USE_CCACHE=y V=2 everything check @@ -239,7 +241,7 @@ jobs: cmake meson ninja-build \ ttf-bitstream-vera - - name: Compile XCSoar + - name: Compile OpenSoar run: | make -j$(nproc) \ TARGET=${{env.TARGET}} \ @@ -256,7 +258,7 @@ jobs: - name: Deploy to Staging server if: | - github.repository == 'XCSoar/XCSoar' && + github.repository == 'OpenSoaring/OpenSoar' && github.ref == 'ref/head/master' && github.event == 'push' uses: easingthemes/ssh-deploy@main @@ -273,8 +275,8 @@ jobs: env: TARGET: ANDROIDFAT - TARGET_BIN: XCSoar-debug - TARGET_FINAL: XCSoar-debug + TARGET_BIN: OpenSoar-debug + TARGET_FINAL: OpenSoar-debug TARGET_EXT: apk NDK: r26c @@ -283,7 +285,7 @@ jobs: if: github.event_name == 'push' run: | echo "DEBUG=n" >> $GITHUB_ENV - echo "TARGET_FINAL=XCSoar" >> $GITHUB_ENV + echo "TARGET_FINAL=OpenSoar" >> $GITHUB_ENV - id: checkout uses: actions/checkout@v4 @@ -338,7 +340,7 @@ jobs: rm android-ndk-${{env.NDK}}-linux.zip echo ANDROID_NDK_LATEST_HOME=$PWD/android-ndk-${{env.NDK}} >> $GITHUB_ENV - - name: Compile XCSoar + - name: Compile OpenSoar run: | make -j$(nproc) \ TARGET=${{env.TARGET}} \ @@ -356,7 +358,7 @@ jobs: - name: Deploy to Staging server if: | - github.repository == 'XCSoar/XCSoar' && + github.repository == 'OpenSoaring/OpenSoar' && github.ref == 'ref/head/master' && github.event == 'push' uses: easingthemes/ssh-deploy@main @@ -375,8 +377,8 @@ jobs: env: TARGET: WIN64 - TARGET_BIN: XCSoar - TARGET_FINAL: XCSoar-debug + TARGET_BIN: OpenSoar + TARGET_FINAL: OpenSoar-debug TARGET_EXT: .exe steps: @@ -384,7 +386,7 @@ jobs: if: github.event_name == 'push' run: | echo "DEBUG=n" >> $GITHUB_ENV - echo "TARGET_FINAL=XCSoar" >> $GITHUB_ENV + echo "TARGET_FINAL=OpenSoar" >> $GITHUB_ENV - name: Install build dependencies run: | @@ -438,7 +440,7 @@ jobs: - name: Patch mingw intrin.h (mingw64 v8 bug workaround) run: sed -i -e '/extern.* __builtin/d' /usr/share/mingw-w64/include/intrin.h - - name: Compile XCSoar + - name: Compile OpenSoar run: | make -j$(nproc) TARGET=${{env.TARGET }} DEBUG=${{ env.DEBUG }} USE_CCACHE=y V=2 everything @@ -451,7 +453,7 @@ jobs: - name: store checks and compile artefacts uses: actions/upload-artifact@v4 with: - name: xcsoar-${{ env.TARGET }}-artifact + name: opensoar-${{ env.TARGET }}-artifact path: | ${{ github.workspace }}/output/${{ env.TARGET }} !${{ github.workspace }}/output/${{ env.TARGET }}/lib/build @@ -460,7 +462,7 @@ jobs: - name: Deploy to Staging server if: | - github.repository == 'XCSoar/XCSoar' && + github.repository == 'OpenSoaring/OpenSoar' && github.ref == 'ref/head/master' && github.event == 'push' uses: easingthemes/ssh-deploy@main @@ -485,9 +487,9 @@ jobs: - name: fetch artifacts uses: actions/download-artifact@v4 with: - name: xcsoar-${{ env.TARGET }}-artifact + name: opensoar-${{ env.TARGET }}-artifact path: ${{ github.workspace }}/output/${{ env.TARGET }} - - name: XCSoar run checks on ${{ env.TARGET }} + - name: OpenSoar run checks on ${{ env.TARGET }} run: make check-no-build working-directory: ${{ github.workspace }} @@ -534,12 +536,13 @@ jobs: curl \ lua - - name: Compile XCSoar + - name: Compile OpenSoar # We use "-O0" instead of the default "-Og" to work around a # LLVM bug in Apple Xcode which crashes clang with "fatal # error: error in backend: Cannot select: intrinsic # %llvm.coro.size" run: | + clang --version && gmake -j$(sysctl -n hw.logicalcpu) TARGET=${{env.TARGET }} USE_CCACHE=y \ OPTIMIZE="-O0" \ USE_HOMEBREW=y \ @@ -548,7 +551,7 @@ jobs: - name: Deploy to Staging server if: | - github.repository == 'XCSoar/XCSoar' && + github.repository == 'OpenSoaring/OpenSoar' && github.ref == 'ref/head/master' && github.event == 'push' uses: easingthemes/ssh-deploy@main @@ -604,7 +607,7 @@ jobs: imagemagick gettext sox \ cmake ninja - - name: Compile XCSoar + - name: Compile OpenSoar # TODO: remove the "||true" as soon as the remaining SDL2 # linker failure ("Undefined symbols: _SDL_IsIPad, _main") is # fixed. @@ -615,7 +618,7 @@ jobs: - name: Deploy to Staging server if: | - github.repository == 'XCSoar/XCSoar' && + github.repository == 'OpenSoaring/OpenSoar' && github.ref == 'ref/head/master' && github.event == 'push' uses: easingthemes/ssh-deploy@main diff --git a/.github/workflows/cmake-native.yml b/.github/workflows/cmake-native.yml new file mode 100644 index 00000000000..e7fcd4eac19 --- /dev/null +++ b/.github/workflows/cmake-native.yml @@ -0,0 +1,128 @@ +--- +on: + workflow_dispatch: + push: + paths-ignore: + - 'cloud/**' + - 'doc/**' + - 'fuzzer/**' + - 'ide/**' + - 'kobo/**' + - 'python/**' + - '.github/workflows/build-container.yml' + - '.github/workflows/build-unix.yml' + branches: + - master + - dev-branch + + pull_request: + paths-ignore: + - 'cloud/**' + - 'doc/**' + - 'fuzzer/**' + - 'ide/**' + - 'kobo/**' + - 'python/**' + - '.github/workflows/build-container.yml' + - '.github/workflows/build-unix.yml' + branches: + - master + - dev-branch + +env: + DEBUG: y + BOOST: boost_1_84_0 + +jobs: + build-windows: + runs-on: ubuntu-22.04 + + env: + TARGET: WIN64 + TARGET_BIN: OpenSoar + TARGET_FINAL: OpenSoar-debug + TARGET_EXT: .exe + + steps: + - name: set vars for push + if: github.event_name == 'push' + run: | + echo "DEBUG=n" >> $GITHUB_ENV + echo "TARGET_FINAL=OpenSoar" >> $GITHUB_ENV + - id: checkout + uses: actions/checkout@v3 + with: + submodules: true + - id: cache-ccache + uses: hendrikmuhs/ccache-action@v1 + with: + key: ${{ env.TARGET }} + + - name: "Cache Boost" + uses: actions/cache@v3 + with: + key: ${{ env.BOOST }}-${{ hashFiles('lib/boost/patches/**') }} + path: | + ${{ github.workspace }}/output/download/${{ env.BOOST }}.tar.bz2 + ${{ github.workspace }}/output/src/stamp-${{ env.BOOST }} + ${{ github.workspace }}/output/src/${{ env.BOOST }}/boost + + - name: "Cache third-party libraries" + uses: actions/cache@v3 + with: + key: ${{ runner.os }}-libs-${{ env.TARGET }}-${{ hashFiles('build/**') }} + path: | + ${{ github.workspace }}/output/${{ env.TARGET }}/lib + !${{ github.workspace }}/output/${{ env.TARGET }}/lib/build + + - name: find githash + run: | + echo "git_hash=$(git rev-parse --short $GITHUB_SHA)" >> $GITHUB_ENV + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y --no-install-recommends \ + make \ + quilt \ + g++ \ + g++-mingw-w64 \ + python3 \ + librsvg2-bin xsltproc \ + imagemagick gettext sox \ + cmake ninja-build + + - name: Compile OpenSoar + run: | + make -j$(nproc) TARGET=${{env.TARGET }} DEBUG=${{ env.DEBUG }} USE_CCACHE=y V=2 everything + + - name: upload artifact + uses: actions/upload-artifact@v3 + with: + name: ${{ env.TARGET_FINAL }}-${{ env.git_hash }}${{ env.TARGET_EXT }} + path: output/${{ env.TARGET }}/bin/${{ env.TARGET_BIN }}${{ env.TARGET_EXT }} + + - name: store checks and compile artefacts + uses: actions/upload-artifact@v3 + with: + name: opensoar-${{ env.TARGET }}-artifact + path: | + ${{ github.workspace }}/output/${{ env.TARGET }} + !${{ github.workspace }}/output/${{ env.TARGET }}/lib/build + !**.d + retention-days: 1 + + - name: Deploy to Staging server + if: | + github.repository == 'OpenSoaring/OpenSoar' && + github.ref == 'ref/head/master' && + github.event == 'push' + uses: easingthemes/ssh-deploy@main + env: + SSH_PRIVATE_KEY: ${{ secrets.REPOSITORY_SSH_KEY }} + ARGS: "-rltgoDzvO" + SOURCE: output/${{ env.TARGET }}/bin/${{ env.TARGET_BIN }}.${{ env.TARGET_EXT }} + REMOTE_HOST: ${{ secrets.REPOSITORY_HOST }} + REMOTE_USER: ${{ secrets.REPOSITORY_SSH_USER }} + TARGET: ${{ secrets.REPOSITORY_REMOTE_PATH }}/testing/${{ env.TARGET }}/ + diff --git a/.github/workflows/codacy-analysis.yaml b/.github/workflows/codacy-analysis.yaml new file mode 100644 index 00000000000..6b7e21c6d4a --- /dev/null +++ b/.github/workflows/codacy-analysis.yaml @@ -0,0 +1,14 @@ +name: Codacy Analysis CLI + +on: ["push"] + +jobs: + codacy-analysis-cli: + name: Codacy Analysis CLI + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@main + + - name: Run Codacy Analysis CLI + uses: codacy/codacy-analysis-cli-action@master \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8e74cd2f497..7139970ffda 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,6 +18,8 @@ jobs: echo 'CHANGELOGENTRY<> $GITHUB_ENV ./tools/changelog.sh $TAG >> $GITHUB_ENV echo 'EOF' >> $GITHUB_ENV + echo $GITHUB_ENV + echo '-----------------' id: changelogentry - name: Create release id: create_release diff --git a/.gitignore b/.gitignore index 15cc71efb2d..c21af01bd46 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,5 @@ build/local-config.mk .*.swp .idea +/VERSION.txt +/src/OpenVario/_DustBin diff --git a/3rd_party/3rd_party.cmake b/3rd_party/3rd_party.cmake new file mode 100644 index 00000000000..4efb79af079 --- /dev/null +++ b/3rd_party/3rd_party.cmake @@ -0,0 +1,88 @@ +# D:\Projects\OpenSoaring\OpenSoar\3rd_party\3rd_party.cmake +# ./3rd_party/3rd_party.cmake +# ================================================================= + +set(BOOST_VERSION "1.84.0") +set(CARES_VERSION "1.24.0") # not valid! +# 25.12.23 +set(CARES_VERSION "1.17.1") # old version necessary... +set(CURL_VERSION "8.5.0") +set(PNG_VERSION "1.6.40") +set(SODIUM_VERSION "1.0.18") +set(LUA_VERSION "5.4.6") +set(FMT_VERSION "10.1.1") + +if (NO_MSVC) + set(TIFF_VERSION "4.5.1") + set(JPEG_VERSION "3.0.0") + set(PROJ_VERSION "9.3.1") + set(FREETYPE_VERSION "2.13.1") + set(OPENSSL_VERSION "3.1.2") + set(UPSTREAM_VERSION "8.0.1") + set(GCC_VERSION "13.2.0") + set(BINUTILS_VERSION "2.41") +endif() + + +set(ZLIB_VERSION "1.3") +set(INKSCAPE_VERSION "1.2.1") +set(FREEGLUT_VERSION "3.2.2") +set(SDL_VERSION "2.28.5") # for OpenGL... +set(GLM_VERSION "0.9.9.8") # GL Mathematics for OpenGL... +# set(RSVG_VERSION "2.55.1") +if (NO_MSVC) + set(XLST_VERSION "1.1.37") + set(XML2_VERSION "2.10.2") + set(ICONV_VERSION "1.17") +endif() + +# 3rd-party! +if(JASPER_OUTSIDE) + set(JASPER_VERSION "2.0.33") #"25") +else() + set(JASPER_LIB "jasper") +endif() + +# set(XCSOAR_MAPSERVER_VERSION "mapserver-0.0.1") +set(XCSOAR_MAPSERVER_VERSION "mapserver-xcsoar") +# 3rd-party! +if (ZZIP_OUTSIDE) + # set(XCSOAR_ZZIP_VERSION "zzip-0.0.1") + # set(XCSOAR_ZZIP_VERSION "zzip-0.36c") + set(XCSOAR_ZZIP_VERSION "zzip-xcsoar") +else() + set(ZZIP_LIB "zzip") +endif() + +set(XCSOAR_XMLPARSER_VERSION "xml-1.08") +set(XMLPARSER_VERSION "1.08") + +#========================= +# August2111: Why that???? +if (MSVC) # VisualStudio: + message(STATUS "+++ 3rd party System: MSVC!") + set(WITH_3RD_PARTY ON) + set(LIB_PREFIX "" ) + set(LIB_SUFFIX ".lib") +elseif(WIN32 AND (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")) + message(STATUS "+++ 3rd party System: WinClang!") + set(WITH_3RD_PARTY ON) + set(LIB_PREFIX "lib") + set(LIB_SUFFIX ".a") + + + # set(TOOLCHAIN clang14) # ??? 2022-09-08: necessary??? + set(LINK_LIBS D:/Projects/link_libs) +elseif (MINGW) # MinGW + message(STATUS "+++ 3rd party System: MINGW!") + set(WITH_3RD_PARTY ON) + set(LIB_PREFIX "lib") + set(LIB_SUFFIX ".a") +else() +# message(FATAL_ERROR "+++ unknown (3rd party-)System: ${CMAKE_SYSTEM}, Compiler = ${CMAKE_CXX_COMPILER_ID} !") + set(WITH_3RD_PARTY ON) + set(LIB_PREFIX "lib") + set(LIB_SUFFIX ".a") +endif() +#========================= + diff --git a/3rd_party/CMakeLists.txt b/3rd_party/CMakeLists.txt new file mode 100644 index 00000000000..03654b12fa8 --- /dev/null +++ b/3rd_party/CMakeLists.txt @@ -0,0 +1,167 @@ +# if (ON) + # 3rd-Party # 3rd-Party # 3rd-Party # 3rd-Party # 3rd-Party # 3rd-Party # 3rd-Party # 3rd-Party # 3rd-Party # 3rd-Party + cmake_minimum_required(VERSION 3.15) + + if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") + endif() + + if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + set(CLANG ON) + endif() + + include(3rd_party.cmake) + + # set(EP_BASE "${THIRD_PARTY}/external") # later remove 'External!' # not used up to now! + set(EP_CMAKE "${THIRD_PARTY}") ##/cmake") # later remove 'cmake!' + # set(EP_BINARIES "${BINARY_DIR}/3rd_party") # Binaries dahin verlagern? + option(USE_SYSTEM_${TARGET_CNAME} "Should we use the system ${TARGET_NAME}?" OFF) + option(EP_BUILD_ALWAYS "Build 3rd party packages always?" OFF) + option(EP_BUILD_IN_SOURCE "Build 3rd party in sources (Recommended: OFF)?" OFF) + + +# file(GLOB_RECURSE SCRIPT_FILES *.txt *.cmake *.in) +# file(GLOB_RECURSE SCRIPT_FILES *.txt *.in) + +include(CMakeSource.cmake) + +set(EXTRA_BUILD 1) + + +#macro(prepare_3rdparty target_name) # lib_name) +macro(prepare_3rdparty target_name lib_name) + string(TOUPPER ${target_name} TARGET_CNAME) + + string(LENGTH ${TARGET_CNAME} _LENGTH) + math(EXPR _LENGTH2 "15 - ${_LENGTH}") + string(REPEAT " " ${_LENGTH2} _DIFF_STRING) + set(_NEW_STRING "# ${TARGET_CNAME}${_DIFF_STRING}" ) + string(REPEAT ${_NEW_STRING} 6 _DISPLAY_STRING) + message(STATUS "${_DISPLAY_STRING}") + # message(STATUS "${_DISPLAY_STRING} (${_LENGTH} vs ${_LENGTH2})") # to check the length + + set(LIB_TARGET_NAME ${target_name}) + set(${TARGET_CNAME}_TARGET ${LIB_TARGET_NAME}_3rd) + + if(${EXTRA_BUILD}) + set(_BUILD_TARGET ${LIB_TARGET_NAME}_build) + else() + set(_BUILD_TARGET ${${TARGET_CNAME}_TARGET}) + endif() + # --------------------------------------------------------------------------- + option(USE_SYSTEM_${TARGET_CNAME} "Should we use the system ${LIB_TARGET_NAME}?" OFF) + + set(XCSOAR_${TARGET_CNAME}_VERSION "${LIB_TARGET_NAME}-${${TARGET_CNAME}_VERSION}") + set(_INSTALL_DIR "${LINK_LIBS}/${LIB_TARGET_NAME}/${XCSOAR_${TARGET_CNAME}_VERSION}") + set(${TARGET_CNAME}_INSTALL_DIR "${_INSTALL_DIR}") + # set(${TARGET_CNAME}_INSTALL_DIR "${LINK_LIBS}/${LIB_TARGET_NAME}/${XCSOAR_${TARGET_CNAME}_VERSION}") + set(${TARGET_CNAME}_PREFIX "${EP_CMAKE}/${LIB_TARGET_NAME}/${XCSOAR_${TARGET_CNAME}_VERSION}") + set(${TARGET_CNAME}_SOURCE_DIR "${${TARGET_CNAME}_PREFIX}/src/${LIB_TARGET_NAME}") + + + #------------------- + if(INCLUDE_WITH_TOOLCHAIN) + set(${TARGET_CNAME}_INCLUDE_DIR "${_INSTALL_DIR}/include/${TOOLCHAIN}") + else() + set(${TARGET_CNAME}_INCLUDE_DIR "${_INSTALL_DIR}/include") + endif() + + # set(_INSTALL_DIR "${LINK_LIBS}/${LIB_TARGET_NAME}/${XCSOAR_${TARGET_CNAME}_VERSION}") + # set(INSTALL_BIN "${_INSTALL_DIR}/bin/${TOOLCHAIN}") + # set(INSTALL_LIB "${_INSTALL_DIR}/lib/${TOOLCHAIN}") + set(_INSTALL_BIN "bin/${TOOLCHAIN}") + set(_INSTALL_LIB "lib/${TOOLCHAIN}") + + if(${EXTRA_BUILD}) + set(_BUILD_TARGET ${LIB_TARGET_NAME}_build) + else() + set(_BUILD_TARGET ${${TARGET_CNAME}_TARGET}) + # string(REPLACE "\\" "/" _BUILD_TARGET ${${TARGET_CNAME}_TARGET}) + endif() + + set(_TARGET_LIBS "${_INSTALL_DIR}/lib/${TOOLCHAIN}/${LIB_PREFIX}${lib_name}${LIB_SUFFIX}") ## D:/Project/link_libs... + string(REPLACE "\\" "/" _PREFIX_DIR ${${TARGET_CNAME}_PREFIX}) + + set(${TARGET_CNAME}_LIB ${_TARGET_LIBS}) ## for internal use +if (${lib_name} MATCHES "fmt") + set(_TARGET_LIBS "${_INSTALL_DIR}/lib/${TOOLCHAIN}/${LIB_PREFIX}${lib_name}d${LIB_SUFFIX}") ## D:/Project/link_libs... + set( + ${TARGET_CNAME}_LIB + optimized "${_INSTALL_DIR}/lib/${TOOLCHAIN}/${LIB_PREFIX}${lib_name}${LIB_SUFFIX}" + debug "${_INSTALL_DIR}/lib/${TOOLCHAIN}/${LIB_PREFIX}${lib_name}d${LIB_SUFFIX}" + PARENT_SCOPE + ) ## D:/Project/link_libs... +else() + set(${TARGET_CNAME}_LIB ${_TARGET_LIBS} PARENT_SCOPE) ## D:/Project/link_libs... +endif() + set(${TARGET_CNAME}_TARGET ${${TARGET_CNAME}_TARGET} PARENT_SCOPE) # f.e. zlib_3rd, sodium_3rd + +if (MSVC OR MINGW OR CLANG) + set( _BINARY_STEP BINARY_DIR ${${TARGET_CNAME}_PREFIX}/build/${TOOLCHAIN}) +else() + set( _BINARY_STEP ) + string(REPLACE "\\" "/" _INSTALL_DIR ${${TARGET_CNAME}_INSTALL_DIR}) +# message(FATAL_ERROR "_INSTALL_DIR = ${_INSTALL_DIR}") +endif() + + set(_INSTALL_COMMAND INSTALL_COMMAND cmake --build . --target install --config Release) + +if(EXISTS ${_TARGET_LIBS}) ## for internal use + set(_COMPLETE_INSTALL OFF) +else() + set(_COMPLETE_INSTALL ON) +endif() + +endmacro() + + +macro(post_3rdparty) + if(${EXTRA_BUILD}) + # ExternalProject_Get_Property(${_BUILD_TARGET} _INSTALL_DIR) + add_library(${${TARGET_CNAME}_TARGET} STATIC IMPORTED GLOBAL) + # set_source_files_properties(${${TARGET_CNAME}_LIB} PROPERTIES GENERATED TRUE) + # set_target_properties(${${TARGET_CNAME}_TARGET} PROPERTIES IMPORTED_LOCATION ${${TARGET_CNAME}_LIB} GENERATED TRUE) + set_target_properties(${${TARGET_CNAME}_TARGET} PROPERTIES IMPORTED_LOCATION ${_TARGET_LIBS} GENERATED TRUE) + set_target_properties(${${TARGET_CNAME}_TARGET} PROPERTIES FOLDER 3rdParty) + add_dependencies(${${TARGET_CNAME}_TARGET} ${_BUILD_TARGET}) + endif() + +if (_COMPLETE_INSTALL) + set_target_properties(${_BUILD_TARGET} PROPERTIES FOLDER 3rdParty) # either zlib_build or zlib_3rd +endif() + set(${TARGET_CNAME}_TARGET_LIBS ${_TARGET_LIBS} PARENT_SCOPE) + set(${TARGET_CNAME}_INCLUDE_DIR ${${TARGET_CNAME}_INCLUDE_DIR} PARENT_SCOPE) + list(APPEND THIRDPARTY_INCLUDES ${${TARGET_CNAME}_INCLUDE_DIR}) + + # list(APPEND 3RDPARTY_TARGETS ${LIB_TARGET_NAME}) + list(APPEND 3RDPARTY_TARGETS ${${TARGET_CNAME}_TARGET}) # zlib_3rd +endmacro() + + foreach(cmake_file ${CMAKE_FILES}) + include(${cmake_file}) + endforeach() + + #this makes the THIRDPARTY_INCLUDES visible to outside in general: + set(THIRDPARTY_INCLUDES ${THIRDPARTY_INCLUDES} PARENT_SCOPE) + + source_group("Scripts" FILES ${SCRIPT_FILES} ) + source_group("Targets" FILES ${CMAKE_FILES}) + + ## message(FATAL_ERROR "SCRIPT_FILES = ${SCRIPT_FILES}") + add_custom_target(ThirdParty + # EXCLUDE_FROM_ALL + SOURCES + ${CMAKE_FILES} + ${SCRIPT_FILES} + ) + + set(3RDPARTY_TARGETS ${3RDPARTY_TARGETS} PARENT_SCOPE) + + if (DISPLAY_TARGETS) + foreach(_target ${3RDPARTY_TARGETS} ) + message(STATUS "### 3RDPARTY_TARGETS = ${_target}") + endforeach() + # message(FATAL_ERROR "SCRIPT_FILES = ${SCRIPT_FILES}") + endif() + +set_target_properties(ThirdParty PROPERTIES FOLDER 3rdParty) diff --git a/3rd_party/CMakeSource.cmake b/3rd_party/CMakeSource.cmake new file mode 100644 index 00000000000..540b87f1084 --- /dev/null +++ b/3rd_party/CMakeSource.cmake @@ -0,0 +1,55 @@ +file(GLOB SCRIPT_FILES *.txt *.in) +list(APPEND SCRIPT_FILES CMakeSource.cmake 3rd_party.cmake) + + +set(CMAKE_FILES + boost.cmake + zlib.cmake + lua.cmake + png.cmake + cares.cmake +) + +if (${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows") + list(APPEND CMAKE_FILES curl.cmake) +else() +# TODO(August2111): only temporarily curl.cmake +endif() + +list(APPEND CMAKE_FILES sodium.cmake) +list(APPEND CMAKE_FILES fmt.cmake) + +if(0) # MapServer + list(APPEND CMAKE_FILES mapserver.cmake) +endif() +if(0) # zzip + list(APPEND CMAKE_FILES zzip.cmake) +endif() +if(0) # XML-Parser + list(APPEND CMAKE_FILES xmlparser.cmake) +endif() + +# for icon convert: +if(0) # RSVG + list(APPEND CMAKE_FILES rsvg.cmake) +endif() +if(0) # InkScape + list(APPEND CMAKE_FILES inkscape.cmake) +endif() +if(0) # RSVG + list(APPEND CMAKE_FILES iconv.cmake) + list(APPEND CMAKE_FILES xml2.cmake) + list(APPEND CMAKE_FILES xlst.cmake) +endif() + + +# For OpenGL: +if(0) # freeglut + list(APPEND CMAKE_FILES freeglut.cmake) +endif() +if(ENABLE_SDL) # SDL for OpenGL? + list(APPEND CMAKE_FILES sdl.cmake) +endif() +if(ENABLE_GLM) # GLM for OpenGL? + list(APPEND CMAKE_FILES glm.cmake) +endif() diff --git a/3rd_party/boost.cmake b/3rd_party/boost.cmake new file mode 100644 index 00000000000..34e783a5755 --- /dev/null +++ b/3rd_party/boost.cmake @@ -0,0 +1,220 @@ +set(DISPLAY_STRING "# BOOST # BOOST # BOOST # BOOST # BOOST") +message(STATUS "${DISPLAY_STRING}") +cmake_minimum_required(VERSION 3.10) + +set(INCLUDE_WITH_TOOLCHAIN 0) # special include path for every toolchain! + +set(LIB_TARGET_NAME boost) +#========================================================== +string(TOUPPER ${LIB_TARGET_NAME} TARGET_CNAME) + +# check correct link_libs_path on Flaps6 +if(NOT ${LINK_LIBS} MATCHES "link_libs") + message(STATUS "LINK_LIBS = ${LINK_LIBS}") + message(FATAL_ERROR "Stop!") +endif() + +# BOOST_VERSION is defined in 3rd_Party.cmake +set(XCSOAR_BOOST_VERSION "${LIB_TARGET_NAME}-${BOOST_VERSION}") +string(FIND ${BOOST_VERSION} "." BOOST_VERSION_LEN REVERSE ) # search for the last dot! +string(SUBSTRING ${BOOST_VERSION} 0 ${BOOST_VERSION_LEN} BOOST_SHORTVERSION) + +string(REPLACE "." "_" _BOOST_SHORTVERSION ${BOOST_SHORTVERSION}) # defined in 3rd_Party.cmake +message(STATUS "### BOOST_VERSION = ${BOOST_VERSION} ||| short(1): ${BOOST_SHORTVERSION} ||| short(2): ${_BOOST_SHORTVERSION} ") +# message(FATAL_ERROR "Stop!") + +set(BOOST_ROOT "${LINK_LIBS}/boost/boost-${BOOST_VERSION}") + +#======================================= +# TOOLCHAIN is defined from CMAKE caller +if(${TOOLCHAIN} MATCHES "msvc") + set(_TOOLSET msvc) + if(${TOOLCHAIN} MATCHES "msvc2022") + set(Boost_COMPILER "-vc143") # msvc2022 + elseif(${TOOLCHAIN} MATCHES "msvc2019") + set(Boost_COMPILER "-vc142") # msvc2019 + else() + endif() +elseif((${TOOLCHAIN} MATCHES "mgw") OR (${TOOLCHAIN} MATCHES "unix")) + set(_TOOLSET gcc) + if(${TOOLCHAIN} MATCHES "mgw122") + set(Boost_COMPILER "-mgw12") + elseif(${TOOLCHAIN} MATCHES "mgw112") + set(Boost_COMPILER "-mgw11") + elseif(${TOOLCHAIN} MATCHES "mgw103") + set(Boost_COMPILER "-mgw10") + else() + set(Boost_COMPILER "-gcc11") # TODO(August2111): meke this real! + endif() +elseif(${TOOLCHAIN} MATCHES "clang") + set(_TOOLSET clang) + set(Boost_COMPILER "-clang") +else() + message(FATAL_ERROR "+++ Unknown ToolChain: '${TOOLCHAIN}'!") +endif() +message(STATUS "Boost_COMPILER = ${Boost_COMPILER}") +#======================================= + + +set(Boost_USE_STATIC_LIBS ON) +set(Boost_USE_MULTITHREADED ON) +set(Boost_USE_STATIC_RUNTIME OFF) +set(Boost_USE_RELEASE_LIBS ON) +set(Boost_RELEASE_ABI_TAG "") +set(Boost_USE_DEBUG_LIBS OFF) +set(Boost_DEBUG OFF) # Debugging more info in the find_package-process! +set(BOOST_LIBRARYDIR "${BOOST_ROOT}/lib/${TOOLCHAIN}") +# set(BOOST_COMPONENTS system regex filesystem thread chrono date_time) # headers) +set(BOOST_COMPONENTS system regex filesystem chrono date_time) # headers) +# thread make a lot of problems (2023-12-28): list(APPEND BOOST_COMPONENTS thread) +if(NOT ${TOOLCHAIN} MATCHES "mgw122") + list(APPEND BOOST_COMPONENTS json) # headers) +endif() + +set(Boost_INCLUDE_DIR "${BOOST_ROOT}/include/boost-${_BOOST_SHORTVERSION}") + +if (BOOST_COMPONENTS) +### 2022-09-01 ??? find_package(Boost ${BOOST_VERSION} COMPONENTS ${BOOST_COMPONENTS}) +else() + find_package(Boost ${BOOST_SHORTVERSION}) # REQUIRED) +endif() + +if(Boost_FOUND) + message(Status "+++ Boost found! ${Boost_INCLUDE_DIR}") +else() + message(STATUS "Boost NOT found!") + # message(FATAL_ERROR "Stop: Boost missing!") +endif() + +set(Boost_DIR "${BOOST_ROOT}/lib/${Boost_COMPILER}/cmake/Boost-${BOOST_VERSION}") +## 2022-09-02: set(Boost_INCLUDE_DIR "${BOOST_ROOT}/include/boost-${_BOOST_SHORTVERSION}") + +if(EXISTS "${Boost_INCLUDE_DIR}/boost/version.hpp") + set(BOOST_IS_READY ON) +else() + # message(FATAL_ERROR "!!! Boost: include directories not found! (BOOST_ROOT = ${BOOST_ROOT})") + set(BOOST_IS_READY OFF) +endif() + +# --------------------------------------------------------------------------- +option(USE_SYSTEM_BOOST "Should we use the system ${LIB_TARGET_NAME}?" OFF) + +set(BOOST_BUILD_COMPONENTS) +set(BOOST_BUILD_TEST) +foreach(component ${BOOST_COMPONENTS} headers) + list(APPEND BOOST_BUILD_COMPONENTS --with-${component}) + string(APPEND BOOST_BUILD_TEST "--with-${component} ") +# list(APPEND BOOST_BUILD_COMPONENTS ${} +endforeach() +message(STATUS "XXX ${BOOST_BUILD_COMPONENTS}") +message(STATUS "XXX ${BOOST_BUILD_TEST}") + +## see above: set(${TARGET_CNAME}_VERSION "1.77.0") +set(BOOST_INSTALL_DIR "${LINK_LIBS}/${LIB_TARGET_NAME}/${XCSOAR_BOOST_VERSION}") +set(BOOST_PREFIX "${EP_CMAKE}/${LIB_TARGET_NAME}/${XCSOAR_BOOST_VERSION}") +# set(BOOST_BUILD_DIR "${EP_CMAKE}/${LIB_TARGET_NAME}/${XCSOAR_BOOST_VERSION}/build") + +set(_SRC_DIR ${EP_CMAKE}/${LIB_TARGET_NAME}/${XCSOAR_BOOST_VERSION}/src/${LIB_TARGET_NAME}) # = src_dir +if(EXISTS ${_SRC_DIR}) + message(STATUS "_SRC_DIR = ${_SRC_DIR}") +else() + message(STATUS "_SRC_DIR = '${_SRC_DIR}' doesn't exist!") +### message(FATAL_ERROR "Stop!") +endif() + + +if (CLANG) + set(BOOST_CXX_FLAGS "cxxflags=-fms-runtime-lib=\"static\"" ) + set(BOOST_LINK_FLAGS "linkflags=-fms-runtime-lib=\"static\"") +elseif() + set(BOOST_CXX_FLAGS ) + set(BOOST_LINK_FLAGS ) +endif() +# variant=release +set(_BUILD_CMD ./b2 -j4 toolset=${_TOOLSET} link=static runtime-link=shared threading=multi address-model=64 --layout=versioned ${BOOST_CXX_FLAGS} ${BOOST_LINK_FLAGS} --prefix=${BOOST_INSTALL_DIR} --build-dir=${BOOST_PREFIX}/build/${TOOLCHAIN} ${BOOST_BUILD_COMPONENTS} --includedir=${BOOST_INSTALL_DIR}/include --libdir=${BOOST_INSTALL_DIR}/lib/${TOOLCHAIN} install) + +set(_INSTALL_DIR "${LINK_LIBS}/${LIB_TARGET_NAME}/${XCSOAR_BOOST_VERSION}") + +if (${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows") + string(REPLACE "/" "\\" _SRC_DIR ${_SRC_DIR}) + set(_CONFIGURE_CMD if not exist b2.exe call bootstrap.bat) +elseif (${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Linux") + set(_CONFIGURE_CMD [[ -f "${_SRC_DIR}/b2" ]] && echo "b2 exists." || ./bootstrap.sh) +endif() + + +if (ON) +# if (MSVC) # in this moment not for MinGW enabled!! +#=========================================== +#------------------- +# if(NOT EXISTS "${_INSTALL_DIR}") + +# if(OFF) + +# if(NOT Boost_FOUND) +if(${WITH_3RD_PARTY}) # ON) + +message(STATUS "### ${EP_CMAKE}/${LIB_TARGET_NAME}/${XCSOAR_BOOST_VERSION}/src/${LIB_TARGET_NAME}") +message(STATUS "### Build-Command: ${_BUILD_CMD}") + +#------------------- +ExternalProject_Add( + ${LIB_TARGET_NAME} + GIT_REPOSITORY "https://github.com/boostorg/boost.git" + GIT_TAG "${XCSOAR_BOOST_VERSION}" + + PREFIX "${BOOST_PREFIX}" + INSTALL_DIR "${_INSTALL_DIR}" + # BINARY_DIR "${BOOST_PREFIX}/build/${TOOLCHAIN}" + BINARY_DIR "${_SRC_DIR}" + + # PATCH_COMMAND "bootstrap" + CONFIGURE_COMMAND "${_CONFIGURE_CMD}" + # 29.08.2022 herausgenommen: +# CONFIGURE_COMMAND bootstrap ## "${EP_CMAKE}/${LIB_TARGET_NAME}/${XCSOAR_BOOST_VERSION}/src/${LIB_TARGET_NAME}/TestOutput.cmd" + + BUILD_COMMAND ${_BUILD_CMD} + INSTALL_COMMAND echo Install done + BUILD_ALWAYS OFF + CONFIGURE_HANDLED_BY_BUILD ON + # BUILD_IN_SOURCE # ${EP_BUILD_IN_SOURCE} + WORKING_DIRECTORY ${_SRC_DIR} + BUILD_BYPRODUCTS ${${TARGET_CNAME}_LIB} + EXCLUDE_FROM_ALL ON + EXCLUDE_FROM_DEFAULT_BUILD ON + UPDATE_COMMAND "" +) +#=========================================== +set_target_properties(${LIB_TARGET_NAME} PROPERTIES FOLDER 3rdParty) # ExternalProjectTargets) + +endif() # if not exist + +endif() # MSVC +## 2022-09-02: set(BOOST_LIB "${_INSTALL_DIR}/lib/${TOOLCHAIN}/${LIB_PREFIX}${LIB_TARGET_NAME}${LIB_SUFFIX}") +## 2022-09-02: set(BOOST_INCLUDE_DIR "${_INSTALL_DIR}/include") # 29.06.2022: das ist falsch! +## 2022-09-02: set(BOOST_INCLUDE_DIR ${Boost_INCLUDE_DIR}) # 29.06.2022: ...und das richtig? +# PARENT_SCOPE only available in Parent, not here... +if(EXISTS "${BOOST_LIB}") + set(BOOST_LIB ${BOOST_LIB} PARENT_SCOPE) +else() + set(BOOST_LIB ${LIB_TARGET_NAME} PARENT_SCOPE) +endif() +## 2022-09-02: set(BOOST_INCLUDE_DIR ${BOOST_INCLUDE_DIR} PARENT_SCOPE) +set(Boost_INCLUDE_DIR ${Boost_INCLUDE_DIR} PARENT_SCOPE) # 29.06.2022: ...und das richtig? + +# set(THIRDPARTY_INCLUDES ${THIRDPARTY_INCLUDES} ${Boost_INCLUDE_DIR} PARENT_SCOPE) +list(APPEND THIRDPARTY_INCLUDES ${Boost_INCLUDE_DIR}) +set(BOOST_ROOT ${BOOST_ROOT} PARENT_SCOPE) + +# link_directories(${BOOST_ROOT}/lib/${TOOLCHAIN} PARENT_SCOPE) # aug: not affected in main project.. + +if (MSVC OR MINGW OR CLANG) # in this moment not for MinGW enabled!! + message(STATUS "Boost: BOOST_ROOT = ${BOOST_ROOT} /// Boost_DIR = ${Boost_DIR}") +elseif(UNIX) + set(Boost_DIR "$ENV{HOME}/Projects/link_libs/boost/boost-${BOOST_VERSION}/lib/unix/cmake/Boost-${BOOST_VERSION}") +else() + message(FATAL_ERROR "BOOST-Stop: ${BOOST_ROOT} /// ${Boost_DIR} ") +endif() + +set(BOOST_TARGET ${LIB_TARGET_NAME} PARENT_SCOPE) +list(APPEND 3RDPARTY_TARGETS ${LIB_TARGET_NAME}) # boost diff --git a/3rd_party/cares.cmake b/3rd_party/cares.cmake new file mode 100644 index 00000000000..f58d3170663 --- /dev/null +++ b/3rd_party/cares.cmake @@ -0,0 +1,43 @@ +cmake_minimum_required(VERSION 3.15) + +set(INCLUDE_WITH_TOOLCHAIN 1) # special include path for every toolchain! +prepare_3rdparty(cares cares) + +if (_COMPLETE_INSTALL) + set( CMAKE_ARGS + "-DCMAKE_INSTALL_PREFIX=${_INSTALL_DIR}" + "-DCMAKE_INSTALL_BINDIR=${_INSTALL_BIN}" + "-DCMAKE_INSTALL_LIBDIR=${_INSTALL_LIB}" + # "-DCMAKE_INSTALL_COMPONENT=bin/${TOOLCHAIN}" + "-DCMAKE_INSTALL_INCLUDEDIR=include/${TOOLCHAIN}" + "-DCMAKE_BUILD_TYPE=Release" + "-DCARES_SHARED=OFF" + "-DCARES_STATIC=ON" + "-DCARES_STATIC_PIC=ON" + "-DCARES_BUILD_TESTS=OFF" ) + + string(REPLACE "." "_" GIT_TAG cares-${${TARGET_CNAME}_VERSION}) # after 1.17.1 only 'cares', before c-ares! + + ExternalProject_Add( + ${_BUILD_TARGET} + GIT_REPOSITORY "https://github.com/c-ares/c-ares.git" + GIT_TAG ${GIT_TAG} # cares-1_1_17 -> for this use string(REPLACE...) + PREFIX "${${TARGET_CNAME}_PREFIX}" + ${_BINARY_STEP} + INSTALL_DIR "${_INSTALL_DIR}" # ${LINK_LIBS}/${LIB_TARGET_NAME}/${XCSOAR_${TARGET_CNAME}_VERSION}" + # PATCH_COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/CURL_CMakeLists.txt.in" /CMakeLists.txt + CMAKE_ARGS ${CMAKE_ARGS} + # INSTALL_COMMAND cmake --build . --target install --config Release + ${_INSTALL_COMMAND} + BUILD_ALWAYS ${EP_BUILD_ALWAYS} + BUILD_IN_SOURCE ${EP_BUILD_IN_SOURCE} + DEPENDS ${ZLIB_TARGET} # !!!! + BUILD_BYPRODUCTS ${_TARGET_LIBS} # ${${TARGET_CNAME}_LIB} + ) +endif() + +post_3rdparty() + +if (_COMPLETE_INSTALL) + add_dependencies(${_BUILD_TARGET} ${ZLIB_TARGET}) +endif() diff --git a/3rd_party/curl.cmake b/3rd_party/curl.cmake new file mode 100644 index 00000000000..caaa70cc230 --- /dev/null +++ b/3rd_party/curl.cmake @@ -0,0 +1,85 @@ +cmake_minimum_required(VERSION 3.15) + +set(INCLUDE_WITH_TOOLCHAIN 0) # special include path for every toolchain! + +prepare_3rdparty(curl curl) +if (_COMPLETE_INSTALL) + + set(CMAKE_ARGS + # "-DCMAKE_INSTALL_PREFIX=" + "-DCMAKE_INSTALL_PREFIX=${_INSTALL_DIR}" + "-DCMAKE_INSTALL_BINDIR=${_INSTALL_BIN}" + "-DCMAKE_INSTALL_LIBDIR=${_INSTALL_LIB}" + # "-DCMAKE_INSTALL_COMPONENT=bin/${TOOLCHAIN}" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + "-DCMAKE_BUILD_TYPE=Release" + + "-DBUILD_CURL_EXE=OFF" + "-DBUILD_SHARED_LIBS=OFF" + "-DENABLE_ARES=ON" + "-DCURL_DISABLE_LDAP=ON" + "-DCURL_DISABLE_TELNET=ON" + "-DCURL_DISABLE_DICT=ON" + "-DCURL_DISABLE_FILE=ON" + "-DCURL_DISABLE_TFTP=ON" + "-DCURL_DISABLE_LDAPS=ON" + "-DCURL_DISABLE_RTSP=ON" + "-DCURL_DISABLE_PROXY=ON" + "-DCURL_DISABLE_POP3=ON" + "-DCURL_DISABLE_IMAP=ON" + "-DCURL_DISABLE_SMTP=ON" + "-DCURL_DISABLE_GOPHER=ON" + "-DCURL_DISABLE_COOKIES=ON" + "-DCURL_DISABLE_CRYPTO_AUTH=ON" + "-DCURL_DISABLE_IMAP=ON" + "-DCMAKE_USE_LIBSSH2=OFF" + "-DBUILD_TESTING=OFF" + "-DPERL_EXECUTABLE=${PERL_APP}" #### "D:/Programs/Perl64/bin/perl.exe" # Windows only!! + + "-DZLIB_INCLUDE_DIR=${ZLIB_INCLUDE_DIR}" + "-DZLIB_LIBRARY=${ZLIB_LIB}" + # "-DZLIB_LIBRARY_DEBUG=${ZLIB_LIB}" + # "-DZLIB_LIBRARY_RELEASE=${ZLIB_LIB}" + "-DCARES_LIBRARY=${CARES_LIB}" + # "-DCARES_LIBRARY_RELEASE=${CARES_LIB}" + # "-DCARES_LIBRARY_DEBUG=${CARES_LIB}" + "-DCARES_INCLUDE_DIR=${CARES_INCLUDE_DIR}" + + "-DHAVE_IOCTLSOCKET_FIONBIO=1" + + "-DLIBCURL_OUTPUT_NAME=${LIB_PREFIX}curl" + ) + + if(WIN32) + list(APPEND CMAKE_ARGS # Windows Only + "-DCURL_USE_SCHANNEL=ON" + ) + else() + list(APPEND CMAKE_ARGS # for Linux/Android,...? + "-DLIB_EAY_DEBUG=${_CRYPTO_LIB}" + "-DLIB_EAY_RELEASE=${_CRYPTO_LIB}" + "-DOPENSSL_INCLUDE_DIR=${_SSL_DIR}" + ) + endif() + string(REPLACE "." "_" GIT_TAG ${XCSOAR_${TARGET_CNAME}_VERSION}) + ExternalProject_Add( + ${_BUILD_TARGET} + GIT_REPOSITORY "https://github.com/curl/curl.git" + GIT_TAG ${GIT_TAG} + PREFIX "${CURL_PREFIX}" + ${_BINARY_STEP} + # BINARY_DIR "${${TARGET_CNAME}_PREFIX}/build/${TOOLCHAIN}" + INSTALL_DIR "${_INSTALL_DIR}" # ${LINK_LIBS}/${LIB_TARGET_NAME}/${XCSOAR_${TARGET_CNAME}_VERSION}" + CMAKE_ARGS ${CMAKE_ARGS} + # PATCH_COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/CURL_CMakeLists.txt.in" /CMakeLists.txt + # INSTALL_COMMAND cmake --build . --target install --config Release + ${_INSTALL_COMMAND} + BUILD_ALWAYS ${EP_BUILD_ALWAYS} + # BUILD_IN_SOURCE ${EP_BUILD_IN_SOURCE} + DEPENDS ${ZLIB_TARGET} ${CARES_TARGET} + BUILD_BYPRODUCTS ${_TARGET_LIBS} # ${${TARGET_CNAME}_LIB} + ) + +endif() + +post_3rdparty() diff --git a/3rd_party/fmt.cmake b/3rd_party/fmt.cmake new file mode 100644 index 00000000000..eaee627b21a --- /dev/null +++ b/3rd_party/fmt.cmake @@ -0,0 +1,55 @@ +cmake_minimum_required(VERSION 3.15) +# get_filename_component(LIB_TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) +set(INCLUDE_WITH_TOOLCHAIN 0) # special include path for every toolchain! +# set(_LIB_NAME libfmt) # "liblibfmt.a" +### debug fmtd optimized fmt +set(_LIB_NAME fmt) # "liblibfmt.a" +## set(_LIB_NAME fmtd) # "liblibfmt.a" +Prepare_3rdParty(fmt ${_LIB_NAME}) + + +string(REPLACE "\\" "/" _INSTALL_DIR ${FMT_INSTALL_DIR}) +string(REPLACE "\\" "/" _SOURCE_DIR ${FMT_PREFIX}/src/${LIB_TARGET_NAME}) + +if (WIN32 AND MSVC) + set(BUILD_COMMAND devenv ${_SOURCE_DIR}/libfmt.sln /Build Release|x64) + set(CONFIGURE_COMMAND echo ${BUILD_COMMAND}) + # set(INSTALL_COMMAND xcopy ${_SOURCE_DIR}\\Build\\Release\\x64\\*.lib ${_INSTALL_DIR}\\lib\\${TOOLCHAIN}\\* /Y /T) + set(INSTALL_COMMAND xcopy ${_SOURCE_DIR}/src/libfmt/include/*.h ${_INSTALL_DIR}/include/* /Y /I /S /E) +elseif (WIN32 AND MINGW AND NOT CLANG) + find_program(MAKE_EXECUTABLE NAMES gmake make mingw32-make REQUIRED) +endif() + +if (_COMPLETE_INSTALL) + set(CMAKE_ARGS + "-DCMAKE_INSTALL_PREFIX=${_INSTALL_DIR}" + "-DCMAKE_INSTALL_BINDIR=${_INSTALL_BIN}" + "-DCMAKE_INSTALL_LIBDIR=${_INSTALL_LIB}" + # "-DCMAKE_INSTALL_COMPONENT=bin/${TOOLCHAIN}" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + "-DCMAKE_BUILD_TYPE=Release" + ) + + # message(FATAL_ERROR "+++ BINARY_STEP (${TARGET_CNAME}): ${_BINARY_STEP}") + + ExternalProject_Add( + ${_BUILD_TARGET} + + GIT_REPOSITORY "https://github.com/fmtlib/fmt.git" + GIT_TAG ${FMT_VERSION} + + PREFIX "${${TARGET_CNAME}_PREFIX}" + ${_BINARY_STEP} + INSTALL_DIR "${_INSTALL_DIR}" # ${LINK_LIBS}/${LIB_TARGET_NAME}/${XCSOAR_${TARGET_CNAME}_VERSION}" + + # PATCH_COMMAND ${CMAKE_COMMAND} -E copy_if_different "${PROJECTGROUP_SOURCE_DIR}/3rd_party/fmt_CMakeLists.txt.in" /CMakeLists.txt + CMAKE_ARGS ${CMAKE_ARGS} + # INSTALL_COMMAND cmake --build . --target install --config Release + ${_INSTALL_COMMAND} + BUILD_ALWAYS ${EP_BUILD_ALWAYS} + # BUILD_IN_SOURCE ${EP_BUILD_IN_SOURCE} + BUILD_BYPRODUCTS ${_TARGET_LIBS} # ${${TARGET_CNAME}_LIB} + ) +endif() + +post_3rdparty() diff --git a/3rd_party/freeglut.cmake b/3rd_party/freeglut.cmake new file mode 100644 index 00000000000..6cd9546382e --- /dev/null +++ b/3rd_party/freeglut.cmake @@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 3.15) + +set(INCLUDE_WITH_TOOLCHAIN 0) # special include path for every toolchain! + +prepare_3rdparty(freeglut freeglut) +set(CMAKE_ARGS + "-DCMAKE_INSTALL_PREFIX=${_INSTALL_DIR}" + "-DCMAKE_INSTALL_BINDIR=${_INSTALL_BIN}" + "-DCMAKE_INSTALL_LIBDIR=${_INSTALL_LIB}" + # "-DCMAKE_INSTALL_COMPONENT=bin/${TOOLCHAIN}" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + "-DCMAKE_BUILD_TYPE=Release" +) + +ExternalProject_Add( + ${_BUILD_TARGET} + GIT_REPOSITORY "https://github.com/FreeGLUTProject/freeglut.git" + GIT_TAG v${FREEGLUT_VERSION} + + PREFIX "${${TARGET_CNAME}_PREFIX}" + ${_BINARY_STEP} + INSTALL_DIR "${_INSTALL_DIR}" # ${LINK_LIBS}/${LIB_TARGET_NAME}/${XCSOAR_${TARGET_CNAME}_VERSION}" + + # PATCH_COMMAND ${CMAKE_COMMAND} -E copy_if_different "${PROJECTGROUP_SOURCE_DIR}/3rd_party/${LIB_TARGET_NAME}_CMakeLists.txt.in" /CMakeLists.txt + CMAKE_ARGS ${CMAKE_ARGS} + # INSTALL_COMMAND cmake --build . --target install --config Release + ${_INSTALL_COMMAND} + BUILD_ALWAYS ${EP_BUILD_ALWAYS} + # BUILD_IN_SOURCE ${EP_BUILD_IN_SOURCE} + BUILD_BYPRODUCTS ${_TARGET_LIBS} # ${${TARGET_CNAME}_LIB} +) + +post_3rdparty() diff --git a/3rd_party/glm.cmake b/3rd_party/glm.cmake new file mode 100644 index 00000000000..c741b14c315 --- /dev/null +++ b/3rd_party/glm.cmake @@ -0,0 +1,36 @@ +cmake_minimum_required(VERSION 3.15) + +set(INCLUDE_WITH_TOOLCHAIN 0) # special include path for every toolchain! + +prepare_3rdparty(glm glm_static) +if (_COMPLETE_INSTALL) + set(CMAKE_ARGS + "-DCMAKE_INSTALL_PREFIX=${_INSTALL_DIR}" + "-DCMAKE_INSTALL_BINDIR=${_INSTALL_BIN}" + "-DCMAKE_INSTALL_LIBDIR=${_INSTALL_LIB}" + # "-DCMAKE_INSTALL_COMPONENT=bin/${TOOLCHAIN}" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + "-DCMAKE_BUILD_TYPE=Release" + "-DGLM_TEST_ENABLE=OFF" + ) + + ExternalProject_Add( + ${_BUILD_TARGET} + GIT_REPOSITORY "https://github.com/g-truc/glm" + GIT_TAG ${GLM_VERSION} + + PREFIX "${${TARGET_CNAME}_PREFIX}" + ${_BINARY_STEP} + INSTALL_DIR "${_INSTALL_DIR}" # ${LINK_LIBS}/${LIB_TARGET_NAME}/${XCSOAR_${TARGET_CNAME}_VERSION}" + + # PATCH_COMMAND ${CMAKE_COMMAND} -E copy_if_different "${PROJECTGROUP_SOURCE_DIR}/3rd_party/${LIB_TARGET_NAME}_CMakeLists.txt.in" /CMakeLists.txt + CMAKE_ARGS ${CMAKE_ARGS} + # INSTALL_COMMAND cmake --build . --target install --config Release + ${_INSTALL_COMMAND} + BUILD_ALWAYS ${EP_BUILD_ALWAYS} + BUILD_IN_SOURCE ${EP_BUILD_IN_SOURCE} + BUILD_BYPRODUCTS ${_TARGET_LIBS} # ${${TARGET_CNAME}_LIB} + ) +endif() + +post_3rdparty() diff --git a/3rd_party/iconv.cmake b/3rd_party/iconv.cmake new file mode 100644 index 00000000000..31b87e436e3 --- /dev/null +++ b/3rd_party/iconv.cmake @@ -0,0 +1,34 @@ +cmake_minimum_required(VERSION 3.15) + +set(INCLUDE_WITH_TOOLCHAIN 0) # special include path for every toolchain! + +prepare_3rdparty(iconv iconv) +set(CMAKE_ARGS + "-DCMAKE_INSTALL_PREFIX=${_INSTALL_DIR}" + "-DCMAKE_INSTALL_BINDIR=${_INSTALL_BIN}" + "-DCMAKE_INSTALL_LIBDIR=${_INSTALL_LIB}" + # "-DCMAKE_INSTALL_COMPONENT=bin/${TOOLCHAIN}" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + "-DCMAKE_BUILD_TYPE=Release" +) + +ExternalProject_Add( + ${_BUILD_TARGET} + # GIT_REPOSITORY "https://github.com/xbmc/libiconv" + GIT_REPOSITORY "git://git.savannah.gnu.org/libiconv.git" + GIT_TAG v${ICONV_VERSION} + + PREFIX "${${TARGET_CNAME}_PREFIX}" + ${_BINARY_STEP} + INSTALL_DIR "${_INSTALL_DIR}" # ${LINK_LIBS}/${LIB_TARGET_NAME}/${XCSOAR_${TARGET_CNAME}_VERSION}" + + # PATCH_COMMAND ${CMAKE_COMMAND} -E copy_if_different "${PROJECTGROUP_SOURCE_DIR}/3rd_party/${LIB_TARGET_NAME}_CMakeLists.txt.in" /CMakeLists.txt + CMAKE_ARGS ${CMAKE_ARGS} + # INSTALL_COMMAND cmake --build . --target install --config Release + ${_INSTALL_COMMAND} + BUILD_ALWAYS ${EP_BUILD_ALWAYS} + BUILD_IN_SOURCE ${EP_BUILD_IN_SOURCE} + BUILD_BYPRODUCTS ${_TARGET_LIBS} # ${${TARGET_CNAME}_LIB} +) + +post_3rdparty() diff --git a/3rd_party/inkscape.cmake b/3rd_party/inkscape.cmake new file mode 100644 index 00000000000..02c5a0eb1b9 --- /dev/null +++ b/3rd_party/inkscape.cmake @@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 3.15) + +set(INCLUDE_WITH_TOOLCHAIN 0) # special include path for every toolchain! + +prepare_3rdparty(inkscape inkscape) +set(CMAKE_ARGS + "-DCMAKE_INSTALL_PREFIX=${_INSTALL_DIR}" + "-DCMAKE_INSTALL_BINDIR=${_INSTALL_BIN}" + "-DCMAKE_INSTALL_LIBDIR=${_INSTALL_LIB}" + # "-DCMAKE_INSTALL_COMPONENT=bin/${TOOLCHAIN}" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + "-DCMAKE_BUILD_TYPE=Release" +) + +ExternalProject_Add( + ${_BUILD_TARGET} + GIT_REPOSITORY "https://gitlab.com/inkscape/inkscape.git" + # GIT_TAG v${INKSCAPE_VERSION} + GIT_TAG INKSCAPE_1_2_1 + + PREFIX "${${TARGET_CNAME}_PREFIX}" + ${_BINARY_STEP} + INSTALL_DIR "${_INSTALL_DIR}" + + # PATCH_COMMAND ${CMAKE_COMMAND} -E copy_if_different "${PROJECTGROUP_SOURCE_DIR}/3rd_party/${LIB_TARGET_NAME}_CMakeLists.txt.in" /CMakeLists.txt + CMAKE_ARGS ${CMAKE_ARGS} + ${_INSTALL_COMMAND} + BUILD_ALWAYS ${EP_BUILD_ALWAYS} + BUILD_IN_SOURCE ${EP_BUILD_IN_SOURCE} + BUILD_BYPRODUCTS ${_TARGET_LIBS} # ${${TARGET_CNAME}_LIB} +) + +post_3rdparty() diff --git a/3rd_party/jasper.cmake b/3rd_party/jasper.cmake new file mode 100644 index 00000000000..342a8ae228a --- /dev/null +++ b/3rd_party/jasper.cmake @@ -0,0 +1,72 @@ +if (JASPER_OUTSIDE) + # noch ohne jasper-package (jasper inside) +set(DISPLAY_STRING "# JASPER # JASPER # JASPER # JASPER # JASPER") +message(STATUS "${DISPLAY_STRING}") +cmake_minimum_required(VERSION 3.15) + +set(LIB_TARGET_NAME jasper) +#============================================================ + + +string(TOUPPER ${LIB_TARGET_NAME} TARGET_CNAME) +# --------------------------------------------------------------------------- +option(USE_SYSTEM_${TARGET_CNAME} "Should we use the system ${LIB_TARGET_NAME}?" OFF) + +set(_VERSION "${${TARGET_CNAME}_VERSION}") +set(XCSOAR_${TARGET_CNAME}_VERSION "${LIB_TARGET_NAME}-${_VERSION}") +set(${TARGET_CNAME}_INSTALL_DIR "${LINK_LIBS}/${LIB_TARGET_NAME}/${XCSOAR_${TARGET_CNAME}_VERSION}") +set(${TARGET_CNAME}_PREFIX "${EP_CMAKE}/${LIB_TARGET_NAME}/${XCSOAR_${TARGET_CNAME}_VERSION}") +#------------------- +set(INSTALL_DIR "${LINK_LIBS}/${LIB_TARGET_NAME}/${XCSOAR_${TARGET_CNAME}_VERSION}") +#------------------- +### if(NOT EXISTS "${INSTALL_DIR}") +# if(On) +if(${WITH_3RD_PARTY}) + +if (MSVC OR MINGW) + set( BINARY_STEP BINARY_DIR "${${TARGET_CNAME}_PREFIX}/build/${TOOLCHAIN}") +else() + set(BINARY_STEP ) +endif() + ExternalProject_Add( + ${LIB_TARGET_NAME}_3rd + # URL "file://${THIRD_PARTY}/_Download/${XCSOAR_JASPER_VERSION}.tar.gz" + GIT_REPOSITORY "https://github.com/mdadams/jasper.git" + GIT_TAG "version-${${TARGET_CNAME}_VERSION}" # git tag by jasper! + + PREFIX "${${TARGET_CNAME}_PREFIX}" + ${BINARY_STEP} + # BINARY_DIR "${${TARGET_CNAME}_PREFIX}/build/${TOOLCHAIN}" + INSTALL_DIR "${INSTALL_DIR}" # "${LINK_LIBS}/${LIB_TARGET_NAME}/${XCSOAR_${TARGET_CNAME}_VERSION}" + + CMAKE_ARGS "-DCMAKE_INSTALL_PREFIX=" + "-DCMAKE_INSTALL_BINDIR=bin/${TOOLCHAIN}" # :PATH=/bin/${TOOLCHAIN}" + "-DCMAKE_INSTALL_LIBDIR=lib/${TOOLCHAIN}" # :PATH=/lib/${TOOLCHAIN}" + # "-DCMAKE_INSTALL_COMPONENT=bin/${TOOLCHAIN}" # :PATH=/lib/${TOOLCHAIN}" + + "-DJAS_ENABLE_PROGRAMS=OFF" + "-DJAS_ENABLE_SHARED=OFF" + "-DJAS_ENABLE_OPENGL=OFF" + BUILD_ALWAYS ${EP_BUILD_ALWAYS} + # BUILD_IN_SOURCE ${EP_BUILD_IN_SOURCE} + ) +endif() + +set(LIB_NAME ${LIB_PREFIX}${LIB_TARGET_NAME}) +# set(LIB_NAME lib${LIB_TARGET_NAME}) + +# TODO(aug): move this to a macro!!! +set(${TARGET_CNAME}_LIB "${INSTALL_DIR}/lib/${TOOLCHAIN}/${LIB_NAME}${LIB_SUFFIX}") +set(${TARGET_CNAME}_INCLUDE_DIR "${INSTALL_DIR}/include") +# PARENT_SCOPE only available in Parent, not here... +if(EXISTS "${${TARGET_CNAME}_LIB}") + set(${TARGET_CNAME}_LIB ${${TARGET_CNAME}_LIB} PARENT_SCOPE) +else() + set(${TARGET_CNAME}_LIB ${LIB_TARGET_NAME} PARENT_SCOPE) +endif() +set(${TARGET_CNAME}_INCLUDE_DIR ${${TARGET_CNAME}_INCLUDE_DIR} PARENT_SCOPE) + +list(APPEND THIRDPARTY_INCLUDES ${${TARGET_CNAME}_INCLUDE_DIR}) +else(JASPER_OUTSIDE) + set(JASPER_LIB "jasper" PARENT_SCOPE) +endif(JASPER_OUTSIDE) \ No newline at end of file diff --git a/3rd_party/lua.cmake b/3rd_party/lua.cmake new file mode 100644 index 00000000000..86dbae3eaf3 --- /dev/null +++ b/3rd_party/lua.cmake @@ -0,0 +1,34 @@ +cmake_minimum_required(VERSION 3.15) + +set(INCLUDE_WITH_TOOLCHAIN 0) # special include path for every toolchain! + +prepare_3rdparty(lua lua) +if (_COMPLETE_INSTALL) + set(CMAKE_ARGS + "-DCMAKE_INSTALL_PREFIX=${_INSTALL_DIR}" + "-DCMAKE_INSTALL_BINDIR=${_INSTALL_BIN}" + "-DCMAKE_INSTALL_LIBDIR=${_INSTALL_LIB}" + # "-DCMAKE_INSTALL_COMPONENT=bin/${TOOLCHAIN}" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + "-DCMAKE_BUILD_TYPE=Release" + ) + + ExternalProject_Add( + ${_BUILD_TARGET} + GIT_REPOSITORY "https://github.com/lua/lua.git" + GIT_TAG v${LUA_VERSION} + + PREFIX "${${TARGET_CNAME}_PREFIX}" + ${_BINARY_STEP} + INSTALL_DIR "${_INSTALL_DIR}" # ${LINK_LIBS}/${LIB_TARGET_NAME}/${XCSOAR_${TARGET_CNAME}_VERSION}" + + PATCH_COMMAND ${CMAKE_COMMAND} -E copy_if_different "${PROJECTGROUP_SOURCE_DIR}/3rd_party/${LIB_TARGET_NAME}_CMakeLists.txt.in" /CMakeLists.txt + CMAKE_ARGS ${CMAKE_ARGS} + # INSTALL_COMMAND cmake --build . --target install --config Release + ${_INSTALL_COMMAND} + BUILD_ALWAYS ${EP_BUILD_ALWAYS} + # BUILD_IN_SOURCE ${EP_BUILD_IN_SOURCE} + BUILD_BYPRODUCTS ${_TARGET_LIBS} # ${${TARGET_CNAME}_LIB} + ) +endif() +post_3rdparty() diff --git a/3rd_party/lua_CMakeLists.txt.in b/3rd_party/lua_CMakeLists.txt.in new file mode 100644 index 00000000000..3790bfc0839 --- /dev/null +++ b/3rd_party/lua_CMakeLists.txt.in @@ -0,0 +1,34 @@ +cmake_minimum_required(VERSION 3.18) + +set (TARGET_NAME lua) # lua_3rd) +project(${TARGET_NAME}) +message(STATUS "Target: ${TARGET_NAME}") + +set(_SOURCES + lapi.c lcode.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c + lmem.c lobject.c lopcodes.c lparser.c lstate.c lstring.c + ltable.c ltm.c lundump.c lvm.c lzio.c + lauxlib.c lbaselib.c ldblib.c liolib.c lmathlib.c loslib.c + ltablib.c lstrlib.c loadlib.c linit.c + lctype.c +) + +file(GLOB_RECURSE HEADER_FILES "*.h*") +message(STATUS "========================================") + +foreach(SRC ${_SOURCES}) + set(${TARGET_NAME}_LIBRARY ${${TARGET_NAME}_LIBRARY} ${SRC}) +endforeach() + +add_definitions(-DLUA_ANSI=1) +add_library(${TARGET_NAME} STATIC ${${TARGET_NAME}_LIBRARY} ${HEADER_FILES}) + +install(TARGETS ${TARGET_NAME} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} +) +install(FILES ${HEADER_FILES} ${liblua_headers} + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" # /${TARGET_NAME}" /w/o /lua +) + diff --git a/3rd_party/png.cmake b/3rd_party/png.cmake new file mode 100644 index 00000000000..9f0e4f8e5d8 --- /dev/null +++ b/3rd_party/png.cmake @@ -0,0 +1,55 @@ +cmake_minimum_required(VERSION 3.15) +# get_filename_component(LIB_TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + + set(INCLUDE_WITH_TOOLCHAIN 0) # special include path for every toolchain! +if (MSVC) # unfortunately the lib name is a little bit 'tricky' at libPng.. + set(_LIB_NAME libpng16_static) + # message(FATAL_ERROR LibPng: MSVC') + else() + set(_LIB_NAME png16) +endif() + +prepare_3rdparty(png ${_LIB_NAME}) +if (_COMPLETE_INSTALL) + + # Aug: Wieso ist das nicht besetzt???? + # set(ZLIB_LIB D:/Projects/link_libs/zlib/zlib-1.2.12/lib/clang14/libzlibstatic.a) + # message(FATAL_ERROR "Png-Stop: ${ZLIB_LIB} /// ${ZLIB_INCLUDE_DIR}") + set(CMAKE_ARGS + "-DCMAKE_INSTALL_PREFIX=${_INSTALL_DIR}" + "-DCMAKE_INSTALL_LIBDIR=${_INSTALL_LIB}" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + "-DCMAKE_BUILD_TYPE=Release" + + "-DPNG_ZLIB_BUILD=OFF" + "-DZLIB_INCLUDE_DIR=${ZLIB_INCLUDE_DIR}" + "-DZLIB_LIBRARY=${ZLIB_LIB}" + + "-DPNG_SHARED=OFF" + "-DPNG_STATIC=ON" + "-DPNG_TESTS=OFF" + ) + + ExternalProject_Add( + ${_BUILD_TARGET} + GIT_REPOSITORY "https://github.com/glennrp/libpng.git" + # GIT_REPOSITORY "https://github.com/libpng/libpng.git" # alternateive? + GIT_TAG "v${${TARGET_CNAME}_VERSION}" # git tag by libpng! + + PREFIX "${${TARGET_CNAME}_PREFIX}" + ${_BINARY_STEP} + INSTALL_DIR "${_INSTALL_DIR}" + + # PATCH_COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/LIBPNG/CMakeLists.txt.in" /CMakeLists.txt + CMAKE_ARGS ${CMAKE_ARGS} + # INSTALL_COMMAND cmake --build . --target install --config Release + ${_INSTALL_COMMAND} + + BUILD_ALWAYS ${EP_BUILD_ALWAYS} + # BUILD_IN_SOURCE ${EP_BUILD_IN_SOURCE} + DEPENDS ${ZLIB_TARGET} + + BUILD_BYPRODUCTS ${_TARGET_LIBS} # ${${TARGET_CNAME}_LIB} + ) +endif() +post_3rdparty() diff --git a/3rd_party/rsvg.cmake b/3rd_party/rsvg.cmake new file mode 100644 index 00000000000..c53a591333d --- /dev/null +++ b/3rd_party/rsvg.cmake @@ -0,0 +1,47 @@ +cmake_minimum_required(VERSION 3.15) + +set(INCLUDE_WITH_TOOLCHAIN 0) # special include path for every toolchain! + +## not functional: get_filename_component(_SUBPROJECT ${CMAKE_CURRENT_SOURCE_DIR} NAME) +set(_SUBPROJECT rsvg) +prepare_3rdparty(${_SUBPROJECT} ${_SUBPROJECT}) +set(CMAKE_ARGS + "-DCMAKE_INSTALL_PREFIX=${_INSTALL_DIR}" + "-DCMAKE_INSTALL_BINDIR=${_INSTALL_BIN}" + "-DCMAKE_INSTALL_LIBDIR=${_INSTALL_LIB}" + # "-DCMAKE_INSTALL_COMPONENT=bin/${TOOLCHAIN}" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + "-DCMAKE_BUILD_TYPE=Release" +) + +ExternalProject_Add( + ${_BUILD_TARGET} + GIT_REPOSITORY "https://gitlab.gnome.org/GNOME/librsvg.git" + GIT_TAG librsvg-2.55 + + PREFIX "${${TARGET_CNAME}_PREFIX}" + + BINARY_DIR "${${TARGET_CNAME}_SOURCE_DIR}_build" + + # PATCH_COMMAND "echo currDir = '%CD%' & dir" + # PATCH_COMMAND dir + # CONFIGURE_COMMAND "${_CONFIGURE_CMD}" + CONFIGURE_COMMAND ./configure --host=x86_64-w64-mingw32 RUST_TARGET=x86_64-pc-windows-gnu LIBS="-lws2_32 -luserenv" + BUILD_COMMAND ./make + + # BUILD_COMMAND cd /D ..\\.. & ./configure --host=x86_64-w64-mingw32 RUST_TARGET=x86_64-pc-windows-gnu LIBS="-lws2_32 -luserenv" & make + # BUILD_COMMAND echo "currDir = %CD%" & dir + # ${_BINARY_STEP} + INSTALL_DIR "${_INSTALL_DIR}" # ${LINK_LIBS}/${LIB_TARGET_NAME}/${XCSOAR_${TARGET_CNAME}_VERSION}" + + # PATCH_COMMAND ${CMAKE_COMMAND} -E copy_if_different "${PROJECTGROUP_SOURCE_DIR}/3rd_party/${LIB_TARGET_NAME}_CMakeLists.txt.in" /CMakeLists.txt + CMAKE_ARGS ${CMAKE_ARGS} + # INSTALL_COMMAND cmake --build . --target install --config Release + INSTALL_COMMAND ./configure --host=x86_64-w64-mingw32 RUST_TARGET=x86_64-pc-windows-gnu LIBS="-lws2_32 -luserenv" & make + + BUILD_ALWAYS ${EP_BUILD_ALWAYS} + # BUILD_IN_SOURCE ${EP_BUILD_IN_SOURCE} + BUILD_BYPRODUCTS ${_TARGET_LIBS} # ${${TARGET_CNAME}_LIB} +) + +post_3rdparty() diff --git a/3rd_party/sdl.cmake b/3rd_party/sdl.cmake new file mode 100644 index 00000000000..fd99ee840d8 --- /dev/null +++ b/3rd_party/sdl.cmake @@ -0,0 +1,37 @@ +cmake_minimum_required(VERSION 3.15) + +set(INCLUDE_WITH_TOOLCHAIN 0) # special include path for every toolchain! + +prepare_3rdparty(sdl SDL2-static) +if (_COMPLETE_INSTALL) + set(CMAKE_ARGS + "-DCMAKE_INSTALL_PREFIX=${_INSTALL_DIR}" + "-DCMAKE_INSTALL_BINDIR=${_INSTALL_BIN}" + "-DCMAKE_INSTALL_LIBDIR=${_INSTALL_LIB}" + # "-DCMAKE_INSTALL_COMPONENT=bin/${TOOLCHAIN}" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + "-DCMAKE_BUILD_TYPE=Release" + ) + + ExternalProject_Add( + ${_BUILD_TARGET} + GIT_REPOSITORY "https://github.com/libsdl-org/SDL" + GIT_TAG release-${SDL_VERSION} + + PREFIX "${${TARGET_CNAME}_PREFIX}" + ${_BINARY_STEP} + INSTALL_DIR "${_INSTALL_DIR}" # ${LINK_LIBS}/${LIB_TARGET_NAME}/${XCSOAR_${TARGET_CNAME}_VERSION}" + + # PATCH_COMMAND ${CMAKE_COMMAND} -E copy_if_different "${PROJECTGROUP_SOURCE_DIR}/3rd_party/${LIB_TARGET_NAME}_CMakeLists.txt.in" /CMakeLists.txt + CMAKE_ARGS ${CMAKE_ARGS} + # INSTALL_COMMAND cmake --build . --target install --config Release + ${_INSTALL_COMMAND} + BUILD_ALWAYS ${EP_BUILD_ALWAYS} + BUILD_IN_SOURCE ${EP_BUILD_IN_SOURCE} + BUILD_BYPRODUCTS ${_TARGET_LIBS} # ${${TARGET_CNAME}_LIB} + ) +endif() + +string(APPEND SDL_INCLUDE_DIR /SDL2) + +post_3rdparty() diff --git a/3rd_party/sodium.cmake b/3rd_party/sodium.cmake new file mode 100644 index 00000000000..aa1c9f50d79 --- /dev/null +++ b/3rd_party/sodium.cmake @@ -0,0 +1,52 @@ +cmake_minimum_required(VERSION 3.15) +# get_filename_component(LIB_TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) +set(INCLUDE_WITH_TOOLCHAIN 0) # special include path for every toolchain! +set(_LIB_NAME libsodium) # "liblibsodium.a" +Prepare_3rdParty(sodium ${_LIB_NAME}) + + +string(REPLACE "/" "\\" _INSTALL_DIR ${SODIUM_INSTALL_DIR}) +string(REPLACE "/" "\\" _SOURCE_DIR ${SODIUM_PREFIX}/src/${LIB_TARGET_NAME}) + +if (WIN32 AND MSVC) + set(BUILD_COMMAND devenv ${_SOURCE_DIR}\\libsodium.sln /Build Release|x64) + set(CONFIGURE_COMMAND echo ${BUILD_COMMAND}) + # set(INSTALL_COMMAND xcopy ${_SOURCE_DIR}\\Build\\Release\\x64\\*.lib ${_INSTALL_DIR}\\lib\\${TOOLCHAIN}\\* /Y /T) + set(INSTALL_COMMAND xcopy ${_SOURCE_DIR}\\src\\libsodium\\include\\*.h ${_INSTALL_DIR}\\include\\* /Y /I /S /E) +elseif (WIN32 AND MINGW AND NOT CLANG) + find_program(MAKE_EXECUTABLE NAMES gmake make mingw32-make REQUIRED) +endif() + +if (_COMPLETE_INSTALL) + set(CMAKE_ARGS + "-DCMAKE_INSTALL_PREFIX=${_INSTALL_DIR}" + "-DCMAKE_INSTALL_BINDIR=${_INSTALL_BIN}" + "-DCMAKE_INSTALL_LIBDIR=${_INSTALL_LIB}" + # "-DCMAKE_INSTALL_COMPONENT=bin/${TOOLCHAIN}" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + "-DCMAKE_BUILD_TYPE=Release" + ) + + # message(FATAL_ERROR "+++ BINARY_STEP (${TARGET_CNAME}): ${_BINARY_STEP}") + + ExternalProject_Add( + ${_BUILD_TARGET} + + GIT_REPOSITORY "https://github.com/jedisct1/libsodium.git" + GIT_TAG ${SODIUM_VERSION} + + PREFIX "${${TARGET_CNAME}_PREFIX}" + ${_BINARY_STEP} + INSTALL_DIR "${_INSTALL_DIR}" # ${LINK_LIBS}/${LIB_TARGET_NAME}/${XCSOAR_${TARGET_CNAME}_VERSION}" + + PATCH_COMMAND ${CMAKE_COMMAND} -E copy_if_different "${PROJECTGROUP_SOURCE_DIR}/3rd_party/sodium_CMakeLists.txt.in" /CMakeLists.txt + CMAKE_ARGS ${CMAKE_ARGS} + # INSTALL_COMMAND cmake --build . --target install --config Release + ${_INSTALL_COMMAND} + BUILD_ALWAYS ${EP_BUILD_ALWAYS} + # BUILD_IN_SOURCE ${EP_BUILD_IN_SOURCE} + BUILD_BYPRODUCTS ${_TARGET_LIBS} # ${${TARGET_CNAME}_LIB} + ) +endif() + +post_3rdparty() diff --git a/3rd_party/sodium_CMakeLists.txt.in b/3rd_party/sodium_CMakeLists.txt.in new file mode 100644 index 00000000000..21344132c64 --- /dev/null +++ b/3rd_party/sodium_CMakeLists.txt.in @@ -0,0 +1,57 @@ +cmake_minimum_required(VERSION 3.18) + +set (TARGET_NAME libsodium) +project(${TARGET_NAME}) + +set(_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/libsodium/include) +file(GLOB_RECURSE ${TARGET_NAME}_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/libsodium/*.c") +file(GLOB_RECURSE HEADER_FILES "${_INCLUDE_DIR}/*.h") + +message(STATUS -- Sodium!!!) +foreach(SRC ${${TARGET_NAME}_SOURCES}) + set(${TARGET_NAME}_LIBRARY ${${TARGET_NAME}_LIBRARY} ${SRC}) + message(STATUS -- Sodium: ${SRC}) +endforeach() + +add_compile_definitions(SODIUM_STATIC) +add_compile_definitions(SODIUM_EXPORT=) + +include_directories( + ${_INCLUDE_DIR} + ${_INCLUDE_DIR}/sodium + ${CMAKE_CURRENT_SOURCE_DIR}/test/quirks # test only +) + +set(EXAMPLE "This is an example") +set(VERSION "1.0") +set(NUMBER 3) + +set(VERSION "1.0.18") + +set(SODIUM_LIBRARY_VERSION_MAJOR 10) +set(SODIUM_LIBRARY_VERSION_MINOR 3) +set(SODIUM_LIBRARY_MINIMAL_DEF ) + +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/src/libsodium/include/sodium/version.h.in + ${CMAKE_CURRENT_SOURCE_DIR}/src/libsodium/include/sodium/version.h +) + +# add_definitions(-DLUA_ANSI=1) +add_library(${TARGET_NAME} STATIC ${${TARGET_NAME}_LIBRARY} ${HEADER_FILES}) + +install(TARGETS ${TARGET_NAME} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} +) + +foreach(header ${HEADER_FILES}) + string(REPLACE "${_INCLUDE_DIR}/" "" inc_file ${header}) + get_filename_component(inc_path ${inc_file} DIRECTORY) + install(FILES ${header} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${inc_path}") +endforeach() + +##message(FATAL_ERROR +++ Sodium: Stop!) + + diff --git a/3rd_party/xlst.cmake b/3rd_party/xlst.cmake new file mode 100644 index 00000000000..499485a51f8 --- /dev/null +++ b/3rd_party/xlst.cmake @@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 3.15) + +set(INCLUDE_WITH_TOOLCHAIN 0) # special include path for every toolchain! + +prepare_3rdparty(xlst xlst) +set(CMAKE_ARGS + "-DCMAKE_INSTALL_PREFIX=${_INSTALL_DIR}" + "-DCMAKE_INSTALL_BINDIR=${_INSTALL_BIN}" + "-DCMAKE_INSTALL_LIBDIR=${_INSTALL_LIB}" + # "-DCMAKE_INSTALL_COMPONENT=bin/${TOOLCHAIN}" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + "-DCMAKE_BUILD_TYPE=Release" +) + +ExternalProject_Add( + ${_BUILD_TARGET} + GIT_REPOSITORY "https://github.com/GNOME/libxslt" + GIT_TAG v${XLST_VERSION} + + PREFIX "${${TARGET_CNAME}_PREFIX}" + ${_BINARY_STEP} + INSTALL_DIR "${_INSTALL_DIR}" # ${LINK_LIBS}/${LIB_TARGET_NAME}/${XCSOAR_${TARGET_CNAME}_VERSION}" + + # PATCH_COMMAND ${CMAKE_COMMAND} -E copy_if_different "${PROJECTGROUP_SOURCE_DIR}/3rd_party/${LIB_TARGET_NAME}_CMakeLists.txt.in" /CMakeLists.txt + CMAKE_ARGS ${CMAKE_ARGS} + # INSTALL_COMMAND cmake --build . --target install --config Release + ${_INSTALL_COMMAND} + BUILD_ALWAYS ${EP_BUILD_ALWAYS} + BUILD_IN_SOURCE ${EP_BUILD_IN_SOURCE} + BUILD_BYPRODUCTS ${_TARGET_LIBS} # ${${TARGET_CNAME}_LIB} +) + +post_3rdparty() diff --git a/3rd_party/xml2.cmake b/3rd_party/xml2.cmake new file mode 100644 index 00000000000..4cec06ed772 --- /dev/null +++ b/3rd_party/xml2.cmake @@ -0,0 +1,32 @@ +cmake_minimum_required(VERSION 3.15) + +set(INCLUDE_WITH_TOOLCHAIN 0) # special include path for every toolchain! + +prepare_3rdparty(xml2 xml2) +set(CMAKE_ARGS + "-DCMAKE_INSTALL_PREFIX=${_INSTALL_DIR}" + "-DCMAKE_INSTALL_BINDIR=${_INSTALL_BIN}" + "-DCMAKE_INSTALL_LIBDIR=${_INSTALL_LIB}" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + "-DCMAKE_BUILD_TYPE=Release" +) + +ExternalProject_Add( + ${_BUILD_TARGET} + GIT_REPOSITORY "https://github.com/GNOME/libxml2" + GIT_TAG v${XML2_VERSION} + + PREFIX "${${TARGET_CNAME}_PREFIX}" + ${_BINARY_STEP} + INSTALL_DIR "${_INSTALL_DIR}" # ${LINK_LIBS}/${LIB_TARGET_NAME}/${XCSOAR_${TARGET_CNAME}_VERSION}" + + # PATCH_COMMAND ${CMAKE_COMMAND} -E copy_if_different "${PROJECTGROUP_SOURCE_DIR}/3rd_party/${LIB_TARGET_NAME}_CMakeLists.txt.in" /CMakeLists.txt + CMAKE_ARGS ${CMAKE_ARGS} + # INSTALL_COMMAND cmake --build . --target install --config Release + ${_INSTALL_COMMAND} + BUILD_ALWAYS ${EP_BUILD_ALWAYS} + BUILD_IN_SOURCE ${EP_BUILD_IN_SOURCE} + BUILD_BYPRODUCTS ${_TARGET_LIBS} # ${${TARGET_CNAME}_LIB} +) + +post_3rdparty() diff --git a/3rd_party/xml_CMakeLists.txt.in b/3rd_party/xml_CMakeLists.txt.in new file mode 100644 index 00000000000..96167b352f6 --- /dev/null +++ b/3rd_party/xml_CMakeLists.txt.in @@ -0,0 +1,30 @@ +cmake_minimum_required(VERSION 2.8) + +set (TARGET_NAME xml) +project(${TARGET_NAME}) + + +# file(GLOB_RECURSE ${TARGET_NAME}_SOURCES "*.c*") +file(GLOB_RECURSE HEADER_FILES "*.h*") + +set(${TARGET_NAME}_LIBRARY + Parser.cpp + Writer.cpp + Node.cpp +) + + +add_library(${TARGET_NAME} STATIC + ${${TARGET_NAME}_LIBRARY} + ${HEADER_FILES} +) + +install(TARGETS ${TARGET_NAME} +# RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} +# ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} +) +install(FILES ${HEADER_FILES} + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" +) + diff --git a/3rd_party/xmlparser.cmake b/3rd_party/xmlparser.cmake new file mode 100644 index 00000000000..03b60969ed2 --- /dev/null +++ b/3rd_party/xmlparser.cmake @@ -0,0 +1,62 @@ +if (OFF) + # without XML-Parser yet + +set(DISPLAY_STRING "# XML-PARSER # XML-PARSER # XML-PARSER # XML-PARSER # XML-PARSER") +message(STATUS "${DISPLAY_STRING}") +cmake_minimum_required(VERSION 3.15) + +set(LIB_TARGET_NAME xmlparser) +#========================================================== +string(TOUPPER ${LIB_TARGET_NAME} TARGET_CNAME) + +# --------------------------------------------------------------------------- +option(USE_SYSTEM_${TARGET_CNAME} "Should we use the system ${LIB_TARGET_NAME}?" OFF) + +# set(${TARGET_CNAME}_VERSION "2.44") +set(${TARGET_CNAME}_VERSION "1.08") +set(XCSOAR_${TARGET_CNAME}_VERSION "${LIB_TARGET_NAME}-${${TARGET_CNAME}_VERSION}") # reset! +set(${TARGET_CNAME}_INSTALL_DIR "${LINK_LIBS}/${LIB_TARGET_NAME}/${XCSOAR_${TARGET_CNAME}_VERSION}") +set(${TARGET_CNAME}_PREFIX "${EP_CMAKE}/${LIB_TARGET_NAME}/${XCSOAR_${TARGET_CNAME}_VERSION}") +set(${TARGET_CNAME}_URL "http://www.FlapsOnline.de/XCSoarAug/xml-1.08.zip") + +#------------------- +if(${WITH_3RD_PARTY}) +if (MSVC OR MINGW) + set( BINARY_STEP BINARY_DIR "${${TARGET_CNAME}_PREFIX}/build/${TOOLCHAIN}") +else() + set(BINARY_STEP ) +endif() +ExternalProject_Add( + ${LIB_TARGET_NAME} + # GIT_REPOSITORY "https://github.com/" + # GIT_TAG "v${${TARGET_CNAME}_VERSION}" + + URL "${${TARGET_CNAME}_URL}" + PREFIX "${${TARGET_CNAME}_PREFIX}" + ${BINARY_STEP} + # BINARY_DIR "${${TARGET_CNAME}_PREFIX}/build/${TOOLCHAIN}" + INSTALL_DIR "${LINK_LIBS}/${LIB_TARGET_NAME}/${XCSOAR_${TARGET_CNAME}_VERSION}" + PATCH_COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/${TARGET_CNAME}_CMakeLists.txt.in" /CMakeLists.txt + CMAKE_ARGS "-DCMAKE_INSTALL_PREFIX=" + "-DINSTALL_LIB_DIR:PATH=/lib/${TOOLCHAIN}" + "-DINSTALL_LIB_DIR:PATH=/lib/${TOOLCHAIN}" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + INSTALL_COMMAND cmake --build . --target install --config Release + BUILD_ALWAYS ${EP_BUILD_ALWAYS} + # BUILD_IN_SOURCE ${EP_BUILD_IN_SOURCE} +) +endif() +set(${TARGET_CNAME}_LIB "${INSTALL_DIR}/lib/${TOOLCHAIN}/${LIB_NAME}${LIB_SUFFIX}") +set(${TARGET_CNAME}_INCLUDE_DIR "${INSTALL_DIR}/include") +# PARENT_SCOPE only available in Parent, not here... +if(EXISTS "${${TARGET_CNAME}_LIB}") + set(${TARGET_CNAME}_LIB ${${TARGET_CNAME}_LIB} PARENT_SCOPE) +else() + set(${TARGET_CNAME}_LIB ${LIB_TARGET_NAME} PARENT_SCOPE) +endif() +set(${TARGET_CNAME}_INCLUDE_DIR ${${TARGET_CNAME}_INCLUDE_DIR} PARENT_SCOPE) + +list(APPEND THIRDPARTY_INCLUDES ${${TARGET_CNAME}_INCLUDE_DIR}) + +message(FATAL_ERROR "xmlparser: ${TARGET_CNAME} ${INSTALL_DIR}/include => ${${TARGET_CNAME}_INCLUDE_DIR}") +endif() diff --git a/3rd_party/zlib.cmake b/3rd_party/zlib.cmake new file mode 100644 index 00000000000..90ca470578f --- /dev/null +++ b/3rd_party/zlib.cmake @@ -0,0 +1,45 @@ +cmake_minimum_required(VERSION 3.15) + +set(INCLUDE_WITH_TOOLCHAIN 0) # special include path for every toolchain! +if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows") + set(_LIB_NAME zlibstatic) +else() + set(_LIB_NAME z) +endif() + +prepare_3rdparty(zlib ${_LIB_NAME}) + +if (_COMPLETE_INSTALL) + #---------------------- + set(CMAKE_ARGS + "-DCMAKE_INSTALL_PREFIX=${_INSTALL_DIR}" + "-DINSTALL_BIN_DIR:PATH=${_INSTALL_DIR}/${_INSTALL_BIN}" + "-DINSTALL_LIB_DIR:PATH=${_INSTALL_DIR}/${_INSTALL_LIB}" + # ??? "-DCMAKE_CONFIGURATION_TYPES=Release" + "-DCMAKE_BUILD_TYPE=Release" + + "-DZ_HAVE_UNISTD_H=OFF" # MSVC only!!!! + ) + # message(FATAL_ERROR "+++ BINARY_STEP (${TARGET_CNAME}): ${_BINARY_STEP}") + + ExternalProject_Add( + ${_BUILD_TARGET} + GIT_REPOSITORY "https://github.com/madler/zlib.git" + GIT_TAG "v${${TARGET_CNAME}_VERSION}" + + PREFIX "${${TARGET_CNAME}_PREFIX}" + ${_BINARY_STEP} + INSTALL_DIR "${_INSTALL_DIR}" + CMAKE_ARGS ${CMAKE_ARGS} + + # BUILD_ALWAYS ${EP_BUILD_ALWAYS} + # INSTALL_COMMAND cmake --build . --target install --config Release + ${_INSTALL_COMMAND} + BUILD_ALWAYS ${EP_BUILD_ALWAYS} + CONFIGURE_HANDLED_BY_BUILD ON + # BUILD_IN_SOURCE ${EP_BUILD_IN_SOURCE} + BUILD_BYPRODUCTS ${_TARGET_LIBS} # important for ninja! + ) +endif() + +post_3rdparty() diff --git a/3rd_party/zzip.cmake b/3rd_party/zzip.cmake new file mode 100644 index 00000000000..f53d7d3df32 --- /dev/null +++ b/3rd_party/zzip.cmake @@ -0,0 +1,70 @@ +set(DISPLAY_STRING "# ZZIP # ZZIP # ZZIP # ZZIP # ZZIP") +message(STATUS "${DISPLAY_STRING}") +cmake_minimum_required(VERSION 3.15) + +set(LIB_TARGET_NAME zzip) +set(TARGET_NAME ${LIB_TARGET_NAME}_3rd) +#========================================================== +string(TOUPPER ${LIB_TARGET_NAME} TARGET_CNAME) + +# defined in zlib.cmake: set(ZLIB_DIR ${LINK_LIBS}/zlib/${XCSOAR_ZLIB_VERSION}) + +# --------------------------------------------------------------------------- +option(USE_SYSTEM_${TARGET_CNAME} "Should we use the system ${LIB_TARGET_NAME}?" OFF) +option(USE_DRAHEIM "Should we use the draheim (or the BBDE) system?" OFF) + +set(INSTALL_DIR "${LINK_LIBS}/${LIB_TARGET_NAME}/${XCSOAR_${TARGET_CNAME}_VERSION}") +#------------------- + set(${TARGET_CNAME}_VERSION "xcsoar") # ddebin + + set(XCSOAR_${TARGET_CNAME}_VERSION "${LIB_TARGET_NAME}-${${TARGET_CNAME}_VERSION}") # reset! + set(${TARGET_CNAME}_INSTALL_DIR "${LINK_LIBS}/${LIB_TARGET_NAME}/${XCSOAR_${TARGET_CNAME}_VERSION}") + set(${TARGET_CNAME}_PREFIX "${EP_CMAKE}/${LIB_TARGET_NAME}/${XCSOAR_${TARGET_CNAME}_VERSION}") + set(${TARGET_CNAME}_FILE "${THIRD_PARTY}/zzip/zzip-xcsoar.zip") +if(OFF) # ${WITH_3RD_PARTY}) + set(${TARGET_CNAME}_URL "http://www.FlapsOnline.de/XCSoarAug/zzip-xcsoar.zip") + ExternalProject_Add( + ${LIB_TARGET_NAME}_3rd + URL "${${TARGET_CNAME}_URL}" + PREFIX "${${TARGET_CNAME}_PREFIX}" + # ${BINARY_STEP} + BINARY_DIR "${${TARGET_CNAME}_PREFIX}/build/${TOOLCHAIN}" + INSTALL_DIR "${INSTALL_DIR}" + # PATCH_COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/${TARGET_CNAME}_CMakeLists.txt.in" /CMakeLists.txt + CMAKE_ARGS "-DCMAKE_INSTALL_PREFIX=" + "-DCMAKE_INSTALL_BINDIR=bin/${TOOLCHAIN}" # :PATH=/bin/${TOOLCHAIN}" + "-DCMAKE_INSTALL_LIBDIR=lib/${TOOLCHAIN}" # :PATH=/lib/${TOOLCHAIN}" + "-DCMAKE_INSTALL_COMPONENT=bin/${TOOLCHAIN}" # :PATH=/lib/${TOOLCHAIN}" + "-DCMAKE_INSTALL_INCLUDEDIR=include" # :PATH=/bin/${TOOLCHAIN}" + + "-DZLIB_INCLUDE_DIR=${ZLIB_INCLUDE_DIR}" + "-DZLIB_LIBRARY=${ZLIB_LIB}" + + "-DZLIB_INCLUDE_DIR=${ZLIB_DIR}/include" + "-DZLIB_LIBRARY_DEBUG=${ZLIB_DIR}/lib/${TOOLCHAIN}/zlibstatic.lib" + "-DZLIB_LIBRARY_RELEASE=${ZLIB_DIR}/lib/${TOOLCHAIN}/zlibstatic.lib" + + BUILD_ALWAYS ${EP_BUILD_ALWAYS} + # BUILD_IN_SOURCE ${EP_BUILD_IN_SOURCE} + DEPENDS zlib + ) + else() + message(STATUS "!!! ZZIP-XCSOAR DON'T EXISTS !!!!!!!!!!!!!!!!!!!!!!!") + endif() + +set(${TARGET_CNAME}_LIB "${INSTALL_DIR}/lib/${TOOLCHAIN}/${LIB_PREFIX}${LIB_TARGET_NAME}${LIB_SUFFIX}") +set(${TARGET_CNAME}_INCLUDE_DIR "${INSTALL_DIR}/include") +# PARENT_SCOPE only available in Parent, not here... +if(EXISTS "${${TARGET_CNAME}_LIB}") + set(${TARGET_CNAME}_LIB ${${TARGET_CNAME}_LIB} PARENT_SCOPE) +else() + set(${TARGET_CNAME}_LIB ${LIB_TARGET_NAME} PARENT_SCOPE) +endif() +set(${TARGET_CNAME}_INCLUDE_DIR ${${TARGET_CNAME}_INCLUDE_DIR} PARENT_SCOPE) + +list(APPEND THIRDPARTY_INCLUDES ${${TARGET_CNAME}_INCLUDE_DIR}) + +list(APPEND 3RDPARTY_TARGETS ${LIB_TARGET_NAME}) +set_target_properties(${LIB_TARGET_NAME} PROPERTIES FOLDER 3rdParty) # ExternalProjectTargets) + + diff --git a/3rd_party/zzip_CMakeLists.txt.in b/3rd_party/zzip_CMakeLists.txt.in new file mode 100644 index 00000000000..c311c1ae165 --- /dev/null +++ b/3rd_party/zzip_CMakeLists.txt.in @@ -0,0 +1,23 @@ +cmake_minimum_required(VERSION 3.18) + +set (TARGET_NAME zzip) +project(${TARGET_NAME}) + + +file(GLOB_RECURSE ${TARGET_NAME}_SOURCES "*.c*") +file(GLOB_RECURSE HEADER_FILES "*.h*") + +set(${TARGET_NAME}_LIBRARY coding.c struct_model0.c struct_model1.c + zzip.c block.c bwt.c) + +add_library(${TARGET_NAME} STATIC ${${TARGET_NAME}_LIBRARY} ${HEADER_FILES}) + +install(TARGETS ${TARGET_NAME} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} +) +install(FILES ${HEADER_FILES} + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" +) + diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000000..669d58cefa8 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,500 @@ +cmake_minimum_required(VERSION 3.18) + +set(SHOW_SUBPROJECTS OFF) +message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +message(STATUS "+++ CMAKE_HOST_SYSTEM_NAME: ${CMAKE_HOST_SYSTEM_NAME}") +message(STATUS "+++ CMAKE_SYSTEM_NAME: ${CMAKE_SYSTEM_NAME}") +message(STATUS "+++ TOOLCHAIN: ${TOOLCHAIN}") + + +get_filename_component(PROJECTGROUP_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} ABSOLUTE) +get_filename_component(PROJECTGROUP_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR} ABSOLUTE) +message(STATUS "*** PROJECTGROUP_SOURCE_DIR = '${PROJECTGROUP_SOURCE_DIR}'") +message(STATUS "*** PROJECTGROUP_BINARY_DIR = '${PROJECTGROUP_BINARY_DIR}'") + +get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_BINARY_DIR} NAME) +set (PROJECT_NAME "OpenSoar-${PROJECT_NAME}") +project(${PROJECT_NAME}) +set(TARGET_NAME OpenSoar) +set(PROGRAM_NAME ${TARGET_NAME}) +set(PROGRAM_NAME_CC ${TARGET_NAME}) # CamelCase +string(TOLOWER ${PROGRAM_NAME} PROGRAM_NAME_LC) # lowercase + +### file(READ "VERSION.txt" PROGRAM_VERSION) +# add version string to OpenSoar: +file(READ OpenSoar.config _config_file) +# put the complete string in a list of lines +string(REPLACE "\n" ";" _config_file ${_config_file}) +foreach(_line ${_config_file}) + string(REPLACE "=" ";" _line ${_line} ) + list(GET _line 0 _param0) + list(GET _line 1 _param1) + string(STRIP ${_param0} _param0) + string(STRIP ${_param1} _param1) + set(${_param0} ${_param1}) + # message(STATUS "+++++ '${_param0}' = '${_param1}'") +endforeach()# --------------------------------------------------------------- + +message(STATUS "+++++ PROGRAM_NAME = '${PROGRAM_NAME}'") +message(STATUS "+++++ PROGRAM_VERSION = '${PROGRAM_VERSION}'") + +add_compile_definitions("PROGRAM_VERSION=\"${PROGRAM_VERSION}\"") +file(WRITE "${PROJECTGROUP_BINARY_DIR}/VERSION.txt" ${PROGRAM_VERSION}) + +find_program(CMAKE_APP NAMES cmake REQUIRED) +get_filename_component(CMAKE_PROGRAM_PATH ${CMAKE_APP} DIRECTORY) +get_filename_component(CMAKE_PROGRAM_PATH ${CMAKE_PROGRAM_PATH} DIRECTORY) +get_filename_component(USER_PROGRAM_PATH ${CMAKE_PROGRAM_PATH} DIRECTORY) + message(STATUS "CMAKE_SYSTEM_PROGRAM_PATH - ${CMAKE_SYSTEM_PROGRAM_PATH}") + message(STATUS "CMAKE_PROGRAM_PATH - ${CMAKE_PROGRAM_PATH}") + message(STATUS "USER_PROGRAM_PATH - ${USER_PROGRAM_PATH}") + +include(build/cmake/opensoar.cmake) +get_filename_component(OUTPUT_FOLDER ${PROJECTGROUP_BINARY_DIR}/.. ABSOLUTE) +set(OUTPUT ${OUTPUT_FOLDER}) + +# 2021 clear the right place: +set(JASPER_OUTSIDE OFF) +set(ZZIP_OUTSIDE OFF) + +add_definitions(-DCMAKE_PROJECT) # to decide if make or cmake... + +# find all necessary programs/apps +find_program(PYTHON_APP NAMES python3 python REQUIRED) +find_program(PERL_APP NAMES perl REQUIRED) +# find_program(BMP_CONVERT_APP NAMES ImageMagick/convert ) + list(APPEND CMAKE_PROGRAM_PATH "${USER_PROGRAM_PATH}/GnuWin/libxslt/bin") +find_program(XSLTPROC_APP NAMES xsltproc REQUIRED) + list(APPEND CMAKE_PROGRAM_PATH "${USER_PROGRAM_PATH}/Inkscape/bin") +find_program(INKSCAPE_APP NAMES inkscape REQUIRED) + list(APPEND CMAKE_PROGRAM_PATH "${USER_PROGRAM_PATH}/ImageMagick") +find_program(BMP_CONVERT_APP NAMES convert REQUIRED) +find_program(BMP_MONTAGE_APP NAMES montage REQUIRED) + list(APPEND CMAKE_PROGRAM_PATH "${USER_PROGRAM_PATH}/7-Zip") +find_program(ZIP_APP NAMES 7z gzip REQUIRED) # REQUIRED since CMake 3.18! + +if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + set (PERCENT_CHAR "\%") + set (DOLLAR_CHAR "$$") +# message(FATAL_ERROR "Stop: Clang Compiler??? - '${CMAKE_CXX_COMPILER}'") +elseif(CMAKE_CXX_COMPILER MATCHES "clang[+][+]") + set (PERCENT_CHAR "\%") + set (DOLLAR_CHAR "$$") + set(CLANG ON) +elseif (WIN32 AND (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")) + message(STATUS "MSVC-Compiler - ${CMAKE_CXX_COMPILER_ID}") + set (PERCENT_CHAR "%%") + set (DOLLAR_CHAR "\$") +elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + message(STATUS "GCC-Compiler - ${CMAKE_CXX_COMPILER_ID}") + set (PERCENT_CHAR "%%") + set (DOLLAR_CHAR "$$") +else() + ### message(FATAL_ERROR "GDI-Stop! in ./CmakeLists") + message(FATAL_ERROR "Stop: unknown Compiler??? - '${CMAKE_CXX_COMPILER}'") +endif() + +add_subdirectory(build/cmake) +# add_subdirectory(Data) +# add_subdirectory(po) + +if(UNIX) + set(ENABLE_OPENGL ON) # better outside???? + # moved to build/cmake/LinuxGCC.cmake +elseif (MSVC OR 1) # 1 = always.. +# if (MSVC AND 0) # 0 = never.. +### August, 2022-09-19: + set(ENABLE_OPENGL OFF) # better outside???? + set(USE_MEMORY_CANVAS OFF) # das ist hier auch falsch!!!! +else() + set(ENABLE_OPENGL ON) # better outside???? + set(ENABLE_SDL OFF) # better outside???? + set(USE_MEMORY_CANVAS OFF) # das ist hier auch falsch!!!! +endif() +# Target links to target GLUT::GLUT but the target was not + +#--------------------------------------------------------- +if (USE_MEMORY_CANVAS) + add_compile_definitions(USE_MEMORY_CANVAS) +elseif(ENABLE_OPENGL) + add_compile_definitions(ENABLE_OPENGL) + # add_compile_definitions(ENABLE_SDL) # only windows???? + # add_compile_definitions(USE_FREETYPE) # only windows???? +else() + set(USE_GDI ON) # das ist hier auch falsch!!!! + add_compile_definitions(USE_GDI) + add_compile_definitions(USE_WINUSER) +endif() +#--------------------------------------------------------- + +set_property(GLOBAL PROPERTY USE_FOLDERS ON) # important for folder structure f.e. in Visual Studio +# Setting Area =================================================== +include(ExternalProject) # possible since 3.10 + +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # only by Makefile or Ninja generators: export compile commands +set(XCSOAR_LIB_TYPE STATIC) # SHARED) + +if (CMAKE_TOOLCHAIN_FILE) + message(STATUS "CMAKE_TOOLCHAIN_FILE = '${CMAKE_TOOLCHAIN_FILE}'") + message(STATUS "CMAKE_SYSTEM_NAME = '${CMAKE_SYSTEM_NAME}'") +endif() + +if(ANDROID OR KOBO OR SDL) + add_compile_definitions(HAVE_BATTERY) +endif() + +get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +message(STATUS "CMAKE_HOST_SYSTEM_NAME = ${CMAKE_HOST_SYSTEM_NAME} vs. CMAKE_SYSTEM_NAME = ${CMAKE_SYSTEM_NAME} ") + +set(3RDPARTY_DEPENDENCIES ON) +set(3RDPARTY_TARGETS ) +add_subdirectory(3rd_party) +add_subdirectory(Data) +add_subdirectory(po) + +set(SRC "${PROJECTGROUP_SOURCE_DIR}/src") +include(CMakeSource.cmake) + +if (CMAKE_INCLUDE_SYSTEM) + include(${CMAKE_INCLUDE_SYSTEM}) # build/cmake/LinuxMinGW.cmake) +elseif (WIN32 AND MSVC) + include(build/cmake/WinMSVC.cmake) + elseif(WIN32 AND (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")) + include(build/cmake/WinClang.cmake) + set(CLANG ON) + elseif(WIN32 AND (CMAKE_CXX_COMPILER MATCHES "clang[+][+]")) + message(FATAL_ERROR "+++ Unknown System: CLANG-1!") + include(build/cmake/WinClang.cmake) + set(CLANG ON) + elseif(${CMAKE_HOST_SYSTEM_NAME}' MATCHES 'Linux') # August2111: Test only + include(build/cmake/LinuxMinGW.cmake) + elseif(WIN32 AND MINGW AND (${CMAKE_HOST_SYSTEM_NAME}' MATCHES 'Linux')) + include(build/cmake/LinuxMinGW.cmake) + elseif(WIN32 AND MINGW) + include(build/cmake/WinMinGW.cmake) + elseif(WIN32 AND CLANG) + message(FATAL_ERROR "+++ Unknown System: CLANG!") + elseif(WIN32 AND NINJA) + message(FATAL_ERROR "+++ Unknown System: NINJA!") + elseif(UNIX) + message(STATUS "+++ System = LINUX / GCC(?) (${TOOLCHAIN})!") + include(build/cmake/LinuxGCC.cmake) + elseif(ANDROID) + message(STATUS "+++ System = ANDROID / ${ANDROID_ABI}!") + else() + message(FATAL_ERROR "+++ Unknown System: ${CMAKE_SYSTEM}!") +endif() + +if (MSVC) # Themes for MSVC only! + add_compile_definitions(GNU_CONST=) + add_compile_definitions(GNU_PURE=) +else() ### MSVC + add_compile_definitions("GNU_CONST=[[gnu::const]]") + add_compile_definitions("GNU_PURE=[[gnu::pure]]") +endif() ### MSVC + +message(STATUS "+++ Lib Pre- and Suffix: '${LIB_PREFIX}' -- '${LIB_SUFFIX}' !") + + +include_directories("${SRC}/io") # only regarding Logfile! +include_directories("${SRC}/lib/fmt") # ???! +# include_directories("${OUTPUT_FOLDER}/include") + +#3rd party components +add_compile_definitions(CURL_STATICLIB) + +# git commit hash macro +execute_process( + COMMAND git rev-parse --short HEAD + WORKING_DIRECTORY ${PROJECTGROUP_SOURCE_DIR} + OUTPUT_VARIABLE GIT_COMMIT_ID + OUTPUT_STRIP_TRAILING_WHITESPACE +) +add_compile_definitions("GIT_COMMIT_ID=\"${GIT_COMMIT_ID}\"") + +# 3rd Party !!!! +#============================= +message(STATUS "### THIRDPARTY_INCLUDES = '${THIRDPARTY_INCLUDES}'") +include_directories(${THIRDPARTY_INCLUDES} ) +##################################################################################### +##################################################################################### +add_compile_definitions(NOMINMAX) + +if(ENABLE_OPENGL) + message(FATAL_ERROR "Not funtional yet") + add_compile_definitions(ENABLE_OPENGL) + # set(FreeGLUT_DIR ${LINK_LIBS}/glut/freeglut-3.2.1/lib/msvc2019/cmake/FreeGLUT) + # find_package(FreeGLUT REQUIRED) + set(OpenGL_GL_PREFERENCE LEGACY) + find_package(OpenGL REQUIRED) # FindOpenGL() ??? + # set(GLEW_ROOT D:/link_libs/glew/glew-2.1.0/lib/Release/x64) + # find_package(GLEW REQUIRED) + + if(NOT TARGET OpenGL::GLU) + message(FATAL_ERROR "GLU could not be found") + endif(NOT TARGET OpenGL::GLU) + + message(STATUS "glu: ${OPENGL_glu_LIBRARY}") + message(STATUS "glu: ${OpenGL_INCLUDE_DIR}") + + get_target_property(GLU_IMPORTED_LIBNAME OpenGL::GLU IMPORTED_LIBNAME) + message(STATUS "glu imported libname: ${GLU_IMPORTED_LIBNAME}") + add_compile_definitions(USE_WIN32_RESOURCES) # USE_WINUSER) # USE_WINUSER entspricht USE_GDI! + + if (ANDROID) + # this is a hard coded path! + include_directories(D:/Programs/Android/android-ndk-r25b/toolchains/llvm/prebuilt/windows-x86_64/sysroot/usr/include/GLES2) + else() + # this is a hard coded path! + ## include_directories(D:/Programs/Android/android-ndk-r25b/toolchains/llvm/prebuilt/windows-x86_64/sysroot/usr/include) + endif() + include_directories(${Boost_INCLUDE_DIR}/boost/compute/interop) + + include_directories($ENV{OCL_ROOT}/include) + include_directories(D:/Programs/OCL_SDK_Light/include) # alternative??? + + if (MSVC) + message(FATAL_ERROR "OpenGL-Stop! OpenGL_INCLUDE_DIR = ${OpenGL_INCLUDE_DIR}") + endif() + set(OPENGL_DEFINED ON) +else() + add_compile_definitions(USE_WIN32_RESOURCES USE_WINUSER) +endif() +##################################################################################### +##################################################################################### + +link_directories(${BOOST_ROOT}/lib/${TOOLCHAIN}) # this line in boost.cmake is not affected to the main project! + +get_filename_component(TEMP_INCLUDES ${PROJECTGROUP_BINARY_DIR}/../include ABSOLUTE) +include_directories( + ${PROJECTGROUP_SOURCE_DIR}/src + ${PROJECTGROUP_SOURCE_DIR}/src/Engine + ${TEMP_INCLUDES} + + # better with find_package + ${Boost_INCLUDE_DIR}/boost/predef/other + + ${THIRD_PARTY}/glfw/glfw-3.3.2.bin.WIN64/include + ${LINK_LIBS}/glm/glm-0.9.9/include +) + +if (JASPER_OUTSIDE) # 2021 + # before add_subdirectories!!! + add_compile_definitions(JASPER_OUTSIDE) +endif (JASPER_OUTSIDE) + +set(SOURCE_FILES ) # clean it + add_subdirectory(src/Airspace) + add_subdirectory(src/Atmosphere) + add_subdirectory(src/Audio) + add_subdirectory(src/Blackboard) + add_subdirectory(src/co) + add_subdirectory(src/Computer) +if (OFF) ## - 'Cloud'- files are not used yet + add_subdirectory(src/Cloud) +endif() + add_subdirectory(src/CrossSection) + add_subdirectory(src/Engine) + add_subdirectory(src/event) + add_subdirectory(src/FLARM) + add_subdirectory(src/Form) + add_subdirectory(src/Formatter) + add_subdirectory(src/Gauge) + add_subdirectory(src/Geo) + add_subdirectory(src/Hardware) + add_subdirectory(src/IGC) + add_subdirectory(src/InfoBoxes) + add_subdirectory(src/Input) + add_subdirectory(src/Job) + add_subdirectory(src/json) + add_subdirectory(src/Language) + add_subdirectory(src/Logger) + add_subdirectory(src/Look) + add_subdirectory(src/lua) + add_subdirectory(src/Markers) + add_subdirectory(src/Math) + add_subdirectory(src/Menu) + add_subdirectory(src/Monitor) + add_subdirectory(src/net) + add_subdirectory(src/NMEA) + add_subdirectory(src/Operation) + add_subdirectory(src/system) + add_subdirectory(src/Plane) + add_subdirectory(src/Polar) + add_subdirectory(src/Profile) + add_subdirectory(src/Projection) + add_subdirectory(src/Renderer) + add_subdirectory(src/Replay) + add_subdirectory(src/Repository) + add_subdirectory(src/Screen) + add_subdirectory(src/Task) + add_subdirectory(src/TeamCode) + add_subdirectory(src/Terrain) +# if (NOT JASPER_OUTSIDE) # 2021 + add_subdirectory(src/Terrain/jasper) # 2021 +# endif (NOT JASPER_OUTSIDE) + add_subdirectory(src/thread) + add_subdirectory(src/time) + add_subdirectory(src/Topography) + add_subdirectory(src/ui ) + add_subdirectory(src/UIUtil) + add_subdirectory(src/Units) + add_subdirectory(src/util) + add_subdirectory(src/Waypoint) + add_subdirectory(src/Weather) + add_subdirectory(src/Widget) + add_subdirectory(src/XML) + + add_subdirectory(src/Device) + add_subdirectory(src/Dialogs) + add_subdirectory(src/io) + add_subdirectory(src/MapWindow) + add_subdirectory(src/Tracking) + add_subdirectory(src/net/client/WeGlide) +if(NOT ZZIP_OUTSIDE) + add_subdirectory(src/zzip) # aug: new!! +endif() + add_subdirectory(src/lib) +add_subdirectory(src) # libOpenSoar! + +add_subdirectory(src/OpenVario) # libOpenSoar! + +add_subdirectory(src/Android) # Android -> EXCLUDE_FROM_ALL TRUE + +list(APPEND SOURCE_FILES "src/OpenSoar.cpp") +# list(APPEND SOURCE_FILES "src/Version.cpp") +## configure_file( +## "${CMAKE_CURRENT_SOURCE_DIR}/Data/OpenSoar.rc.in" +## "${OUTPUT_FOLDER}/Data/OpenSoar.rc" +## ) +# list(APPEND SOURCE_FILES "${OUTPUT_FOLDER}/Data/OpenSoar.rc") +list(APPEND SOURCE_FILES "${PROJECTGROUP_BINARY_DIR}/OpenSoar.rc") +## list(APPEND SCRIPT_FILES "${CMAKE_CURRENT_SOURCE_DIR}/Data/OpenSoar.rc.in") +list(APPEND SCRIPT_FILES "CMakeSource.cmake") + +if (MSVC) + file(GLOB DEF_FILE "Data/*.def") + if (DEF_FILE) + list(APPEND SOURCE_FILES ${DEF_FILE}) + endif() +endif() +#========================================================== +#========================================================== + +# preparing target_link_libraries! +list(APPEND XCSOAR_LINK_LIBRARIES libOpenSoar ${XCSOAR_SOURCE_LISTS}) + +# TODO(aug): Cleaning up this code!!! +if(1) + message(STATUS "Boost: BOOST_LIB = ${Boost_LIBRARIES} ") # BOOST_LIB ??? + message(STATUS "C-Ares: CARES_LIB = ${CARES_LIB} / ${CARES_TARGET} ") + message(STATUS "Curl: CURL_LIB = ${CURL_LIB} / ${CURL_TARGET} ") + message(STATUS "Jasper: JASPER_LIB = ${JASPER_LIB} / ${JASPER_TARGET} ") + ## message(STATUS "LibPng: LIBPNG_LIB = ${LIBPNG_LIB} ") + message(STATUS "Png: PNG_LIB = ${PNG_LIB} / ${PNG_TARGET} ") + message(STATUS "Sodium: SODIUM_LIB = ${SODIUM_LIB} / ${SODIUM_TARGET} ") + # message(STATUS "LibSodium: LIBSODIUM_LIB = ${LIBSODIUM_LIB} ") + message(STATUS "Lua: LUA_LIB = ${LUA_LIB} / ${LUA_TARGET} ") + #message(STATUS "Lua_3rd: LUA_LIB_3RD = ${LUA_LIB_3RD} ") + message(STATUS "ZLib: ZLIB_LIB = ${ZLIB_LIB} / ${ZLIB_TARGET} ") + message(STATUS "ZZip: ZZIP_LIB = ${ZZIP_LIB} / ${ZZIP_TARGET} ") + message(STATUS "Fmt: FMT_LIB = ${FMT_LIB} / ${FMT_TARGET} ") + # message(FATAL_ERROR "Stop: XCSOAR_LINK_LIBRARIES") +endif() + +list(APPEND XCSOAR_LINK_LIBRARIES + ${LUA_TARGET} + ${CURL_TARGET} +### ${FMT_TARGET} + ${FMT_LIB} +# ${MAPSERVER_TARGET} + ${LIBPNG_TARGET} + ${ZLIB_TARGET} + ${ZZIP_TARGET} # internal or external... + ${SODIUM_TARGET} # new at 06/2020 + ${SSL_LIB} # new at 03/2021 + ${CRYPTO_LIB} # new at 03/2021 + ${CARES_TARGET} # new at 03/2021 + + ${Boost_LIBRARIES} +) + +if (WIN32) # Windows only: + # BASIC_LINK_LIBRARIES from Toolchain + list(APPEND XCSOAR_LINK_LIBRARIES ${BASIC_LINK_LIBRARIES}) +endif() + #========================================================== + #========================================================== + +list(APPEND SCRIPT_FILES + CMakeSource.cmake + ${PROJECTGROUP_BINARY_DIR}/VERSION.txt + OpenSoar.config + OpenSoar-News.md + OpenSoar-AddOn.md + NEWS.txt +) + +if (ANDROID) # library! + add_library(${TARGET_NAME} STATIC ${SOURCE_FILES}) +elseif(MINGW) + add_executable(${TARGET_NAME} ${SOURCE_FILES} ${SCRIPT_FILES} ${EXT_PROJ}) # ${XCSOAR_LINK_LIBRARIES}) +else() # executable! + message(STATUS "### add_executable(${TARGET_NAME} ${SOURCE_FILES} ${SCRIPT_FILES} ${EXT_PROJ}") + add_executable(${TARGET_NAME} ${SOURCE_FILES} ${SCRIPT_FILES} ${EXT_PROJ}) +endif() + + +list(APPEND XCSOAR_LINK_LIBRARIES ) # sequence is very important, I don't no, why'!!!! + +target_link_libraries(${TARGET_NAME} PUBLIC ${XCSOAR_LINK_LIBRARIES}) +if(MSVC) + target_link_options(${TARGET_NAME} PUBLIC "/SUBSYSTEM:WINDOWS") +endif() + +if(OPENGL_DEFINED) + target_link_libraries(${TARGET_NAME} + PRIVATE # PUBLIC + OpenGL::GL + OpenGL::GLU # single colon - was previous! + ) +endif() + +add_custom_command(TARGET ${TARGET_NAME} PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory ${directory} ${CMAKE_CURRENT_BINARY_DIR}/po +) + +foreach(translation ${TRANSLATIONS}) + add_custom_command(TARGET ${TARGET_NAME} PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PROJECTGROUP_SOURCE_DIR}/src/_Deprecated/${translation}.mo ${CMAKE_CURRENT_BINARY_DIR}/po/${translation}.mo + # TODO(aug): later do the creation here... + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PROJECTGROUP_SOURCE_DIR}/src/_Deprecated/${translation}.mo.c ${CMAKE_CURRENT_BINARY_DIR}/po/${translation}.mo.c + ) +endforeach() + +# list(APPEND SOURCE_FILES "${PROJECTGROUP_BINARY_DIR}/OpenSoar.rc") +# target_sources(${TARGET_NAME} PRIVATE "${PROJECTGROUP_BINARY_DIR}/OpenSoar.rc") + +add_dependencies(${TARGET_NAME} util libOpenSoar) + +# Test-Folder !!!! +#============================= + add_subdirectory(test/src) + add_subdirectory(tools) + message(STATUS "### Test =====================") + +# isn't possible: set_target_properties(ALL_BUILD PROPERTIES FOLDER _CMake) +# isn't possible: set_target_properties(ZERO_CHECK PROPERTIES FOLDER _CMake) +if (MSVC) + if (EXISTS D:/Data/OpenSoarData/August.prf) + set(OPENSOARDATA D:/Data/OpenSoarData) # this is only valid for August/Flaps6! + else () + set(OPENSOARDATA C:/OpenSoarData) + endif () + message(STATUS "Configure: ${PROJECTGROUP_BINARY_DIR}/${TARGET_NAME}.vcxproj.user") + configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/ide/msvc/OpenSoar.vcxproj.user.in" + "${PROJECTGROUP_BINARY_DIR}/${TARGET_NAME}.vcxproj.user" + ) +endif() diff --git a/CMakeSource.cmake b/CMakeSource.cmake new file mode 100644 index 00000000000..5d42ef70d32 --- /dev/null +++ b/CMakeSource.cmake @@ -0,0 +1,73 @@ +#============================================================================== +### NO LIBRARY: ### +set(Compatibility_SOURCES + Compatibility/fmode.cpp +) +#============================================================================== + +set(XCSOAR_LIB_LISTS + Profile # profile.a + Renderer ##?? + Widget # libwidget.a + Form # form.a + Look # liblook.a + ui # screen.a + io # io.a + co # libcoroutines + Task # libtask + Airspace + net + system + thread + util + InfoBoxes + + Computer + CrossSection + Gauge + Atmosphere + Audio + Blackboard + Dialogs + FLARM + Formatter + Hardware + IGC + Input + Job + Language + Logger + lua + Markers + Menu + Monitor + NMEA + Operation + Plane + Polar + Replay + Repository + TeamCode + Topography + UIUtil + Units + Waypoint + Weather + XML + + Device + Dialogs + MapWindow + Tracking + WeGlide # subdirectory off: src/net/client + + time + + zzip # Attention: this is the internal package, 3rd party lib zzip_3rd + jasper # Attention: this is the internal package, 3rd party lib jasper_3rd + + lib +) + + +list(APPEND XCSOAR_SOURCE_LISTS ${XCSOAR_LIB_LISTS}) diff --git a/Data/CMakeLists.txt b/Data/CMakeLists.txt new file mode 100644 index 00000000000..41a6217b0e8 --- /dev/null +++ b/Data/CMakeLists.txt @@ -0,0 +1,401 @@ +cmake_minimum_required(VERSION 3.18) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + +# set(_COMPLETE_INSTALL ON) + +get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +# the internal used directories: +set(_INCLUDE_OUTPUT ${OUTPUT}/include) +set(_DATA_INPUT ${PROJECTGROUP_SOURCE_DIR}/Data) +set(_DATA_OUTPUT ${OUTPUT}/Data) +set(_ICONS_OUTPUT ${_DATA_OUTPUT}/icons) +set(_TEMP_OUTPUT ${_DATA_OUTPUT}/temp) +set(_GRAPHICS_OUTPUT ${_DATA_OUTPUT}/graphics) + +include(CMakeSource.cmake) + +set (BIN_FILES + AUTHORS.gz + COPYING.gz + NEWS.txt.gz + OpenSoar-News.md.gz + Data/other/egm96s.dem +) + +set(GRAPHIC_FILES + ${_DATA_INPUT}/graphics/logo.svg + ${_DATA_INPUT}/graphics/progress_border.svg + ${_DATA_INPUT}/graphics/title.svg + + # ${_DATA_INPUT}/graphics/dialog_title.svg + # ${_DATA_INPUT}/graphics/launcher.svg +) + + +if("${PERCENT_CHAR}" STREQUAL "") + message(FATAL_ERROR PERCENT_CHAR not used: Stop!) +endif() + +set(SHOW_MATCHES OFF) + +set(SCRIPT_FILES ) +set(C_FILES) # Reset to empty... +if(ON) # MSVC) # mit minGW geht das nicht?? +# if(WIN32) # bei Linux klappt etwas nich!!! +foreach(bin_file ${BIN_FILES}) + get_filename_component(c_file ${bin_file} NAME) + set(c_file ${OUTPUT_FOLDER}/Data/${c_file}.c) + # set(c_file Data/${c_file}.c) + # similar add_custom_command - but not the same ;-( + if(${bin_file} MATCHES "\.gz$") + string(REGEX REPLACE "\.gz$" "" txt_file ${bin_file}) + if(SHOW_MATCHES) + message(STATUS "MATCHES!!!! ${bin_file} --- ${txt_file}") + endif() + set(zip_file "${_TEMP_OUTPUT}/${bin_file}") + # set(zip_file "${_DATA_OUTPUT}/temp/${bin_file}") + set (bin_file "${zip_file}") + if(SHOW_SOURCE_FILES) + message(STATUS "OUTPUT: ${bin_file} --> ${c_file}") + endif() + # message(STATUS "Zip-App: '${ZIP_APP}'") + add_custom_command(OUTPUT ${c_file} + COMMENT "BIN2C: ${bin_file}, " + COMMAND ${CMAKE_COMMAND} -E make_directory ${_DATA_OUTPUT} + # COMMAND echo "${ZIP_APP} a ${zip_file} ${txt_file}" + COMMAND ${ZIP_APP} a ${zip_file} ${txt_file} + # COMMAND echo "${PYTHON_APP} tools/python/bin2c.py ${bin_file} ${_DATA_OUTPUT}" + COMMAND ${PYTHON_APP} tools/python/bin2c.py ${bin_file} ${_DATA_OUTPUT} + WORKING_DIRECTORY ${PROJECTGROUP_SOURCE_DIR} + DEPENDS ${bin_file} + # DEPENDS ${PROJECTGROUP_SOURCE_DIR}/${bin_file} + ) + else() + message(STATUS "UNMATCHES!!!! ${bin_file} --- ${txt_file}") + message(STATUS "OUTPUT: ${bin_file} --> ${c_file}") + add_custom_command(OUTPUT ${c_file} + COMMENT BIN2C: ${bin_file}, + # COMMAND echo "Cmd: '${PYTHON_APP} tools/python/bin2c.py ${bin_file} ${_DATA_OUTPUT}' ==> ${c_file}" + COMMAND ${CMAKE_COMMAND} -E make_directory ${_DATA_OUTPUT} + COMMAND ${PYTHON_APP} tools/python/bin2c.py ${bin_file} ${_DATA_OUTPUT} + WORKING_DIRECTORY ${PROJECTGROUP_SOURCE_DIR} + DEPENDS ${PROJECTGROUP_SOURCE_DIR}/${bin_file} + # DEPENDS ${bin_file} + ) + endif() + list(APPEND C_FILES ${c_file}) +endforeach() +# endif(WIN32) + +message(STATUS "Image-App: '${BMP_CONVERT_APP}' ") + +# ============================================================================ +add_custom_command(OUTPUT ${_TEMP_OUTPUT}/title.svg + COMMENT "Replace Strings!" + COMMAND ${CMAKE_COMMAND} -E make_directory ${_TEMP_OUTPUT} + COMMAND ${PYTHON_APP} ${PROJECTGROUP_SOURCE_DIR}/tools/python/replace.py + ${PROJECTGROUP_SOURCE_DIR}/OpenSoar.config + ${_DATA_INPUT}/graphics/title.svg + ${_TEMP_OUTPUT}/title.svg + ${_INCLUDE_OUTPUT}/ProgramVersion.h + DEPENDS ${_DATA_INPUT}/graphics/title.svg + ${PROJECTGROUP_SOURCE_DIR}/OpenSoar.config + ${PROJECTGROUP_BINARY_DIR}/VERSION.txt + ${PROJECTGROUP_SOURCE_DIR}/tools/python/replace.py + WORKING_DIRECTORY ${PROJECTGROUP_SOURCE_DIR} +) +# ============================================================================ +if (0) # NOT MINGW) # geht bei MinGW nicht??? +# create the resource file (for all targets ) +# add_custom_command(OUTPUT ${_DATA_OUTPUT}/${PROGRAM_NAME}.rc +add_custom_command(OUTPUT ${PROJECTGROUP_BINARY_DIR}/${PROGRAM_NAME}.rc + COMMENT "Create Resource File!" + COMMAND ${PYTHON_APP} ${PROJECTGROUP_SOURCE_DIR}/tools/python/create_resource.py + # ${CMAKE_CURRENT_SOURCE_DIR}/OpenSoar.rc # Input + ${CMAKE_CURRENT_SOURCE_DIR}/OpenSoar.rc # Input + ${PROJECTGROUP_BINARY_DIR}/${PROGRAM_NAME}.rc # Output + ${_DATA_INPUT} + ${_DATA_OUTPUT} + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/OpenSoar.rc + # ${PROJECTGROUP_SOURCE_DIR}/tools/python/create_recource.py + # WORKING_DIRECTORY ${PROJECTGROUP_SOURCE_DIR} +) # add_custom_command +endif() + +add_custom_command(OUTPUT ${PROJECTGROUP_BINARY_DIR}/${PROGRAM_NAME}.rc + COMMENT "Create Resource File!" + COMMAND ${PYTHON_APP} ${PROJECTGROUP_SOURCE_DIR}/tools/python/create_resource.py + # ${CMAKE_CURRENT_SOURCE_DIR}/OpenSoar.rc # Input + ${CMAKE_CURRENT_SOURCE_DIR}/resources.txt # Input + ${PROJECTGROUP_BINARY_DIR}/${PROGRAM_NAME}.rc # Output + ${_DATA_INPUT} + ${_DATA_OUTPUT} + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/resources.txt +) +# message(FATAL_ERROR "!!!!!! ${PROJECTGROUP_BINARY_DIR}/${PROGRAM_NAME}.rc") +# if (_COMPLETE_INSTALL) +set(GRAPHIC_BITMAPS + ${_GRAPHICS_OUTPUT}/logo_160.bmp + ${_GRAPHICS_OUTPUT}/logo_80.bmp + ${_GRAPHICS_OUTPUT}/launcher_640.bmp + ${_GRAPHICS_OUTPUT}/launcher_640_1.bmp + ${_GRAPHICS_OUTPUT}/launcher_640_2.bmp + ${_GRAPHICS_OUTPUT}/title_320.bmp + ${_GRAPHICS_OUTPUT}/title_110.bmp +) # set + +# ============================================================================ +add_custom_command(OUTPUT ${GRAPHIC_BITMAPS} + COMMENT "Convert graphics!" + COMMAND ${CMAKE_COMMAND} -E make_directory ${_GRAPHICS_OUTPUT} + COMMAND ${BMP_CONVERT_APP} -size 160 Data/graphics/logo.svg bmp3:${_GRAPHICS_OUTPUT}/logo_160.bmp + COMMAND ${BMP_CONVERT_APP} -size 80 Data/graphics/logo.svg bmp3:${_GRAPHICS_OUTPUT}/logo_80.bmp + COMMAND ${BMP_CONVERT_APP} -background white -layers flatten +matte +dither -compress none -type optimize -colors 256 Data/graphics/launcher.svg bmp3:${_GRAPHICS_OUTPUT}/launcher_640.bmp + COMMAND ${BMP_CONVERT_APP} -crop "50${PERCENT_CHAR}x100${PERCENT_CHAR}" -scene 1 ${_GRAPHICS_OUTPUT}/launcher_640.bmp "bmp3:${_GRAPHICS_OUTPUT}/launcher_640_${PERCENT_CHAR}d.bmp" + COMMAND ${BMP_CONVERT_APP} Data/graphics/progress_border.svg bmp3:${_GRAPHICS_OUTPUT}/progress_border.bmp + COMMAND ${BMP_CONVERT_APP} -size 110x110 ${_TEMP_OUTPUT}/title.svg bmp3:${_GRAPHICS_OUTPUT}/title_110.bmp + COMMAND ${BMP_CONVERT_APP} -size 320x320 ${_TEMP_OUTPUT}/title.svg bmp3:${_GRAPHICS_OUTPUT}/title_320.bmp + + # COMMAND ${BMP_CONVERT_APP} -size 320 -background white -layers flatten +matte +dither -compress none -type optimize -colors 256 Data/graphics/title.svg bmp3:${_GRAPHICS_OUTPUT}/title_320.bmp + # WORKING_DIRECTORY ${PROJECTGROUP_SOURCE_DIR} + DEPENDS ${_DATA_INPUT}/graphics/logo.svg + ${_DATA_INPUT}/graphics/progress_border.svg + ${_DATA_INPUT}/graphics/launcher.svg + ${_TEMP_OUTPUT}/title.svg + WORKING_DIRECTORY ${PROJECTGROUP_SOURCE_DIR} +) #add_custom_command +# endif() + +set(ICON_BITMAPS ) # set to empty +if(ON) # ==> for test it only with few icons! + file(GLOB ICON_FILES ${_DATA_INPUT}/icons/*.svg) +else() + set (ICON_FILES + ${_DATA_INPUT}/icons/map_bridge.svg + ${_DATA_INPUT}/icons/map_castle.svg + ) +endif() +# set(ICON_FILES ) # empty!!!! +foreach(icon_file ${ICON_FILES}) + get_filename_component(_filename ${icon_file} NAME_WE) + set(icon_file_out ${_ICONS_OUTPUT}/${_filename}) + set(icon_file_std ${_ICONS_OUTPUT}/${_filename}_96) + set(icon_file_hd ${_ICONS_OUTPUT}/${_filename}_160) + set(icon_file_uhd ${_ICONS_OUTPUT}/${_filename}_300) + set(tmp_file ${_TEMP_OUTPUT}/icons/${_filename}) + set(BMP_CONVERT_PARAM +dither -compress none -type optimize -colors 256 ) + set(BMP_BACKGROUND white) # original gray! + # if (_COMPLETE_INSTALL) + list(APPEND ICON_BITMAPS ${icon_file_std}.bmp ${icon_file_hd}.bmp ${icon_file_uhd}.bmp) + if (WITH_REMOVE) + set (REMOVE_CMD + COMMAND ${CMAKE_COMMAND} -E remove -f ${tmp_file}_alpha.png + COMMAND ${CMAKE_COMMAND} -E remove -f ${tmp_file}_rgb.png + COMMAND ${CMAKE_COMMAND} -E remove -f ${tmp_file}.png + ) + else() + set (REMOVE_CMD) + endif() + if (OFF) + # August2111: linux is using XSLTPROC_APP, on Windows we using INKSCAPE_APP, is this the same??? + set (COPY_CMD + COMMAND ${XSLTPROC_APP} --nonet --stringparam DisableAA_Select "MASK_NOAA_" --output ${PROJECTGROUP_SOURCE_DIR}/build/svg_preprocess.xsl ${icon_file} + ) + else() + set (COPY_CMD + COMMAND ${INKSCAPE_APP} ${icon_file_out}.svg --export-dpi=124 --export-type=PNG --export-overwrite --export-filename=${icon_file_std}.png + COMMAND ${INKSCAPE_APP} ${icon_file_out}.svg --export-dpi=200 --export-type=PNG --export-overwrite --export-filename=${icon_file_hd}.png + COMMAND ${INKSCAPE_APP} ${icon_file_out}.svg --export-dpi=300 --export-type=PNG --export-overwrite --export-filename=${icon_file_uhd}.png + ) + endif() + # ========================================================================= + add_custom_command(OUTPUT ${icon_file_std}.bmp ${icon_file_hd}.bmp ${icon_file_uhd}.bmp + COMMENT File aus 'icons': ${icon_file_uhd}.bmp + COMMAND ${CMAKE_COMMAND} -E make_directory ${_ICONS_OUTPUT} + COMMAND ${CMAKE_COMMAND} -E make_directory ${_TEMP_OUTPUT}/icons + COMMAND ${CMAKE_COMMAND} -E copy ${icon_file} ${icon_file_out}.svg + ${COPY_CMD} + COMMAND ${BMP_CONVERT_APP} ${icon_file_uhd}.png -alpha Extract -colors 8 ${tmp_file}_alpha.png + # "-alpha Off" == "+matte" + COMMAND ${BMP_CONVERT_APP} ${icon_file_uhd}.png -background ${BMP_BACKGROUND} -flatten -alpha Off +dither -colors 64 ${tmp_file}_rgb.png + COMMAND ${BMP_MONTAGE_APP} -tile 2x1 -geometry +0+0 ${tmp_file}_alpha.png ${tmp_file}_rgb.png -depth 8 ${tmp_file}.png + COMMAND ${BMP_CONVERT_APP} ${tmp_file}.png -resize 132x66 -colors 64 BMP3:${icon_file_uhd}.bmp + COMMAND ${BMP_CONVERT_APP} ${tmp_file}.png -resize 44x22 -colors 64 BMP3:${icon_file_hd}.bmp + COMMAND ${BMP_CONVERT_APP} ${tmp_file}.png -resize 44x22 -colors 64 BMP3:${icon_file_std}.bmp + # COMMAND ${BMP_CONVERT_APP} ${tmp_file}.png -resize 20x10 -colors 64 BMP3:${icon_file_std}.bmp + ${REMOVE_CMD} + MAIN_DEPENDENCY ${icon_file} + DEPENDS ${icon_file} + WORKING_DIRECTORY ${PROJECTGROUP_SOURCE_DIR} + ) +# endif() +endforeach() + +# pure cmd line in console with output in console (bypass: > resource.h): +# perl -ne "print \"#define $1 $2\n\" if /^MAKE_RESOURCE\((\w+), (\d+)\);/;" [path-to-xcsoar]/XCSoar/src/Resources.hpp + +## moved to WinMSVC and so on! +if("${DOLLAR_CHAR}" STREQUAL "") + message(FATAL_ERROR DOLLAR_CHAR not used: Stop!) +endif() + set (PERL_CMD ${PERL_APP} -ne \"print \\\"\#define ${DOLLAR_CHAR}1 ${DOLLAR_CHAR}2\\n\\\" ) + string(APPEND PERL_CMD "if /^MAKE_RESOURCE\\\(\(\\w+\), \(\\d+\)\\\)") + string(APPEND PERL_CMD "\;/\;\"") + + set(PERL_INPUT ${PROJECTGROUP_SOURCE_DIR}/src/Resources.hpp) + set(RESOURCE_OUT ${_INCLUDE_OUTPUT}/resource.h) + message(STATUS PERL_CMD = "${PERL_CMD} ${PERL_INPUT} >${RESOURCE_OUT}") + # message(FATAL_ERROR Stop!) + + + add_custom_command( # TARGET ${TARGET_NAME} PRE_BUILD + OUTPUT ${RESOURCE_OUT} + COMMAND ${CMAKE_COMMAND} -E make_directory ${_INCLUDE_OUTPUT} + COMMAND echo ${PERL_CMD} ${PERL_INPUT} -- ${RESOURCE_OUT} + COMMAND ${PERL_CMD} ${PERL_INPUT} >${RESOURCE_OUT} + # COMMAND ${PERL_CMD} ${PERL_INPUT} + ## >${RESOURCE_OUT} + # COMMAND ${PERL_CMD} ${PERL_INPUT} >res2.h + # DEPENDS src/Resources.hpp # ${_INCLUDE_OUTPUT}/dirstamp + # DEPENDS ${PERL_INPUT} + DEPENDS ${PROJECTGROUP_SOURCE_DIR}/src/Resources.hpp + WORKING_DIRECTORY ${PROJECTGROUP_SOURCE_DIR} + COMMENT ==== + ) + + if (ON) # MSVC) # in other targets not possible to add this files to the project??? + source_group("Bitmaps" FILES ${ICON_BITMAPS} ${GRAPHIC_BITMAPS}) + endif() + source_group("Icons" FILES ${ICON_FILES}) + source_group("Graphics" FILES ${GRAPHIC_FILES}) + + ## add_custom_command(TARGET ${TARGET_NAME} PRE_LINK + set(INPUTEVENTS_CPP + ${_INCLUDE_OUTPUT}/InputEvents_Char2GCE.cpp + # ${_INCLUDE_OUTPUT}/InputEvents_Char2GCE.cpp + ${_INCLUDE_OUTPUT}/InputEvents_Char2NE.cpp + ${_INCLUDE_OUTPUT}/InputEvents_Text2Event.cpp + ${_INCLUDE_OUTPUT}/InputEvents_Text2GCE.cpp + ${_INCLUDE_OUTPUT}/InputEvents_Text2NE.cpp + ${_INCLUDE_OUTPUT}/InputEvents_default.cpp + ) + + set(DEFAULT_XCI ${_DATA_INPUT}/Input/defaultOV.xci) + # set(DEFAULT_XCI ${_DATA_INPUT}/Input/${DEFAULT_XCI_FILE}) + add_custom_command(OUTPUT ${_INCLUDE_OUTPUT}/InputCppFiles.txt + COMMENT Create InputEvents_*.cpp! + COMMAND ${CMAKE_COMMAND} -E make_directory ${_INCLUDE_OUTPUT} + COMMAND perl tools/Char2GCE.pl src/Input/InputQueue.hpp >${_INCLUDE_OUTPUT}/InputEvents_Char2GCE.cpp + COMMAND perl tools/Char2NE.pl src/Input/InputQueue.hpp >${_INCLUDE_OUTPUT}/InputEvents_Char2NE.cpp + COMMAND perl tools/Text2Event.pl src/Input/InputEvents.hpp >${_INCLUDE_OUTPUT}/InputEvents_Text2Event.cpp + COMMAND perl tools/Text2GCE.pl src/Input/InputQueue.hpp >${_INCLUDE_OUTPUT}/InputEvents_Text2GCE.cpp + COMMAND perl tools/Text2NE.pl src/Input/InputQueue.hpp >${_INCLUDE_OUTPUT}/InputEvents_Text2NE.cpp + COMMAND perl tools/xci2cpp.pl ${DEFAULT_XCI} >${_INCLUDE_OUTPUT}/InputEvents_default.cpp + COMMAND perl tools/xci2cpp.pl ${DEFAULT_XCI} >${_INCLUDE_OUTPUT}/InputCppFiles.txt + DEPENDS ${PROJECTGROUP_SOURCE_DIR}/src/Input/InputQueue.hpp + ${PROJECTGROUP_SOURCE_DIR}/src/Input/InputEvents.hpp + ${DEFAULT_XCI} + WORKING_DIRECTORY ${PROJECTGROUP_SOURCE_DIR} + ) + + add_custom_command( OUTPUT ${OUTPUT_FOLDER}/include/Status_defaults.cpp + # add_custom_command( OUTPUT DefaultStatus + # add_custom_command(TARGET ${TARGET_NAME} PRE_BUILD + # COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECTGROUP_SOURCE_DIR}/${_INCLUDE_OUTPUT} + COMMAND ${CMAKE_COMMAND} -E make_directory ${_INCLUDE_OUTPUT} + COMMAND perl tools/xcs2cpp.pl Data/Status/default.xcs >${OUTPUT_FOLDER}/include/Status_defaults.cpp + DEPENDS ${_DATA_INPUT}/Status/default.xcs + WORKING_DIRECTORY ${PROJECTGROUP_SOURCE_DIR} + ) + + list(APPEND INPUTEVENTS_CPP ${OUTPUT_FOLDER}/include/Status_defaults.cpp) + + # list(APPEND C_FILES ${_INCLUDE_OUTPUT}/Status_defaults.cpp) + + list(APPEND GRAPHIC_FILES "${_DATA_INPUT}/graphics/logo.svg") + list(APPEND GRAPHIC_FILES "${_DATA_INPUT}/graphics/progress_border.svg") + list(APPEND GRAPHIC_FILES "${_DATA_INPUT}/graphics/title.svg") + + include_directories(${_DATA_INPUT}) +endif() + include_directories( ${OUTPUT_FOLDER}/include ) + include_directories(${Boost_INCLUDE_DIR}) + +if(MSVC) + add_compile_definitions(__MSVC__) +endif() + +if(WIN32) + set(BITMAP_EXTENSION .bmp) +else() + set(BITMAP_EXTENSION .png) +endif() + +### configure_file( +### # "${CMAKE_CURRENT_SOURCE_DIR}/Data/OpenSoar.rc.in" +### "${CMAKE_CURRENT_SOURCE_DIR}/OpenSoar.rc.in" +### # OpenSoar.rc.in +### ${_DATA_OUTPUT}/OpenSoar.rc +### ) + +# list(APPEND SOURCE_FILES "${OUTPUT_FOLDER}/Data/OpenSoar.rc") +# list(APPEND SCRIPT_FILES "${CMAKE_CURRENT_SOURCE_DIR}/Data/OpenSoar.rc.in") + +if(MSVC) +set(RESOURCE_FILES +# ${CMAKE_CURRENT_SOURCE_DIR}/OpenSoar.rc # Input +# ${OUTPUT_FOLDER}/Data/OpenSoar.rc +# ${_DATA_OUTPUT}/${PROGRAM_NAME}.rc + ${PROJECTGROUP_BINARY_DIR}/${PROGRAM_NAME}.rc +) +elseif(MINGW) +set(RESOURCE_FILES + # ${CMAKE_CURRENT_SOURCE_DIR}/OpenSoar.rc.in + # ${_DATA_OUTPUT}/${PROGRAM_NAME}.rc + ### by Clang?? + # ${PROJECTGROUP_BINARY_DIR}/${PROGRAM_NAME}.rc +) +elseif(CLANG) +set(RESOURCE_FILES + # ${OUTPUT}/${PROGRAM_NAME}.rc + # ${PROJECTGROUP_BINARY_DIR}/${PROGRAM_NAME}.rc +# Clang:? ${CMAKE_CURRENT_SOURCE_DIR}/OpenSoar.rc +) +else() + # ${_DATA_OUTPUT}/OpenSoar.rc + # ${PROGRAM_NAME}.rc +endif() + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + + ${RESOURCE_FILES} # depends on system? + + ${C_FILES} + ${HEADER_FILES} + ${RESOURCE_OUT} + # GraphicBitmaps # the role... + ${GRAPHIC_BITMAPS} + ${GRAPHIC_FILES} + ${ICON_BITMAPS} + ${ICON_FILES} + ${PROJECTGROUP_SOURCE_DIR}/tools/Char2GCE.pl + # ${INPUTEVENTS_CPP} + ${_INCLUDE_OUTPUT}/InputCppFiles.txt + # InputCppFiles # role for input files + # DefaultStatus # role for status defaults + ${_INCLUDE_OUTPUT}/resource.h + # EXCLUDE_FROM_ALL + # ${CMAKE_CURRENT_SOURCE_DIR}/${PROGRAM_NAME}.rc.in +) + +set_target_properties(${TARGET_NAME} PROPERTIES + LINKER_LANGUAGE C + FOLDER Data + # ENABLE_EXPORTS TRUE +) + +add_dependencies(${TARGET_NAME} util) + diff --git a/Data/CMakeSource.cmake b/Data/CMakeSource.cmake new file mode 100644 index 00000000000..401a65b086a --- /dev/null +++ b/Data/CMakeSource.cmake @@ -0,0 +1,17 @@ +set (BIN_FILES + AUTHORS.gz + COPYING.gz + OpenSoar-News.md.gz + NEWS.txt.gz + Data/other/egm96s.dem +) + +file(GLOB ICON_FILES "icons/*.svg") +set(GRAPHIC_FILES ) +list(APPEND GRAPHIC_FILES "${_DATA_INPUT}/graphics/logo.svg") +list(APPEND GRAPHIC_FILES "${_DATA_INPUT}/graphics/progress_border.svg") +list(APPEND GRAPHIC_FILES "${_DATA_INPUT}/graphics/title.svg") + +set(SCRIPT_FILES ) +set(C_FILES) # Reset to empty... + diff --git a/Data/Input/default.xci b/Data/Input/default.xci index 9831175f97c..9b542a4b5e7 100644 --- a/Data/Input/default.xci +++ b/Data/Input/default.xci @@ -82,6 +82,12 @@ type=key data=ESCAPE event=Mode default +mode=default pan Nav1 Nav2 Display1 Display2 Config1 Config2 Config3 Info1 Info2 Menu Vario1 Vario2 +type=key +data=X +event=Exit system +event=Mode default + mode=default pan type=key data=ESCAPE @@ -1271,3 +1277,94 @@ data=0 event=AirSpace toggle label=Airspace\n$(AirspaceToggleActionName) location=34 + +mode=RemoteStick +type=key +data=0 +event=QuickMenu 57 +event=Mode default +event=Sounds quieter +label=Vario Audio Quieter +location=57 + +mode=RemoteStick +type=key +data=0 +event=QuickMenu 58 +event=Mode default +event=Sounds toggle +label=Vario Audio On/Off +location=58 + +mode=RemoteStick +type=key +data=0 +event=QuickMenu 59 +event=Mode default +event=Sounds louder +label=Vario Audio Louder +location=59 + +mode=RemoteStick +type=key +data=0 +event=Exit restart +event=Mode default +label=Restart +location=60 + +mode=RemoteStick +type=key +data=0 +event=Exit system +event=Mode default +label=Quit +location=61 + + +# ------------- +# Define AudioMenu buttons for Audio app +# - the PCM mixer controlled by OpenSoar +# ------------- + +mode=AudioMenu +type=key +data=DOWN +event=Sounds quieter +label=VOLUME- (DOWN) +location=1 + +mode=AudioMenu +type=key +data=RETURN +event=Sounds toggle +label=VOLUME ON/OFF (ENTER) +location=2 + +mode=AudioMenu +type=key +data=UP +event=Sounds louder +label=VOLUME+ (UP) +location=3 + +mode=AudioMenu +type=key +data=ESCAPE +event=Mode default +label=BACK (ESC) +location=5 + +mode=default RemoteStick +type=key +data=M +event=Mode AudioMenu + +## look line 85 +## mode=default +## type=key +## data=X +## event=Exit system + + + diff --git a/Data/Input/defaultOV.xci b/Data/Input/defaultOV.xci new file mode 100644 index 00000000000..e0de4a6e34e --- /dev/null +++ b/Data/Input/defaultOV.xci @@ -0,0 +1,1418 @@ +# ------------------- +# GlideComputerEvents +# ------------------- +### directly to SetupSystem after Switch On +### mode=default +### type=gce +### data=STARTUP_REAL +### # event=KeyPressed UP UP ENTER +### event=Setup System + +mode=default +type=gce +data=TASK_START +event=Beep 1 +event=TaskTransition start + +mode=default +type=gce +data=TASK_FINISH +event=Beep 1 +event=TaskTransition finish + +mode=default +type=gce +data=TASK_NEXTWAYPOINT +event=Beep 1 +event=TaskTransition next + +mode=default +type=gce +data=GPS_CONNECTION_WAIT + +mode=default +type=gce +data=COMMPORT_RESTART + +mode=default +type=gce +data=GPS_FIX_WAIT + +mode=default +type=gce +data=STARTUP_SIMULATOR + +mode=default +type=gce +data=STARTUP_REAL + +mode=default +type=gce +data=TAKEOFF +event=AutoLogger start +event=AddWaypoint takeoff +event=StatusMessage Takeoff + +mode=default +type=gce +data=LANDING +event=StatusMessage Landing +event=AutoLogger stop + +mode=default +type=gce +data=FLIGHTMODE_FINALGLIDE_ABOVE +event=StatusMessage Above final glide + +mode=default +type=gce +data=FLIGHTMODE_FINALGLIDE_BELOW +event=StatusMessage Below final glide + +mode=default +type=gce +data=FLIGHTMODE_FINALGLIDE_TERRAIN +event=StatusMessage Final glide through terrain + +mode=default +type=gce +data=LANDABLE_UNREACHABLE +event=Beep 1 + +# ------------ +# mode=default +# ------------ + +mode=Nav1 Nav2 Display1 Display2 Config1 Config2 Config3 Info1 Info2 Menu Vario1 Vario2 +type=key +data=ESCAPE +event=Mode default + +mode=default pan Nav1 Nav2 Display1 Display2 Config1 Config2 Config3 Info1 Info2 Menu Vario1 Vario2 +type=key +data=X +event=Shutdown shutdown +event=Mode default + +mode=default pan Nav1 Nav2 Display1 Display2 Config1 Config2 Config3 Info1 Info2 Menu Vario1 Vario2 +type=key +data=R +event=Shutdown reboot +event=Mode default + +mode=default pan Nav1 Nav2 Display1 Display2 Config1 Config2 Config3 Info1 Info2 Menu Vario1 Vario2 +type=key +data=Y +event=Exit restart +event=Mode default + +mode=default pan Nav1 Nav2 Display1 Display2 Config1 Config2 Config3 Info1 Info2 Menu Vario1 Vario2 +type=key +data=N +event=Exit newstart +event=Mode default + +mode=default pantype=key +data=ESCAPE +event=Page restore + +mode=default.Traffic +type=key +data=RETURN +event=Traffic details + +###### pan mode + +mode=pan +type=key +data=DOWN +event=Pan down + +mode=pan +type=key +data=UP +event=Pan up + +mode=pan +type=key +data=LEFT +event=Pan left + +mode=pan +type=key +data=RIGHT +event=Pan right + +mode=pan +type=key +data=APP1 +event=Pan off +label=Cancel +location=1 + +mode=pan +type=key +data=APP2 +event=Zoom in +label=Zoom\n+ +location=2 + +mode=pan +type=key +data=APP3 +event=Zoom out +label=Zoom\n- +location=3 + +mode=pan +type=key +data=APP4 +event=NearestMapItems +label=What's here? +location=4 + +mode=pan +type=key +data=F1 +event=Zoom in +location=5 + +mode=pan +type=key +data=F3 +event=Zoom out +location=6 + +mode=pan +type=key +data=RETURN +event=NearestMapItems +location=7 + +###### main entry buttons + +mode=default +type=key +data=F1 +event=QuickMenu + +mode=default +type=key +data=F2 +event=Analysis +event=Mode default + +mode=default +type=key +data=F3 +event=Checklist +event=Mode default + +mode=default +type=key +data=F4 +event=FlarmTraffic +event=Mode default + +mode=default +type=key +data=F5 +event=GotoLookup +event=Mode default + +mode=default +type=key +data=F6 +event=Setup Alternates +event=Mode default + +mode=default +type=key +data=F7 +event=Setup Task +event=Mode default + +mode=default +type=key +data=F8 +event=Setup Basic +event=Mode default + +mode=default +type=key +data=MENU +event=Mode Menu + +mode=default +type=key +data=APP1 +event=Mode Nav1 + +mode=default +type=key +data=APP2 +event=Mode Display1 + +mode=default +type=key +data=APP3 +event=Mode Config1 + +mode=default +type=key +data=APP4 +event=Mode Info1 + +# Always active buttons. (unless over-written) + +mode=default +type=key +data=DOWN +event=Zoom out + +mode=default +type=key +data=UP +event=Zoom in + +mode=default +type=key +data=RETURN +event=FLARMRadar toggle +event=ClearAirspaceWarnings +event=ClearStatusMessages + +mode=default +type=key +data=LEFT +event=ScreenModes previous + +mode=default +type=key +data=RIGHT +event=ScreenModes next + +# Gestures + +mode=default +type=gesture +data=U +event=Zoom in + +mode=default +type=gesture +data=D +event=Zoom out + +mode=default +type=gesture +data=UD +event=Zoom auto show +event=Zoom auto on + +mode=default +type=gesture +data=R +event=ScreenModes previous + +mode=default +type=gesture +data=L +event=ScreenModes next + +mode=default +type=gesture +data=DR +event=WaypointDetails select + +mode=default +type=gesture +data=DL +event=Setup Alternates + +mode=default +type=gesture +data=DU +event=Mode Menu + +mode=default +type=gesture +data=RD +event=Calculator + +mode=default +type=gesture +data=URD +event=Analysis + +mode=default +type=gesture +data=LDR +event=Checklist + +mode=default +type=gesture +data=URDL +event=Pan on + +mode=default +type=gesture +data=LDRDL +event=Status all + +### + +mode=default +type=key +data=6 +event=Setup Basic +event=Mode default + +mode=default +type=key +data=7 +event=Calculator + +#mode=default +#type=key +#data=8 +#event=Setup Task +#event=Mode default + +mode=default +type=key +data=9 +event=Setup Target + +#mode=default +#type=key +#data=0 +#event=ArmAdvance show +#event=ArmAdvance toggle + + +# ------------- +# mode=Nav1 +# ------------- + +mode=Nav1 +type=key +data=APP1 +event=Mode Nav2 +label=Nav\nPage 2/2 +location=1 + +mode=Nav1 +type=key +data=6 +event=Calculator +event=Mode default +label=Task Manager +location=5 + +mode=Nav1 +type=key +data=7 +event=AdjustWaypoint previousarm +label=$(WaypointPreviousArm) +location=6 + +mode=Nav1 +type=key +data=8 +event=AdjustWaypoint nextarm +label=$(WaypointNextArm) +location=7 + +mode=Nav1 +type=key +data=9 +event=WaypointDetails select +event=Mode default +label=Waypoint List$(CheckWaypointFile) +location=8 + +mode=Nav1 +type=key +data=0 +event=Setup Alternates +event=Mode default +label=Alternates$(CheckWaypointFile) +location=9 + +# ------------- +# mode=Nav2 +# ------------- + +mode=Nav2 +type=key +data=APP1 +event=Mode default +label=Cancel +location=1 + +mode=Nav2 +type=key +data=6 +event=Mode default +event=AbortTask toggle +label=Task\n$(TaskAbortToggleActionName)$(CheckWaypointFile) +location=5 + +mode=Nav2 +type=key +data=7 +event=Mode default +event=StatusMessage Dropped marker +event=Logger note Mark +event=MarkLocation +label=Marker Drop +location=6 + +mode=Nav2 +type=key +data=8 +event=Mode default +event=StatusMessage Pilot event announced +event=Logger note PEV +event=PilotEvent +label=Pilot Event Announce +location=7 + +mode=Nav2 +type=key +data=9 +event=Setup Target +event=Mode default +label=Target Show$(CheckTask)$(CheckTaskResumed) +location=8 + +# ------------- +# mode=Display1 +# ------------- + +mode=Display1 +type=key +data=APP2 +event=Mode Display2 +label=Display\nPage 2/2 +location=2 + + +mode=Display1 +type=key +data=6 +event=Zoom in +label=Zoom\n+ +location=5 + +mode=Display1 +type=key +data=7 +event=Zoom out +label=Zoom\n- +location=6 + +mode=Display1 +type=key +data=8 +event=Zoom auto show +event=Zoom auto toggle +label=Zoom\n$(ZoomAutoToggleActionName) +location=7 + +mode=Display1 +type=key +data=9 +event=ScreenModes cycle +label=Page Show\n$(NextPageName) +location=8 + +mode=Display1 +type=key +data=0 +event=Pan on +label=Pan Mode +location=9 + +# ------------- +# mode=Display2 +# ------------- + +mode=Display2 +type=key +data=APP2 +event=Mode default +label=Cancel +location=2 + +mode=Display2 +type=key +data=6 +event=DeclutterLabels show +event=DeclutterLabels toggle +label=Labels\n$(MapLabelsToggleActionName) +location=5 + +mode=Display2 +type=key +data=7 +event=SnailTrail show +event=SnailTrail toggle +label=Trail\n$(SnailTrailToggleName) +location=6 + +mode=Display2 +type=key +data=8 +event=TerrainTopography terrain toggle +label=Terrain\n$(TerrainToggleActionName) +location=7 + +mode=Display2 +type=key +data=9 +event=TerrainTopography topography toggle +label=Topo.\n$(TopographyToggleActionName) +location=8 + +mode=Display2 +type=key +data=0 +event=AirSpace toggle +label=Airspace\n$(AirspaceToggleActionName) +location=9 + +# ------------- +# mode=Config1 +# ------------- +mode=Config1 +type=key +data=APP3 +event=Mode Config2 +label=Config\nPage 2/3 +location=3 + +mode=Config1 +type=key +data=6 +event=Setup System +event=Mode default +label=System +location=5 + +mode=Config1 +type=key +data=7 +event=Setup Plane +event=Mode default +label=Plane +location=6 + +mode=Config1 +type=key +data=8 +event=Device list +event=Mode default +label=Devices +location=7 + +mode=Config1 +type=key +data=9 +event=Setup Basic +event=Mode default +label=Flight +location=8 + +mode=Config1 +type=key +data=0 +event=Setup Wind +event=Mode default +label=Wind +location=9 + +# ------------- +# mode=Config2 +# ------------- +mode=Config2 +type=key +data=APP3 +event=Mode Config3 +label=Config\nPage 3/3 +location=3 + +mode=Config2 +type=key +data=6 +event=Setup Profile +event=Mode default +label=Profiles +location=5 + +mode=Config2 +type=key +data=8 +event=WaypointEditor +event=Mode default +label=Waypoint Editor +location=7 + +mode=Config2 +type=key +data=9 +event=FileManager +event=Mode default +label=File Manager +location=8 + +mode=Config2 +type=key +data=0 +event=Setup Replay +event=Mode default +label=Replay$(CheckReplay) +location=9 + +# ------------- +# mode=Config3 +# ------------- +mode=Config3 +type=key +data=APP3 +event=Mode default +label=Cancel +location=3 + +mode=Config3 +type=key +data=6 +event=Logger show +event=Logger toggle ask +label=Logger\n$(LoggerActive)$(CheckLogger) +location=5 + +mode=Config3 +type=key +data=8 +event=Logger nmea +label=Raw Logger$(CheckLogger) +location=6 + +mode=Config3 +type=key +data=7 +event=RunLuaFile +event=Mode default +label=Lua +location=7 + +mode=Config3 +type=key +data=9 +event=Mode Vario1 +label=Vega$(CheckVega) +location=8 + +# ------------- +# mode=Vario1 +# ------------- + +mode=Vario1 +type=key +data=APP3 +event=Mode Vario2 +label=Vega\nPage 2/2 +location=3 + +mode=Vario1 +type=key +data=6 +event=Setup Switches +event=Mode default +label=Airframe Switches +location=5 + +mode=Vario1 +type=key +data=8 +event=AdjustVarioFilter xdemo +label=Manual Demo +location=7 + +mode=Vario1 +type=key +data=9 +event=AdjustVarioFilter zero +label=Setup Stall +location=8 + +mode=Vario1 +type=key +data=0 +event=AdjustVarioFilter accel +label=Accel +location=9 + +# ------------- +# mode=Vario2 +# ------------- + +mode=Vario2 +type=key +data=APP3 +event=Mode default +label=Vega\n2/2 +location=3 + +mode=Vario2 +type=key +data=6 +event=AdjustVarioFilter zero +event=StatusMessage Vario ASI zeroed +label=ASI Zero +location=5 + +mode=Vario2 +type=key +data=7 +event=StatusMessage Accelerometer leveled +label=Accel Zero +location=6 + +mode=Vario2 +type=key +data=8 +event=AdjustVarioFilter save +event=StatusMessage Stored to EEPROM +label=Store +location=7 + +mode=Vario2 +type=key +data=9 +event=AdjustVarioFilter demostf +label=Cruise Demo +location=8 + +mode=Vario2 +type=key +data=0 +event=AdjustVarioFilter democlimb +label=Climb Demo +location=9 + +# ------------- +# mode=Info1 +# ------------- +mode=Info1 +type=key +data=APP4 +event=Mode Info2 +label=Info\nPage 2/3 +location=4 + +mode=Info1 +type=key +data=6 +event=FlarmTraffic +event=Mode default +label=FLARM Radar$(CheckFLARM) +location=5 + +mode=Info1 +type=key +data=7 +event=Weather +event=Mode default +label=Weather +location=6 + +mode=Info1 +type=key +data=8 +event=NearestMapItems +event=Mode default +label=What's here? +location=7 + +mode=Info1 +type=key +data=9 +event=Checklist +event=Mode default +label=Checklist +location=8 + +mode=Info1 +type=key +data=0 +event=Analysis +event=Mode default +label=Analysis +location=9 + +# ------------- +# mode=Info2 +# ------------- +mode=Info2 +type=key +data=APP4 +event=Mode Info3 +label=Info\nPage 3/3 +location=4 + +mode=Info2 +type=key +data=6 +event=Status all +event=Mode default +label=Status +location=5 + +mode=Info2 +type=key +data=8 +event=Setup Teamcode +event=Mode default +label=Team Code +location=7 + +mode=Info2 +type=key +data=9 +event=FlarmDetails +event=Mode default +label=Traffic List +location=8 + +mode=Info2 +type=key +data=0 +event=ThermalAssistant +event=Mode default +label=Thermal Assistant +location=9 + +# ------------- +# mode=Info3 +# ------------- +mode=Info3 +type=key +data=APP4 +event=Mode default +label=Cancel +location=4 + + +mode=Info3 +type=key +data=6 +event=Credits +event=Mode default +label=Credits +location=5 + +mode=Info3 +type=key +data=7 +event=AirSpace list +event=Mode default +label=Airspaces +location=6 + +mode=Info3 +type=key +data=8 +event=RepeatStatusMessage +label=Message Repeat +location=7 + +# ------------- +# mode=Menu +# ------------- + +mode=Menu +type=key +data=APP1 +event=Mode Nav1 +label=Nav +location=1 + +mode=Menu +type=key +data=APP2 +event=Mode Display1 +label=Display +location=2 + +mode=Menu +type=key +data=APP3 +event=Mode Config1 +label=Config +location=3 + +mode=Menu +type=key +data=APP4 +event=Mode Info1 +label=Info +location=4 + +mode=Menu +type=key +data=9 +event=LockScreen +event=Mode default +label=Lock Screen +location=7 + +mode=Menu +type=key +data=9 +event=Mode default +label=Cancel +location=8 + +mode=Menu +type=key +data=0 +event=Exit system +event=Mode default +label=Quit +location=9 + +# ---------------------------------- +# mode=default.TA (ThermalAssistant) +# ---------------------------------- + +# --------------------- +# mode=Display1.Traffic +# --------------------- + +mode=Display1.Traffic +type=key +data=6 +event=Traffic zoom in +label=Zoom\n+ +location=5 + +mode=Display1.Traffic +type=key +data=7 +event=Traffic zoom out +label=Zoom\n- +location=6 + +mode=Display1.Traffic +type=key +data=8 +event=Traffic zoom auto toggle +label=Zoom\n$(TrafficZoomAutoToggleActionName) +location=7 + +mode=Display1.Traffic +type=key +data=0 +event=Traffic northup toggle +label=$(TrafficNorthUpToggleActionName) +location=9 + +mode=Display2.Traffic +type=key +data=6 +event=Traffic label toggle +label=AVG/ALT +location=5 + +# ------------- +# mode=RemoteStick +# ------------- + +mode=RemoteStick +type=key +data=0 +event=Calculator +event=Mode default +label=Task +location=0 + +mode=RemoteStick +type=key +data=0 +event=AdjustWaypoint previousarm +label=$(WaypointPreviousArm) +location=1 + +mode=RemoteStick +type=key +data=0 +event=AdjustWaypoint nextarm +label=$(WaypointNextArm) +location=2 + +mode=RemoteStick +type=key +data=0 +event=WaypointDetails select +event=Mode default +label=Waypoint List$(CheckWaypointFile) +location=3 + +mode=RemoteStick +type=key +data=0 +event=Setup Alternates +event=Mode default +label=Alternates$(CheckWaypointFile) +location=4 + +mode=RemoteStick +type=key +data=0 +event=Mode default +event=AbortTask toggle +label=Task\n$(TaskAbortToggleActionName)$(CheckWaypointFile) +location=5 + +mode=RemoteStick +type=key +data=0 +event=GotoLookup +event=Mode default +label=GoTo$(CheckWaypointFile) +location=6 + +mode=RemoteStick +type=key +data=0 +event=Setup Target +event=Mode default +label=Target Show$(CheckTask)$(CheckTaskResumed) +location=7 + + +mode=RemoteStick +type=key +data=0 +event=Zoom auto show +event=Zoom auto toggle +label=Zoom\n$(ZoomAutoToggleActionName) +location=9 + +mode=RemoteStick +type=key +data=0 +event=Mode default +event=StatusMessage Dropped marker +event=Logger note Mark +event=MarkLocation +label=Marker Drop +location=10 + +mode=RemoteStick +type=key +data=0 +event=Pan on +label=Pan Mode +location=11 + +mode=RemoteStick +type=key +data=0 +event=DeclutterLabels show +event=DeclutterLabels toggle +label=Labels\n$(MapLabelsToggleActionName) +location=12 + +mode=RemoteStick +type=key +data=0 +event=SnailTrail show +event=SnailTrail toggle +label=Trail\n$(SnailTrailToggleName) +location=13 + +mode=RemoteStick +type=key +data=0 +event=TerrainTopography terrain toggle +label=Terrain\n$(TerrainToggleActionName) +location=14 + +mode=RemoteStick +type=key +data=0 +event=TerrainTopography topography toggle +label=Topo.\n$(TopographyToggleActionName) +location=15 + + +mode=RemoteStick +type=key +data=0 +event=MacCready auto show +event=MacCready auto toggle +label=$(CheckAutoMc)MC\n$(MacCreadyToggleActionName) +location=16 + +mode=RemoteStick +type=key +data=0 +event=Setup Basic +event=Mode default +label=Flight Setup +location=17 + +mode=RemoteStick +type=key +data=0 +event=Setup Wind +event=Mode default +label=Setup Wind +location=18 + +mode=RemoteStick +type=key +data=0 +event=Setup System +event=Mode default +label=Setup System +location=19 + +mode=RemoteStick +type=key +data=0 +event=Setup Airspace +event=Mode default +label=Settings Airspace$(CheckAirspace) +location=20 + +mode=RemoteStick +type=key +data=0 +event=Logger show +event=Logger toggle ask +label=Logger\n$(LoggerActive)$(CheckLogger) +location=21 + +mode=RemoteStick +type=key +data=0 +event=Logger nmea +label=Raw Logger$(CheckLogger) +location=22 + +mode=RemoteStick +type=key +data=0 +event=Device list +event=Mode default +label=Devices +location=23 + +mode=RemoteStick +type=key +data=0 +event=Setup Plane +event=Mode default +label=Setup Plane +location=24 + +mode=RemoteStick +type=key +data=0 +event=FlarmTraffic +label=FLARM Radar$(CheckFLARM) +location=25 + +mode=RemoteStick +type=key +data=0 +event=Weather +event=Mode default +label=Weather +location=26 + +mode=RemoteStick +type=key +data=0 +event=NearestAirspaceDetails +event=Mode default +label=Nearest Airspace$(CheckAirspace) +location=27 + +mode=RemoteStick +type=key +data=0 +event=Checklist +event=Mode default +label=Checklist +location=28 + +mode=RemoteStick +type=key +data=0 +event=Analysis +event=Mode default +label=Analysis +location=29 + +mode=RemoteStick +type=key +data=0 +event=Status all +event=Mode default +label=Status +location=30 + +mode=RemoteStick +type=key +data=0 +event=ThermalAssistant +event=Mode default +label=Thermal Assistant$(CheckCircling) +location=31 + +mode=RemoteStick +type=key +data=0 +event=FileManager +event=Mode default +label=File Manager +location=32 + +mode=RemoteStick +type=key +data=0 +event=Mode default +event=StatusMessage Pilot event announced +event=Logger note PEV +event=PilotEvent +label=Pilot Event Announce +location=33 + +mode=RemoteStick +type=key +data=0 +event=AirSpace toggle +label=Airspace\n$(AirspaceToggleActionName) +location=34 + + +mode=RemoteStick +type=key +data=0 +event=QuickMenu 57 +event=Mode default +event=Sounds quieter +label=Vario Audio Quieter$(CheckAudioQuiet) +location=57 + +mode=RemoteStick +type=key +data=0 +event=QuickMenu 58 +event=Mode default +event=Sounds toggle +label=Vario Audio\n$(AudioOnOff) +location=58 + +mode=RemoteStick +type=key +data=0 +event=QuickMenu 59 +event=Mode default +event=Sounds louder +label=Vario Audio Louder$(CheckAudioLoud) +location=59 + +mode=RemoteStick +type=key +data=0 +event=Exit restart +event=Mode default +label=Restart +location=60 + +mode=RemoteStick +type=key +data=0 +event=Exit system +event=Mode default +label=Quit +location=61 + +# OpenVario only: +mode=RemoteStick +type=key +data=0 +event=Shutdown reboot +event=Mode default +label=Reboot +location=62 + +# OpenVario only: +mode=RemoteStick +type=key +data=0 +event=Shutdown shutdown +event=Mode default +label=Shutdown +location=63 + +# ------------- +# Define AudioMenu buttons for Audio app +# - the PCM mixer controlled by OpenSoar +# ------------- + +mode=AudioMenu +type=key +data=DOWN +event=Sounds quieter +label=VOLUME- (DOWN)$(CheckAudioQuiet) +location=1 + +mode=AudioMenu +type=key +data=RETURN +event=Sounds toggle +label=VOLUME $(AudioOnOff)\n(ENTER) +location=2 + +mode=AudioMenu +type=key +data=UP +event=Sounds louder +label=VOLUME+ (UP)$(CheckAudioLoud) +location=3 + +mode=AudioMenu +type=key +data=ESCAPE +event=Mode default +label=BACK (ESC) +location=5 + +mode=default RemoteStick +type=key +data=M +event=Mode AudioMenu + +## Shutdown looks line 85 + +### call SetupSystem with 'p' +mode=default RemoteStick +type=key +data=P +event=Setup System + +### check using KeyPressed event with 'z' +mode=default RemoteStick +type=key +data=Z +event=KeyPressed P + + diff --git a/Data/OpenSoar.def b/Data/OpenSoar.def new file mode 100644 index 00000000000..e69de29bb2d diff --git a/Data/XCSoar.rc b/Data/OpenSoar.rc similarity index 100% rename from Data/XCSoar.rc rename to Data/OpenSoar.rc diff --git a/Data/OpenSoar.rc.in b/Data/OpenSoar.rc.in new file mode 100644 index 00000000000..c33d55126ef --- /dev/null +++ b/Data/OpenSoar.rc.in @@ -0,0 +1,238 @@ +// Enables High Resolution Legacy Support on Windows Mobile devices (> WM 5.0) +// (see http://msdn.microsoft.com/en-us/library/ms889982.aspx) +HI_RES_AWARE CEUX {1} + +// #include "D:/Projects/Binaries/OpenSoar/dev-branch/include/resource.h" +#include "../include/resource.h" + +#if !defined(ANDROID) || defined(ANDROID_DRAWABLE) +#define BITMAP(name, path) name BITMAP DISCARDABLE path +#else +/* on Android, these are included as drawable resources (PNG) */ +#define BITMAP(name, path) +#endif + +#ifdef _WIN32 + +#ifdef __MSVC__ +#define XC_RESOURCE(name, type, dir, file, ext) name type DISCARDABLE \ + dir##file##ext +#else +# include +# include +#define XC_RESOURCE(name, type, dir, file, ext) name type DISCARDABLE \ + BOOST_PP_STRINGIZE(dir) BOOST_PP_STRINGIZE(file) BOOST_PP_STRINGIZE(ext) +#endif + +// XC_RESOURCE(name, BITMAP, @CMAKE_CURRENT_SOURCE_DIR@/Data/bitmaps/, +#define BITMAP_BITMAP(name, file) \ + XC_RESOURCE(name, BITMAP, @_DATA_INPUT@/bitmaps/, \ + file, ${BITMAP_EXTENSION}) + +#define BITMAP_ICON(name, file) \ + XC_RESOURCE(name, BITMAP, icons/, file, ${BITMAP_EXTENSION}) + +#define BITMAP_GRAPHIC(name, file) \ + XC_RESOURCE(name, BITMAP, graphics/, file, ${BITMAP_EXTENSION}) + +/* only GDI knows how to deal with hatched brushes, the rest uses transparency */ +# define HATCH_BITMAP(name, file) BITMAP_BITMAP(name, file) + +# define SOUND(name, file) \ + XC_RESOURCE(name, WAVE, @_DATA_INPUT@/sound/, file, .wav) + +// XC_RESOURCE(name, WAVE, @CMAKE_CURRENT_SOURCE_DIR@/Data/sound/, file, .wav) +#else +#define BITMAP_ICON(name, file) +#define BITMAP_GRAPHIC(name, file) +# define HATCH_BITMAP(name, file) +# define SOUND(name, file) + +#endif // _WIN32 + +// --- Icons --- +ICON_ICON(IDI_XCSOAR, OpenSoar) + +// --- Bitmaps --- + +// IDB_ABORT BITMAP DISCARDABLE "D:/Projects/Binaries/OpenSoar/dev-branch/Data/graphics/mode_abort.bmp" + +BITMAP_ICON(IDB_ABORT, mode_abort) +BITMAP_ICON(IDB_ABORT_HD, mode_abort_160) + +HATCH_BITMAP(IDB_ABOVETERRAIN, aboveterrain) + +BITMAP_ICON(IDB_AIRPORT_REACHABLE, alt_reachable_airport) +BITMAP_ICON(IDB_AIRPORT_REACHABLE_HD, alt_reachable_airport_160) +BITMAP_ICON(IDB_AIRPORT_MARGINAL, alt_marginal_airport) +BITMAP_ICON(IDB_AIRPORT_MARGINAL_HD, alt_marginal_airport_160) +BITMAP_ICON(IDB_AIRPORT_UNREACHABLE, alt_landable_airport) +BITMAP_ICON(IDB_AIRPORT_UNREACHABLE_HD, alt_landable_airport_160) +BITMAP_ICON(IDB_AIRPORT_MARGINAL2, alt2_marginal_airport) +BITMAP_ICON(IDB_AIRPORT_MARGINAL2_HD, alt2_marginal_airport_160) +BITMAP_ICON(IDB_AIRPORT_UNREACHABLE2, alt2_landable_airport) +BITMAP_ICON(IDB_AIRPORT_UNREACHABLE2_HD, alt2_landable_airport_160) + + // airspace3 is a bad design on PC and WIN64 +HATCH_BITMAP(IDB_AIRSPACE0, airspace3) +HATCH_BITMAP(IDB_AIRSPACE1, airspace1) +HATCH_BITMAP(IDB_AIRSPACE2, airspace2) +HATCH_BITMAP(IDB_AIRSPACE3, airspace3) +HATCH_BITMAP(IDB_AIRSPACE4, airspace4) +HATCH_BITMAP(IDB_AIRSPACE5, airspace5) +HATCH_BITMAP(IDB_AIRSPACE6, airspace6) +HATCH_BITMAP(IDB_AIRSPACE7, airspace7) + +BITMAP_ICON(IDB_AIRSPACEI, airspace_intercept) +BITMAP_ICON(IDB_AIRSPACEI_HD, airspace_intercept_160) +BITMAP_ICON(IDB_CRUISE, mode_cruise) +BITMAP_ICON(IDB_CRUISE_HD, mode_cruise_160) +BITMAP_ICON(IDB_CLIMB, mode_climb) +BITMAP_ICON(IDB_CLIMB_HD, mode_climb_160) +BITMAP_BITMAP(IDB_CLIMBSMALL, climb_12) +BITMAP_BITMAP(IDB_CLIMBSMALLINV, climb_12inv) +BITMAP_ICON(IDB_FOLDER, folder) +BITMAP_ICON(IDB_FOLDER_HD, folder_160) +BITMAP_ICON(IDB_SETTINGS, settings) +BITMAP_ICON(IDB_SETTINGS_HD, settings_160) +BITMAP_ICON(IDB_TASK, task) +BITMAP_ICON(IDB_TASK_HD, task_160) +BITMAP_ICON(IDB_CALCULATOR, calculator) +BITMAP_ICON(IDB_CALCULATOR_HD, calculator_160) +BITMAP_ICON(IDB_WRENCH, wrench) +BITMAP_ICON(IDB_WRENCH_HD, wrench_160) +BITMAP_ICON(IDB_GLOBE, globe) +BITMAP_ICON(IDB_GLOBE_HD, globe_160) +BITMAP_ICON(IDB_DEVICE, device) +BITMAP_ICON(IDB_DEVICE_HD, device_160) +BITMAP_ICON(IDB_RULES, rules) +BITMAP_ICON(IDB_RULES_HD, rules_160) +BITMAP_ICON(IDB_CLOCK, clock) +BITMAP_ICON(IDB_CLOCK_HD, clock_160) + +#ifdef EYE_CANDY +#ifdef XCSOAR_TESTING +BITMAP_GRAPHIC(IDB_DIALOGTITLE, dialog_title_red) +#else +BITMAP_GRAPHIC(IDB_DIALOGTITLE, dialog_title) +#endif +#endif +BITMAP_ICON(IDB_FINALGLIDE, mode_finalglide) +BITMAP_ICON(IDB_FINALGLIDE_HD, mode_finalglide_160) +BITMAP_ICON(IDB_TRAFFIC_SAFE, flarm_traffic) +BITMAP_ICON(IDB_TRAFFIC_SAFE_HD, flarm_traffic_160) +BITMAP_ICON(IDB_TRAFFIC_WARNING, flarm_warning) +BITMAP_ICON(IDB_TRAFFIC_WARNING_HD, flarm_warning_160) +BITMAP_ICON(IDB_TRAFFIC_ALARM, flarm_alarm) +BITMAP_ICON(IDB_TRAFFIC_ALARM_HD, flarm_alarm_160) +BITMAP_ICON(IDB_GPSSTATUS1, gps_acquiring) +BITMAP_ICON(IDB_GPSSTATUS1_HD, gps_acquiring_160) +BITMAP_ICON(IDB_GPSSTATUS2, gps_disconnected) +BITMAP_ICON(IDB_GPSSTATUS2_HD, gps_disconnected_160) +BITMAP_ICON(IDB_LANDABLE, winpilot_landable) +BITMAP_ICON(IDB_LANDABLE_HD, winpilot_landable_160) +#ifdef XCSOAR_TESTING +BITMAP_GRAPHIC(IDB_LAUNCHER1, launcher_red_640_1) +BITMAP_GRAPHIC(IDB_LAUNCHER2, launcher_red_640_2) +#else +BITMAP_GRAPHIC(IDB_LAUNCHER1, launcher_640_1) +BITMAP_GRAPHIC(IDB_LAUNCHER2, launcher_640_2) +#endif +BITMAP_ICON(IDB_MAPSCALE_LEFT, scalearrow_left) +BITMAP_ICON(IDB_MAPSCALE_RIGHT, scalearrow_right) +BITMAP_ICON(IDB_MAPSCALE_LEFT_HD, scalearrow_left_160) +BITMAP_ICON(IDB_MAPSCALE_RIGHT_HD, scalearrow_right_160) +BITMAP_ICON(IDB_MARK, map_flag) +BITMAP_ICON(IDB_MARK_HD, map_flag_160) +BITMAP_ICON(IDB_OBSTACLE, map_obstacle) +BITMAP_ICON(IDB_OBSTACLE_HD, map_obstacle_160) +BITMAP_ICON(IDB_OUTFIELD_REACHABLE, alt_reachable_field) +BITMAP_ICON(IDB_OUTFIELD_REACHABLE_HD, alt_reachable_field_160) +BITMAP_ICON(IDB_OUTFIELD_MARGINAL, alt_marginal_field) +BITMAP_ICON(IDB_OUTFIELD_MARGINAL_HD, alt_marginal_field_160) +BITMAP_ICON(IDB_OUTFIELD_UNREACHABLE, alt_landable_field) +BITMAP_ICON(IDB_OUTFIELD_UNREACHABLE_HD, alt_landable_field_160) +BITMAP_ICON(IDB_OUTFIELD_MARGINAL2, alt2_marginal_field) +BITMAP_ICON(IDB_OUTFIELD_MARGINAL2_HD, alt2_marginal_field_160) +BITMAP_ICON(IDB_OUTFIELD_UNREACHABLE2, alt2_landable_field) +BITMAP_ICON(IDB_OUTFIELD_UNREACHABLE2_HD, alt2_landable_field_160) +BITMAP_ICON(IDB_MOUNTAIN_PASS, map_pass) +BITMAP_ICON(IDB_MOUNTAIN_PASS_HD, map_pass_160) +#ifdef XCSOAR_TESTING +BITMAP_GRAPHIC(IDB_PROGRESSBORDER, progress_border_red) +#else +BITMAP_GRAPHIC(IDB_PROGRESSBORDER, progress_border) +#endif +BITMAP_ICON(IDB_REACHABLE, winpilot_reachable) +BITMAP_ICON(IDB_REACHABLE_HD, winpilot_reachable_160) +BITMAP_ICON(IDB_MARGINAL, winpilot_marginal) +BITMAP_ICON(IDB_MARGINAL_HD, winpilot_marginal_160) +BITMAP_ICON(IDB_SMALL, map_small) +BITMAP_ICON(IDB_SMALL_HD, map_small_160) +#ifdef XCSOAR_TESTING +BITMAP_GRAPHIC(IDB_LOGO_HD, logo_red_160) +BITMAP_GRAPHIC(IDB_LOGO, logo_red_80) +#else +BITMAP_GRAPHIC(IDB_LOGO_HD, logo_160) +BITMAP_GRAPHIC(IDB_LOGO, logo_80) +#endif +BITMAP_ICON(IDB_TARGET, map_target) +BITMAP_ICON(IDB_TARGET_HD, map_target_160) +BITMAP_ICON(IDB_TEAMMATE_POS, map_teammate) +BITMAP_ICON(IDB_TEAMMATE_POS_HD, map_teammate_160) +BITMAP_ICON(IDB_TERRAINWARNING, map_terrainw) +BITMAP_ICON(IDB_TERRAINWARNING_HD, map_terrainw_160) +BITMAP_ICON(IDB_THERMALSOURCE, map_thermal_source) +BITMAP_ICON(IDB_THERMALSOURCE_HD, map_thermal_source_160) +BITMAP_ICON(IDB_TOWN, map_town) +BITMAP_ICON(IDB_TOWN_HD, map_town_160) +BITMAP_ICON(IDB_TURNPOINT, map_turnpoint) +BITMAP_ICON(IDB_TURNPOINT_HD, map_turnpoint_160) +BITMAP_ICON(IDB_TASKTURNPOINT, map_taskturnpoint) +BITMAP_ICON(IDB_TASKTURNPOINT_HD, map_taskturnpoint_160) +BITMAP_ICON(IDB_MOUNTAIN_TOP, map_mountain_top) +BITMAP_ICON(IDB_MOUNTAIN_TOP_HD, map_mountain_top_160) +BITMAP_ICON(IDB_BRIDGE, map_bridge) +BITMAP_ICON(IDB_BRIDGE_HD, map_bridge_160) +BITMAP_ICON(IDB_TUNNEL, map_tunnel) +BITMAP_ICON(IDB_TUNNEL_HD, map_tunnel_160) +BITMAP_ICON(IDB_TOWER, map_tower) +BITMAP_ICON(IDB_TOWER_HD, map_tower_160) +BITMAP_ICON(IDB_POWER_PLANT, map_power_plant) +BITMAP_ICON(IDB_POWER_PLANT_HD, map_power_plant_160) +BITMAP_ICON(IDB_THERMAL_HOTSPOT, map_thermal_hotspot) +BITMAP_ICON(IDB_THERMAL_HOTSPOT_HD, map_thermal_hotspot_160) +BITMAP_ICON(IDB_VOR, map_vor) +BITMAP_ICON(IDB_VOR_HD, map_vor_160) +BITMAP_ICON(IDB_NDB, map_ndb) +BITMAP_ICON(IDB_NDB_HD, map_ndb_160) +BITMAP_ICON(IDB_DAM, map_dam) +BITMAP_ICON(IDB_DAM_HD, map_dam_160) +BITMAP_ICON(IDB_CASTLE, map_castle) +BITMAP_ICON(IDB_CASTLE_HD, map_castle_160) +BITMAP_ICON(IDB_INTERSECTION, map_intersection) +BITMAP_ICON(IDB_INTERSECTION_HD, map_intersection_160) +BITMAP_ICON(IDB_REPORTING_POINT, map_reporting_point) +BITMAP_ICON(IDB_REPORTING_POINT_HD, map_reporting_point_160) +BITMAP_ICON(IDB_PGTAKEOFF, map_pgtakeoff) +BITMAP_ICON(IDB_PGTAKEOFF_HD, map_pgtakeoff_160) +BITMAP_ICON(IDB_PGLANDING, map_pglanding) +BITMAP_ICON(IDB_PGLANDING_HD, map_pglanding_160) +#ifdef XCSOAR_TESTING +BITMAP_GRAPHIC(IDB_TITLE, title_red_110) +BITMAP_GRAPHIC(IDB_TITLE_HD, title_red_320) +#else +BITMAP_GRAPHIC(IDB_TITLE, title_110) +BITMAP_GRAPHIC(IDB_TITLE_HD, title_320) +#endif +BITMAP_ICON(IDB_WEATHER_STATION, map_weather_station) +BITMAP_ICON(IDB_WEATHER_STATION_HD, map_weather_station_160) +// --- Audio --- + +SOUND(IDR_FAIL, fail) +SOUND(IDR_INSERT, insert) +SOUND(IDR_REMOVE, remove) + +SOUND(IDR_WAV_BEEPBWEEP, beep_bweep) +SOUND(IDR_WAV_CLEAR, beep_clear) +SOUND(IDR_WAV_DRIP, beep_drip) diff --git a/Data/bitmaps/OpenSoar.ico b/Data/bitmaps/OpenSoar.ico new file mode 100644 index 00000000000..a3244495ef7 Binary files /dev/null and b/Data/bitmaps/OpenSoar.ico differ diff --git a/Data/bitmaps/xcsoarswift.ico b/Data/bitmaps/xcsoarswift.ico deleted file mode 100644 index a48ff01227b..00000000000 Binary files a/Data/bitmaps/xcsoarswift.ico and /dev/null differ diff --git a/Data/graphics/dialog_title.svg b/Data/graphics/dialog_title.svg index 120bdc44d4a..435e3601a37 100644 --- a/Data/graphics/dialog_title.svg +++ b/Data/graphics/dialog_title.svg @@ -89,7 +89,7 @@ style="display:inline" sodipodi:insensitive="true"> + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/Data/graphics/launcher.svg b/Data/graphics/launcher.svg index b1ab11aeed9..a9821027a2d 100644 --- a/Data/graphics/launcher.svg +++ b/Data/graphics/launcher.svg @@ -2,14 +2,6 @@ image/svg+xml + inkscape:current-layer="layer6" + inkscape:showpageshadow="2" + inkscape:pagecheckerboard="0" + inkscape:deskcolor="#ff00ff" /> \ No newline at end of file + style="fill:#ffffff;fill-opacity:1;stroke:none" /> diff --git a/Data/graphics/launcher_xcs.svg b/Data/graphics/launcher_xcs.svg new file mode 100644 index 00000000000..b1ab11aeed9 --- /dev/null +++ b/Data/graphics/launcher_xcs.svg @@ -0,0 +1,468 @@ + + + +image/svg+xml + + + + + + \ No newline at end of file diff --git a/Data/graphics/logo.svg b/Data/graphics/logo.svg index a465122a381..53ee4b612ea 100644 --- a/Data/graphics/logo.svg +++ b/Data/graphics/logo.svg @@ -15,7 +15,7 @@ id="svg6431" version="1.1" inkscape:version="0.92.1 r15371" - sodipodi:docname="logo.svg" + sodipodi:docname="logo_red.svg" inkscape:export-filename="C:\Documents and Settings\Administrator\Desktop\XCSoar 48x48_10.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" @@ -334,7 +334,7 @@ transform="translate(2.9999921,194.31251)" sodipodi:insensitive="true"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Data/graphics/progress_border.svg b/Data/graphics/progress_border.svg index d587074b5f4..24167b93343 100644 --- a/Data/graphics/progress_border.svg +++ b/Data/graphics/progress_border.svg @@ -15,7 +15,7 @@ id="svg2" version="1.1" inkscape:version="0.48.3.1 r9886" - sodipodi:docname="progress_border.svg" + sodipodi:docname="progress_border_open_soar.svg" style="enable-background:new"> @@ -89,7 +89,7 @@ style="display:inline" sodipodi:insensitive="true"> + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/Data/graphics/title.svg b/Data/graphics/title.svg index ea2a407a6ef..9de5c72654d 100644 --- a/Data/graphics/title.svg +++ b/Data/graphics/title.svg @@ -2,19 +2,19 @@ + inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)" + sodipodi:docname="title.svg" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + inkscape:window-width="2400" + inkscape:window-height="1261" + inkscape:window-x="2391" + inkscape:window-y="-9" + inkscape:window-maximized="1" + inkscape:showpageshadow="2" + inkscape:pagecheckerboard="0" + inkscape:deskcolor="#d1d1d1" /> @@ -43,7 +46,6 @@ image/svg+xml - @@ -51,35 +53,33 @@ inkscape:label="XCSoar" inkscape:groupmode="layer" id="layer1" - transform="translate(0,-1037.3622)"> + transform="translate(-2.5436861,-1039.4086)"> XCSoar + x="1.8" + y="1034.8907" + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:17.3333px;line-height:1.25;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke-width:0.983665" + id="tspan273">@PROGRAM_NAME@ + transform="translate(-2.5436861,-1.0464608)"> 7 + x="106.47736" + y="14.124277" + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:17.3333px;line-height:1.25;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#008000;fill-opacity:1">@PROGRAM_VERSION@ + - An experimental Fork of XCSoar diff --git a/Data/graphics/title_xcs.svg b/Data/graphics/title_xcs.svg new file mode 100644 index 00000000000..ea2a407a6ef --- /dev/null +++ b/Data/graphics/title_xcs.svg @@ -0,0 +1,95 @@ + + + + + + + + + + image/svg+xml + + + + + + + XCSoar + + + 7 + + diff --git a/Data/resources.txt b/Data/resources.txt index 27b735692d5..4b73734d98f 100644 --- a/Data/resources.txt +++ b/Data/resources.txt @@ -1,10 +1,14 @@ +#ifdef TEST + +#endif /* This file contains definitions of all resources used by XCSoar. Various Perl scripts convert it to a C header and target-specific files (e.g. the Windows RC format). */ // Application Icons -app_icon IDI_XCSOAR "xcsoarswift" +//app_icon IDI_XCSOAR "xcsoarswift" +app_icon IDI_XCSOAR "OpenSoar" // Bitmaps diff --git a/Makefile b/Makefile index 16c2db271e8..a658fbf539e 100644 --- a/Makefile +++ b/Makefile @@ -63,6 +63,65 @@ # USE_CCACHE "y" to build with ccache # +# ============================================================ +# Make Caller Info: +RUN_ARGS := $(wordlist 1,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS)) + +ifneq ($(TARGET),) + ARGS := $(ARGS) TARGET=$(TARGET) + $(info * TARGET = $(TARGET)) +endif +ifneq ($(DEBUG),) + ARGS := $(ARGS) DEBUG=$(DEBUG) + $(info * DEBUG = $(DEBUG)) +endif +ifneq ($(ANDROID_SDK),) + ARGS := $(ARGS) ANDROID_NDK=$(ANDROID_SDK) + $(info * ANDROID_SDK = $(ANDROID_SDK)) +endif +ifneq ($(ANDROID_NDK),) + ARGS := $(ARGS) ANDROID_NDK=$(ANDROID_NDK) + $(info * ANDROID_NDK = $(ANDROID_NDK)) +endif +ifneq ($(NDK),) + ARGS := $(ARGS) ANDROID_NDK=$(NDK) + $(info * NDK = $(NDK)) +endif +ifneq ($(USE_CCACHE),) + ARGS := $(ARGS) USE_CCACHE=$(USE_CCACHE) + $(info * USE_CCACHE = $(USE_CCACHE)) +endif +ifneq ($(V),) + ARGS := $(ARGS) V=$(V) + $(info * V = $(V)) +endif + +ifneq ($(USE_HOMEBREW),) + ARGS := $(ARGS) USE_HOMEBREW=$(USE_HOMEBREW) + $(info * USE_HOMEBREW = $(USE_HOMEBREW)) +endif +ifneq ($(OPTIMIZE),) + ARGS := $(ARGS) OPTIMIZE=$(OPTIMIZE) + $(info * OPTIMIZE = $(OPTIMIZE)) +endif +ifneq ($(XXX),) + ARGS := $(ARGS) XXX=$(XXX) + $(info * XXX = $(XXX)) +endif +ifneq ($(RUN_ARGS),) + $(info * RUN_ARGS = $(RUN_ARGS)) +endif +# ============================================================ + +PROGRAM_NAME_LC = opensoar +PROGRAM_NAME_CC = OpenSoar + +ifeq ($(HAVE_POSIX),y) +PROGRAM_NAME = $(PROGRAM_NAME_CC) # all programs CamelCase +else +PROGRAM_NAME = $(PROGRAM_NAME_CC) +endif + .DEFAULT_GOAL := all topdir = . @@ -87,6 +146,8 @@ include $(topdir)/build/abi.mk include $(topdir)/build/coverage.mk include $(topdir)/build/libintl.mk +include $(topdir)/build/version.mk + ifeq ($(HEADLESS),y) else include $(topdir)/build/libglm.mk @@ -115,7 +176,6 @@ include $(topdir)/build/java.mk include $(topdir)/build/android.mk include $(topdir)/build/llvm.mk include $(topdir)/build/tools.mk -include $(topdir)/build/version.mk include $(topdir)/build/darwin.mk include $(topdir)/build/ios.mk include $(topdir)/build/osx.mk @@ -207,12 +267,19 @@ endif ifeq ($(TARGET_IS_LINUX),y) include $(topdir)/build/cloud.mk -include $(topdir)/build/kobo.mk -ifeq ($(USE_POLL_EVENT),y) -include $(topdir)/build/ov.mk +# include $(topdir)/build/kobo.mk endif + +ifeq ($(TARGET_IS_KOBO),y) +include $(topdir)/build/kobo.mk endif +# ifeq ($(TARGET_IS_OPENVARIO),y) +# ifeq ($(USE_POLL_EVENT),y) +# include $(topdir)/build/ov.mk +# endif +# endif + include $(topdir)/build/hot.mk include $(topdir)/build/nolto.mk @@ -246,7 +313,7 @@ OUTPUTS := $(XCSOAR_BIN) $(VALI_XCS_BIN) endif ifeq ($(TARGET),ANDROID) -OUTPUTS += $(ANDROID_BIN)/XCSoar-debug.apk +OUTPUTS += $(ANDROID_BIN)/$(PROGRAM_NAME)-unsigned.apk endif ifeq ($(TARGET_IS_KOBO),y) diff --git a/OpenSoar-AddOn.md b/OpenSoar-AddOn.md new file mode 100644 index 00000000000..9ca96cca3dc --- /dev/null +++ b/OpenSoar-AddOn.md @@ -0,0 +1,22 @@ +Differences OpenSoar to XCSoar-Project +-------------------------------------- + +Windows: +* use a different serial port name: Unique COMx (instead of 'COMx:' or '\\.\COMxx' + +Additional Drivers +================== + +| Driver | _ | Manufacture | _ | Remark | +|:----- |:----- |:----- |:----- |:----- | +| **FreeVario** | | Blaubart | | a driver for the FreeVario... | +| **anemoi** | | RS-Flight | | realtime wind | +| **Larus** | | Larus Breeze | | realtime wind and variometer| +| **Becker AR62xx** | | Becker | | Becker Radio driver | + +Build-Process +============= + +* organizing the (Linux-) make build process with 1 script file ./build/cmake/MakeComplete.sh, dependend from include file ./build/cmake/MakeAll.sh + +* CMake build process only available on Windows with VisualStudio, MinGW64 and Clang (and only with Windows executable) yet \ No newline at end of file diff --git a/OpenSoar-News.md b/OpenSoar-News.md new file mode 100644 index 00000000000..6dee76ae5d9 --- /dev/null +++ b/OpenSoar-News.md @@ -0,0 +1,3927 @@ +OpenSoar Version 7.42.22.A - 2024/04/21 - PreRelease A to 7.42.22 +--------------- +* System: add possibility to restart OpenSoar without exit to system +* TCP Port - Bugfix on closing the TCP client as receiver on this port: +* End of program with (short) restart, newstart, reboot, shutdown and normal program end +* QuickMenu extended with + - Volume control + - several program ends (Reboot, Restart) +* User interface + - create a (simple) audio volume control menu (similar to the OpenVario control) in the default event file +* Setup Menu + - add OpenVario menu (see next item) +* OpenVario: + - WiFi selection, setting and enabling + - OpenVario menu inserted with + - (OpenVario) 'System Settings': Firmware, SensorD, VarioD, SSH, Wifi, Sensor Calibration + - 'Display Settings': (Device!) Rotation, Brightness, Touch Calibration + - 'File Transfer': IGC, OpenSoar data, system data + - split default.xci to defaultOV.xci +* NMEA Settings: Better shows which USB or Bluetooth device is in use for serial devices on Windows (similar to Android) +* Driver/Larus - extend with bidirectional settings parameters $PLARS +* Simulator: remove SIM option from standard, further available with option '-simulator' only +* Development + - rename src folder 'OV' in 'OpenVario' + - remove UNICODE define at Windows + - the 1st step before removing all UNICODE code parts, TCHAR, tstring + - all string handler works with UTF-8, also Windows too +* Bugfix: + - Display rotation on OpenVario on setting +* Open Issues + - Display rotation on Linux behaves wrong! + - OV-Firmware Download don't work (SetupMenu->OpenVario->SystemSettings) + - OV-WiFi work only with one wifi connection and only with a Wifi access WITH password properly! + +#### XCSoar Version 7.42 - 2024/03/01 +* merge xcsoar 7.42 '9ee29aa606' +* ui + - new terrain ramp High Contrast + - fix unreadable icons in task manager and status dialog + - render icons at 300 dpi +* data files + - fix bogus "Latin-1 to UTF-8 conversion failed" error + - parse elevations in feet correctly in cup files + - ignore unit for radio frequency in airspace files +* devices + - validate wind direction +* Kobo + - Wifi setup, display signal level in dBm for new models + - scale icons on hi-dpi displays (e.g. Clara HD) +* user interface + - new mountain pass and bridge icons +* Android + - update 'white list' of USB devices with more PIDs for SoftRF Academy + +OpenSoar Version 7.41.21 - 2023/12/28 +--------------- +* (xcsoar-)bugfix with dead QuickMenu button +* CMake + - reenable MinGW + - update Clang (but not succesful) + +#### XCSoar Version 7.41 - 2023/12/21 +* merge xcsoar 7.41 '96457465d0' +* data files + - fix crash with empty user.cup +* Android + - fix BLE/HM10 data corruption + - fix crash if IOIO connect was canceled quickly + - fix crash if not allowed to start service in foreground +* Kobo + - fix Wifi setup (7.40 breakage) + - hide all pseudo tty ports + +OpenSoar Version 7.40.20.2 - 2023/12/12 +--------------- +* CMake + - improve the test suite (partial aligned to the make suite) +* known bugs + - disabled switch Vario/STF (because code requirements) +* OpenSoar fullfilled all build checks and tests on build server + +OpenSoar Version 7.40.20.1 - 2023/11/28 +--------------- +* Driver + - FreeVario: rework to fullfill requierements of Blaubart +* OpenVario + - add an menu point in the system menu for OV settings (in the moment only + a firmware info field displayed) + - add a target OPENVARIO_CB2 to built-in the OV properties without + influance all other targets + - add a ShutDown and a Reboot event, so a jump over the shell menu is possible +* Wind Display + - bugfix with doubled vector +* remove a lot of compile errors +* merge xcsoar 7.40 '1164801fe9' from 2023/11/02 + +#### XCSoar Version 7.40 - 2023/11/02 +* merge xcsoar commit '1164801f' from 2023/11/02 +* merge xcsoar commit '32147e1e' from 2023/08/24 +* user interface + - Added infobox that combines ETA with AAT dT + - FLARM: Add 100m zoom option. + - hide mouse cursor after 10 seconds of inactivity + - Move glider icon on thermal assist according to 30s average. +* Linux + - fix the /etc/xcsoar data directory +* Android + - raise targetSdkVersion to 33 + +OpenSoar Version 7.39.19 - 2023/08/13 +--------------- +* merge xcsoar 7.39 only +* xcsoar merge release v7.39, '1418e0dc' + +#### XCSoar Version 7.39 - 2023/07/28 +* Android + - fix Bluetooth device list on Android versions older than 12 + - do not request permission WRITE_EXTERNAL_STORAGE on Android 11 or newer + +OpenSoar Version 7.38.18 - 2023/08/13 +--------------- +* merge xcsoar 7.38 only +* merge NEWS.txt in OpenSoar-News.md +* xcsoar merge release v7.38, '7f3184b8' + +#### XCSoar Version 7.38 - 2023/07/27 +* WeGlide + - fix another crash bug +* Android + - support scanning QR codes with XCTrack tasks + - fix location permission request on old Android versions + - fix IllegalArgumentException crash on old Android versions + - improved error messages for problems opening devices + - fix crash on Android 5 + - fix conflict between "org.xcsoar" and "org.xcsoar.testing" apps + +OpenSoar Version 7.37.17, 2023/08/12 +--------------- +* This is a weak step towards bringing OpenSoar up to date with XCSoar (current version v7.39) like the merges before, no additional features! +* Build Process: Very strange behavior: On an incremental build, the app crashed on Android when local GPS permissions were requested. After a full build it behaves like xcsoar with version v7.37 + +* xcsoar merge release v7.37, '33fbf7be' + +#### XCSoar Version 7.37 - 2023/07/21 +* WeGlide + - fix crash bug +* Android + - request ACCESS_FINE_LOCATION only when internal GPS is used + - request BLUETOOTH_CONNECT and BLUETOOTH_SCAN only when Bluetooth is used + - re-enable background location (yet another attempt) + - fix crash with disallowed IOIO Accessory connection + - remove Nook support + - add SoftRF Ham and Midi into 'white list' of USB devices + +OpenSoar Version 7.36.16, 2023/08/11 +--------------- +* xcsoar merge release v7.36, 'a626d3ef' + +#### XCSoar Version 7.36 - 2023/07/02 +* task + - save outer radius and angle of custom keyholes in task files +* calculations + - implement the "predict" option for Netcoupe FFVV, WeGlide, Charron +* WeGlide + - allow downloading all user tasks and public task declarations +* Lua scripting + - add blackboard.altitude_agl +* Kobo + - fix flight durations on power-off screen + - fix bogus last entry on power-off screen + +OpenSoar Version 7.35.15, 2023/08/10 +--------------- +* xcsoar merge release v7.35, 'c5c49879' + +#### XCSoar Version 7.35 - 2023/06/16 +* user interface + - fix crash in plane list + - show terrain, topopgraphy and airspaces on task/contest analysis pages +* calculations + - fix bogus "Task Started" after re-entering the start zone +* fix IGC logger crash with very long turnpoint names + +OpenSoar Version 7.34.14, 2023/08/10 +--------------- +* xcsoar merge release v7.34, '9987faae' + +#### XCSoar Version 7.34 - 2023/06/06 +* user interface + - fix crash with long InfoBox set names + - rename "Inverse InfoBoxes" to "Dark mode" + - planes: "New" creates an empty plane + - planes: add "Copy" button +* map display + - thicker border on disappeared FLARM traffic +* devices + - allow listing up to 512 flights (increased from 128) +* calculations + - fix freeze bug in route planner +* Android + - fix crash with failed IOIO Accessory connection + - use the global dark mode setting by default +* OpenVario + - set system clock from GPS if NTP is unavailable + +OpenSoar Version 7.33.13, 2023/08/09 +--------------- +* xcsoar merge release v7.33, 'e122cbc5' + +#### XCSoar Version 7.33 - 2023/05/26 +* map display + - fix crash bug in FLARM traffic renderer + +OpenSoar Version 7.32.12, 2023/08/08 +--------------- +* xcsoar merge release v7.32, '2351dab' + +#### XCSoar Version 7.32 - 2023/05/25 +* user interface + - fix horizon roll, show bank angles greater than 90° + - fix horizon pitch, show sky instead of ground when pitch is greater than 50° + - improve font scaling in the vario gauge + - support hot keys, gestures and double click on Horizon page +* map display + - draw the trail even if there is no GPS fix + - keep showing disappeared FLARM traffic for some time +* data files + - support waypoints without elevation data +* devices + - IMI: fix crash when there are more than 128 recorded flights + - FLARM: parse AircraftType hex values correctly in PFLAA +* Linux + - Wayland XDG_WM_BASE support + - Wayland keyboard support +* Android + - don't disable IOIO completely if Bluetooth permission was not granted + - fix crash with initial IOIO connection + - fix lockup with IOIO Accessory connection + +#### XCSoar Version 7.31 - 2023/05/12 +* user interface + - fix crash during startup +* WeGlide + - fix crash bug after WeGlide flight upload + - show WeGlide error messages +* Android + - fix crash with buggy graphics drivers + +OpenSoar Version 7.30.11, 2023/08/08 +--------------- +* xcsoar merge release v7.30, 'b32faf31' + +because xcsoar 7.29 and 7.31 only very short term releases no version +OpenSoar 7.29.xx and 7.31.xx released! + +* xcsoar merge 'bedf78b0f' (2023/05/07) - with version 7.29 +* xcsoar merge '3fe70253b' (2023/04/17) +* xcsoar merge '618996223' (2023/03/27) + +#### XCSoar Version 7.30 - 2023/05/09 +* fix crash in "ProfileSave" event +* user interface + - reload fonts on window resize +* Windows + - look up serial ports in the registry +* Android + - UsbSerial: fix permission crash bug + - UsbSerial: fix null pointer crash bug + - negotiate MTU on Bluetooth HM10 devices + - fix circle airspace display problems on Adreno GPUs + +OpenSoar Version 7.28.05, 2023/03/24 +--------------- +* cleanup the commit history to have a clean starting point for OpenSoar-branch +* additional Becker driver for AR62xx +* xcs-vali removed (still available on XCSoar) + +OpenSoar Version 7.28.04, 2023/02/05 +--------------- +* cleanup the commit history to have a clean starting point for OpenSoar-branch + +This is the Base Commit as Starting point for OpenSoar +Do not touch commits below here + +OpenSoar Version 7.28.03, 2023/02/05 +--------------- +* Release prepared for most oft the platforms to publish in internet at https://opensoar.de/releases/2023-02-05 + +OpenSoar Version 7.28.02, 2023/02/01 +--------------- +* 1st release named 'OpenSoar' +* Driver + * Larus with special NMEA sentences + * $PLARA - Attitude + * $PLARB - Battery + * $PLARD - Air Density + * $PLARV - Vario + * $PLARW - Wind + * $HCHDT - (true) Heading + * Anemoi included + * FreeVario included + * AirControlDisplay updated with + +* Releases: Win64, Linux, Android + + +OpenSoar Version 7.28.01 +--------------- +* 1st release of OpenSoar, still with name 'XCSoar' +* Driver Larus included, unplanned(?) NMEA sentences $PTAS1, $POV, $HCHDT +* New Infoboxes: + * Wind Drift + * RealTime Wind Arrow + * RealTime Wind Value + * RealTime Wind Value +* Releases: Win64, Linux, Android, OpenVario, OpenVario package + +#### XCSoar Version 7.29 - 2023/05/03 +* data files + - reject implausible runway lengths in CUP files + - fix crash when arc airspace has no center + - allow xci files to be downloaded from repository + - in OpenAir format use AC as Class and AY as Type (#1118) + - show correct line number on airspace file error + - add RASP file selection +* devices + - ATR833: read-out active and standby frequencies + - AirControlDisplay: Set and readout of transponder code + - AirControlDisplay: forward gps data to device +* Android + - get rid of not usable USB interfaces in the 'Device -> Port' list + - Upgrade targetSdkVersion to 31 + - fix write errors to Bluetooth HM10 devices +* Kobo + - Add support for Libra H2O + - Add support for Clara 2E + - fix truncate wifi list if hidden ssid detected + - Reboot without -f (force) + - Fix OTG mode for newer models + - Add an E-ink friendly trail type + - Add Brightness control to Clara HD + - Support Brightness and Colour for ComfortLight PRO models +* Windows + - show serial port names + - support COM10..COM255 +* Polars + - Add LS-5 polar + - Add Silene E78 polar + - Add Std Austria S polar + - updated handicap factors for 2023 +* fix exchange frequencies crash when no frequency was set +* user interface + - show FLARMGauge only when traffic is within 4Km + - redesigned waypoint type icons + - align labels in forms on the left side + - increased precision in polar edit dialogue + - extend QuickMenu to maximum of 64 entries + - add PEV,FlarmTraffic,FileManager to joystick QuickMenu + - add transponder code infobox + - Pan mode fully keyboard / joystick operatable + - Pan mode use buttons for zoom and what's here + - Slight increase in touch selection on map + +#### XCSoar Version 7.28 - 2022/10/29 +* data files + - fix crash after loading new map file + - fix AAT OZ angles in tasks loaded from CUP files +* map display + - fix terrain reach display +* user interface + - fix task manager crash bug + - fix WeGlide 'Automatic Upload' not persistent + - file manager, show description and update date + - ATC Radial infobox can display magnetic radial with configurable declination + - fix wrong type in waypoint editor +* waypoint editor + - add more SeeYou waypoint types +* Android + - add SoftRF Balkan and Prime Mk3 into 'white list' of USB devices +* Kobo + - Add support for Libra 2 + +* Windows serial ports + - allow connection to COM port 10 to 254 (f.e. for BlueTooth user) + - remove index based COM port setting (obsolete since XCSoar 5) + +#### XCSoar Version 7.27 - 2022/09/23 +* user interface + - vertical scroll bar in some modal dialogs + - rasp sources from repository + - fix file manager crash +* devices + - FLARM: fix crash bug +* weather + - New Rasp Color schemes for Thermalmap + - Support 15 minute intervals in RASP files +* task + - add WeGlide declared task download +* Android + - allow file explorer to access the XCSoar data files +* Polars + - add JS-1B (18m) polar + - add JS-1C (21m) polar + - add JS-3 (15m) polar + - add JS-3 (18m) polar +* fix IGC logger crash on I/O errors + +#### XCSoar Version 7.26 - 2022/09/03 +* user interface + - fix pressed InfoBox colors in inverted mode +* task + - add custom keyhole support +* Android + - improve native serial port enumeration + - fix UsbSerial/FTDI crash bug + - fix UsbSerial/FT4232 data corruption +* Kobo + - fix crash bug + +#### XCSoar Version 7.25 - 2022/08/24 +* stricter airspace parser +* user interface + - add radio frequency buttons to airspace dialogs + - fix the airspace warning "Enable" button + - fix thermalmap.info icon display + - show thermalmap.info thermals in the map item list dialog +* devices + - IMI: fix task declaration bug +* Android + - prompt before deleting data when uninstalling XCSoar + - support USB serial adapters with more than one port + - support multiple USB serial adapters of the same kind + - auto-start XCSoar when USB serial adapter gets connected + - fix crash when GPS access was rejected by user + - fix deadlock while quitting XCSoar + - add U-BLOX 7 USB GPS into 'white list' of USB devices +* Kobo + - display XCSoarData/kobo/poweroff.txt at the bottom + - fix crash in waypoint dialog + +#### XCSoar Version 7.24 - 2022/07/22 +* user interface + - padding in fields + - rework menu labels + - increase popup message timeouts + - fix missing wind arrow InfoBox updates +* file handling + - guard against file corruption in poweroff situations +* FLARM + - timeouts in flight downloads +* Linux + - fix terrain renderer bug + - allow changing the language at runtime +* OpenVario + - menu: fix bogus clicks after returning from XCSoar +* Android + - add SoftRF Lego into 'white list' of USB devices + - disable background location again to go back to Google Play +* calculations + - support for LVZC Charron contest + - new asw27 polar from idaflieg +* Windows + - new default fonts + - use 6 devices in serial port list (like all other targets) +* XCVario/Borgelt + - revert cruise/circling mode change +* Kobo + - add ca certificates for https downloads + +#### XCSoar Version 7.23 - 2022/02/10 +* user interface + - add "Set Frequency" buttons to alternates list + - revamped Credits dialog + - put "Details" button to first position in map elements dialog + - make "range" and "radial" in target dialog editable with keyboard +* support uploading IGC files to WeGlide +* Linux + - fix command-line option "--datapath" +* Raspberry Pi / Cubieboard + - probe both /dev/dri/card0 and /dev/dri/card1 + - reduce input lag +* Android + - add SoftRF Academy and ES into 'white list' of USB devices + - fix crash with empty SD card slot +* Kobo + - fix broken button text background + - add OTG support (serial, sound, net) for Clara HD + - fix "Network failure" in Wifi dialog + +#### XCSoar Version 7.22 - 2022/01/14 +* user interface + - close the download dialog after successful download + - add "Share" button to the status dialog +* glide computer + - implement event "AIRSPACE_ENTER" + - add event "AIRSPACE_NEAR" +* Polars + - add DG-800S +* devices + - FLARM: send turn point names in task declaration +* user interface + - allow cursor navigation in most dialogs (for OpenVario) + - add 3x6 InfoBoxes layout +* weather + - Thermal Info Map integration +* Lua scripting + - add blackboard.{clock,time,date_time_utc} +* Android + - use app-specific data directory by default + - allow using all external storages + +#### XCSoar Version 7.21 - 2021/12/11 +* data files + - Support for AF/AR frequency fields in OpenAir +* devices + - fix inverted cruise/circling mode in borgelt and xcvario driver +* Kobo + - Add support for Clara HD + - Control backlight brightness of the Kobo Glo HD +* Android + - re-enable background location and comply with Google Play Store policy + +#### XCSoar Version 7.20 - 2021/10/22 +* map + - fix crash in the topography loader +* tracking + - SkyLines: fix "URL using bad/illegal format" +* Android + - disable background location access due to Google Play Store policy + - fix compatibility with Android older than 7 + +#### XCSoar Version 7.19 - 2021/10/01 +* data files + - fix bug in OpenAir arc parser + - fix crash bug in terrain loader + - support short name in CUP files + - search waypoints via short name + - ability to display short name on map +* devices + - improved support for LXNAV S8x/S10x varios, including task declaration. + - IMI: fix task declaration over Bluetooth + - IMI: show progress bar for flight download +* user interface + - consistent progress bar during startup +* Android + - fix crash with USB serial adapter + - add WCH CH9102F into the list of accepted USB serial adapters + +#### XCSoar Version 7.18 - 2021/09/10 +* data files + - load terrain while XCSoar is running +* devices + - TCP Client: fix crash bug +* tracking + - SkyLines: fix "Show nearby traffic" setting +* user interface + - add 3x5 InfoBoxes layout +* Android + - fix opening waypoint pictures + +#### XCSoar Version 7.17 - 2021/09/04 +* map display + - fix airspace display bug +* user interface + - add 8x3 InfoBoxes portrait layout +* weather + - update RASP provider list +* task management + - add option to score start on entry +* Android + - fix startup crash bug + - use native text entry dialog +* Linux text mode console + - fix program termination for some DRI drivers, e.g. VMWare + in full-screen mode without Window manager. +* Cubieboard + - Mali: Support for old Linux-Sunxi EGL headers, and new Bootlin EGL headers + - Support for KMS/DRI and Lima instead of closed source Mali blob. + +#### XCSoar Version 7.16 - 2021/08/27 +* user interface + - don't draw "---" over graphical InfoBoxes +* Android + - fix deadlock bug with Bluetooth sensors and the internal GPS + +#### XCSoar Version 7.15 - 2021/08/23 +* user interface + - fix crash in Config/System + - fix overlapping axes labels in cross section + - fix graphics error (vertical black lines) in cross section + - fix missing labels in cross section on high-resolution screens + - draw small tick every 10 minutes in analysis dialog (instead of 6) +* Android + - fix crash on Android 5 and 6 + +#### XCSoar Version 7.14 - 2021/08/20 +* Android + - keep screen on, even if not in full-screen mode + - fix bottom bar background in non-full-screen mode + - fix touch position in non-full-screen mode + +#### XCSoar Version 7.13 - 2021/08/19 +* fix freeze bug +* fix terrain cache file bug +* task management + - Use task defaults for start and finish height ref (MSL or AGL) when loading + tasks from soarscore.com +* Kobo + - fix crash in Kobo menu +* Android + - fix GPS time from the Flytec Sensbox + - support speed, track and acceleration from Flytec Sensbox + - don't apply Geoid separation to Flytec Sensbox GPS altitude + - use the 8 Hz vario from Flytec Sensbox GPS altitude instead of 1 Hz + - restore full-screen mode properly after returning to XCSoar + - disable full-screen mode in multi-window mode + - make full-screen mode optional + +#### XCSoar Version 7.12 - 2021/08/13 +* calculations + - fix the "Height above takeoff" InfoBox +* devices + - send Pilot Event (PEV) to LXNAV S10x/S8x devices (requires firmware 8.01 or newer) + - correct Pilot Event (PEV) message for PowerFLARM devices +* Android + - fix broken GPS date/time from internal GPS + - various fixes for the Flytec Sensbox driver +* Kobo + - throttle sensor-triggered screen updates + - improve performance of graphical InfoBoxes + +#### XCSoar Version 7.11 - 2021/07/30 +* fix crash bug in pc_met viewer +* user interface + - new vario gauge background + - fix truncated labels in many dialogs +* Lua scripting + - add HTTP client + - prefer Lua gesture handlers +* Android + - show Bluetooth LE device features + - support Bluetooth LE heart rate sensors + - support the Flytec Sensbox + - add DroidSoar/I2C calibration dialog + - fix reconnect to Bluetooth LE devices + - fix distorted colors on some devices + - detect USB serial adapter disconnect + - support baud rate switching on USB serial adapters +* Polars + - new Wassmer WA 26 P Squale polar + +#### XCSoar Version 7.10 - 2021/07/09 +* weather + - work around connection problems to NOAA server (for METAR/TAF) +* Raspberry Pi + - fix text input with touch screen +* Android + - fix crash with reconnected USB serial adapter + +#### XCSoar Version 7.9 - 2021/07/05 +* fix crash bug in terrain renderer +* fix crash bug in IGC file parser +* settings + - allow LiveTrack24 tracking intervals smaller than 5 seconds +* user interface + - support for Pilot Event (PEV) start procedure + - properly update device status in device list dialog + - add alternate 2 glide ratio infobox +* devices + - TCP Client: fix automatic reconnect after connection loss + - GliderLink: fix disappearing configuration +* calculations + - fix AAT task optimization bug +* Android + - support USB serial adapters + - auto-reconnect to IOIO UARTs + +#### XCSoar Version 7.8 - 2021/06/02 +* don't delete old IGC files automatically +* devices + - TCP: fix error "Address already in use" on reconnect +* Android + - fix downloads on Android 10 and later + - fix logging while in background on Android 10 and later + +#### XCSoar Version 7.7 - 2021/05/14 +* user interface + - fix dialog labels + - fix freeze bug in waypoint/airspace list dialog +* devices + - add "Radio" indicator to device list +* Android + - writing to port times out after 5 seconds (to avoid locking up XCSoar) + +#### XCSoar Version 7.6 - 2021/05/01 +* user interface + - fix disappearing aircraft symbol + - fix crash bug in task editor + +#### XCSoar Version 7.5 - 2021/04/30 +* fix crash bug in terrain loader +* fix paths with backslashes +* user interface + - use different colors to indicate relative traffic altitude +* calculations + - support for WeGlide distance contests +* Kobo + - fix touch screen + +#### XCSoar Version 7.4 - 2021/04/08 +* user interface + - properly save and apply updated settings in the configuration dialog + - fix overlapping observation zones in the task point list + - fix text background in the analysis graphs + +#### XCSoar Version 7.3 - 2021/04/07 +* user interface + - fix crash in waypoint editor + - fix swapped longitude/latitude in waypoint editor + - fix "Import" button in waypoint editor + - fix zoom button label in Traffic Radar View + - fix the vario trace infobox +* Android + - fix download progress + +#### XCSoar Version 7.2 - 2021/04/04 +* user interface + - fix task point editor + - display goto button in wp details when called from alternate +* data files + - fix crash bug when loading broken CUP files +* fix crash when loading broken PNG files + +#### XCSoar Version 7.1 - 2021/03/28 +* user interface + - fix crash when canceling a download + - fix crash when repository index download failed +* Android + - handle DownloadManager errors + - show early initialisation errors + - store the terrain cache in the Android cache directory + +#### XCSoar Version 7.0 - 2021/03/25 +* LUA scripting +* user interface + - screen layout with 12 infoboxes on the left, vario+3 infoboxes on right + - new translations: Bulgarian, Catalan, Traditional Chinese, Telugu + - new Logger-setting "CoPilot" + - new setting "Thermal Averager needle" + - select position of Thermal Assistant + - new setting "Cruise/Circling mode switch period" +* data files + - optimise the terrain loader + - support runway width in CUP files +* devices + - fix deadlock bug + - parse wind from standard NMEA sentence WMV + - driver for XC Tracer Vario + - driver for KRT2 radio + - driver for Air Control Display altimeter + - show detailed error message in device list + - FLARM/OGN - make it possible to set/download registered device database + - device manager: show flag if device provides data from + environmental sensors (temperature, humidity) + - combine traffic from all FLARM devices (support both FLARM and OGN devices on board) + - GliderLink: new driver + - AirControlDisplay: read radio frequencies from PAAVS,COM sentence + - driver for LXNano modified, so declaration contains copilot + - driver for Becker AR62xx radios: setting of active or passive channel out of waypoint database, behaves like KRT2 driver +* weather + - merge all weather data in one dialog + - allow showing both terrain and RASP + - RASP download from various well-known providers + - show satellite images from pc_met (Deutscher Wetterdienst) + - show wave forecast from pc_met (Deutscher Wetterdienst) +* calculations + - merge redundant waves + - task restart +* tracking + - use DNS to resolve SkyLines server IP (#2604) + - enable SkyLines traffic display on Windows + - add option to show SkyLines traffic names on the map + - show thermals obtained from the XCSoar Cloud server +* analysis + - enhanced graphics: minor tics, color scheme, layout + - key labels drawn on lines in several pages + - task turnpoint label drawn on relevant pages + - barogram: improved working band ceiling and floor calculation + - climb history: new display uses time of climb as width of bars + - new page: vario histogram in climb and cruise mode + - new page: maccready cross-country speed + - glide polar: dolphin speed line drawn on polar +* map display + - new display: glide range line drawn to working floor + - per page zoom state +* thermal band + - new algorithm, with improved statistics + - separate active climb and encounter-averaged bands +* infoboxes + - improved formula for the title font size + - added ":1" unit for gradient type displays + - new infobox: % time non-circling climb + - new infobox: % climb chart showing proportions of time spent circling climb (gray), cruise, + climbing cruise (green), circling non-climb (orange) + - improved auto-scaling of vario-like graphical infoboxes + - new infobox: "Number Of Satellites" + - new infoboxes for radio frequencies, including setting the frequencies +* Windows + - drop support for Windows CE + - require Windows Vista or later + - allow starting multiple XCSoar instances +* Linux + - drop support for SDL 1.2 + - display rotation +* Android + - drop support for ARMv6 and MIPS CPUs + - support devices with aspect ratio greater than 16:9 +* Kobo + - support Kobo Glo HD +* Raspberry Pi + - resizable mouse cursor + - autodetect display orientation + +#### XCSoar Version 6.8.17 - 2020/09/22 +* tracking + - SkyLines: update tracking IP address +* terrain + - fix several crash bugs (JasPer) + +#### XCSoar Version 6.8.16 - 2020/07/26 +* input events + - fix two crash bugs with malformed files +* user interface + - fix crash bug in waypoint editor +* devices + - added ports 8880, 8881, 8882 to tcp-client +* glide computer + - fix crash bug +* terrain + - fix several crash bugs (JasPer) +* Android + - fix several crash bugs + - fix rendering errors on very wide text lines + +#### XCSoar Version 6.8.15 - 2020/06/13 +* user interface + - vario: fix overlapping text lines +* tracking + - SkyLines: update tracking IP address +* support for long-form `DTE` header in IGC files +* Windows + - fix buffer overflow causing crashes in the waypoint dialog +* Raspberry Pi + - support 64 bit kernels + - Raspberry Pi 4 support + - detect display dimensions and scale user interface accordingly +* macOS + - add macOS Catalina font path + +#### XCSoar Version 6.8.14 - 2020/05/14 +* user interface + - fix average needle color in inverted mode +* Android + - compatibility with Android 9 + - request all permissions without manual restarts + - fix crash bug +* Kobo + - fix crash bug + +#### XCSoar Version 6.8.13 - 2020/04/08 +* devices + - LX: fix buffer overflow + - LX: support downloading flights from LX7000 Pro IGC +* Android + - use the full screen on very narrow/wide displays +* Kobo + - fix build failure with GCC 9 + - switch from glibc to Musl +* WinCE + - build with GCC 9 +* allow the hyphen in XCI files + +#### XCSoar Version 6.8.12 - 2019/04/30 +* weather + - update source URLs for METARs and TAFs (https://) +* Android + - increase targetSdkVersion to 26 (required by Google Play) + - request storage and GPS permissions on Android 6+ + - fix crash when permission to use GPS is revoked + - fix notification on Android 8+ +* Task Editor + - fixed task editor crashes (Ticket 3930). +* devices + - IMI: raise max payload size to 2kB +* fix IGC logger crash when no date is available + +#### XCSoar Version 6.8.11 - 2018/08/18 +* terrain + - fix yet another crash bug (libJasper) +* Android + - fix crash on Android 8 due to overzealous seccomp filter + +#### XCSoar Version 6.8.10 - 2017/10/07 +* terrain + - fix crash bug (6.8.9 regression) + +#### XCSoar Version 6.8.9 - 2017/10/05 +* terrain + - fix several crash bugs +* fix two crash bugs +* Kobo + - fix internet access (#3869) + - support for Kobo Glo HD Refurbished + +#### XCSoar Version 6.8.8 - 2017/09/09 +* data files + - support "GSEC" in OpenAir files +* weather + - update source URLs for METARs and TAFs +* devices + - CAI302: fix waypoint download (#3830) + - IMI: fix PGRMZ parsing (was interpreted as altitude, now is pressure altitude) + - LX: fix Nano 3 task declaration (#3858) +* Kobo + - support for Kobo Aura Edition 2 + - support for Kobo Glo Refurbished + - fix Wi-Fi on recent Kobo firmware releases (#3850) + - fix USB storage compatibility with Windows 10 +* Raspberry Pi + - fix Raspbian Stretch compatibility +* Raspberry Pi / Cubieboard + - fix for freeze on shutdown (#3679) + +#### XCSoar Version 6.8.7 - 2016/08/12 +* data files + - fix freeze after loading malformed topography file +* tracking + - SkyLines: fix SkyLines tracking on non-Android + - SkyLines: fix two buffer overflow bugs + - new client for the experimental "XCSoar Cloud" +* Android + - remove the deprecated crash dumper + +#### XCSoar Version 6.8.6 - 2016/07/22 +* calculations + - show takeoff time after landing (#3786) +* user interface + - fix graphics error on FLARM gauge + - fix crash in waypoint label renderer (#3781) + - fix several crashes in waypoint editor (#3553, #3784) + - fix crash in task manager + - use task speed unit for OLC speed InfoBox (#3785) +* devices + - EW: use first 6 characters of turn point names (was: 3) + - EW: fix broken umlauts in turn point names + - LX: fix Nano 3 firmware 2.0 compatibility (#3764) +* settings + - adjust range and step size of terrain/arrival safety height settings +* map + - increase upper limit of the number of waypoint labels displayed +* Android + - fix crash due to Bluetooth LE connect failure +* Kobo + - support USB-OTG for Kobo Glo HD and Kobo Touch 2.0 + +#### XCSoar Version 6.8.5 - 2016/06/12 +* calculations + - update circling percentage only when flying + - fix circling height gain calculation +* user interface + - fix "kg/m^2" and "lb/ft^2" unit display + - fix inverse colors in horizon page + - reduce CPU load of some InfoBoxes (#3757) +* calculations + - add option to disable external wind (#3693, #3773) +* devices + - fix crash on malformed NMEA time stamp +* Android + - improve Bluetooth LE compatibility (#3745) +* Kobo + - reduce ghosting on old Kobo models; regression due to screen + flashing fix in 6.8.4 (#3756) + +#### XCSoar Version 6.8.4 - 2016/05/18 +* airspace cross-section + - use airspace visibility configuration (#3751) +* data files + - accept "Military Aerodrome Traffic Zone" (MATZ) airspaces in + OpenAir files (#3732) +* devices + - CAI302: fix "airspace" marker in waypoint uploader (#3750) +* calculations + - improve landing detection at high wind speeds (#3748) +* logger + - fix crash in NMEA logger +* user interface + - Australian units for weight are kg +* Windows + - fix terrain loader (#3747) +* Android + - fix crash bug in IOIO driver (#3744) + - fix crash bug on Android 1.6 (#3742) +* Kobo + - eliminate screen flashing on Kobo Glo HD, Kobo Touch 2.0 + - support battery status on Kobo Glo HD, Kobo Touch 2.0 + +#### XCSoar Version 6.8.3 - 2016/03/09 +* map + - fix distorted terrain when zoomed out + - fix missing airspaces in cross section (#3537) +* calculations + - update SIS-AT to 2016 scoring rules + - fix landing time display (#3690) + - fix AAT range display +* data files + - use correct "comment" field for OziExplorer files + - relax file format detection for OziExplorer files + - fix bogus arrival heights on watched waypoints when GPS unavailable + - fix crash in airspace parser + - fix crash in XML parser + - save user.cup after edit (#3701) +* devices + - GTAltimeter: remove unmaintained driver (#3661) +* Kobo + - support Kobo Glo HD, Kobo Touch 2.0 +* fix crash in SkyLines tracking + +#### XCSoar Version 6.8.2 - 2015/09/19 +* Rubik R-26S polar +* user interface + - save settings after copy&pasting an InfoBox set (#3649) +* map + - fix crash in the topography renderer +* calculations + - fix task progress display after finish achieved (#3657) +* devices + - fix wrong baud rate after task declaration (#3654) +* Android + - support the "escape" key (#3647) + - fix all RS232 permissions on Android (#3648) +* Kobo + - fix wrong IP address display (#3650) +* Raspberry Pi / Cubieboard + - support digit and letter keys (#3611) + +#### XCSoar Version 6.8.1 - 2015/08/27 +* fix freeze bug when starting without GPS fix +* fix crash with empty xcsoar-checklist.txt file +* devices + - fix TCP port on Windows (#3428) +* Windows + - fix the airspace file parser (#3633) +* Kobo + - fix overlapping text (#3634) +* Android + - fix USB-RS232-OTG permissions on Android + +#### XCSoar Version 6.8 - 2015/08/18 +* data files + - optimise the topography loader + - faster RASP map change + - show all RASP maps + - fix comments in TNP files + - ignore trailing whitespace in airspace files (#3546) + - store user-edited waypoints and markers in "user.cup" +* devices + - remove option "Ignore checksum" + - CAI302: add sink tone configuration + - LX: implement LXNAV Nano3 task declaration (#3295) + - LX: remove support for LX1600 pass-through mode + - ATR833: new driver + - Volkslogger: support DAeC keyhole declaration + - Westerboer VW921: remove buggy driver (#3215) + - added TCP port 2000 to portlist (part of #3326) + - support LXNAV V7 pass-through mode (#1913, #2808, #2919) +* calculations + - wave assistant + - use maximum speed configured in plane setup as limit for calculations + - use WGS84 earth ellipsoid for distance calculations (#2809) + - remove setting "Prefer external wind" + - reduce EKF wind latency + - fix bogus value in "Nearest Airspace H" InfoBox (#3589) + - obey the maximum start speed (#2841) +* airspace cross-section + - sync map & cross-section view zoom setting (#2913) +* infoboxes + - add "Fin MC0 AltD" infobox (#2824) + - add "Next arrow" infobox (#3128) +* task editor + - added one-click task reversal (#1730) + - show name of loaded/saved tasks in dialog title (#1924) + - support large legs in the FAI triangle renderer (#3413) + - task calculator moved to "Status" dialog + - markers can be used in tasks and for "goto" +* map + - allow "Mark Drop" while panning + - airspace labels +* user interface + - allow horizontal speeds in m/s + - allow mass in lb, wing loading in lb/ft^2 + - download data files from site configuration + - remove support for custom status files + - merge airspace warning buttons "ACK Warn" and "ACK Space" (#1086) + - show airspace warning at bottom (#1378, #2628, #3275) + - profile manager + - password-protected profiles (#851) + - checklist remembers last opened list (#3110) + - use configured coordinate format in waypoint editor + - remove custom font support, replaced with global "text size" setting + - improved font sizes + - improved font renderer + - display rotation for Raspberry Pi and Cubieboard (#3238) + - use /dev/input/event* on Raspberry Pi and Cubieboard (#3179) + - support mouse wheel on Raspberry Pi and Cubieboard + - scale touchscreen coordinates to screen size + - bigger icons on high-dpi screens (#2795, #3267, #3397, #3540) + - improved keypad support (#3281) + - new translation: Simplified Chinese +* tracking + - new option disables tracking while roaming on the cell network + - queue SkyLines tracking fixes while data connection is unavailable + - fix SkyLines traffic display on southern hemisphere (#3601) + - show SkyLines traffic even if we have no GPS fix yet + - show nearby waypoint in SkyLines traffic list + - show altitude in list (#3606) + - show all nearby traffic (#2814) + - pass vehicle name to LiveTrack24 +* Linux + - Wayland support +* Android + - fix IOIO connection on Android 4.x (#2959, #3260) + - support IOIO-OTG with the Android device in USB host mode + - support IOIO over Bluetooth + - support Bluetooth LE + - timeout for the HTTP client (e.g. LiveTrack24) +* Kobo + - menu button + - add UI allowing the start of external scripts to KoboMenu (#3194) + - support Wifi with WEP (#3138) + - support open Wifi networks (#3391) + - support USB-OTG + - export data partition via USB storage + - support the Kobo Aura screen (#3490) + +#### XCSoar Version 6.7.9 - 2015/07/03 +* user interface + - fix crash in task editor + - fix crash while panning the map + - improved font renderer +* data files + - fix comments in TNP files +* calculations + - faster triangle score calculation + - fix crash in triangle score calculation (#3576) +* Android + - timeout for the HTTP client (e.g. LiveTrack24) +* Kobo + - enable crash dumps in XCSoarData/crash/ + +#### XCSoar Version 6.7.8 - 2015-05-22 +* user interface + - draw gray title bar on inactive dialogs + - improved dialog button placement + - fix missing buttons in terrain configuration (#3421) +* task + - support large legs in the FAI triangle renderer (#3413) + - make "Cruise efficiency" read-only +* devices + - fix crash when downloading flight without "logs" folder +* Linux + - support Raspberry Pi 2 + - show ports renamed by udev + +#### XCSoar Version 6.7.7 - 2015/02/20 +* airspace + - accept airspaces of class RMZ in OpenAir format files (#3437) + - fix wrong AGL height due to longitude east/west wraparound (#3468) +* infoboxes + - fix data for OLC infoboxes if "OLC League" is used (#3461) +* calculations + - fix handicap factor for "OLC League" scores + - fix reach calculation problems at border of map (#3239) + - simplified EKF wind algorithm (#3062) +* input events + - allow '_' character in event identifiers (#3464) +* replay + - fix replay progress while replay is paused (#3446) + +#### XCSoar Version 6.7.6 - 2014/10/18 +* tracking + - updated SkyLines server IP +* user interface + - fix crash when switching pages with cross section (#3012, #3231, #3395) +* devices + - LX: relax download timeout (#3199) + - OpenVario: new device driver + - Vaulter: new device driver +* replay + - accept "$GNRMC" in replay of NMEA files +* calculations + - improve circling detection when using some external NMEA devices (#3360, #3372) +* configuration + - report missing plane configuration file in log file + +#### XCSoar Version 6.7.5 - 2014/06/09 +* fix crash in task manager (#3305) +* work around crash on Windows (PC) (#3284) +* devices + - fixed attitude data handling + - properly detect LXNAV Nano 3 + - FLARM: fix declaration with asterisk in task point name (#3323) +* airspace + - assume all airspaces are active if day of week is not known + - restore "Repetitive Sound" setting on startup (#3308) +* Android + - fix crash when opening IOIO port (#3309) + - allow reconnecting IOIO sensors +* tasks + - fix loading of some tasks from .cup files + +#### XCSoar Version 6.7.4 - 2014/04/11 +* map + - fix topography rendering for polygon shapes (#3245) + - fix SDL clipped polygon rendering algorithm (#3250) +* devices + - Westerboer: ignore implausible values from buggy devices +* logger + - create "logs" directory automatically for external flight downloads +* user interface + - show status message when switching to next turnpoint (#3270) +* airspace + - relax parsing of TNP airspace files (#3272) +* infoboxes + - don't use depreciated content in default configuration (#3278) + +#### XCSoar Version 6.7.3 - 2014/01/22 +* tracking + - changed host for DHV tracking server (#3208) +* user interface + - fix missing battery info in status panels +* map + - fix disappearing observation zones at left/top screen border (#3212) + - fix RASP display +* devices + - LX: improved logger handshake (#3199) + - LX: auto-retry after errors during IGC download +* Android + - load XCSoarData from external SD card if available (#3198) +* Kobo + - fix touch screen bug (#3195, #3204, #3211) + +#### XCSoar Version 6.7.2 - 2013/12/19 +* user interface + - fix crash in alternates list (#3146) + - new translation: Slovenian +* infoboxes + - fix "Fin Dist" infobox for GOTO tasks (#3152) +* configuration + - increase upper limit for plane wing area (#3154) + - fix saving of custom polars (#3173) +* waypoints + - correctly handle S latitudes and W longitudes in waypoint editor (#3155) + - fix saving waypoints to cup format files from waypoint editor +* devices + - auto-reconnect TCP client (#3127) + - handle time warps in NMEA replay + - another midnight wraparound bug fix (#2973) +* Android + - enable Vivante workaround for GC600 (#3184) + - faster map renderer (#3124) + - improved font quality + - enable cursor key navigation in dialogs (#3133) +* Kobo + - fix misassigned passphrase in WiFi dialog (#3151) + - work around Kobo Touch N905B kernel crash in display driver (#3145) + - work around Kobo Touch N905B touch screen bug + - the "Home" button opens the menu + - mount /dev/pts for telnetd (#3135) + - fix crash in file manager and METAR/TAF dialog (#3078) + +#### XCSoar Version 6.7.1 - 2013/10/11 +* replay + - fix crash replaying an IGC file with no B record extensions (#3107) +* data files + - save the previous log file in "xcsoar-old.log" +* user interface + - new translation: Lithuanian +* devices + - CAI302: work around transmission errors during IGC file download (#3074) +* Android + - fix crash in "credits" dialog on Android 4 (#3106) + - work around Vivante GPU texture bugs (#1995, #2228, #2990, #2998, #3105) +* Kobo + - fix passphrase entry in WiFi setup (#3053) + - fix compatibility with old Kobo firmware + +#### XCSoar Version 6.7 - 2013/09/30 +* new target: Kobo e-book readers +* user interface + - resizable main window + - added AutoZoom gesture (up-down) + - obsolete configuration pages "devices", "polar", "logger info" removed + - new page: "horizon" (#1592) + - default page gesture changed right/left sense according to other xc ui interaction pattern + - pressing the Escape key in task manager switches to "Close" tab (#2877) + - separate font for dialogs (#723, #2806) + - repetitive airspace warning sound (#2952) + - never close dialogs due to display rotation + - disable custom fonts on Altair + - improve small dialog font on Altair + - fix loading translations on Linux (#2041) +* map + - terrain countour lines (#2451) + - continue loading terrain/topography without GPS fix (#2723) + - suppress drawing duplicate topography labels + - draw projected path when turning + - additional zoom levels (#3037) + - global "don't fill airspace" setting (#3047) + - fix rendering errors when some airspaces have no border (#3045) + - fix distinct page zoom in conjunction with circling zoom (#2907) +* infoboxes + - new content "Speed task last hour" + - new content "Next distance (nominal)" + - new content "Takeoff distance" (#3059) + - new panel for "Team code" provides quick access to team code settings (#2899) + - new content "OLC speed" (#2352) +* tasks + - custom "start requires arm" setting (#2782) + - new option to disable OLC optimisation + - MAT: ask user whether to add turn points while flying over it + - update the calculator without a GPS fix (#2876) + - fix task speed and time estimates before task start (#2876, #2906) + - show "arm advance" button when manual arming is necessary (#1729) + - support the OLC/DMSt 500km triangle threshold (#2963) + - render finish point as achieved when task is finished (#2140) + - subtract start/finish cylinder radius from task distance (#2308) + - fix parsing of .cup task files +* route planner + - ignore inactive and acknowledged airspaces (#2866) +* calculations + - add more weight to zig-zag wind compared to circling wind + - enable circling wind calculation in IGC replay (#2672) + - fix OLC triangle display (#2775) +* waypoint editor + - delete waypoint implemented + - CUP file support added +* devices + - enabling/disabling devices on-the-fly + - "debug" button + - more robust midnight wraparound handling (#2857) + - new driver from Cambridge L-Nav + - support TCP client connection +* Android + - support IOIO via OpenAccessory (Android 4.x) + - support USB host mode and USB-RS232 adapters on the Nook (#2886) + - show Bluetooth name instead of MAC address in device list + - enable fast refresh mode on Nook Simple Touch +* Analysis + - a retrospective task is compiled that summarises waypoints the aircraft has + visited (within 15km radius). These waypoints are drawn on OLC page of analysis dialog. +* data files + - default profile is called "default.prf" instead of "xcsoar-registry.prf" + - log file is called "xcsoar.log" instead of "xcsoar-startup.log" + - fix name truncation when saving a waypoint file on Windows (#3096) + +#### XCSoar Version 6.6.5 - 2013/08/21 +* user interface + - reduce flickering in system configuration +* map + - reduce CPU usage of airspace and topography renderer +* tasks + - remove keyhole from the BGA start sector zone +* devices + - enable Nook's internal GPS for mock locations (#2999) +* configuration + - fix loading home waypoint on longitudes bigger than 90 degrees + +#### XCSoar Version 6.6.4 - 2013/07/11 +* map + - fix stuttering terrain on Windows CE + - fix multi-touch pan gesture (#2684) +* calculations + - improve robustness of the zig-zag wind algorithm (#2961) +* devices + - FLARM: work around a Garrecht TRX-1090 firmware bug (#2745, #2749) + - LX: faster LXNAV Nano detection over Bluetooth (#2819) + - Volkslogger: increase timeout to calculate security (#2910) + - fix bogus error message after pressing "Cancel" + - show Bluetooth name instead of MAC address in device list + +#### XCSoar Version 6.6.3 - 2013/07/02 +* map + - fill FAI triangle areas on Windows +* devices + - FLARM: improve task declaration reliability + - LX: support Nano firmware 2.10 (#2819) +* Android + - fix compatibility issue with Android 2.2 + - detect when internal GPS is lost on Android 2.3 and older (#2929) +* user interface + - fix unit display for pressure in flight setup dialog (#2933) +* data files + - added "Pilatus B4" polar + +#### XCSoar Version 6.6.2 - 2013/06/12 +* map + - fix misplaced topography labels (#2564) + - fix keyboard panning with track up (#2908) +* infoboxes + - ensure that the unit symbol is visible + - fix ballast display in vario gauge (#2911) +* tasks + - update all settings after task type change +* devices + - Volkslogger: fix IGC file download on Windows CE + - EWmicroRecorder: fix corrupt task declaration (#2921) + - fix potential crash when garbage is received from device + - fix IOIO reconnect + - generate G record even when first device has no GPS (#2849) +* cross section + - also display unknown airspace types (#2884) +* Raspberry Pi + - fix instant crash (#2922) +* Altair + - never override data path (#2509) +* Android + - faster startup + +#### XCSoar Version 6.6.1 - 2013/05/08 +* cross section + - fix airspace display after display rotation (#2825) +* user interface + - fix malformed name in airspace warning dialog (#2813) + - don't lost focus to waypoint list on Altair (#2835) + - don't forget map zoom when returning to map (#2805) +* devices + - indicate duplicate devices in list + - allow using more than one TCP/UDP device + - fix spurious errors after IOIO baud rate change (#2733, #2754) + - K6Bt: fix configured baud rate setup on Android (#2836) + - work around Android 2.3 Bluetooth crash bug +* tasks + - prevent moving target out of the cylinder (#2794) +* configuration + - fix regression with polar configuration (#2803) +* support gcc 4.8 + +#### XCSoar Version 6.6 - 2013/04/23 +* map + - optional distinct map zoom on each page (#1603) + - add label selection "Task waypoints & airfields" + - allow configuration of "Final glide bar" display (#2554) + - new snail trail option "Vario-scaled dots and lines" + - topography icons + - don't draw pan info over north arrow (#2765) +* cross section + - show airspace names (#1149, #2390) + - use glide polar instead of current glide ratio (#2687) +* infoboxes + - green InfoBox distance when inside observation zone (#2560) + - limit the InfoBox aspect ratio + - new InfoBox styles "Shaded" (#1852), "Glass" (#2466) + - waypoint details button in target dialog (#1967) + - show distance in radial InfoBox comment (#2577) + - new InfoBox "ATC radial" with distance in nautical miles (#2269, #2706) + - improved wind edit panel (#2770) +* user interface + - replay fast-forward + - new waypoint location editor (#343) + - show required glide ratio in waypoint details (#1573) + - add airspace ack button to map item list (#2139) + - additionally show airspace altitude in feet (#2379) + - show more files in replay file picker (#2582) + - clicking with Ctrl key pressed moves the simulator (#199) + - vario bar at the right edge of the map +* tasks + - MAT tasks (#563) + - custom symmetric quadrant (#2125) + - AAT keyhole (#1687) + - add AST point option "Score exit" (#2544) + - optimise start point + - allow up to 30 turn points in racing tasks + - local time for task start open/close time (#2645) + - enforce the task start open/close time (#2678) + - fix start auto-advance +* calculations + - improve the circling wind algorithm (#2690) +* devices + - Volkslogger: support IGC file download (#1972) + - Volkslogger: declaration no longer erases waypoint database from logger + - CAI302: support uploading all waypoint file types (#2054) + - V7: support for QNH synchronization to V7 vario +* Android + - faster map renderer on some Android devices +* other + - new polars for two G 102 Astir variants (#2701) + - new option "auto bugs" increases bug setting every hour (#1526) +* configuration + - fix saving of configuration values in non-metric setups (#2771) + +#### XCSoar Version 6.5.4 - 2013/04/10 +* devices + - Volkslogger: increase timeout for reading flight list + - V7: fix QNH change +* logger + - fix failing IGC logger (#2658, #2735, #2736, #2746, #2751) + +#### XCSoar Version 6.5.3 - 2013/03/26 +* user interface + - eliminate flickering in the cross section on Windows + - fix wrong radial display in target dialog + - start at terrain center when there's no GPS fix and no home location +* task + - fix line OZ rounding error (#2599) +* devices + - FLARM: fix IGC file download on firmware 5.09 (#2619) +* Android + - fix crash with Hebrew language +* Mac OS X + - fix crash on startup (#2607, #2667) + - show missing serial ports, hide internal devices (#2668) +* infoboxes + - fix rendering of thermal assistant aircraft symbol (#2702) + +#### XCSoar Version 6.5.2 - 2013/03/15 +* user interface + - fix hang during startup (#2662, #2663) + - fix freeze in dialogs (#2664) + - automatically re-enable manual wind controls (#2336) + - fix crash after connecting FLARM (#2669) + +#### XCSoar Version 6.5.1 - 2013/03/12 +* infoboxes + - fix MacCready adjustment for non-metric units (#2654) +* user interface + - fix bogus "restart XCSoar" messages + - fix cross section render error on some OpenGL chips (#2631, #2661) + - allow gestures in cross section (#2655) +* devices + - fix crash in Android Bluetooth driver (#2636, #2656) + - fix NMEA input on Android Bluetooth Server +* data files + - use the terrain cache even when the system clock is wrong + - fix G record regression (#2657) + +#### XCSoar Version 6.5 - 2013/03/08 +* map + - lower zoom levels possible while circling (#1120) + - draw FAI triangle areas (#1563) + - optimise the terrain renderer + - added "Wind Up" display orientation + - high-resolution terrain renderer (Android/Linux only) + - kinetic panning (Android/Linux only) + - new terrain color ramp "Gaudy" +* calculations + - don't detect landing while climbing in a wave (#1330, #2289, #2406) + - basic support for the contest "DMSt" (#2208) +* tasks + - add task start countdown (#136, #1080) + - optimise racing tasks for minimum distance + - allow observation zone sizes up to 200km (#2401) + - always use "arrival safety height" when calculating arrival heights + for intermediate task turnpoints +* devices + - LX: support flight download from LXNAV Nano (#2085) + - LX: support flight download from LX5000/LX7000 pro IGC + - LX: read bugs setting from the LX160 vario (#2167) + - Android/IOIO: support BMP085 sensor (DroidSoar V2) + - Android/IOIO: support MS5611 pressure sensor + - added driver for Levil AHRS device + - Leonardo: read indicated airspeed from PDGFTL1 sentence + - C-Probe: read IAS/TAS from the device + - K6Bt: fix baud rate switching with various drivers + - K6Bt: fix configured baud rate setup on Android +* data files + - added MATZ airspace class (#2530) + - integrated handicaps from DAEC 2012 +* logger + - auto-flush IGC logger after every fix +* user interface + - preselect first item with details in map item list for + faster access (#2069, #2207) + - non-modal FLARM radar (with InfoBoxes and menu) + - show FAI triangle sectors in task manager + - can drag modal dialogs + - short click opens InfoBox dialog + - support keyboard input on desktop computer + - improved angle input (e.g. wind direction, sector radials) + - faster map initialisation during startup + - reduce audio vario latency + - better bold fonts on Linux + - add page option to show cross section below map + - allow pages with FLARM radar and thermal assistant + - double click on vario opens main menu + - allow opening main menu while panning + - new translations: Hebrew, Vietnamese +* infoboxes + - added thermal assistant infobox + - inverse colors for wind arrow infobox and flarm gauge (#2337) +* track friends via internet connection (SkyLines live tracking) +* SkyLines tracking enabled on Windows CE +* Android + - check if external storage is mounted +* Documentation + - started a French translation of the manual + - included an almost complete German translation of the manual + +#### XCSoar Version 6.4.6 - 2013/01/23 +* devices + - Leonardo: fixed vario parser for the $c sentence + - C-Probe: fixed temperature offset bug + - GTAltimeter: fixed vario parser + - SerialPort: fixed lockup/hang problem when closing for some CE devices (#2515) +* user interface + - sort airspaces properly in the airspace list dialog (#2528) +* infoboxes + - fixes broken wind arrow display in some situations (#2295) + - fix font scaling on screen rotation change (Android/Linux OpenGL) +* data files + - fixed arc airspace approximation threshold handling (#2360) +* configuration + - save waypoint label display configuration changed from menu (#2548) + +#### XCSoar Version 6.4.5 - 2012/12/14 +* calculations + - fix rounding error in convex boundary calculation (#2477) +* devices + - Vega: fix MacCready setting feedback loop (#1218, #2490) +* user interface + - faster gesture drawing + - fix crash in InfoBox page setup (#2122) + - allow scrolling the check list on Altair (#1289) +* map + - fix crash in terrain renderer with broken map file (#2478) +* data files + - added "LAK-12" polar + +#### XCSoar Version 6.4.4 - 2012/11/15 +* devices + - CAI302: longer timeout for "CLEAR LOG" +* user interface + - fix font preview in configuration dialog + - fix the Escape key on Altair + - fix wind InfoBox dialog layout (#2192) + - add missing "Switch InfoBox" button (#2246) +* Android + - fix text rendering on some PowerVR GPUs +* Windows + - fix garbled screen area in task manager (#2272) + +#### XCSoar Version 6.4.3 - 2012/11/01 +* devices + - fix freeze bug on device reconnect + - LXNAV Nano: fix crash in Nano configuration dialog + - LXNAV V7: fix NMEA setup over Bluetooth + - Colibri/LX20: fix LXN/FIL to IGC conversion (#2262) +* user interface + - fix the download manager on Samsung phones + +#### XCSoar Version 6.4.2 - 2012/10/17 +* calculations + - contest: relax altitude difference check (#2348) + - improve take-off and landing detection (#2391) +* devices + - CAI302, B800: fix ballast command (#2387) + - IOIO: fix baud rate switching, fixes LXNAV V7 and Volkslogger (#2277) +* data files + - added polar of "Ka 6E" and corrected the "Ka 6CR" one (#2327) + - added polars of "AK-8" and "Blanik L13-AC" (#2329) +* map + - suspend the map renderer while thermal assistant is shown +* user interface + - closing the XCSoar window cancels the current modal dialog (was + broken on Windows) + - fix off-by-one bug in combo list (#2382) + - fix map updates in replay/simulator on Linux (#2236) + - fix file manager on new XCSoarData directory + - fix excess error messages in file manager (#2395) + - validate UTF-8 in xcsoar-checklist.txt (#2396) + +#### XCSoar Version 6.4.1 - 2012/08/30 +* calculations + - fix "final GR" calculation (#2256) + - improved great circle vector calculation precision +* map + - new option to disable the wind arrow +* data files + - increased arc airspace resolution for large radiuses +* devices + - fix potential crash in I/O thread + - fix date/time parsing in Flytec device driver + - Volkslogger: fix task declaration over Bluetooth + - CAI GPS-NAV: work around timing problem + - LX: fix Colibri/LX20 declaration problems + - Westerboer: support for smaller steps in MC value setting + - improved Bluetooth support on Windows CE + - work around Windows CE serial port driver bug, fixes freeze during + Nano task declaration (#2255) +* user interface + - remove duplicate "trail drift" setting (#2252) + - fix flarm teamcolor saving (#2291) + - fix flarm targets in map item list (#2267) +* logger + - IGC B record is invalid ("V") with just 2D fix + - log pressure altitude in IGC files +* fix crash on low battery in simulator mode (#2306) + +#### XCSoar Version 6.4 - 2012/07/31 +* calculations + - Contest: add FFVV NetCoupe (#1648) + - Contest: optionally include next task point in OLC classic/plus + score calculation (#1561) +* devices + - support up to 6 devices + - buffered serial port I/O + - FLARM: new FLARM setup dialog + - added drivers for GliderTools GT Altimeter and Compass C-Probe + - LXNAV V7 and Nano configuration dialog +* data files + - removed support for separate terrain/topography files, now XCM only +* map + - configurable airspace rendering (#1847) + - "dots for sink" trail styles + - weather stations on the map (#1487) +* user interface + - added "Airspace On/Off" menu button + - save Flarm team mates in the profile (#1997) + - added para- and hang glider and aircraft symbols (#1626) + - audio vario (#1576) + - improved airspace list rendering + - configurable map item list (#1936) + - "GoTo" button in map item list (#2069) + - show corresponding waypoint file in waypoint details dialog (#1624) + - show gesture path while dragging + - file manager, can download data files + - new option to disable the "final glide" display mode +* infoboxes + - added automatic altitude infobox (baro. altitude with GPS fallback) + - added wind arrow infobox (#1598) +* Android + - support x86 and MIPS CPUs + - Bluetooth server for NMEA out + +#### XCSoar Version 6.3.11 - 2012/07/27 +* calculations + - fix freeze in glide solver + - fix transition in small cylinder for key hole observation zones + (e.g. BGA, #2229) + - fix AAT buttons in new tasks (#2183) +* data files + - fix crash in CUP task loader +* map + - fix rounding error in annulus renderer (#2221) + - redraw map after target was moved (#2216) + - fix bogus "around terrain: -1" map element (#2205) + - fix waypoint label style when no map is loaded + +#### XCSoar Version 6.3.10 - 2012/07/20 +* calculations + - fix rounding error in sector angle calculation (#2102, #2209) + +#### XCSoar Version 6.3.9 - 2012/07/18 +* calculations + - show AAT/target info before the first GPS fix (#2183) +* data files + - fix crash in the "Status File" loader +* devices + - plausibility tests for NMEA input + - fixed Westerboer VW921 airspeed reading + +#### XCSoar Version 6.3.8 - 2012/06/22 +* fix broken graphics (#2182, #2184, #2185) + +#### XCSoar Version 6.3.7 - 2012/06/21 +* calculations + - show altitude difference to target point, not area centre + - enforce the 150 minutes limit for OLC league (#2174) + - fix airspace warnings on old ARM CPUs (#2127) +* devices + - LX: improved LXNav V7 support + - skip failed devices for task declaration +* replay + - fix parsing of flight date in IGC files +* Android + - fix crash during METAR download (#2156) + - fix map flipping (#2154) + +#### XCSoar Version 6.3.6 - 2012/06/06 +* calculations + - fix task start arming inconsistency + - fix crash in thermal locator (#2137) + - consider head wind in STF only if MacCready setting is zero +* devices + - fix NMEA out +* data files + - added "ASW-28 (15m)" polar (#1919) +* user interface + - ignore double clicks when mouse/finger has moved + - the "back" key returns focus to map +* Windows + - check for XCSoarData in the XCSoar.exe directory (#2136) +* Android + - fix crash on IOIO reconnect (#2130) + - fix interference of two or more IOIO UARTs (#2107) + - eliminate delay from IOIO connect + +#### XCSoar Version 6.3.5 - 2012/05/31 +* calculations + - fix rounding error in task minimum search for finish lines (#2102) +* devices + - fix crash on connection failure during flight download (#2107) +* map + - fix horizontal terrain stripes (#1745) +* Android + - fix compatibility with Android 1.6 + - fix hanging IOIO/Bluetooth connection + - fix crash in FLARMNet dialog + - save crash dumps in directory "XCSoarData/crash/"; + this requires the Android permission "READ_LOGS" + +#### XCSoar Version 6.3.4 - 2012/05/24 +* calculations + - fix overflow in ETE/ETA calculations on big tasks (#2066) + - fix bogus landing detection right after takeoff (#2081) +* task manager + - fix FAI start/finish line length (#2079) +* devices + - CAI302: fix connection lost after MacCready update (#2029) +* user interface + - increase double click interval to 500ms (#2088) + - fix UTC offset preview (#2082) +* map + - sanitise map scale (#2086) + - fix crash on topography triangulation failure (#2089) +* Android + - fix profile path on Samsung devices with external SD card (#2051) + +#### XCSoar Version 6.3.3 - 2012/05/05 +* calculations + - use arrival height instead of terrain safety height for MC0 Alt.D + (#1991, #1992) + - fix arrival heights on map when no terrain is available (#2018) +* user interface + - refresh the device list automatically +* Android + - fix crash after too many network failures (#1957) + - improve the pressure sensor's Kalman filter + - fix Bluetooth/IOIO receive data truncation + - reduce the risk of getting killed by the Android Activity Manager +* logger + - Fix logging of "start" events + - Fix logging of "before takeoff position fixes" in IGC logs (#2052) + +#### XCSoar Version 6.3.2 - 2012/04/26 +* devices + - FLARM: fix flight download (#2024) +* user interface + - improved list colors, white text on dark blue background + - limit form field labels that are too wide (#2025) +* Android + - apply a Kalman filter to the pressure reading (#1928) + +#### XCSoar Version 6.3.1 - 2011/04/19 +* calculations + - fix crash with far away task (#1969) + - fix high speed remaining when wind drift is disabled (#1962) + - fix crash when scrolling beyond the poles (#2005) + - fix airspace activity (day of week) calculation +* devices + - allow standard NMEA sentences to begin with 'P' + - add missing NMEA checksum verifications + - Borgelt: send bugs and ballast to the B800 (#1940) + - Borgelt: read the ballast setting from the B800 (#1940) + - LX: support the LXNav V7 + - Flymaster: initiate NMEA mode + - AltairPro: relax timeouts + - FLARM: relax timeouts + - fix timeouts on Windows CE (FLARM driver and others) (#1970) + - ignore garbage at the beginning of NMEA lines + - fix the NMEA out driver (for Altair double seater and others) (#1982) +* logger + - fix format of IGC 'C' records for takeoff/landing (ambiguous spec) (#1993) + - fix landing time in flight logger (#2012) +* map + - don't fill acked airspaces (#1958) + - fix display of full-circle annulus (#2000) +* task manager + - fix rename/delete function for task files (#1985) + - also clear optional starts with "Clear All" button (#2014) +* waypoints + - add all examined waypoints to recently used waypoint list (#2009) +* Linux + - fix HTTP networking bugs +* Android + - fix hanging shutdown after IOIO connection failure + - fix saving of airspace colors (workaround for android compiler bug) (#1954) +* Windows + - fix double key presses on Windows CE / PPC2000 +* Altair + - recover focused dialog control (#1868) + +#### XCSoar Version 6.3 - 2012/03/29 +* calculations + - real-time OLC score + - configurable permanent polar degradation + - finish: allow flight to boundary (reenabled) +* devices + - COM port monitor + - fix for TCP port on Windows + - added separate FLARM driver for declaration and IGC file download + - FLARM: generate checksums for task declaration + - added driver for the Westerboer VW921/VW922 devices + - added driver for the FlyNet variometer + - allow up to 4 devices + - LX: support the LX Color Vario + - LX: send QNH and ballast to device + - LX: send keep-alives while in flight list + - LX: support LX1600 pass-through mode + - send/receive bugs setting to/from device, if driver support it + - support for K6-Bt baud rate switching + - CAI302: units editor + - CAI302: write waypoint database to CAI302 + - CAI302: baud rate switching + - Flytec: correct airspeed and ground speed factor +* map + - airspace rendering fixed + - show new map items list on click + - reduce map jiggling, improved E Ink display support + - multi-touch drag triggers pan + - waypoint labels: support "required glide ratio" instead of + "arrival height" +* user interface + - show METAR data in natural language + - sort METAR stations by name + - added kinetic scrolling for non-WinCE platforms + - enable font anti-aliasing on Linux and Mac OS X + - show airspaces in the task manager + - larger form rows on touch screens + - added UTM coordinate format + - single click in target dialog moves the target + - dpi-aware dialog layout + - show units in the analysis dialog + - optional full-screen mode on Linux +* logger + - added "Start only" option for auto logger +* data files + - added support for CompeGPS waypoint files +* internet + - added LiveTrack24 live tracking +* Windows + - use XCSoarData folder on removable drives/cards if available +* Android + - support reverse screen modes for Galaxy Tab + - support baro sensor + - fix profile saving bug after initial installation + - improve Bluetooth and IOIO error handling +* Altair + - fix configuration dialog navigation +* LX MiniMap + - support for the hardware buttons + +#### XCSoar Version 6.2.6 - 2012/02/25 +* calculations + - fix bogus terrain warnings + - fix incorrect expiration of wind data, e.g. for temporary manually + overridden automatic wind calculations results + - fix auto MacCready calculation +* devices: + - Vega: fix Vega configuration dialog + - Android: don't auto-reopen the internal GPS periodically + - Android: fix deadlock when internal GPS is disabled + - fix rare crash bug during task declaration +* fix parsing of weather station codes read from profile +* Altair: + - fix a few broken dialog hot keys +* Windows + - allow configuring the UTC offset on Windows CE + +#### XCSoar Version 6.2.5 - 2012/01/27 +* calculations + - fix time calculation when goal is above aircraft + - fix speed to fly when goal is below aircraft + - fix minor OLC miscalculation + - enable the logger ID on all platforms + - prevent spikes and jumps during IGC replay +* infoboxes + - fix display of "FIN ETE VMG" and "WP ETE VMG" +* user interface + - enable 5 InfoBoxes on the right in landscape mode +* settings + - fix handling negative UTC offsets +* devices: + - fix regression in EW MicroRecorder task declaration + - EW MicroRecorder: make task declaration cancellable +* Android + - fix black screen after resume +* Windows + - fix freeze on the Windows Mobile "Today" screen + +#### XCSoar Version 6.2.4 - 2011/12/24 +* calculations + - fix arrival altitude calculation when goal is above aircraft + - take terrain safety height into account for start point + - calculate final glide MacCready even when no thermal was measured yet + - fix rare crash in AutoMacCready calculation + - converge AutoMacCready to zero when goal is unreachable + - fix crash with far away task + - fix crash in terrain reach calculator +* devices + - Borgelt: send MacCready to B800 with CAI302 protocol + - Flytec: fixed the $FLYSEN parser (more data, including GPS) +* Android + - fix bogus long InfoBox clicks + - fix crash after resuming + - don't reveal InfoBoxes after rotating the display during pan +* Windows + - work around startup problem on hx4700 with Windows Mobile 5 +* Altair + - fix crash in InfoBox cursor movement +* user interface + - restore the current menu after rotating the display + - fix sorting by filename in file selector of task manager + - allow modification of some additional infobox values with up/down keys + (or volume keys on android devices). + - fix crash in the .xci file parser + - new translation: Korean +* map + - performance improvements for large maps + - redraw map after terrain cache update +* settings + - load configured METAR/TAF stations on startup + - remember UTC offsets > +12 hours. + +#### XCSoar Version 6.2.3 - 2011/11/19 +* calculations + - show correct "next distance" even if glide solver fails + - don't discard manual wind when auto wind is disabled + - don't discard manual wind until a new estimate is calculated + - fix memory leak +* user interface + - reduce menu flickering + - fix crash in waypoint list dialog when waypoints have large comments + - prevent waypoint editing if waypoint file is read-only + - fix clipped task display on wide screens +* map + - speed up the map renderer + - reduce memory usage on PPC2000 +* data files + - Automatically try to detect character encoding of airfield details file + - speed up waypoint/airspace loading +* logger + - Added competition id to IGC file output +* Linux + - display error message when fonts could not be loaded +* Mac OS X + - initial public release, distributed in a DMG package + +#### XCSoar Version 6.2.2 - 2011/11/04 +* devices + - save the "bulk baud rate" setting + - don't auto-restart NMEAOut and XCOM760 +* calculations + - fix instant L/D formula + - fix malformed F records in IGC files + - minor fix for FLARM stealth calculations + - fix auto QNH formula + - fix reach/route arrival calculations with strong wind +* user interface + - fixed several minor bugs in the plane database dialog + - fix MacCready steps for knots and ft/min + - manual and translation updates + - support "airspace margin" setting for "All below" + - fix crash in font editor +* data files + - fixed bugs in TNP airspace file parsing +* Android + - acquire "Vibrate" permission + +#### XCSoar Version 6.2.1 - 2011/09/26 +* faster METAR and TAF download +* devices + - FLARM: clear old barometric altitude as soon as FLARM is detected +* user interface + - show validation errors before task declaration +* Windows / Altair + - restore the "Enter" key in dialogs (knob click on Altair) +* Android + - fix hang on quit + - fix screen corruption when rotating the progress screen + - fix startup crash with manual display orientation + - fix memory leak in network code + - implement timeout in network code +* Mac OS X + - fix clock query + - store data in ~/XCSoarData + +#### XCSoar Version 6.2 - 2011/09/08 +* devices + - Android IOIO + - Android: support native serial ports and USB-RS232 adapters + - added task declaration support for the IMI ERIXX logger + - improved support for the Digifly Leonardo + - auto-detect serial ports on Windows CE + - serial port support on UNIX + - CAI302: fix byte order bug on PC + - CAI302: IGC file download + - IMI ERIXX: IGC file download + - LX/Colibri: IGC file download + - LX: support baud rate switching + - Volkslogger: fix task declaration on PC + - Vega: update vario when there is no GPS fix + - PosiGraph: task declaration + - device declaration can be cancelled + - reconnect individual devices after failure or timeout + - device manager dialog, with manual reconnect +* calculations + - dry mass is seperated from the polar reference mass + - airspace distance miscalculations fixed + - new wind algorithm "EKF", replacing ZigZag + - OLC calculation speedup +* user interface + - added support for reverse portrait/landscape screen orientations + - multiple flarm team mates and teams possible + - nearest airspace distance info boxes + - better font for large info box values + - airspace warnings: show vertical distance if above/below + - profiles are not incremental anymore; initial support for editable + user profiles + - MacCready InfoBox: scale increments according to user unit + - METAR and TAF +* map + - redraw terrain only if needed (saves battery power) + - airspace rendering optimised +* data files + - auto-detect the character encoding in waypoint/airspace files +* tasks + - allow finish height in MSL or AGL + +#### XCSoar Version 6.1.5 - 2011/08/20 +* data files + - fixed arcs in TNP airspace files +* devices + - fixed temperature reading from Altair/Vega and Westerboer devices +* calculations + - airspace distance miscalculations fixed + - fixed builtin polars with points above 200 km/h +* Android + - fix timer crash + +#### XCSoar Version 6.1.4 - 2011/07/30 +* memory leaks fixed +* calculations + - fix miscalculation in start point chooser + - finish: revert "allow flight to boundary" for now +* map + - fix for the aircraft symbol + - airspace rendering optimised + - disable huge topography files on PPC2000 and Altair +* Android + - fix text rendering on Adreno GPUs + - fix another suspend/resume crash + - clip the unit symbol in info boxes + - smooth CPU usage info box +* Altair: + - fix upside down screen + +#### XCSoar Version 6.1.3 - 2011/07/14 +* devices + - fix task declaration on PC + - LX: correct byte alignment for task declaration +* calculations + - reduce memory usage + - finish: allow flight to boundary + - Racing task, FAI Task: allow 11 turnpoints + - task: support AGL maximum start height +* user interface + - translation updates + - new translations: Japanese, Ukrainian + - support mouse wheel on Linux + - fix duplicate text input in edit controls on PC + - update info boxes after leaving full-screen + - fix PNA model type +* map + - fix map location when all devices fail +* Android + - support hardware keyboard in custom XCI files + - clip text in the "credits" dialog + - catch Java exceptions in the text renderer + - reduce texture memory usage on newer GPUs + - fix terrain rendering on Mali-400 (Samsung Galaxy S II) + +#### XCSoar Version 6.1.2 - 2011/06/28 +* devices + - workaround for GPGGA/GPRMC clock difference +* calculations + - reduce memory usage further + - fix boundary routine of the key hole zone + - set system clock only from a real GPS fix + - set system clock again after device reconnect + - MacCready setting defaults to safety MacCready on startup +* user interface + - change low battery thresholds + - manual and translation updates + - fix UTC offset setting + - fix overlapped InfoBox text + - translation updates +* map + - fixed coast line display (areas below zero no longer flooded) +* Linux + - fix broken textures on GPUs with power-of-two dimensions +* Android + - enable sound effects on task start, arm turn, GPS connection + - continue calculations while airspace warning is displayed +* Altair + - the Escape button saves dialogs (such as InfoBox setup) + +#### XCSoar Version 6.1.1 - 2011/06/01 +* calculations + - fix arrival heights which are below the safety height + - reduce memory usage + - fixed several bugs in the teamcode calculation and display +* user interface + - new option for large glider symbol + - re-enable the team bearing diff InfoBox + - fix crash in the waypoint editor +* Windows + - workaround for PPC2000 bug that caused lockups +* Android + - fix crash bug after orientation change and resume + - support non-standard SD card mount points +* Altair + - fix UI lag + - fix default task on startup + - optionally load XCSoarData from USB drive + - swap "ACK Warn" / "ACK Space" hot keys + - disallow the on-screen keyboard + - fix clipped cursor in text entry dialog + - fix default font for "important topology" + +#### XCSoar Version 6.1 - 2011/05/19 +* devices + - CAI302: read QNH setting + - Vega: send configured QNH to Vega + - allow disabling a device explicitly + - listen for NMEA on TCP port + - automatically restart FLARM after declaration + - Stealth mode detection of other FLARM targets +* user interface + - "pan to" button in waypoint dialog + - waypoint selection screen shows last used waypoints if no filter is set + - change the info box geometry without restarting XCSoar + - change the display orientation without restarting XCSoar + - tabbed Task dialog with icons or text on tabs per settings + - new InfoBox configuration dialog + - configurable aircraft symbol + - new translations: Danish, Norwegian Bokmal, Romanian +* route planning + - new optional minimum-time route planning around airspace and terrain. + - allows avoidance or terrain, airspace or both + - takes final glide and cruise-climb portions of flight into account + - Configuration in Route Planner page of settings. + - Feature is by default disabled. + - See settings help text for configuration options + - Limitations of current version: + - does not update the final glide bar, task times etc for any obstacle deviations + - does not handle aircraft or destination location inside airspace + - does not allow paths with course deviations greater than 90 degrees each leg. + - some "jumping" of the solution may be experienced as altitude/location changes. +* reach (glide terrain footprint) + - new engine for calculating the where the glider can fly in final glide, + formerly known as the glide terrain footprint, now referred to as 'reach'. + - this can calculate the reach around terrain obstacles + - landable waypoints visible on the map are marked according to whether they are + reachable + - the reach calculation is configurable, turning search can be disabled if + running on low-powered devices. +* map + - north arrow is automatically hidden in north-up mode + - added configurable slope shading (off/fixed/wind/sun) + - autozoom uses stepless zooming and has configurable upper distance bound + - "north up" map orientation now respects "glider position offset" + by configuring a "shifting axis", i.e. + - shifting based on bearing to target (i.e. North orientated "target up") + - shifting based on average of recent ground track + (i.e. North orientated "track up") + - the estimated thermal position is now used as map center during circling + - a selection of which waypoint labels are displayed is now possible + (All, Task & Landables, Task and None). + - different rendering of roads based on importance (major, normal, minor) + - a different font is used for rendering important topology labels (i.e. big cities) + - landables can be displayed with runway heading and proportional length if the + necessary data is contained in the waypoint files + - glide terrain range line more detailed, uses 50 radial points rather than 20 + - added option to display track bearing line in map + - optional transparent airspace rendering + - terrain ramp auto-scaling disabled +* data files + - support for SeeYou .CUP task files in the task manager + - support for GPSDump/FS FormatGEO and FormatUTM waypoint files (.wpt) + - support for OziExplorer/CompeGPS waypoint files (.wpt) + - added airspace class G + - wing area field is read from extended polar files if available + - zander files: description field is used for additional airport detection + - added frequency parsing for airspace files + - TNP: RADIO field + - OpenAir: AR command + - the frequency and runway heading/length given in cup files are now displayed + - use runway heading and length contained in cup waypoint files + - for WELT2000 generated winpilot waypoint files (.dat) use runway heading +* task + - new Task Manager and calculator dialogs + - FAI Triangle filter when adding turnpoints + - added BGA start point sector + - added AAT inner radius sector + - configurable alternate sorting + - by arrival altitude + - along task direction + - along home direction + - "long-click" in task turnpoint zone displays Target dialog + - "arm advance" menu buttons removed. Next/previous buttons function as normal + for turnpoints (including startpoints) not requiring arming, for those that do + require arm, "next" reads and functions as "arm" on first press and once armed, + reads and functions as "next". "previous" reads and functions as "previous" if + not armed, "disarm" if armed. + - time margin of AAT optimisation is configurable under "Default task turnpoints" page, expert mode + as "Optimisation Margin" option. + - auto goto task: when no task is defined then on takeoff, if there is a waypoint + within 1km of the takeoff location, a goto task pointing back to this location + is automatically created. +* infoboxes + - new graphical infoboxes + - barogram + - vario trace + - netto vario trace + - thermal circling trace + - thermal band + - task progress + - new infoboxes: + - time below maximum task start height + - wp and task ETE assuming ground speed is maintained +* Android + - support landscape/portrait switching +* Dialog updates + - Analysis dialog shows multiple contest (OLC etc) results + - Analysis dialog includes a thermal band graph + - Waypoint select dialog allows filtering by start/finish + - Airspace warning dialog only shows buttons suitable for the respective airspace item, + +#### XCSoar Version 6.0.10 - 2011-04-29 +* fix crash in flarm teammate setting +* user interface + - enable gestures by default + - show the primary data directory in the configuration dialog +* calculations + - fix wind direction on glide terrain line + - enable warnings for GND airspaces when AGL altitude is negative +* Android + - fix two crash bugs on sound effect +* Altair + - correct key handling behaviour in Lists + - prevent wraparound of cursor navigation + +#### XCSoar Version 6.0.9 - 2011-04-06 +* devices + - work around iPaq Bluetooth driver bug +* map + - fix for hanging map on slow hardware +* Windows + - fix setting the system time from GPS + - PPC2000: major performance improvement + - more backslash path fixes on Windows CE +* Android + - don't require GPS and Bluetooth on Android Market + - implement the battery InfoBox + - internal GPS: show "waiting for fix" until location is obtained + - allow SD card installation + - "Droid Sans" is the default Android font + - enable font preview + - dead hardware keys fixed + - implement sound effects + +#### XCSoar Version 6.0.8 - 2011/03/23 +* don't estimate thermal source for skewed thermals +* devices + - CAI302: fix task declaration on Android + - EW microRecorder: minor task declaration fix +* configuration + - Units: fix "feet per minute" support + - save the "Auto Logger" setting +* Windows + - use backslash for paths on Windows CE +* Android + - calculate WGS84 to real altitude (internal GPS) + - fix incorrect airspace warning repetitions + - auto-reconnect to Bluetooth GPS after timeout + - support the acceleration sensor +* Linux + - more dialog improvements + - fix bold font rendering + - case insensitive file name matching + +#### XCSoar Version 6.0.7 - 2011/03/12 +* devices + - EW microRecorder: timeout during connect + - EW microRecorder: increase RX timeout + - EW microRecorder: insert new declaration into old EW-USER.TXT +* map + - Airspace: support alternative OpenAir coordinate format + - allow zooming in to 1 km +* replay: don't execute recorded input events +* Windows + - hide the task bar on Windows CE Core +* Android + - disable auto-restart on various Android configuration events + - import time from internal GPS correctly + - read internal GPS accuracy + - the "back" hardware key cancels dialogs + - map the volume keys to cursor up/down +* Linux + - improved button and checkbox rendering + - dialog keyboard navigation implemented + - enable keyboard repeat + +#### XCSoar Version 6.0.6 - 2011/03/04 +* devices: + - fix declaration crash in Volkslogger, EW, CAI302, CAI GPS NAV + - EW: remove duplicate newline in declaration output +* map + - Airspace: add option to re-enable stencil buffer on PPC2000 +* other + - select waypoint: update heading filter only on large changes + - reduce dialog memory usage +* Windows + - compile vali-xcs.exe as console application +* Android + - fix crash due to invalid UTF-8 labels + - more pause/resume crash fixes + - take advantage of ARMv7 CPUs + - dialogs are modal now +* Linux + - implement the serial port + +#### XCSoar Version 6.0.5 - 2011/02/26 +* devices: + - EWMicroRecorder: fix hang during task declaration + - FLARM: parse PGRMZ as altitude above 1013.25 hPa +* user interface + - scale the "Today Screen" buttons on large screens + - fix page numbers in satellite image renderer + - generate satellite file name from original waypoint id +* map + - terrain: permanently disable failed tiles + - terrain: fix "unexpected marker segment type" error + - AAT: don't draw "dead zone" on ancient hardware (PPC2000) + - Airspace: disable stencil buffer on ancient hardware (PPC2000) +* Android + - fix bitmap loading on Samsung Galaxy Tab + - show Bluetooth device names in configuration dialog + - larger default fonts + - improved airspace rendering +* Altair + - fix dialog hot keys + - task editor: bind F5/F6 to move up/down + +#### XCSoar Version 6.0.4 - 2011/02/19 +* devices + - EWMicroRecorder: parse PGRMZ as altitude above 1013.25 hPa + - FlymasterF1: convert pressure to altitude + - FlymasterF1: don't override the baro altitude of the primary device + - LX: parse LXWP0 as altitude above 1013.25 hPa + - Zander: PZAN1 contains QNH altitude + - Zander: verify checksum + - don't force cruise mode when no Vega/B50 is present +* user interface + - prevent potential crash while using flarm radar dialogs + - improve behaviour if "circling zoom" is disabled + - vario: fix circling mode display +* map + - enable terrain and topology by default + - Terrain: load fewer raster tiles on Altair +* task + - abort: for non-final glide options, don't prefer airports + - task manager: reduce memory usage + - olc: DHV-XC contest optimisation + - olc: SIS-AT 2011 contest optimisation +* configuration + - don't forget the home airport after a configuration change +* Android + - device: support NMEA over Bluetooth RFCOMM + - more pause/resume crash fixes + - don't process hardware keys twice + - fix bitmap loading on Android 2.3 + +#### XCSoar Version 6.0.3 - 2011/02/02 +* devices + - EW, Volkslogger: restart I/O thread after declaration failure + - CAI302: check for I/O errors during declaration + - Volkslogger: enable task declaration + - Condor: fixed wind direction processing +* user interface + - Language: translation updates + - Auto zoom: don't disable in circling mode + - more airspace rendering fixes for Android +* map + - Terrain: load more raster tiles on modern devices (second try) +* Android + - keep display backlight on, don't suspend + - support extra large displays (tablets) + - allow task switching + - disallow multiple instances of XCSoar + - show notification icon while running + - implement "Quit" properly + - enable cruise/climb mode switching + - use the external SD card on Samsung Galaxy + - show on-screen keyboard buttons + - fix profile breakage + - show flarm and thermal assistant gauge + - show text in splash screen + +#### XCSoar Version 6.0.2 - 2011/01/20 +* devices + - more robust NMEA checksum parser + - CAI302: restart I/O thread after declaration failure + - CAI302: parse PCAID baro altitude if "!w" unavailable + - Condor: read wind from LXWP0 +* user interface + - Language: translation updates + - Language: add Spanish translation + - Language: add Russian translation + - Language: translations Czech, Greek, Croatian, Italian, Serbian, + Swedish imported from LK8000 + - Window: disable sunken window edges on HP31x + - Target: adjust map layout +* map + - Waypoints: more reliable waypoint decluttering + - Topology: fix rendering bug + - Terrain: reduce slope shading artefacts + - Terrain: load more raster tiles on modern devices + - Task: fix crash when drawing deformed sectors +* data files + - Fixed potential crash while reading airfields files + - Added more polars (Hang gliders, DG1000, Blanik, Jantar, ...) +* Android / Linux / OpenGL + - enable translations + - fix dialog titles + - support big displays (tablets) + - implement check boxes (for enabling "Expert" mode) + - fix airspace rendering + +#### XCSoar Version 6.0.1 - 2010/12/26 +* map + - task, glide terrain: fix rendering bugs +* user interface + - Language: translation updates + - Language: always fall back to resource data + - Language: enable translation on PPC2000/PPC2003 + - dialog "Switches": portrait mode layout fixed + - dialog "Statistics": draw trace on task page +* terrain / topology + - minor memory leak fixed +* glide computer + - new built-in polars: IS28B2 and SZD30 + +#### XCSoar Version 6.0 - 2010/12/19 +* build system + - compile with gcc / mingw32 / mingw32ce instead of Visual C++ +* data files + - support for SeeYou and Zander waypoint files + - support for TNP airspace files + - when started from SD card, XCSoarData is stored on SD card, too + - when a XCSoarData directory exists on SD card, it is preferred +* devices + - Altair Pro: task declaration + - new drivers: + - Flymaster F1 + - Flytec + - ILEC SN10 + - Leonardo + - NMEA logger and NMEA replay +* terrain / topology + - cached terrain load during startup (faster) + - incremental (faster) terrain/topology updates + - faster terrain/topology rendering + - slope shading can be turned off + - auto-scale terrain colors +* user interface + - mouse gestures + - translation compatible with gettext / libintl + - language auto-detection + - configurable temperature unit (Fahrenheit) + - configurable trail colors +* gauges + - new FLARM radar screen + - thermal assistant +* task + - full rewrite of the engine, new task editor + - support more task types + - saved tasks are XML + - alternates list + - instant OLC score + - OLC plus rules + - instant AAT optimization + +Changes from 5.2.2: +PAOLO: +- colorful vario gauge by Paolo (for FIVV only) +- (minor) infobox config layout in configuration +TOBIAS: +- ballast dump works outside task calculator +- start task info +ROB DUNNING: +- Font editing patch +- Allow DebugStore to use varargs and convert all ca +- Allow StartupStore to use varargs and convert all.patch +- Fix font in checklist dialog +- Allow synce pcp to be overridden via make + +JMW: +- Added Condor device + +Changes from 5.1.9beta9: +- Fixed bug in tasman vario gauge display +- Clearer display of flarm target climb rate +- renamed variables to improve readibility +- Added option to enable/disable FLARM radar separately from map +- Removed option to display trapezoidal relative altitude on FLARM radar +- Fixed LDNext bug +- Compatibility for widescreen displays courtesy of Rob Dunning +- PNA port work courtesy of Paul Coolwind +- Fixed SZD55 polar (more accurate) courtesy Luke Szczepaniak +- Added DG-300 polar courtesy Paul Coolwind + +Changes from 5.1.9beta8: +- Info on persist load/save in startup log +- Clear logs if not enough space for persist +- Persist save of cruise efficiency +- Fixed mc speed bug when cruise efficiency modified + +Changes from 5.1.9beta7: +- Draggable targets on touchscreen version +- Cursor toggle mode in landscape target dialog +- AAT Time to go resets to zero on cleared task +- AAT Time to go never negative +- Fixed bug in waypoint exclude outside terrain checking +- Fixed bug in time calculations with short final legs in task + (final glide around multiple points). + +Changes from 5.1.9beta6: +- added clear button to task editor dialog in portrait mode, + courtesy Jacques Fournier +- added missing infobox copy/paste buttons in portrait mode +- added display of wing loadings for built in polars +- added GRecord stuff to Altair +- updated copyright text to source code +- moved close button in basic settings to left to improve usability on PNA +- FLARM targets display of average climb rate courtesy Lars H +- Team code position shown on map courtesy Lars H +- GRecord updates for Altair, PNA +- FLARM on-map display updates +- Button labels update for PNA +- Fixed minor bugs in calculator re ete (energy height not used in fractional calculations) +- Restart time now one hour +- Fixed bug in display of start in analysis page (barograph) +- Selective fine control of float attributes +- Added LAK17-15, Lak17-18, ASG29-15 (mod from ASW27-W) +- Display weight info on glide polar page +- FLARM declaration bug fix + +Changes from 5.1.9beta2: +- Alternate text entry methods +- Can now use flarm database, courtesy Lars H +- Added copy/paste to infoboxes in configuration dialog +- Flymaster F1 bug fix (vario units) +- Porting to cegcc with Russell King +- Task/leg times to go etc only shown if task is completeable at current Mc +- Infobox selector has items sorted alphabetically +- Multiple start points ensure the current start is in the list. +- Draw cross in final glide bar if unreachable at current MC +- Initial support for XCOM760 radio +- Added input event to add temporary landable waypoint +- Goto function now allows tasks to be resumed +- Bug fix in DD.dddd waypoint edit format +- enabled use of flarmnet ids in flarm display (courtesy Lars H) +- Added input event to switch orientation modes +- added support for declarations to IGC approved FLARM devices +- added missing help for new infoboxes +- added control of circling zoom to input events +- battery voltage infobox for Altair (others to follow) +- added Ventus CM17.6 polar +- added duo discus XT polars courtesy Derrek Ruddock +- added option to set 800x480 resolution for ipaq 310 testing +- mods to allow configuration of Vega in portrait mode +- robustness enhancements (avoid buffer overrun in long waypoint comments) +- build script +- version bump +- More porting to cegcc; allow O3 optimisation, variable initialisation + +Changes from 5.1.9beta1: +- Added Flymaster F1 device +- Fixed bug in AutoQNH +- Finer units in task rules dialog + +Changes from 5.1.8: +- Draw red line on thermal band at start height when there's a start + height limit and on start waypoint +- Touching list forms in the scrollbar area moves to that position in the list +- Don't display meters in airspace altitudes as well as feet unless meters is + the user altitude unit. +- FL altitudes rounded to nearest 10 units to ease readability +- Zander support split off into its own device +- Fixed IAS of Zander (km/h -> m/s) +- Fixed bug in declaration to EW micro +- Added ASG29E-18 polar + +-------------------- + + +Changes from 5.1.7 beta6: +- Projected track line in AAT mode when track from last turn >10 degrees off target +- Allow start through top of start sector +- Bug fix, baro and GNSS altitude in log files swapped +- Fixed lockup on auto shutdown in simulator mode when out of batteries +- Higher colour contrast snail trail +- Changed "Ack for day?" to YES/NO/CANCEL + (NO unacknowledges for day) +- Airspaces drawn closed if open +- Added UNL (unlimited) airspace top as used in wgc08 +- Fixed lock/unlocking of targets in portrait mode +- Fixed direction of arrows on task line in AAT mode + +Changes from 5.1.7 beta6: +- Energy height referenced to Mc speed to fly +- Fixes to airspace rendering in analysis dialog +- DMS/DMmmm/DDdddd units in waypoint edit +- Added proper dialog for airspace queries +- Prevent log points > 500 m from being added to snail trail or OLC store +- Minor Auto Mc improvements +- Ballast in basic settings has a timer, activated/deactivated + by pressing ENTER, which progressively reduces ballast according to + the rate set in the configuration settings (dump time). Timer is only + active while the basic settings dialog is open. +- AAT/FAI Sector rendering on screen now more accurate +- Bug fixes and cosmetic cleanups to airspace warning dialog +- Final glide through terrain status message warning logic improved +- Enhancements to thermal profile band and risk MC with respect to flying in + mountains +- Added option for final glide terrain line to shade terrain outside glide range + +Changes from 5.1.7 beta4: +- Airspace display in analysis dialog sped up slightly +- Airspace queries report MSL referenced height as MSL instead of "Alt" + +Changes from 5.1.7 beta2: + +- Task speed instantaneous improvements +- Fixed bug in start height reference in dialogs +- Added terrain height to barograph in analysis dialog +- Pressing ENTER on Mc value in task calculator sets it to time-averaged + climb rate from circling +- Support for AGL airspace, now tested +- Bug fix in parsing airspace "M"/"MSL" +- Some graphical cleanups +- Pressing ENTER on range value in task calculator does optimise +- Auto Mc (final glide) won't wind down to zero the first time final + glide is achieved. It will wind down to zero after that though. +- Energy height used in achieved speed, cruise efficiency calcs +- When off-course by more than 10 degrees, shows distance penalty + in % for that leg along track line on map. +- Cruise efficiency stays at user-set value; if the field is selected and press ENTER, then the value will be calculated (and set to that value). +- Fixed minor bug in energy height compensation of thermal stats +- Minor improvements to analysis dialog +- Improvements to task speed instantaneous (new, more robust algorithm) +- Airspace AGL supported (not tested), will add terrain height at center of airspace to base. +- Analysis dialog shows mc speed, sink rate on glide polar page +- Analysis dialog shows terrain height in airspace page +- Allow auto mc to function when no task defined +- Added task rules dialog from task start point +- Added height reference for Start max height rule (allows MSL or AGL) +- Increased accuracy of terrain footprint +- Added LS6-15 polar +- Cruise efficiency displayed and adjustable in task calculator. The cruise efficiency + is the increased average speed of the glider in cruise, due to dolphining or flying in + rising air. It is calculated and displayed in the task calculator. + If the value is edited, then it will be used subsequently in arrival time calculations. +- Added g load estimation when acceleromter not connected +- Added experimental distance vario infobox. + This is the the difference in height required to complete the task divided by the time step. +- Improved task speed instantaneous +- Hour glass used in nearestairspace input event, since this can take a few + seconds. +- White bold (a la Google maps) on task waypoint labels +- Added input event "GotoLookup" which allows a single menu item to bring up the waypoint select + dialog, and if a waypoint is selected, it will Goto and clear task. + See pc.xci for example (it replaces the "Task Save" button) +- Fixed situation where auto Mc can wind down after task start due to manoeuvering near start +- When logger is started, if the task hasn't been saved, it is saved to the default task. + +Changes from 5.1.7 beta1: +- Vario gauge shows thick red/blue line for sink/lift +- Last thermal stats only used if thermal gain > 0 and + thermal time > 45 seconds. This prevents spurious entries for ignored + thermals, or for quick pullups in thermals without sustained turns. +- Not just airports but landpoints can now have "airfield" details + +Changes from 5.1.6: +- Map scale display for non-metric units +- Fixed initialisation of AAT properties when adding waypoints from + waypoint dialog + +------------------------------------------------------- + +Changes from 5.1.5 beta 6: +- Snail trail rendering improvements: + -- removed 'wobble' of snail trail from long time ago + -- don't crop partially visible lines +- Bug fix in AAT sector detection when start angle > end angle +- "Speed remaining" in status dialog renamed to "Speed estimated" as + it gives the estimated final speed of the task +- Increased size of up/down arrows in FLARM gauge +- In target dialog, can move target up/down/left/right on Altair with + DISP/CFG/F5/F6 keys, on PC with 2/3/6/7 keys +- Added blue line of constant distance arc in AAT sectors +- Fixed bug in LD vario and LD GPS calculations +- Added LX sentance (LXWP0) to support Condor +- Fixed bug in auto mc +- Task speed stats reset on task start/restart. + +Changes from 5.1.5 beta 5: +- In target dialog, north up and north track modes cause screen orientation + to be north-up +- Calculations in the target dialog is based on a timer now rather than triggered + on change, to prevent calculations slowing down the refresh. + +Changes from 5.1.5 beta 4: +- Infoboxes (AA Time, Task Time To Go, Next Time To Go, + Task Arrival Time, AA Delta Time) + now use consistent color format: + black/white: AAT est > min time + blue: AAT est turning now > min time + red: AAT est < min time +- Task editor/overview page shows file name of task in caption, and shows '*' + if task is edited and not saved. +- Bug fixes to tasman instruments vario +- Text entry dialog uses larger font +- Flight logger can use short file name, if "Logger short file" is true. +- Flight logger gets ID from 3-letter logger ID + in System config, if not set this defaults to 'AAA'. +- AAT zero range (nominal) task is displayed thin green dashed, + target task is displayed in thick green dashed +- Added new infobox "Thermal All / TC All" for gps vario averaged across + all time spent in circling mode. +- Speedups and bug fixes to effective/achieved Mc calculations. + achieved Mc is no longer influenced by gliding off high starts. +- AAT optimiser more accurate for setting range to 5 mins over min time, + faster, and more robust. +- Prevented re-start of snail trail on minimum height if OLC disabled +- Full snail trail (OLC) data thinning bug fixes + +Changes from 5.1.5 beta 3: +- "Smart averager", averager resets on cruise/climb transition +- Display AAT sizes next to waypoints in task edit +- Set AAT default size from sector size setting +- Target radial setting can wrap around +- "Target locked" is in target dialog now +- Improved robustness of AAT optimise buttons etc +- "Target" instead of "Mark Location" on default menu of Altair/PC +- Snail trail color scale fixes +- Target details cleared when changing a turnpoint +- AAT nominal task is displayed thick green dashed, + target task is displayed in thin green dashed + +Changes from 5.1.5 beta 2: +- Task speed statistics reset on task restart +- Draw vertical lines on analysis dialog barograph and task speed + where legs started +- Locked targets are unlocked as soon as the AAT area is entered + +Changes from 5.1.5 beta 1: +- Changed ExternalTriggerCruise to enum, so it can be off, + "flap", or "SC" (speed command). + Existing value of true is equivalent to "flap". +- Draw centroid/'bmw' symbol at targets in AAT task +- Calculate AAT time to go if turning now while in sector, then + going to remaining targets after this. +- AA dT infobox goes blue if task time > AAT time + 5 minutes when in sector + and pilot turns now. + Therefore, particularly in last AAT sector, when AA dT is blue, + it is reasonably safe to turn now, even if the target is deeper in the + sector. (only if color infoboxes are on) +- Set waypoint bearing and best cruise track to first leg bearing + when in start sector, so blue arrow points to first target, and + so does screen orientation. + +Changes from 5.1.4: +- Target dialog steps in 2% and 2 degrees instead of 5. +- AAT target direction and best cruise track arrow (blue) extends + towards task line from previous target through aircraft when advancing + the target (aircraft is going past target) +- Less wandering of AAT target while in sector due to shift along track +- AAT delta T goes red when going under time +- Failure to load a task keeps old start/finish/aat properties + +Changes from 5.1.3 beta9: +- Cleaned up portrait waypoint select and airspace select/control dialogs. +- When circling and in target dialog, orient towards waypoint +- Cleaned up compilation warnings for include files that aren't used +- Added display of 30s average glide angle to airspace page of analysis dialog +- Added labels "h" and "D" to airspace page of analysis dialog +- Added E/W, N/S fields to waypoint edit dialog +- Task editor asks whether added waypoints are the finish points, + means user doesn't need to go back into AAT turnpoints after adding them +- Reorganised fields in task editor waypoint properties for more intuitive + ordering. +- When adding waypoints from task editor, don't show misc buttons in turnpoint + dialog (e.g. details, move up/down, select, remove) since they're not + required here. +- Task editor, removed move down/up buttons when at extremities of task +- Added 2 more airspace patterns +- Added AA delta T infobox +- Fixed bug where North/Track method was not being saved +- Increased status message delay time for default messages to 2.5 seconds + +Changes from 5.1.3 beta8: +- Added support for declaration to EW MicroRecorder +- Added instantaneous task speed to analysis dialog +- Fixed instantaneous task speed calc + + +Changes from 5.1.3 beta7: +- Cleaner startup and shutdown +- Task calculator and target pages from analysis dialog hides analysis dialog +- Fixed some ranges and units in configuration dialogs +- Fixed greying out of previous waypoint menu +- Fixed hang on exit on PPC2000/PPC2002 platforms +- Cleaned up display of waypoint and task list columns +- Fixed netto vario calculation when not flying or very slow +- Added TE probe calibration to vega configuration +- OLC handicap factor limited to values between 50 and 150 % +- Task overview dialog hides when launching calculator and analysis dialog + so target display works from there. +- Fixed acceleration compensation for netto vario calculation when used + with a vario that doesn't supply netto but does supply acceleration +- Auto positioning of targets when behind target inside AAT sector is disabled + when target dialog is open +- TC Avg infobox now shown in red if value < 2/3 of Mc +- Risk Mc used in colored info boxes (TC 30s, TC av) instead of absolute Mc +- Allow negative times in infoboxes and dialogs (in particular for AAT + time to go) +- AAT time to go infobox can be negative (e.g. in excess of min time) + +Changes from 5.1.3 beta6: +- G load factoring for polar etc take absolute value of G, in case + meter (or aircraft!) is upside down +- Fixed airspace query message when inside airspace area but below/above it + +Changes from 5.1.3 beta5: +- Fix to target dialog when active waypoint changes while dialog is active +- Fixed help on infoboxes final glide and auxiliary page +- Added highlighting of selected item in lists etc, to improve + readability +- Added seconds to infoboxes in comment line +- Added big infobox display mode, activated in Altair/PC via escape then F1. +- Added ASSERTs to xml parsing to check for memory problems +- Fixed some aspects of Vega demo handling +- Cleaned up program exit +- Changes to vega vario config dialog + +Changes from beta4: +- Fixed waypoint save when using xcm files +- Added estimated achieved speed and ETE to target dialog +- Moved teamcode button to Info page 2, replaced with target dialog +- Write "No data" on analysis dialog when no data available to display +- Changed progress dialog from TOPMOST to TOP so other dialogs (e.g. error + dialogs) don't get obscured by it. + +Changes from beta3 to beta 4: +- Added delay/protection in launcher to try to prevent XCSoar being + started twice. +- LD vario was wrong sign (negative down), now fixed. +- Prevent crash on start with xcm files that have oversized tiles +- Circling % takes turn rate into account to prevent bad stats due + to flap switches and dolphin soaring +- Added relative altitude arrows to FLARM gauge in Bearing mode +- Nearest waypoint in status dialog now working even if waypoint is not + visible on map +- Climb stats are now calculated relative to total energy height +- File properties are now sorted alphabetically +- Added locking of targets, and target dialog (from task calculator) to + allow preview of task points and to move targets + +Changes from 5.1.2 stable to 5.1.3 beta2 +- Fixed bug in waypoint parsing of second file +- Waypoints outside terrain are always loaded if no terrain file +- Marks reset bug fix +- Added condition monitor for start rules +- Changed "V Task" instantaneous to "V Tsk Ins" +- Changed "Speed achieved" to "Speed average" label in status dialog +- Task speed value preserved over reset +- Status dialog allows left/right cursor to change pages +- RASP: Changed wstar color scale, better for strong conditions +- RASP: Sfctemp colour/offset fix +- RASP: only available times are displayed in dialog, half hour times + supported +- RASP: weather dialog allows "Now" time (auto updated) or set time +- RASP: fixed white-out of display outside RASP range +- RASP: added wblmaxmin (convergence) and blcwbase (Cu cloudbase) to RASP +- Added progress dialog text for initialising terrain tiles (jpg2000) +- "acknowledgment Time" setting was ignored, now correctly used by airspace + warning manager +- In airspace query status message, top now drawn above base (was the + other way around) +- Reorganised airspace select and waypoint select dialogs in portrait + orientation for greater readibility +- Barograph in analysis dialog time axis starts from zero. +- Analysis dialog: sensible output when not valid; remove display of data + which might be confusing +- Added hourglass cursor for slow events (configuration, airspace lookup, + OLC optimise, shutdown) +- File xcsoar-startup.log is now proper text file +- Marks files deleted on exit +- Enabled display of battery % for PDAs in status dialog, + and warning on low battery + +--------------------------------------------------------------------- + +Changes from 5.1.1 beta 7 +- Allow for new or edited waypoints if the primary waypoint file is + in the xcm file or blank ---> generated files become waypoints1.dat + and waypoints2.dat +- Fixed marks reset +- Start height in status dialog (task rules) is represented as altitude +- Changed "nearest" button in analysis dialog to "warnings" +- Day-acknowledged airspace is always unshaded (outline still drawn) +- Bigger/italic font of labels on analysis page +- Airspace lookup dialog doesn't exit immediately after acknowledging an + airspace. +- Added dwcrit and wblmaxmin to RASP parameters +- Added "Times" page to status dialog, with separate landing/takeoff/flight times +- Added "Max Height Gain" to status dialog +- Fixed alternate glide bar style in portrait mode + +Changes from 5.1.1 beta 6 +- Ensure FLARM becomes visible if suppressed and alert level >0 +- Added missing port functions for second port +- Prevent 2d fixes from being added to logger buffer +- Bug fixes to port handlers, now task Declaration to external loggers + stands a chance of working +- Added Volkslogger device +- Added FAI 1000m start rules option +- Thickened green lines in Analysis dialog +- Added display of grid values in Analysis dialog +- Merged status pages into single dialog, and moved weather button to + where status aircraft used to be. +- New status page "Rules" showing start/finish details +- Fixed minor memory leak in RASP weather loading +- Splash screen on PC works now +- Added COM0 to available ports + +Changes from 5.1.1 beta 5 +- Preliminary support for RASP overlays +- Task waypoints preserved even if waypoint file is changed +- B50 bug fixes, support now for external cruise/climb switch +- Loads default language file "default.xcl" if it exists and no language + file is specified. +- Added several missing translations +- Fixed terrain cache method for PDAs with low memory +- Added new polars: Speed Astir, LS-6-18W, LS-8-15, LS-8-18, ASH-26E, ASG29-18, ASW28-18 +- Added named tasks +- Added ability to lookup airspaces by name/distance/direction/type + and acknowledge for whole day. Access via "Airspace Settings" menu, + "Lookup" button. + +Changes from 5.1.1 beta 4 +- Minor bug fix to ballast calculation in B50 vario support +- Fixed baro altitude parser bugs +- Fixed time wrapover with end of month and midnight +- Cleanups of LD limiting functions and filter +- Cleanup of calculation time limits +- Cleanup of calculation code for readability +- Menu translations for waypoint next/previous in abort mode +- Fixed display of FLARM targets beyond 2.5 km +- Display final glide through terrain crosshair on top of everything + except aircraft. +- Fixed rendering errors at edge of jpg2000 tiles +- Separated Borgelt B50 series devices into their own device (no longer Generic) +- Fixed AAT sector bug +- Force/unforce final glide menu item is hidden if AutoForceFinalGlide is on +- Added some missing translations +- Fixed previous page button bug in waypoint details +- Line drawn from FLARM target to edge of radar display for alert targets, + makes it easier to see direction to search for traffic. +- Code fixes to device.cpp to prevent crashes with badly written device drivers + +Changes from 5.1.1 beta 3: +- Force visibility scan after loading new airspace/topology/waypoints +- Progress bar for jpg2000 loading enabled +- Baro altitude from RMZ/RMA sentences only used if no primary + baro source from a non-generic device +- Increased string length for parsing waypoints and airspace to 300 +- Set GPS position to map center on startup if no home waypoint +- Fixed bug in rendering at very small zoom errors (could lead to crash) +- Rendering is smooth now even for jpg2000 terrain from overview +- Added reset function to MarkLocation event + +Changes from 5.1.1 beta 2: +- Consolidated validity checks for info boxes + +Changes from 5.1.1 beta 1: +- Fixed terrain shading bands in portrait mode +- Fixed terrain shading near coast boundaries +- Enabled portrait mode for Altair +- Enabled gauge vario in portrait mode for Altair +- Added file size method to zzip +- Added support for loading waypoint files from XCM +- Added support for loading airspace files from XCM (disabled, because too slow) +- Consolidated sizes of strings in ReadString methods +- Airspace parser and bounds fix when airspace goes past 180E + +Changes from 5.1.0 beta 3: +- AAT target in sector fixes +- AAT sector/circle radius default value is 500 meters +- AppendTo function bug fix +- Mc Risk bug fix +- Replay finish stats bug fix +- Airspace parser more robust to syntax errors +- % Circling resets on valid start +- Screen unblanked if status message appears +- Terrain color ramp is user configurable (Low lands or mountainous) +- Terrain rendering speedups +- Polygon rendering speedups +- Replay logger bug fix (sometimes gave heading=0) +- New experimental jpeg2000 tiled terrrain loading +- Terrain rendering speedups and improvements +- Task speed unit bitmap fixes +- Fixed problem with declaration time occurring after takeoff time + due to buffering of pre-takeoff data +- Bigger buttons in landscape mode for non-Altair versions to allow + room for German translations +- User distance units in waypoint select dialog +- Memory leak in JPG2000 fixed +- Fast sine/cosine speedups +- Terrain rendering speedups +- Additional terrain ramps added (Imhof, ICAO) +- Option in expert configuration to disable the auto start/stop of logger on + takeoff and landing +- Zip container code added +- "XCM" (XCSoar Map) file format support added +- fixed top line of terrain +- bumped version to 5.1.1beta1 +- fixed airspace parser dialog bug + + +Changes from 5.1.0 beta 2: +- Added code to generate missing translations file on windows PC debug builds +- Grey out of some task specific menu items if in abort mode. +- Style option to draw an arrow body alongwith the arrow head + under option "Wind Arrow" in Settings->Map Display(Expert) +- Fixed bug in query airspace if inside airspace +- Added gettext() to enumerated parameters + +- New notifications: AAT too early, arrival past sunset, + significant wind change +- Fixed bug in Arm start mode (wasn't advancing) + +Changes from 5.1.0 beta 1: +- Speed to fly compensated for risk +- Logger buffered for 60 seconds +- Energy height uses estimated true air speed if no IAS is available +- Support (read-only) for Zander variometer and Tasman Instruments variometer +- Changed scale on final glide bar to +/- 500 meters (was +/- 2000 meters) +- Attempt to resolve slow response with in FLY mode on older PDAs +- Fixed bad line in default.xci + +Changes from 5.0.9: +- Added NMEAOut, PosiGraph devices +- Input events for forced cruise/climb displays (etc?) + (FLARM display forcing) +- Waypoint selection filter by type, and by heading 360 deg +- Smoother scrolling of lists +- Setup dialog for NMEA devices changed. +- If any landable point is visible and reachable, final glide bar goes orange + if below final glide. +- Menu label macros added: WaypointNext, WaypointPrevious, AdvanceArmed, LoggerActive, + TerrainTopologyToggleName, SnailTrailToggleName, CheckAirspace, CheckTask, + CheckWaypointFile, CheckSettingsLockout, CheckReplay, CheckFLARM, CheckTerrain +- Menu labels grey out if actions are unavailable +- Dialog details for AAT vs non-AAT are visible only when AAT is set or not, + in task calculator, task status, and task waypoint editor +- Fixed restart problems where >10 minutes, still was restarting +- Start/restart now more user friendly. Auto restart only happens up to first turnpoint +- Fixed bug in ETE calculations when force final glide is on. +- Terrain not rendered in not valid at aircraft +- Fixed bug in waypoint lookup (search by turnpoint) +- Moved some config parameters to "Site" configuration page +- Added advanced vs basic configuration settings +- Added -small startup option for PC +- Fixed bugs in ZigZag wind algorithm, and improved accuracy and response +- Don't draw final glide through terrain icon if no task +- Wind estimate set by user in wind settings dialog (with SAVE button) + overrides the internal estimate until a new estimate is obtained. +- Minor cleanups of text in dialogs +- Invalid infobox data is greyed out so it doesn't distract user + +Changes from 5.0.9 release 1: +- Fixed ETE and final glide calculations for Mc=0, proper compensation + for wind and unreachable at current Mc etc. +- Fixed task distance rounding to nearest 0.1 units + +Changes from 5.0.8: +- Fixed bug in wind initialisation/calculation +- AAT start/finish radials step in 1 degree increments +- Fixes for build on VS2005 (PC) +- Fixed various out of bound bugs for task waypoints +- Fixed display of topology labels +- Fixed AAT distance thread dead lock +- Volkslogger parser fix by Rolf Muller-Nilsen +- Fixed adjustable logger time steps +- Fixed AAT distance bug for final waypoint +- Transparent airspaces are not filled, so airspace below is visible + +Changes from 5.0.7: + +- FIXED Start arm premature + messages are confusing though, we don't get notification when re-entering a start + sector (after arming it), nor when approaching a start line. +- New snail trail mode "Full" which displays entire flight. In all modes, + the snail trail is short in circling mode in order to prevent screen clutter. +- New feature: added 'optimise' button to task calculator. This adjusts the + range (increases or decreases) so that the estimated task time exceeds the + assigned task time by less than five minutes. +- FLARM targets on the map are drawn as arrow heads pointing in their track bearing. +- Added missing 'Auto Display Blank' to configuration settings for PDA platform +- Fixed Borgelt B50 sentence parsing (Thanks RMN) +- Bug fix for half hour UTC offsets +- Total energy is calculated from difference in true airspeed to best LD in + true airspeed +- Task radii expressed in user units +- Bug fix, profile support for PC and PDA restored +- Bug fix, protected use of message in NearestAirspace function with thread lock +- Bug fix, NearestAirspace search array out of bounds due to unsigned int loop +- QNH, Bugs, Ballast and MacCready saved at program exit and restored on startup +- FLARM radar can be selected to display relative altitude or bearing. +- Removed asking whether to delete old log files to make space when logger is started. + Deleting old log files happens automatically now. + +Changes from 5.0.6: +- Max manoeuvering speed set to 300 units in configuration dialog +- System beep and message on task/waypoint advance +- Messages given in arm modes (arm start or arm) as reminders to press arm + when ready to advance +- Bug fix to waypoint editing (second waypoint file was cleared) +- Warning added to waypoint file save when filtering for + waypoints outside terrain range is enabled. +- Bug fix, task statistics were not updated after task finish. + +Dialogs changed: +- dlgTaskWaypoint.xml +- dlgTaskCalculator.xml +- dlgConfiguration.xml +- dlgConfiguration_L.xml +- dlgTaskOverview_L.xml +- dlgTaskWaypoint_L.xml +- dlgStatusTask.xml +- dlgStatusSystem.xml + +Changes from 5.0.0: +- Fixed non-drawing of infobox borders on PPC2002 +- Added Declare button on Task Calculator +- Fixed terrain display offset bug in portrait mode +- Map scale increased resolution +- Increased maximum radius/sector size on AAT to 100 km +- "Show gross" vario configuration (default true) +- Color speed chevrons, and larger: + -- blue pull up (slow down) + -- red push to earth speed up +- Lightened blue color in infoboxes +- Auto disarm mode message only appears if in arm mode +- Task calculator, shows estimated task speed for remainder of task +- Task calculator, shows effective MacCready +- Task calculator, shows achieved speed +- Task calculator, cancel button restores Mc at entry +- Auto MacCready: climb stats are reset on takeoff +- Previous waypoint selects through all multiple start points +- Bug fix, aat target continuation was only working on first sector +- Autozoom for AAT, distance used in zoom is set by max of + distance to target and distance to center (so scratch task should + always be visible in autozoom mode) +- Fixed bug in glide time required (wasn't taking final glide into account) +- AAT areas drawn in reverse sequence so next area is on top, + previous AAT areas not drawn. +- Zigzag wind disabled if on ground (slow or not flying) +- Wide version of FLARM target display on map (ON/Scaled) +- Achieved MacCready accuracy improvements (was overestimating + with start circles) +- Achieved maccready, height difference compensation +- AAT projection when in sector +- Task calculator, changed "Range" to "Set range" +- Bug fix, "Nearest airfield changed" problem if two airfields are coincident +- Abort mode bug: multiple waypoints close to home give "nearest airfield + changed" repeatedly. Now message is given only if nearest airfield + is more than 2km from previous one. +- All up Weight is displayed in analysis dialog glide polar page +- Minimum zoom increase in AAT (for autozoom) +- Task speed achieved is average speed dist/time + time + to climb back to start height. +- Task editor, removing waypoints preserves AAT details of successive + waypoints +- Fixed TASK_START event +- New infobox for distance to home +- New infobox for speed task achieved +- Added AutoBlank configuration option for PDA versions +- Changed text in task status dialog for clarity +- Changed flap forces cruise to now use landing flap switch, and works + for switching into cruise and into circling +- Bug fixes to AAT distance calculations +- Added ventus 2cx to polar +- Bug fix, sound volume was set to zero on exit +- Added flap landing to switch dialog +- Added close button to text entry widget on non Altair systems +- Allowed wraparound of letters on text entry dialog +- Minor changes to help text and labels of configuration items for clarity +- Lighter blue/red for inverse mode +- Time/date fix for IGC files (UTC used throughout as per spec) +- North/track up display orientation +- Waypoint select on add-waypoint in task editor +- Arm advance to work outside AAT sector if already been in that sector +- Prevent landing/takeoff detection when GPS is disconnected +- Configuration of lat/lon units +- Changed 'aircraft rego' to 'competition ID' to be consistent with IGC +- Improved cropping of polygons +- Minor bugfixes + +Dialogs changed: + dlgConfiguration.xml + dlgStartPoint.xml + dlgTaskWaypoint.xml + dlgTeamCode.xml + dlgTextEntry.xml + dlgWayPointDetails.xml + dlgWindSettings.xml + +Changes from 4.7.7: +- Make terrain file loader check file size, to improve robustness if + bad file. +- Added text entry dialog +- Added pilot name, aircraft type and rego to configuration dialog +- Added support for team code +- Map zoom improvements +- Fixed bug: Waypoints label in abort +- Fixed bug: Default task at startup if no task defined +- Fixed bug in altair.xci, nearest waypoint details were pan-relative +- Minor UI cleanups (cosmetics) +- Logger inactive when in IGC replay mode +- Circling wind estimator won't update if less than one fix every 2 + seconds. +- Zigzag wind estimate inactive when in IGC replay mode +- Analysis dialog: base/ceiling estimation improvements +- Task speed now altitude compensated +- New task speed instantaneous +- All flight statistics retained when exiting XCSoar and loaded at startup, + so previous flight can be reviewed later. +- Task is saved when exiting XCSoar and loaded at startup. + (Default.tsk) +- Removed unused/default processor definitions, + NEWINFOBOX, NEWAIRSPACEWARNING as this is default now. +- Added support for alternate start points +- All file paths are now converted to/from local path for that machine + so registry files can be transferred between PC and PDA/Altair. +- PC and PDA version all data files now in "My Documents/XCSoarData". +- Thermal locator improvements +- UI change: All reachable landable points arrival heights are shown on map in + all waypoint label display modes +- Average task speed improvements: compensation for altitude, + now computes task speed accurately for achieved scorable AAT distance. +- Task page on analysis dialog shows in thick red dashed line the scorable + AAT paths. +- Fixed bug, task finish detection was previously disabled +- Fixed bug, stats for finished task after reset were not displayed correctly +- Fixed bug, waypoint details dialog arrival height was relative to sea + level not ground. +- Waypoint details altitude arrival, removed "alt diff mc safety" +- Removed unused menu and dialogs from PC version. +- CatMul-Rom interpolator used for logger replay now, provides better + reconstructed paths and wind estimates when used with low logging rate. +- Thermal markers shown in cruise mode only at close zoom scales, + to avoid clutter. +- When infobox colors are enabled, the thermal last 30 second average + is red when the average is less than 0.5*MACCREADY. This can be used + to clearly show when it is time to leave a thermal. +- AAT max/min/target speeds in infoboxes show '---' if minimum time + remaining is zero. +- Minimum zoom level in autozoom set to reasonable level (1.5km) to + prevent zooming in too close when going past a turnpoint. +- List items in dialog can be selected with mouse/touchscreen. Touch twice + to emulate return key. +- Added configuration option to adjust snail trail width +- Fixed bug, made airfield details parser robust to wrong files. +- Fixed bug, nearest waypoint details did not work for first waypoint +- Fixed bug, airspace warning dialog was not shown from + 'nearest airspace' menu when there was an active acknowledgement +- Fixed bug, PC version crashed if exit via close button and a dialog was + still open +- Home waypoint always added to abort task list if reachable +- 'Clear' button added to task dialog in landscape mode +- Team Code dialog updates dynamically +- Fixed bug, range/bearing was incorrect sometimes +- Improved rendering of distance to airspace in airspace warning dialog +- Fixed bug, portrait mode text in analysis dialog (some items were cropped) +- Infobox border fixup in portrait mode +- Fixed bug, hang on nearest airspace +- Bearing to target shown in great circle arc +- Fixed bug, in abort mode (introduced just 2 days ago) +- Fixed bug, sound volume was set to zero +- Updates to menu, default.xci for PDA +- Return key now toggles suppression of FLARM radar. If new traffic appears, + the suppression is turned off again. +- Fixed bug in PPC2002 infobox selector graphics +- Fixed bug in abort mode (possible cause of crash/hang) +- Task calculator range increments in 5% +- Added infobox for 'Home Distance' +- Auto QNH only activated when not flying for more than 10 seconds +- Button menu fixes for PDA, PC +- (Feature request 1281639) Editing/saving waypoints +- Protected task edit from buffer overruns +- Fixed bug, increased text size for airspace parser +- Disabled CDI gauge as it has no control in the configuration settings and hasn't + been updated +- Fixed bug, FAI finish sector was incorrect + + +Dialogs changed: + ALL dialogs + dlgHelp.xml + +Changes from 4.7.5: +- Added small histeresis to instantenous LD vario +- Airspace parser updates +- Added Cambridge GPS NAV device +- Added option to force cruise on neutral/negative flap (for Vega) + (Flap forces cruise) +- Terrain contrast/shading improvements +- Snail trail now drawn with outline to improve visibility over terrain +- Added V TAS infobox +- Improvements to wind estimator algorithm +- Vario gauge unit bitmap for knots +- Vega configuration, added page for audio schemes +- Vega configuration, added missing parameter (BaudRateA) +- Altitude AGL uses baro altitude if "Nav by baro altitude" +- New units for task speed (separate from airspeed/wind/ground speed units) +- Added FAI 90 start/finish type +- Added thermal locator (shows centroid of lift when circling), option 'Lift center' + in configuration options. +- Fixed minor bug, auto macready by average was not working when no + task was defined. +- Modified least squares algorithm to handle weighted least squares. +- Add 'Append' waypoint function, so users can create a task by selecting + waypoints from the map in sequence +- Task waypoint move up/down in task waypoint pages. +- Terrain database loaded into memory if sufficient RAM + 5 Meg free +- New smooth shading of terrain, major improvement +- New landscape progress dialog hides screen for cleaner startup +- Default task to home if no task loaded at startup +- Added labels to climb and temperature trace analysis pages +- Added help system. Press enter for 2 seconds on a dialog property + to display help text. +- Fixed minor bug, landable points were not always visible for some + label modes. +- Fixed minor bug, baro altitude set by GPS for IGC replay. +- Online Contest optimisation (analysis page, configuration settings, + three rule sets available) +- Analysis pages now each have a context-sensitive 'action' button. +- Added handicap to glide polar page for OLC scoring +- Fixed GDI resource leak in animateRectangles +- Fixed memory leak from com port threads not having handles released +- Fixed airspace warning dialog losing focus of previous dialog if opened +- Fixed memory leaks in new airspace warning dialog + when another dialog is already open. +- Online contest "in progress" +- Added 'Declutter Labels' inputevent and menu item +- Fixed GDI resource leak in WindowControls +- Refinements to screen lat/lon bounds calculations +- Refinements to thread locking (separate LockTaskData from LockFlightData) +- GCE/NMEA queue blocking bug fix +- Added check for 500kb free space on IGC destination, asks user to + delete old IGC files as required to free up space. +- OLC work (rule interpretations, in-progress only valid if flying) +- Added tab style for infobox border +- Added double buffer for infobox rendering to reduce flicker +- Topology bounds area used for pre-filtering of visibility to improve rendering time +- Toggle terrain map labels button (DeclutterLabels) +- Thread locking improvements to reduce latency +- Computed arrival height AGL at Mc0 Mc safety Mc current +- Startup/shutdown messages saved in xcsoar-startup.log +- Fixed bug, short task duration estimates when Mc=0 or unreachable + in cruise at current Mc setting due to drift. +- Fixed bug, spurious touchscreen detect when pressing menu buttons +- (Feature request 1463308) Auto-mark thermal +- (Feature request 1444335) configurable max/min zoom --> better zoom + levels available now. + +Dialogs changed: + dlgConfiguration.xml + dlgWindSettings.xml + dlgVario.xml + dlgAirspaceWarning.xml + dlgWaypointOutOfTerrain.xml + dlgAirspaceWarning.xml + +Changes from 4.7.4: +- Fixed total energy compensation (final glide) when on ground +- Fixed minor bug, silly ETE values were presented when Mc=0 in AAT + in Task Calculator +- AutoMc disabled if in abort mode +- Fixed: Thermal profile showing distortion (negative values?) +- Fixed: Mc=0 Est task time on task calculator +- Fixed: Trail hang +- Fixed: PC registry not recognising all registry values correctly! +- Auto Mc modes: final glide, set to average, both +- Vario gauge averager should switch to netto averager if not in circling mode +- sam's bug fixes and new features + --> legbearing bug + --> New airspace dialog + --> Waypoints out of terrain +- Fixed: AAT radius display in analysis page shows distortion +- Fixed: Waypoint infobox shows bearing to waypoint, not to target (for AAT) +- Fixed: Vario gauge chevrons not always appearing when they should, + now chevrons always drawn if vario is in non-circling mode +- Fixed: Averager jumps around too much +- Added configuration setting to determine whether to ask/exclude/include + waypoints out of terrain range. +- Added LD vario infobox + +Changes from 4.7.3: +- Added Auto QNH function +- Minor improvements to robustness +- Added preliminary support for vega voice +- Limits on altitude/speed for start, altitude for finish + (Feature request 1444340) +- Changed AutoWind from bool to enum: Manual, Circling, ZigZag, Both +- Added zig zag wind estimator +- Added option to use of barometric altitude for all nav functions +- ** (Feature request 1403702) Configuration option for logger timestep +- FLARM gauge, show colors for threat levels +- Fixed bug, Start/Finish radius drawn half size +- Fixed bug, v task calculations if selecting a previous waypoint after + starting +- Added detection of valid start, now in task status dialog if + start wasn't valid, the start time shows "INVALID" +- Added safety McReady for use in calculating reachable fields and + display of arrival heights, and in abort mode. Option to use + current Mc value for safety McReady when in abort mode. +- (Feature request 1278082) Ellipsoid error correction. Now + detects if ellipsoid/geoid offset is produced by GPS. If not, + it applies geoid correction. +- Added basic support for Cambridge GPS-NAV as a GPS source only + +Changes from 4.7.2: +- Fixed bug: Disabling of airspace warnings by individual types was + ignored. Now working correctly. +- Proper handling of PGRMZ with respect to QNH and when altimeter + also available from variometer + +Changes from 4.7.0: +- Changed "Bugs" to "Clean" in basic settings so meaning is clearer +- Changed "Device 1" etc to "Device A" in configuration settings so meaning + is clearer +- Fixed (Bug 1388996) Airspace outline black option ignored +- (Feature request 1370449) Configuration of autozoom at startup +- (Feature request 1430326) configuration of sys time set by GPS +- Force final glide mode, input event +- Auto force final glide mode option, forces final glide as soon as + you are above final glide. +- Startup reliability fixes +- Terrain offset fixes +- FLARM gauge minor fixes (draws aircraft beyond 2km at 2km) +- Added Ventus2C polar +- Added missing vega configuration parameters +- Fixed PGRMZ parsing to set BaroAltitude, not Altitude +- Airspace warnings etc uses baro altitude if available +- Removed dead code in parser.cpp +- Removed "stall" from switch dialog +- Changed "airbrake extended" to "airbrake locked" in switch dialog +- Added devices for Vega and AltairPro + +Changes from 4.6 to 4.7: +- Ballast also shown as volume in liters in basic settings dialog +- Vario 30 s averager uses vario if available, otherwise altitude. +- IGC file date is system date, should be reset to GPS time on first lock +- FLARM radar limits range to 2k limit (shows aircraft beyond 2k as at 2k) +- Log file renamed "xcsoar-debug.log" + + +Changes from 4.5 to HEAD: + +- Statistics/flight reset on takeoff +- Major speed improvements to rendering, synchronisation between threads, + final glide through terrain calculations, snail trail +- Display "AUX" on screen when in auxiliary infobox mode +- Warning if attempting to change a task once it is declared. +- Added glide computer event for final glide through terrain +- Added german sector type +- Task-alterations are queried if already declared to external device +- All MessageBoxes now use new dialog system (when available) +- Redundancy (dropout) and handling multiple GPS sources, + better autodetection of Vega. +- Improvements to labels in map display, so we don't get so many + waypoint labels writing over each other. +- Gauge vario hides on fullscreen. +- Option to lock out configuration settings in flight +- Minor speedups to map drawing (removed several redundant floating point operations) +- Added finish line and finish area detection, this does nothing other + than bring up a status message currently. +- Configuration option for user defined menu/button timeout +- Added Airspace Settings to input events, allows user to switch on/off + display and warnings for each airspace type +- Warn the user when changing input, language, status files that they need to + restart (in new dialog system) +- "Arm start" option +- Added user defined checklist text dialog (and corresponding inputevent) +- Waypoint advancing can now be manual, automatic (as before), or requiring + 'arming' each waypoint to be advanced. +- Text in airspace details has scrolling +- New Waypointselect dialog allows scrolling in list box +- Added option for autozoom optionally on at startup + (in new config dialog) +- Added option for speed command driven by dolphin speed or block maccready + (in new config dialog), this is shown in VOpt infobox +- Added in new dialog system a vario configuration page for Vega +- Added UTC offset configuration parameter for Altair +- Added task status dialog +- Added drawing of task in analysis dialog +- 'Target' offset for each AAT waypoint +- 'Run' inputevent so people can execute another program from XCSoar. Program + must exit before XCSoar continues +- Added 'autoadvance' option (default true) to allow disabling of + automatic waypoint advances +- AAT sectors now drawn as shaded segments +- Total energy height compensation for kinetic energy in final glide +- Name in task display also shows names of landpoints/airports +- Added LoadProfile to inputevents, so we can have menu buttons + trigger pilot/region specific settings +- Windows PC port using Visual studio 6. +- When terrain file is valid, only waypoints within terrain area are loaded +- All waypoint labels shown when in pan mode +- Added 'pan' to nearestWaypoint inputevent, to return item nearest to + center of screen if in pan mode. +- Force redraw of map if not redrawn for 5 seconds (due to gps not connected) +- FLARM status, FLARM aircraft display on map +- Added FLARM TRAFFIC and FLARM NOTRAFFIC glide computer events +- Added basic FLARM status support in parser and Status dialog +- Filter out "Railway station" as miscpop label +- Added infoboxes to support temperature acquisition and traces +- Added atmospheric analysis (temperature trace, convection estimation) +- Snail trail uses netto vario if available +- Added NMEA processing and NE (NMEA Events) into InputEvents +- Minor terrain rendering fixes at close zoom levels +- Improvements to topology polygon rendering +- Added ETA infoboxes (as distinct from ETE) +- Default task (Default.tsk) file may be loaded automatically at startup + if present (through InputEvent TaskLoad on STARTUP_REAL/STARTUP_SIMULATOR) +- Chevrons only on if airspeed available + +- Fixed bug 1467530 Installation to Storage Card +- Fixed bug 1457674 Airspace Display - Danger Areas Obscured +- Fixed bug 1444806 Final Glide L/D +- Fixed bug 1433504 Start line +- Fixed bug 1433497 AAT-sector areas not being displayed +- Fixed bug 1430954 Waypoints with same name. +- Fixed bug 1420989 AAT not enabled when loading a task +- Fixed bug 1399143 Incorrect lat/long display +- Fixed bug 1395611 AAT Area masks display +- Fixed bug 1389003 Airspace area with many points +- Fixed bug 1382036 Profile Load missing data +- Fixed bug 1376376 Bugs - the six legged kind +- Fixed minor memory leak in shape labels +- Fixed minor memory leak in new dialog system +- Fixed bug, array out of bounds in inputevent +- Fixed bug, strange circling lockout (maybe) +- Fixed bug, airspace visibility (airspace wasn't warning if not visible) +- Fixed bug, superpan with autozoom +- Fixed bug in default.xci "Marginal final glide" now reads "Below final glide" +- Fixed bug in final glide alert, now has low pass filter to prevent + too many alerts when using Auto Mc. +- Fixed bug in startup, program locks calculation/display before starting up + to ensure everything is initialised properly. +- Fixed bug in FAI task sector auto advancement +- Fixed bug, start line works now +- Fixed bug in task save/load, also clears task on error when loading +- Fixed bug in wind speed infobox units display (now uses aircraft speed units) +- Fixed bug, AAT Areas were drawn on top of everything, including task lines. +- Fixed bug in profile save routine (bad \r\n encoding) +- Fixed spurious captions in subtitle infoboxes +- Fixed bug, "1m" in baro altitude infobox for alternate user units +- Fixed bug, snail trail was never red in sink, now working properly +- Fixed bug in topology bounds refresh +- Fixed bug BUG 1366197: Second Airspace File now works +- Fixed bug in display of more than 500 airspace areas +- Fixed bug in bringing up WaypointDetails from SelectedWaypoint when not + using infoboxes +- Fixed bug, temp trace max temperature now relative to ground offset +- Fixed memory leak in new dialog system (bitmap unnecessary) +- Fixed display of airfield details in new dialog +- Fixed bug BUG 1368752: Fix display orientation for square displays e.g. hp 6515 (untested) +- Fixed bug BUG 1305089: Sound restored at exit +- Fixed bug in arrival altitude calculation with respect to bugs +- Fixed bug in local time display +- Fixed daylight savings bug +- Fixed BUG 1366492: Improved landing detection by checking altitude AGL to avoid false + landings when flying in high winds +- Seeding random NMEA static strings from Input Events +- Triggering events from NMEA substring matches (may be limited to certain + types due to performance limitations). + + +Changes from 4.22 to 4.5 + +- Fix waypoint parsing - make it completely bullet proof +- Package and release fonts (part of standard cab/exe) +- Button & Event mapping - default and legacy + legacy = same as version 4.22 + default = changed from 4.22... + APP1 = Show button menu (was Full Screen) + APP3 = Full Screen (was Vario Sounds Toggle) + Take Off = Start logger (was manually) + Landing = Stop logger (was manually) + Info Box Control = Show labels (were hidden) +- Allow display of screen mode (Normal, Auxiliary, Full) +- Fix spelling of MacCready (it was McCready). + (reference: http://www.achievement.org/autodoc/page/mac0bio-1) +- Exit simulator if battery lower than 20% (warning < 30%) +- Fixed crash during Waypoint details, when none selected +- Reduce length of labels where possible +- Change default.xci buttons to stay consistent between modes, + removed some defatul modes changes +- Added sensible default sounds to play during Glide Computer Events + (\My Documents\XCSoarData\ - Start_Simulator,Start_Real,Takeoff,Landing, + FinalGlide,Tiptoe - .wav) +- Default.xci updated to hide Main button and map closely to 4.3 (APP1 does Main/) +- Fixed a number of memory leaks and buffer overruns in parsing data files +- Fixed Input Events label corruption. Fixed associated debug failure when + comparing uninitialized variables. +- Modified variable names for Language and Status (more sensible) +- Use windows device time instead of GPS time in simulator +- Fixed spurious button press bug +- Status messages can be acknowledged by touching them +- Fixed message disappearing problem after 1 second (when airspace warnings were off) +- RETURN key in default.xci needs to be mapped +- Default set of status messages - now automatically generated from default.xcs +- Enable secondary files clear button +- Arbitrary DLL Load and Function calls from InputEvents +- Config files (input, language and status) now support "\r\n" strings correctly +- PlaySound now supports external WAV files automatically. Also allows WAV files + to be referenced as Input Events - assumes local resource unless ends in ".wav" +- Automatically lookup localised "My Documents" directory to support multiple + language releases of Pocket PC +- Version number (build date) is automatically generated for non-released versions +- Added debounce timeout registry setting in settings->interface files +- Added input menu timeout +- Added new status message interface (thread-safe, single window, ability + to repeat messages and acknowledge) +- Fixed hard-coded screen coordinates in PolygonVisible function +- Airspace warnings now use new message class +- Added method to find nearest airspace boundary (interior or exterior) +- Input event to display info on nearest airspace boundary (interior or exterior) +- Renamed fixed "longditude" and "lattitude" spelling mistakes +- Display speed-to-fly bar only if flying +- Debugging of input events file when in simulator mode +- Added glide computer events for entering and leaving airspace +- Added glide computer events for task start and next waypoint +- Audio vario sound updates +- Allow acknowledgement of individual airspaces, and per-day +- Fix acknowledgement bug when re-entering airspace +- Minor font adjustments +- "GPS 2D fix" changed to "GPS waiting for fix" +- New high-visibility icons for flight modes by Simon Taylor. +- Blinking logger icon when logger is active. +- Code cleanups, eliminated BOOL occurances +- Fixed missing sentances in IGC file, so now loadable by TaskNav +- Added "Logger note blahblah" event to put a pilot note in IGC log file. +- Speed-to-fly climb mode bug fix +- Thermal band mode fix +- Audio vario sound updates +- Fixed waypoint arrival altitude bug +- New airspace parser, faster and more robust +- New language customisation +- New status message customisation +- Wind algorithm improvements especially at low wind speeds +- Analysis dialog now has page for wind at altitude +- Fixed defaulting to cruise mode when no waypoint active +- Miscellaneous dialog cleanups +- Snail trail colour scales to visible range to make colors more vibrant +- Safe recovery from critical errors when loading files +- Fixed bug of polar loading on multiple lines +- Fixed ordering of Menu buttons when using cursor to navigate +- Blanking improvements (prevent timeout advancing when any dialog is active) +- Added Auxiliary infobox display, accessible from APP_KEY1, which now + toggles through normal (mode-specific) infoboxes, auxiliary infoboxes, + and fullscreen. +- Settings->Task start line/cylinder labels change dynamically to avoid + confusion +- AutoMcready improvements, fix for overshoot hunting +- "Reset infobox defaults" button from Settings->Load Profile +- Moved handling of bug degradation to sink model to make it consistent + everywhere. +- Optimised display of titles in infoboxes to prevent over-use of gettext +- Added units display to AAT settings to avoid confusion +- New functions to save/restore registry from text file +- Save/Load profile uses registry save/restore code +- New button input event system +- Fix infobox reset to defaults +- Allow reset of flight start time when relaunching +- Takeoff/landing events, can be hooked up to autostart logger + + +Changes from 4.21 to 4.22 + +- Fixed bug when airspace warning display is not refreshed when another + window overlaps it. +- New "Analysis" pages showing barograph, thermal history and glide polar +- Fixed bug in snail trail, IGC logger update rate +- Additional waypoint file can be specified for competition waypoints +- Fixed font for message box, status dialog +- Minor bugfixes in vario comms thread processing +- Implemented Borgelt B50 vario parsing (untested) +- Improvements to performance and latency of audio +- Terrain cache updates +- File loading improvements +- New wind vector graphics +- New labels with Mc0 arrival height above safety arrival height for + reachable airfields +- Updated aircraft graphics +- Proper units display in dialogs. +- All configuration options now can be expressed in custom units +- New Netto vario infobox +- New dolphin speed-to-fly infobox +- Improved audio vario sounds +- Speed-to-fly director chevrons on right of screen when connected to + vario with ASI source. +- Fixed rare bugs in McCready calculation +- Fixed bug in terrain rendering, where level of detail was previously + set at default, and didn't change with zoom. +- Airspace parser made faster, so binary airspace loader now disabled + + +Changes from 4.2 to 4.21 + +- Better recovery of bluetooth GPS after switching device off and on +- Marked points appended to file 'xcsoar-marks.txt' +- CDI display configurable +- Settings->Display split into two pages +- Sunset time shown in waypoint details +- AAT and airspace areas drawn below waypoints and topology +- Messagebox enhancements +- MODIS Satelite images now co-located with waypoint file +- Launcher now uninstalls/reinstalls properly. +- Proper spelling of McCready (sorry, Paul!) +- Display blanking automatically after one minute of UI inactivity if in + battery mode, reactivated with key press +- New GPS status icons, less obtrusive. +- Aircraft disappears when GPS is not connected +- New "Status" summary page from main menu, giving aircraft position, + nearest waypoint range/bearing, local sunset time, GPS status +- Additional airspace file can be specified for NOTAM airspace updates +- Settings->File page split into two (map data separated off) +- Snail trail toggles between no trail, long trail, and short trail + + +Summary of new features since v4.0 + +- Fullscreen mode (app button 1 in map mode); app button 2 now + toggles snail trail +- Terrain shading via phong model, direction set by wind direction +- Wind vectors multiple for 10 knot increments +- Saving/loading wind to registry +- Time aloft infobox (in Waypoint Group) +- New wind calculation method +- Rendering of airspace with cross-hatches and optional black outline +- Added pilot/aircraft information in logger +- Added "Remove" button on waypoint details task page +- Acknowledge airspace warnings +- Audio settings page +- Graduated snail trail color and thickness +- Abort/resume of tasks +- Added netto vario calculations +- Added smart zooming (zooms back out when waypoint changes if in autozoom) +- Added installer and launcher +- Bring up menu with double click on map window +- Can fly in simulator mode by dragging on screen +- Improved colour selector now displays currently chosen colours +- Added calculation of glider heading from bearing and wind +- Added infoboxes: G-load, time of flight, UTC time, local time, LD to next waypoint +- Adjusted infobox descriptions and titles. +- Added infoboxes: Time to next waypoint, time to task completion + + +Fixed buges and code improvements + +- Sound files are now in the code as resources, so no need for Audio directory +- Filtering of files: + Waypoints [.txt] + Airspace [.txt] + Terrain [.dat] + Topology [.tpl] + Polars [.plr] +- Reduced extraneous refresh of navboxes +- Font size improvements +- Second COMM port disabled if set equal to port 1 +- Audio thread is suspended when quiet +- Auto McReady now working again +- Improvements to topology handling +- Better terrain color map +- Terrain shading works with elevation files of any resolution. +- Terrain at sea level or below is rendered as water. +- Minor improvements to thread safety +- Larger Menu page buttons +- Fixed McReady speed calculation with zero distance +- Fixed bugs: Samuel Gisiger (Airspace not displaying, extraneous + selection of waypoints at zoom levels) +- Improved map window responsiveness (only re-drawn when necessary, avoiding + CPU waste of unnecessary re-draws). +- Many hard-wired constants relocated to Sizes.h file +- Waypoint labels have white background so not obscured by terrain +- Labels of topological features now supported +- Fast loading of airspace at startup using binary file +- Wind calculation more reliable +- Fast loading of all startup files + diff --git a/OpenSoar.config b/OpenSoar.config new file mode 100644 index 00000000000..8b890ab7191 --- /dev/null +++ b/OpenSoar.config @@ -0,0 +1,4 @@ +PROGRAM_NAME=OpenSoar +PROGRAM_VERSION=7.42.22.A +ANDROID_VERSIONCODE=22 +ANDROID_PACKAGE=de.opensoar diff --git a/README.md b/README.md index f4e596378ea..8ceacc7b721 100644 --- a/README.md +++ b/README.md @@ -1,43 +1,16 @@ -# XCSoar Logo XCSoar +# OpenSoar Logo OpenSoar -[![.github/workflows/build-native.yml](https://github.com/XCSoar/XCSoar/actions/workflows/build-native.yml/badge.svg)](https://github.com/XCSoar/XCSoar/actions/workflows/build-native.yml) -[![.github/workflows/build-container.yml](https://github.com/XCSoar/XCSoar/actions/workflows/build-container.yml/badge.svg)](https://github.com/XCSoar/XCSoar/actions/workflows/build-container.yml) -[![.github/workflows/build-docs.yml](https://github.com/XCSoar/XCSoar/actions/workflows/build-docs.yml/badge.svg)](https://github.com/XCSoar/XCSoar/actions/workflows/build-docs.yml) +[![.github/workflows/build-native.yml](../../actions/workflows/build-native.yml/badge.svg)](../../actions/workflows/build-native.yml) +[![.github/workflows/build-container.yml](../../actions/workflows/build-container.yml/badge.svg)](../../actions/workflows/build-container.yml) +[![.github/workflows/build-docs.yml](../../actions/workflows/build-docs.yml/badge.svg)](../../actions/workflows/build-docs.yml) -XCSoar is a tactical glide computer for Android, Linux, Mac OS X, -and Windows. - -This file is aimed at developers. Developers should [read the -developer manual](https://xcsoar.readthedocs.io/en/latest/). - -Users can refer to the Users' Manual which, for the latest release, can be -downloaded via the [XCSoar home page](https://xcsoar.org/discover/manual.html). - -## Getting the source - -The XCSoar source code is managed with [git](http://git-scm.com/). It can be -downloaded with the following command: - -```bash -git clone --recursive https://github.com/XCSoar/XCSoar -``` +OpenSoar - is an experimental fork of the wellknown gliding software XCSoar. -To update your repository, type: - -```bash -git pull -``` - -For more information, please refer to the git documentation. - -## Compiling from source - -Please read the current [Developer's -Manual](https://xcsoar.readthedocs.io/en/latest/build.html) for -detailed build instructions. +... and XCSoar is a tactical glide computer for Android, Linux, Mac OS X, +and Windows. -## Submitting patches +For more information (download, developer information, manuals, releases) +about XCSoar please visit +[XCSoar on GitHub](https://github.com/XCSoar/XCSoar) and the +[XCSoar home page](https://xcsoar.org/discover/manual.html) -Patches may be submitted using the Developers' mail list or GitHub. Refer to -chapter 3 of the current Developers' Manual for details of how to write and -submit patches upstream. diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index 0432f458534..3384e19b175 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -1,9 +1,9 @@ + android:versionCode="22" + android:versionName="7.42.22"> - - diff --git a/android/res/values/strings.xml b/android/res/values/strings.xml index 343de43b58a..9151d898239 100644 --- a/android/res/values/strings.xml +++ b/android/res/values/strings.xml @@ -1,5 +1,5 @@ - XCSoar - XCS-test + OpenSoar + OpenSoar-test diff --git a/android/src/AbstractAndroidPort.java b/android/src/AbstractAndroidPort.java index d745fce8cc1..77bb818013a 100644 --- a/android/src/AbstractAndroidPort.java +++ b/android/src/AbstractAndroidPort.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import java.io.InputStream; import java.io.OutputStream; diff --git a/android/src/AllFilesDocumentsProvider.java b/android/src/AllFilesDocumentsProvider.java index c3936afd4f6..1f3d78f61c3 100644 --- a/android/src/AllFilesDocumentsProvider.java +++ b/android/src/AllFilesDocumentsProvider.java @@ -26,7 +26,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ -package org.xcsoar; +package de.opensoar; import android.content.ContentResolver; import android.content.Context; diff --git a/android/src/AndroidPort.java b/android/src/AndroidPort.java index c2a5a4aaeaa..29d30c91bf5 100644 --- a/android/src/AndroidPort.java +++ b/android/src/AndroidPort.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import java.io.Closeable; diff --git a/android/src/AndroidSensor.java b/android/src/AndroidSensor.java index 319f8b383c5..d6ed1209e90 100644 --- a/android/src/AndroidSensor.java +++ b/android/src/AndroidSensor.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import java.io.Closeable; diff --git a/android/src/BMP085.java b/android/src/BMP085.java index 541de073ee8..808e0a62c14 100644 --- a/android/src/BMP085.java +++ b/android/src/BMP085.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import java.io.IOException; diff --git a/android/src/BatteryReceiver.java b/android/src/BatteryReceiver.java index 29320deab1a..9236c2c5e85 100644 --- a/android/src/BatteryReceiver.java +++ b/android/src/BatteryReceiver.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import android.content.Context; import android.content.Intent; diff --git a/android/src/BitmapUtil.java b/android/src/BitmapUtil.java index 59b7a6b033c..5d6434cc67a 100644 --- a/android/src/BitmapUtil.java +++ b/android/src/BitmapUtil.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import android.util.Log; import android.graphics.Bitmap; @@ -16,7 +16,7 @@ * Utilities for dealing with #Bitmap objects and OpenGL. */ final class BitmapUtil { - private static final String TAG = "XCSoar"; + private static final String TAG = "OpenSoar"; public static int validateTextureSize(int i) { return NativeView.validateTextureSize(i); diff --git a/android/src/BluetoothClientPort.java b/android/src/BluetoothClientPort.java index bf1b5cbd4b9..077c901aa50 100644 --- a/android/src/BluetoothClientPort.java +++ b/android/src/BluetoothClientPort.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import java.io.IOException; import android.util.Log; @@ -12,7 +12,7 @@ * connection. */ class BluetoothClientPort extends ProxyAndroidPort implements Runnable { - private static final String TAG = "XCSoar"; + private static final String TAG = "OpenSoar"; private BluetoothSocket socket; diff --git a/android/src/BluetoothHelper.java b/android/src/BluetoothHelper.java index 1db644d731a..65fd9f00bf4 100644 --- a/android/src/BluetoothHelper.java +++ b/android/src/BluetoothHelper.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import java.util.UUID; import java.util.Set; @@ -31,7 +31,7 @@ final class BluetoothHelper extends ScanCallback { - private static final String TAG = "XCSoar"; + private static final String TAG = "OpenSoar"; private static final UUID THE_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); diff --git a/android/src/BluetoothPort.java b/android/src/BluetoothPort.java index 5cb2f1dcac7..65930ff8049 100644 --- a/android/src/BluetoothPort.java +++ b/android/src/BluetoothPort.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import java.io.IOException; import android.bluetooth.BluetoothSocket; diff --git a/android/src/BluetoothSensor.java b/android/src/BluetoothSensor.java index 3668c726190..3efe3fd162b 100644 --- a/android/src/BluetoothSensor.java +++ b/android/src/BluetoothSensor.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import java.util.Queue; import java.util.LinkedList; diff --git a/android/src/BluetoothServerPort.java b/android/src/BluetoothServerPort.java index c17d27af591..c7176c63d40 100644 --- a/android/src/BluetoothServerPort.java +++ b/android/src/BluetoothServerPort.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import java.util.UUID; import java.util.Collection; @@ -20,7 +20,7 @@ final class BluetoothServerPort extends MultiPort implements Runnable, InputListener { - private static final String TAG = "XCSoar"; + private static final String TAG = "OpenSoar"; private BluetoothServerSocket serverSocket; private Collection sockets = @@ -30,7 +30,7 @@ final class BluetoothServerPort extends MultiPort BluetoothServerPort(BluetoothAdapter adapter, UUID uuid) throws IOException { - serverSocket = adapter.listenUsingRfcommWithServiceRecord("XCSoar", uuid); + serverSocket = adapter.listenUsingRfcommWithServiceRecord("OpenSoar", uuid); thread.start(); } diff --git a/android/src/BluetoothUuids.java b/android/src/BluetoothUuids.java index a0024ff1739..27c35db84e8 100644 --- a/android/src/BluetoothUuids.java +++ b/android/src/BluetoothUuids.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import java.util.UUID; diff --git a/android/src/DetectDeviceListener.java b/android/src/DetectDeviceListener.java index 334bb07f239..b2d994e26d7 100644 --- a/android/src/DetectDeviceListener.java +++ b/android/src/DetectDeviceListener.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; /** * Continuously receives callbacks about detected or updated devices. diff --git a/android/src/DownloadUtil.java b/android/src/DownloadUtil.java index b978af6d19f..9213bee16e5 100644 --- a/android/src/DownloadUtil.java +++ b/android/src/DownloadUtil.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import java.io.Closeable; import java.io.File; diff --git a/android/src/EventBridge.java b/android/src/EventBridge.java index 8faa7b0c058..ed49bdc858b 100644 --- a/android/src/EventBridge.java +++ b/android/src/EventBridge.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; class EventBridge { public static native void onKeyDown(int keyCode); diff --git a/android/src/FileProvider.java b/android/src/FileProvider.java index 88faefe5c8d..b924385c28c 100644 --- a/android/src/FileProvider.java +++ b/android/src/FileProvider.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import java.io.File; import java.io.FileNotFoundException; diff --git a/android/src/GliderLinkReceiver.java b/android/src/GliderLinkReceiver.java index eebd4e40e40..e351887d0c2 100644 --- a/android/src/GliderLinkReceiver.java +++ b/android/src/GliderLinkReceiver.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import android.content.Context; import android.content.BroadcastReceiver; @@ -16,7 +16,7 @@ class GliderLinkReceiver extends BroadcastReceiver implements AndroidSensor { - private static final String TAG = "XCSoar"; + private static final String TAG = "OpenSoar"; public static final String ACTION = "link.glider.gliderlink.target_position"; private final Context context; diff --git a/android/src/GlueBMP085.java b/android/src/GlueBMP085.java index 9836fdf28e8..c644e91a28d 100644 --- a/android/src/GlueBMP085.java +++ b/android/src/GlueBMP085.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import ioio.lib.api.IOIO; import ioio.lib.api.exception.ConnectionLostException; diff --git a/android/src/GlueI2Cbaro.java b/android/src/GlueI2Cbaro.java index fe4f00d9635..8655e70c5d5 100644 --- a/android/src/GlueI2Cbaro.java +++ b/android/src/GlueI2Cbaro.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import ioio.lib.api.IOIO; import ioio.lib.api.exception.ConnectionLostException; diff --git a/android/src/GlueIOIOPort.java b/android/src/GlueIOIOPort.java index fd538a07c62..0dc447b2fee 100644 --- a/android/src/GlueIOIOPort.java +++ b/android/src/GlueIOIOPort.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import android.util.Log; import ioio.lib.api.IOIO; @@ -16,7 +16,7 @@ * */ final class GlueIOIOPort extends IOIOPort implements IOIOConnectionListener { - private static final String TAG = "XCSoar"; + private static final String TAG = "OpenSoar"; private IOIOConnectionHolder holder; diff --git a/android/src/GlueNunchuck.java b/android/src/GlueNunchuck.java index ca2b9722489..a222b5b8091 100644 --- a/android/src/GlueNunchuck.java +++ b/android/src/GlueNunchuck.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import ioio.lib.api.IOIO; import ioio.lib.api.exception.ConnectionLostException; diff --git a/android/src/GlueVoltage.java b/android/src/GlueVoltage.java index 7acf9a613b3..975ade2baaf 100644 --- a/android/src/GlueVoltage.java +++ b/android/src/GlueVoltage.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import ioio.lib.api.IOIO; import ioio.lib.api.exception.ConnectionLostException; diff --git a/android/src/HM10Port.java b/android/src/HM10Port.java index f26df91aefc..5255e7cfebf 100644 --- a/android/src/HM10Port.java +++ b/android/src/HM10Port.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import java.io.IOException; @@ -23,7 +23,7 @@ public class HM10Port extends BluetoothGattCallback implements AndroidPort { - private static final String TAG = "XCSoar"; + private static final String TAG = "OpenSoar"; private static final int MAX_WRITE_CHUNK_SIZE = 20; diff --git a/android/src/HM10WriteBuffer.java b/android/src/HM10WriteBuffer.java index 982c2c825dc..cb3e3a73813 100644 --- a/android/src/HM10WriteBuffer.java +++ b/android/src/HM10WriteBuffer.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import java.util.Arrays; @@ -16,7 +16,7 @@ * device. */ final class HM10WriteBuffer { - private static final String TAG = "XCSoar"; + private static final String TAG = "OpenSoar"; private static final int BUFFER_SIZE = 256; diff --git a/android/src/I2Cbaro.java b/android/src/I2Cbaro.java index d43bbc30f45..d64e06fde49 100644 --- a/android/src/I2Cbaro.java +++ b/android/src/I2Cbaro.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import java.io.IOException; import ioio.lib.api.IOIO; diff --git a/android/src/IOIOAgent.java b/android/src/IOIOAgent.java index b76f3e48f82..dbe863c7df4 100644 --- a/android/src/IOIOAgent.java +++ b/android/src/IOIOAgent.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import android.util.Log; import ioio.lib.api.IOIO; @@ -17,7 +17,7 @@ * IOIOConnectionFactory. */ final class IOIOAgent extends Thread { - private static final String TAG = "XCSoar"; + private static final String TAG = "OpenSoar"; interface Listener extends IOIOConnectionListener { boolean onIOIOIdle(IOIO ioio) diff --git a/android/src/IOIOConnectionHolder.java b/android/src/IOIOConnectionHolder.java index 986ff98128b..0d2ed7e52c9 100644 --- a/android/src/IOIOConnectionHolder.java +++ b/android/src/IOIOConnectionHolder.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; /** * An object that manages the connection to a IOIO board. diff --git a/android/src/IOIOConnectionListener.java b/android/src/IOIOConnectionListener.java index 2b82564f619..98e1cb9c3dd 100644 --- a/android/src/IOIOConnectionListener.java +++ b/android/src/IOIOConnectionListener.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import ioio.lib.api.IOIO; import ioio.lib.api.exception.ConnectionLostException; diff --git a/android/src/IOIOHelper.java b/android/src/IOIOHelper.java index 32e272f4027..dfda4daacda 100644 --- a/android/src/IOIOHelper.java +++ b/android/src/IOIOHelper.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import java.util.Collection; import java.util.LinkedList; @@ -22,7 +22,7 @@ */ final class IOIOHelper implements IOIOConnectionHolder, IOIOAgent.Listener { - private static final String TAG = "XCSoar"; + private static final String TAG = "OpenSoar"; private static final Collection bootstraps = new LinkedList(); diff --git a/android/src/IOIOMultiAgent.java b/android/src/IOIOMultiAgent.java index 99446a11a82..6835bbc0933 100644 --- a/android/src/IOIOMultiAgent.java +++ b/android/src/IOIOMultiAgent.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import java.util.ArrayList; import java.util.Collection; diff --git a/android/src/IOIOPort.java b/android/src/IOIOPort.java index adb01dd3e6f..891c76578b8 100644 --- a/android/src/IOIOPort.java +++ b/android/src/IOIOPort.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import ioio.lib.api.Uart; diff --git a/android/src/InputListener.java b/android/src/InputListener.java index e7fc0615ebf..c83d1b59bef 100644 --- a/android/src/InputListener.java +++ b/android/src/InputListener.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; /** * A listener that gets called when data is received on a socket. diff --git a/android/src/InputThread.java b/android/src/InputThread.java index 8e07a7041d0..6528660348b 100644 --- a/android/src/InputThread.java +++ b/android/src/InputThread.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import java.io.IOException; import java.io.InputStream; @@ -11,7 +11,7 @@ * A wrapper for an InputStream which allows reading with a timeout. */ class InputThread extends Thread { - private static final String TAG = "XCSoar"; + private static final String TAG = "OpenSoar"; static final int BUFFER_SIZE = 256; diff --git a/android/src/InternalGPS.java b/android/src/InternalGPS.java index 4ed2612fd91..80b6fde530d 100644 --- a/android/src/InternalGPS.java +++ b/android/src/InternalGPS.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import android.os.Handler; import android.os.Bundle; diff --git a/android/src/Loader.java b/android/src/Loader.java index cd04e7febb0..3f5c47f634a 100644 --- a/android/src/Loader.java +++ b/android/src/Loader.java @@ -1,19 +1,19 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import android.util.Log; public class Loader { - private static final String TAG = "XCSoar"; + private static final String TAG = "OpenSoar"; public static boolean loaded = false; public static String error; static { try { - System.loadLibrary("xcsoar"); + System.loadLibrary("OpenSoar"); loaded = true; } catch (UnsatisfiedLinkError e) { Log.e(TAG, e.getMessage()); diff --git a/android/src/MultiPort.java b/android/src/MultiPort.java index 79a4e0b6625..cc28f43ff7e 100644 --- a/android/src/MultiPort.java +++ b/android/src/MultiPort.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import java.io.IOException; import java.util.Collection; @@ -17,7 +17,7 @@ class MultiPort implements AndroidPort, InputListener { private PortListener portListener; private InputListener inputListener; - private static final String TAG = "XCSoar"; + private static final String TAG = "OpenSoar"; private Collection ports = new LinkedList(); private boolean error = false; diff --git a/android/src/MyService.java b/android/src/MyService.java index 4e819e01534..bdb75d7d9bd 100644 --- a/android/src/MyService.java +++ b/android/src/MyService.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import android.app.Service; import android.app.Notification; @@ -22,7 +22,7 @@ * extreme pressure. Since this services runs in-process, Android * will also not terminate our main Activity. * - * XCSoar needs high reliability, because it usually runs in + * OpenSoar needs high reliability, because it usually runs in * foreground as the only active application and should not be killed * by an incoming phone call. * @@ -30,9 +30,9 @@ * unless you have an excuse as good as ours ;-) */ public class MyService extends Service { - private static final String TAG = "XCSoar"; + private static final String TAG = "OpenSoar"; - private static final String NOTIFICATION_CHANNEL_ID = "xcsoar"; + private static final String NOTIFICATION_CHANNEL_ID = "opensoar"; private NotificationManager notificationManager; @@ -42,7 +42,7 @@ public class MyService extends Service { notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - String name = "XCSoar"; + String name = "OpenSoar"; /* this disables sound: */ int importance = NotificationManager.IMPORTANCE_LOW; @@ -63,17 +63,17 @@ private static Notification createNotification(Context context, PendingIntent in Notification.Builder builder = createNotificationBuilder(context) .setOngoing(true) .setContentIntent(intent) - .setContentTitle("XCSoar") - .setContentText("XCSoar is running") + .setContentTitle("OpenSoar") + .setContentText("OpenSoar is running") .setSmallIcon(R.drawable.notification_icon); return builder.build(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { - /* add an icon to the notification area while XCSoar runs, to + /* add an icon to the notification area while OpenSoar runs, to remind the user that we're sucking his battery empty */ - Intent intent2 = new Intent(this, XCSoar.class); + Intent intent2 = new Intent(this, OpenSoar.class); PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent2, PendingIntent.FLAG_IMMUTABLE); Notification notification = createNotification(this, contentIntent); diff --git a/android/src/NativeDetectDeviceListener.java b/android/src/NativeDetectDeviceListener.java index 0b7d1d68f2b..2fe0b5ca527 100644 --- a/android/src/NativeDetectDeviceListener.java +++ b/android/src/NativeDetectDeviceListener.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; /** * An #DetectDeviceListener implementation that passes method calls to diff --git a/android/src/NativeInputListener.java b/android/src/NativeInputListener.java index 8077f067752..1bba55d9b4f 100644 --- a/android/src/NativeInputListener.java +++ b/android/src/NativeInputListener.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; /** * An #InputListener implementation that passes method calls to native diff --git a/android/src/NativePortListener.java b/android/src/NativePortListener.java index 89f491ebf58..39b9884a509 100644 --- a/android/src/NativePortListener.java +++ b/android/src/NativePortListener.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; /** * An #PortListener implementation that passes method calls to native diff --git a/android/src/NativeSensorListener.java b/android/src/NativeSensorListener.java index 752a52d9b7a..eefdeb38713 100644 --- a/android/src/NativeSensorListener.java +++ b/android/src/NativeSensorListener.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; /** * An #SensorListener implementation that passes method calls to diff --git a/android/src/NativeView.java b/android/src/NativeView.java index e4dd73c0833..d492813fde7 100644 --- a/android/src/NativeView.java +++ b/android/src/NativeView.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import java.io.File; import android.util.Log; @@ -38,7 +38,7 @@ public EGLException(String _msg) { */ class NativeView extends SurfaceView implements SurfaceHolder.Callback, Runnable { - private static final String TAG = "XCSoar"; + private static final String TAG = "OpenSoar"; /** * A native pointer to a C++ #TopWindow instance. @@ -218,10 +218,10 @@ public static int validateTextureSize(int i) { */ private Bitmap loadResourceBitmap(String name) { /* find the resource */ - int resourceId = resources.getIdentifier(name, "drawable", "org.xcsoar"); + int resourceId = resources.getIdentifier(name, "drawable", "de.opensoar"); if (resourceId == 0) { resourceId = resources.getIdentifier(name, "drawable", - "org.xcsoar.testing"); + "de.opensoar.testing"); if (resourceId == 0) return null; } @@ -289,7 +289,7 @@ private void openWaypointFile(int id, String filename) { /* this URI is going to be handled by FileProvider */ Uri uri = new Uri.Builder().scheme("content") - .authority("org.xcsoar") + .authority("de.opensoar") .encodedPath("/waypoints/" + id + "/" + Uri.encode(filename)) .build(); diff --git a/android/src/NetUtil.java b/android/src/NetUtil.java index a5c3b14e169..ff9ad6e3d20 100644 --- a/android/src/NetUtil.java +++ b/android/src/NetUtil.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import android.content.Context; import android.net.ConnectivityManager; @@ -12,7 +12,7 @@ * Utilities for dealing with networking. */ final class NetUtil { - private static final String TAG = "XCSoar"; + private static final String TAG = "OpenSoar"; private static final int STATE_UNKNOWN = 0; private static final int STATE_DISCONNECTED = 1; diff --git a/android/src/NonGPSSensors.java b/android/src/NonGPSSensors.java index 5aec90a7c01..613b04fe55a 100644 --- a/android/src/NonGPSSensors.java +++ b/android/src/NonGPSSensors.java @@ -8,7 +8,7 @@ // all consumer devices. // - Explore new and exotic sensors. -package org.xcsoar; +package de.opensoar; import java.io.Closeable; @@ -31,7 +31,7 @@ public class NonGPSSensors implements SensorEventListener, Runnable, Closeable { - private static final String TAG = "XCSoar"; + private static final String TAG = "OpenSoar"; // Constant array saying whether we want to support certain sensors. // If modifying this array, make certain that the largest ID value inside diff --git a/android/src/Nunchuck.java b/android/src/Nunchuck.java index aaa8c75e4c4..c765256475e 100644 --- a/android/src/Nunchuck.java +++ b/android/src/Nunchuck.java @@ -10,7 +10,7 @@ * White GND */ -package org.xcsoar; +package de.opensoar; import java.io.IOException; @@ -28,7 +28,7 @@ * */ final class Nunchuck extends Thread { - private static final String TAG = "XCSoar"; + private static final String TAG = "OpenSoar"; private static final byte WII_NUN_ADDR = 0x52; private static final byte REG_DATA = 0x00; /* */ diff --git a/android/src/XCSoar.java b/android/src/OpenSoar.java similarity index 91% rename from android/src/XCSoar.java rename to android/src/OpenSoar.java index 913c701a416..3f859677975 100644 --- a/android/src/XCSoar.java +++ b/android/src/OpenSoar.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import java.util.Map; import java.util.TreeMap; @@ -36,8 +36,8 @@ import android.util.Log; import android.provider.Settings; -public class XCSoar extends Activity implements PermissionManager { - private static final String TAG = "XCSoar"; +public class OpenSoar extends Activity implements PermissionManager { + private static final String TAG = "OpenSoar"; private static NativeView nativeView; @@ -68,7 +68,7 @@ public class XCSoar extends Activity implements PermissionManager { if (!Loader.loaded) { TextView tv = new TextView(this); - tv.setText("Failed to load the native XCSoar libary.\n" + + tv.setText("Failed to load the native OpenSoar libary.\n" + "Report this problem to us, and include the following information:\n" + "ABI=" + Build.CPU_ABI + "\n" + "PRODUCT=" + Build.PRODUCT + "\n" + @@ -90,7 +90,7 @@ public class XCSoar extends Activity implements PermissionManager { window.requestFeature(Window.FEATURE_NO_TITLE); TextView tv = new TextView(this); - tv.setText("Loading XCSoar..."); + tv.setText("Loading OpenSoar..."); setContentView(tv); /* after setContentView(), Android has initialised a few default @@ -114,11 +114,23 @@ public class XCSoar extends Activity implements PermissionManager { private void quit() { nativeView = null; - TextView tv = new TextView(XCSoar.this); - tv.setText("Shutting down XCSoar..."); + TextView tv = new TextView(OpenSoar.this); + tv.setText("Shutting down OpenSoar..."); setContentView(tv); finish(); + { + // This is only possible if Android is rooted! + Log.d(TAG, "ShutDown/Reboot Android?"); + try { + Process proc = + Runtime.getRuntime().exec(new String[]{"su", "-c", "reboot -p"}); + proc.waitFor(); + } catch (Exception ex) { + // Log.d(TAG, "Exception"); + ex.printStackTrace(); + } + } } final Handler quitHandler = new Handler() { @@ -130,7 +142,7 @@ public void handleMessage(Message msg) { final Handler errorHandler = new Handler() { public void handleMessage(Message msg) { nativeView = null; - TextView tv = new TextView(XCSoar.this); + TextView tv = new TextView(OpenSoar.this); tv.setText(msg.obj.toString()); setContentView(tv); } @@ -191,7 +203,7 @@ public void initNative() { if (!Loader.loaded) return; - /* check if external storage is available; XCSoar doesn't work as + /* check if external storage is available; OpenSoar doesn't work as long as external storage is being forwarded to a PC */ String state = Environment.getExternalStorageState(); if (!Environment.MEDIA_MOUNTED.equals(state)) { @@ -336,13 +348,13 @@ public synchronized void onRequestPermissionsResult(int requestCode, String[] pe private static String getPermissionRationale(String permission) { if (permission == Manifest.permission.ACCESS_FINE_LOCATION) - return "XCSoar needs permission to access your GPS location - obviously, because XCSoar's purpose is to help you navigate an aircraft."; + return "OpenSoar needs permission to access your GPS location - obviously, because OpenSoar's purpose is to help you navigate an aircraft."; else if (permission == Manifest.permission.ACCESS_BACKGROUND_LOCATION) - return "Several optional features (e.g. flight logging and score calculation) benefit from location access while XCSoar is in background. " + + return "Several optional features (e.g. flight logging and score calculation) benefit from location access while OpenSoar is in background. " + "If you choose not to allow this, calculation results may be incomplete."; else if (permission == Manifest.permission.BLUETOOTH_CONNECT || permission == Manifest.permission.BLUETOOTH_SCAN) - return "If you want XCSoar to connect to Bluetooth sensors, it needs your permission."; + return "If you want OpenSoar to connect to Bluetooth sensors, it needs your permission."; else return null; } @@ -352,14 +364,14 @@ private void showRequestPermissionRationale(final String permission, final PermissionHandler handler) { /* using HTML so the privacy policy link is clickable */ final String html = "

" + - "XCSoar is free software developed by volunteers just for fun. " + - "The project is non-profit - you don't pay for XCSoar, and we don't sell your data (or anything else). " + + "OpenSoar is free software developed by volunteers just for fun. " + + "The project is non-profit - you don't pay for OpenSoar, and we don't sell your data (or anything else). " + "

" + "

" + rationale + "

" + "

" + - "All those accesses are only in your own interest; we don't collect your data and we don't track you (unless you explicitly ask XCSoar to). " + + "All those accesses are only in your own interest; we don't collect your data and we don't track you (unless you explicitly ask OpenSoar to). " + "

" + "

" + "More details can be found in the Privacy policy. " + diff --git a/android/src/OutputThread.java b/android/src/OutputThread.java index 41e0171c064..0c27f5e290b 100644 --- a/android/src/OutputThread.java +++ b/android/src/OutputThread.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import java.io.IOException; import java.io.OutputStream; @@ -11,7 +11,7 @@ * A wrapper for an OutputStream which allows writing with a timeout. */ class OutputThread extends Thread { - private static final String TAG = "XCSoar"; + private static final String TAG = "OpenSoar"; static final int BUFFER_SIZE = 256; diff --git a/android/src/PermissionManager.java b/android/src/PermissionManager.java index c5db154f3fc..0bcf8b84a90 100644 --- a/android/src/PermissionManager.java +++ b/android/src/PermissionManager.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; /** * An interface that allows requesting Android app permissions diff --git a/android/src/PortListener.java b/android/src/PortListener.java index e71edb86464..483360466f3 100644 --- a/android/src/PortListener.java +++ b/android/src/PortListener.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; /** * A listener for #AndroidPort objects. diff --git a/android/src/ProxyAndroidPort.java b/android/src/ProxyAndroidPort.java index a9759ca9587..3c5a20db951 100644 --- a/android/src/ProxyAndroidPort.java +++ b/android/src/ProxyAndroidPort.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import java.io.IOException; diff --git a/android/src/ReceiveTaskActivity.java b/android/src/ReceiveTaskActivity.java index 29175218a19..d99be416cb5 100644 --- a/android/src/ReceiveTaskActivity.java +++ b/android/src/ReceiveTaskActivity.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import android.app.Activity; import android.content.Intent; @@ -10,7 +10,7 @@ import android.util.Log; public class ReceiveTaskActivity extends Activity { - private static final String TAG = "XCSoar"; + private static final String TAG = "OpenSoar"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -39,9 +39,9 @@ private String handleIntent(final Intent intent) { if (data.startsWith("xctsk:")) { final String msg = NativeView.onReceiveXCTrackTask(data.substring(6)); if (msg == null) { - /* the data was handled successfully, and the main "XCSoar" + /* the data was handled successfully, and the main "OpenSoar" activity shows the details - switch to it */ - Intent myIntent = new Intent(this, XCSoar.class); + Intent myIntent = new Intent(this, OpenSoar.class); startActivity(myIntent); return null; } diff --git a/android/src/SafeDestruct.java b/android/src/SafeDestruct.java index 5ad8feed959..651c501ff83 100644 --- a/android/src/SafeDestruct.java +++ b/android/src/SafeDestruct.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; /** * This class manages safe destruction of objects that call native diff --git a/android/src/SensorListener.java b/android/src/SensorListener.java index 253fce49998..a542b478e50 100644 --- a/android/src/SensorListener.java +++ b/android/src/SensorListener.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; /** * Handler for sensor values obtained from Java code. diff --git a/android/src/SoundUtil.java b/android/src/SoundUtil.java index 203cbe86646..7014a60f38f 100644 --- a/android/src/SoundUtil.java +++ b/android/src/SoundUtil.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import java.util.Map; import java.util.HashMap; diff --git a/android/src/TextEntryDialog.java b/android/src/TextEntryDialog.java index 8a57983df80..c235a30c622 100644 --- a/android/src/TextEntryDialog.java +++ b/android/src/TextEntryDialog.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import java.io.Closeable; import android.os.Handler; diff --git a/android/src/TextUtil.java b/android/src/TextUtil.java index caf362a1ade..075f7a7106e 100644 --- a/android/src/TextUtil.java +++ b/android/src/TextUtil.java @@ -4,7 +4,7 @@ /* TextUtil.java - Android text handling to be used by C++ Code via jni. */ -package org.xcsoar; +package de.opensoar; import android.graphics.Rect; import android.graphics.Paint; diff --git a/android/src/UsbSerialHelper.java b/android/src/UsbSerialHelper.java index 88b64101da3..388fd47b76a 100644 --- a/android/src/UsbSerialHelper.java +++ b/android/src/UsbSerialHelper.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import java.util.Arrays; import java.util.Collection; @@ -29,7 +29,7 @@ public final class UsbSerialHelper extends BroadcastReceiver { private static final String TAG = "UsbSerialHelper"; - private static final String ACTION_USB_PERMISSION = "org.xcsoar.otg.action.USB_PERMISSION"; + private static final String ACTION_USB_PERMISSION = "de.opensoar.otg.action.USB_PERMISSION"; private final Context context; private final UsbManager usbmanager; diff --git a/android/src/UsbSerialPort.java b/android/src/UsbSerialPort.java index 780e428c0f0..09db283aa44 100644 --- a/android/src/UsbSerialPort.java +++ b/android/src/UsbSerialPort.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import android.annotation.TargetApi; import android.hardware.usb.UsbDevice; diff --git a/android/src/Voltage.java b/android/src/Voltage.java index 1a1a6c17a74..b6f3ec4d4ff 100644 --- a/android/src/Voltage.java +++ b/android/src/Voltage.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import android.util.Log; import ioio.lib.api.IOIO; @@ -14,7 +14,7 @@ * A driver for voltage measurement on the IOIO board. */ final class Voltage extends Thread { - private static final String TAG = "XCSoar"; + private static final String TAG = "OpenSoar"; private AnalogInput h_volt; private AnalogInput h_temp; diff --git a/android/src/WindowUtil.java b/android/src/WindowUtil.java index 377c10db915..7e417017dc2 100644 --- a/android/src/WindowUtil.java +++ b/android/src/WindowUtil.java @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -package org.xcsoar; +package de.opensoar; import android.view.Window; import android.view.WindowManager; diff --git a/android/testing/AndroidManifest.xml b/android/testing/AndroidManifest.xml index 59741259d00..f0f04335287 100644 --- a/android/testing/AndroidManifest.xml +++ b/android/testing/AndroidManifest.xml @@ -1,9 +1,9 @@ + android:versionCode="22" + android:versionName="7.42.22"> - - diff --git a/build/android.mk b/build/android.mk index 545ebc34b1a..5e3bb4c118a 100644 --- a/build/android.mk +++ b/build/android.mk @@ -1,4 +1,4 @@ -# This Makefile fragment builds the Android package (XCSoar.apk). +# This Makefile fragment builds the Android package (OpenSoar.apk). # We're not using NDK's Makefiles because our Makefile is so big and # complex, we don't want to duplicate that for another platform. @@ -28,7 +28,7 @@ ZIPALIGN = $(ANDROID_BUILD_TOOLS_DIR)/zipalign AAPT = $(ANDROID_BUILD_TOOLS_DIR)/aapt D8 = $(ANDROID_BUILD_TOOLS_DIR)/d8 -ANDROID_LIB_NAMES = xcsoar +ANDROID_LIB_NAMES = $(PROGRAM_NAME) APKSIGN = $(APKSIGNER) sign ifeq ($(V),2) @@ -44,7 +44,7 @@ ifeq ($(origin ANDROID_KEYSTORE_PASS),environment) APKSIGN_RELEASE += --ks-pass env:ANDROID_KEYSTORE_PASS endif -JAVA_PACKAGE = org.xcsoar +JAVA_PACKAGE = de.$(PROGRAM_NAME_LC) NATIVE_CLASSES := \ FileProvider \ @@ -262,9 +262,9 @@ $(ANDROID_OUTPUT_DIR)/resources.apk: $(PNG_FILES) $(SOUND_FILES) $(ANDROID_XML_R -F $(ANDROID_OUTPUT_DIR)/resources.apk # R.java is generated by aapt, when resources.apk is generated -$(GEN_DIR)/org/xcsoar/R.java: $(ANDROID_OUTPUT_DIR)/resources.apk +$(GEN_DIR)/de/$(PROGRAM_NAME_LC)/R.java: $(ANDROID_OUTPUT_DIR)/resources.apk -$(ANDROID_OUTPUT_DIR)/classes.zip: $(JAVA_SOURCES) $(GEN_DIR)/org/xcsoar/R.java | $(JAVA_CLASSFILES_DIR)/dirstamp +$(ANDROID_OUTPUT_DIR)/classes.zip: $(JAVA_SOURCES) $(GEN_DIR)/de/$(PROGRAM_NAME_LC)/R.java | $(JAVA_CLASSFILES_DIR)/dirstamp @$(NQ)echo " JAVAC $(JAVA_CLASSFILES_DIR)" $(Q)$(JAVAC) \ -source 1.7 -target 1.7 \ @@ -273,7 +273,7 @@ $(ANDROID_OUTPUT_DIR)/classes.zip: $(JAVA_SOURCES) $(GEN_DIR)/org/xcsoar/R.java -Xlint:-options \ -Xlint:-static \ -cp $(ANDROID_SDK_PLATFORM_DIR)/android.jar:$(JAVA_CLASSFILES_DIR) \ - -d $(JAVA_CLASSFILES_DIR) $(GEN_DIR)/org/xcsoar/R.java \ + -d $(JAVA_CLASSFILES_DIR) $(GEN_DIR)/de/$(PROGRAM_NAME_LC)/R.java \ -h $(NATIVE_INCLUDE) \ $(JAVA_SOURCES) $(Q)$(ZIP) -0 -r $(ANDROID_OUTPUT_DIR)/classes.zip $(JAVA_CLASSFILES_DIR) @@ -386,11 +386,11 @@ $(HOME)/.android/debug.keystore: -dname "CN=Android Debug" \ -keyalg RSA -keysize 2048 -validity 10000 -$(ANDROID_BIN)/XCSoar-debug.apk: $(ANDROID_BUILD)/aligned.apk $(HOME)/.android/debug.keystore | $(ANDROID_BIN)/dirstamp - @$(NQ)echo " SIGN $@" +$(ANDROID_BIN)/$(PROGRAM_NAME)-unsigned.apk: $(ANDROID_BUILD)/aligned.apk $(HOME)/.android/debug.keystore | $(ANDROID_BIN)/dirstamp + @$(NQ)echo " UNSIGN $@" $(Q)$(APKSIGN) --in $< --out $@ --debuggable-apk-permitted -ks $(HOME)/.android/debug.keystore --ks-key-alias androiddebugkey --ks-pass pass:android -$(ANDROID_BIN)/XCSoar.apk: $(ANDROID_BUILD)/aligned.apk | $(ANDROID_BIN)/dirstamp +$(ANDROID_BIN)/$(PROGRAM_NAME).apk: $(ANDROID_BUILD)/aligned.apk | $(ANDROID_BIN)/dirstamp @$(NQ)echo " SIGN $@" $(Q)$(APKSIGN_RELEASE) --in $< --out $@ -ks $(ANDROID_KEYSTORE) --ks-key-alias $(ANDROID_KEY_ALIAS) diff --git a/build/cmake/CMakeLists.txt b/build/cmake/CMakeLists.txt new file mode 100644 index 00000000000..99f3dc5912a --- /dev/null +++ b/build/cmake/CMakeLists.txt @@ -0,0 +1,96 @@ +cmake_minimum_required(VERSION 3.15) + +message(STATUS "=== Build-Scripts ======================") +set(TARGET_NAME Scripts) + +file(GLOB_RECURSE SCRIPT_FILES + ${PROJECTGROUP_SOURCE_DIR}/src/*.txt + ${PROJECTGROUP_SOURCE_DIR}/src/*.cmake + ${PROJECTGROUP_SOURCE_DIR}/src/*.in + ${PROJECTGROUP_SOURCE_DIR}/build/*.txt + ${PROJECTGROUP_SOURCE_DIR}/build/*.cmake + ${PROJECTGROUP_SOURCE_DIR}/build/*.toolchain + # ${PROJECTGROUP_SOURCE_DIR}/build/*.py + ${PROJECTGROUP_SOURCE_DIR}/build/*.in +) +list(APPEND + ${PROJECTGROUP_SOURCE_DIR}/CMakeSource.cmake + ${PROJECTGROUP_SOURCE_DIR}/NEWS.txt +) + +file(GLOB_RECURSE MAKE_FILES + ${PROJECTGROUP_SOURCE_DIR}/build/*.py + ${PROJECTGROUP_SOURCE_DIR}/build/*.mk +) + +set(_subfolder Scripts) +set(_replacement ${PROJECTGROUP_SOURCE_DIR}) + +foreach(file ${SCRIPT_FILES} ${MAKE_FILES}) + string(REPLACE "${_replacement}/" "" _file ${file}) + get_filename_component(src_path ${_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + set(_folder_name "${_subfolder}\\{src_path}") + else() + set(_folder_name "${_subfolder}") + endif() + if(${file} MATCHES ".mk") + string(APPEND src_path "\\make") + # message(FATAL_ERROR "Stop: ${src_path} -> ${file}") + endif() + # source_group("TestFolder" FILES XX\\${file}) + # source_group("XX\\${src_path}" FILES ${file}) + source_group("${src_path}" FILES ${file}) + +endforeach() + +add_library(${TARGET_NAME} + EXCLUDE_FROM_ALL + ../../src/Version.cpp + ${SCRIPT_FILES} + ${MAKE_FILES} +) +add_custom_target(${TARGET_NAME}X + EXCLUDE_FROM_ALL + ${SCRIPT_FILES} + ${MAKE_FILES} +) + + +# ================ Android ============================= +file(GLOB_RECURSE ANDROID_FILES + ${PROJECTGROUP_SOURCE_DIR}/android/*.* +) +# set(_replacement) +foreach(file ${SCRIPT_FILES} ${ANDROID_FILES}) + string(REPLACE "${_replacement}/" "" _file ${file}) + get_filename_component(src_path ${_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + set(_folder_name "${_subfolder}\\{src_path}") + else() + set(_folder_name "${_subfolder}") + endif() + source_group("${src_path}" FILES ${file}) +endforeach() + +if(0) +add_custom_target(${TARGET_NAME}J + EXCLUDE_FROM_ALL + ${ANDROID_FILES} +) +else() +add_library(${TARGET_NAME}J + EXCLUDE_FROM_ALL + ../../src/Version.cpp + ${ANDROID_FILES} +) +endif() +# ================ Android-End ========================= + +include(xcsoar.cmake) + +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER _Scripts) +set_target_properties(${TARGET_NAME}X PROPERTIES FOLDER _Scripts) +set_target_properties(${TARGET_NAME}J PROPERTIES FOLDER _Scripts) diff --git a/build/cmake/Clang.cmake b/build/cmake/Clang.cmake new file mode 100644 index 00000000000..a99e20212c4 --- /dev/null +++ b/build/cmake/Clang.cmake @@ -0,0 +1,25 @@ +set(TARGET_NAME "XCSoarAug-Clang") # hardcoded + +message(STATUS "+++ System = WIN32 / Clang!") + +set(LIB_PREFIX "" ) # "lib") +set(LIB_SUFFIX ".lib") # "a") +# add_compile_definitions(BOOST_ASIO_SEPARATE_COMPILATION) +add_compile_definitions(__CLANG__) +add_compile_definitions(_AUG_CLANG=1) +# add_compile_definitions(HAVE_MSVCRT) +add_compile_definitions(_UNICODE) +add_compile_definitions(UNICODE) # ??? +add_compile_definitions(STRICT) +add_compile_definitions(_USE_MATH_DEFINES) # necessary under C++17! + +add_compile_definitions(-std=c++20) +# gibt es nicht mehr: --- include_directories("${PROJECTGROUP_SOURCE_DIR}/temp/data") # temporary data! +if (ON OR WIN64) # momentan kein Flag verfügbar! + add_compile_definitions(_AMD64_) +else() + message(FATAL_ERROR "Error: WIN32 not implemented?") +endif() + +set(SSL_LIB ) +set(CRYPTO_LIB ) diff --git a/build/cmake/Compile-OpenSoar-Clang.cmd b/build/cmake/Compile-OpenSoar-Clang.cmd new file mode 100644 index 00000000000..9daa50a845e --- /dev/null +++ b/build/cmake/Compile-OpenSoar-Clang.cmd @@ -0,0 +1,23 @@ +@echo off +cd /D %~dp0../.. + +:: clang 12 - 07.02.2023: scheinbar ordentlich +:: - 01.03.2023: scheitert jetzt am sodium 1.0.18? +:: clang 14 - im toolchainfile muss llvm-ar angegeben werden (ar.exe gibt es nicht!) +:: clang 15 - 07.02.2023: ich weiß auch nicht, wie das schon mal gehen konnte: ich musste ja bei der 15.0.0-Version den Path zu MinGW aufmachen, und da lag ja ein clang12 drin.... Heute auf 15.0.7 geupdated, die toolchain angepasst (llvm-ar und llvm-rc) - danach compilierte er erst einmal durch, hatte nur beim Linken Probleme +:: - 01.03.2023: mit 3 Änderungen lief es besser (durch?)! +:: * llvm-ar.exe kopiert in ar.exe (boost wollte immer das "ar", obwohl im Toolchain-File 'llvm-ar.exe' als CMAKE_AR_COMPILER angegeben war) +:: * in (link_libs)/ares_build.h Zeile 5 #define CARES_TYPEOF_ARES_SSIZE_T __int64 (geändert von ...ssize_t)?? +:: * ABER Boost-Json und Boost-Container-Lib wird falsch angefordert: libboost_***-clangw15-mt-gd-x64-1_81.lib +:: statt libboost_***-clangw15-mt-d-x64-1_81.lib! Warum? eigentlich soll doch das ganze mit HeadersOnly laufen.... + + +::======================= +set CLANG_VERSION=clang15 +::======================= + +echo %CD% +PATH=%CD%;%CD%\build\cmake\python;%PATH% +python build/cmake/python/Start-CMake-OpenSoar.py opensoar %CLANG_VERSION% 3 + +if errorlevel 1 pause diff --git a/build/cmake/Compile-OpenSoar-MGW.cmd b/build/cmake/Compile-OpenSoar-MGW.cmd new file mode 100644 index 00000000000..d8fd7182a22 --- /dev/null +++ b/build/cmake/Compile-OpenSoar-MGW.cmd @@ -0,0 +1,15 @@ +@echo off +cd /D %~dp0../.. + +::======================= +:: Problem ???: set MINGW_VERSION=mgw122 +:: but this don't solve the problem with DeviceEditWidget->SetPort (not seen on MSVC) +set MINGW_VERSION=mgw112 +::======================= + +echo %CD% +PATH=%CD%;%CD%\build\cmake\python;%PATH% +python build/cmake/python/Start-CMake-OpenSoar.py opensoar %MINGW_VERSION% 15 + +if errorlevel 1 pause + diff --git a/build/cmake/Compile-OpenSoar-MSVC.cmd b/build/cmake/Compile-OpenSoar-MSVC.cmd new file mode 100644 index 00000000000..04dee45a7c2 --- /dev/null +++ b/build/cmake/Compile-OpenSoar-MSVC.cmd @@ -0,0 +1,8 @@ +@echo off +cd /D %~dp0../.. + +echo %CD% +PATH=%CD%;%CD%\build\cmake\python;%PATH% +python build/cmake/python/Start-CMake-OpenSoar.py opensoar msvc2022 14 + +if errorlevel 1 pause diff --git a/build/cmake/Compile-XCSoar-Clang15.cmd b/build/cmake/Compile-XCSoar-Clang15.cmd new file mode 100644 index 00000000000..2a7a4b2809a --- /dev/null +++ b/build/cmake/Compile-XCSoar-Clang15.cmd @@ -0,0 +1,16 @@ +@echo off +cd /D %~dp0../.. + +echo %CD% +:: PATH=%CD%;%CD%\build\cmake\python;D:\Programs\MinGW\mgw122\bin;%PATH% +:: PATH=D:\Programs\MinGW\mgw122\bin;%PATH% +PATH=%CD%;%~dp0python;D::\Programs\LLVM\clang15\bin; %PATH% +python build/cmake/python/Start-CMake-XCSoar.py xcsoar clang15 15 + +if errorlevel 1 pause + +exit /B 0 + +D:\Programs\LLVM\clang15\bin\clang++.exe -DCURL_STATICLIB -DGIT_COMMIT_ID=\"76c88d4c9f\" -DGNU_CONST=[[gnu::const]] -DGNU_PURE=[[gnu::pure]] -DNOMINMAX -DSTRICT -DUNICODE -DUSE_GDI -DUSE_WIN32_RESOURCES -DUSE_WINUSER -DXCSOAR_VERSION=\"7.29\" -DZZIP_1_H -D_AMD64_ -D_AUG_CLANG -D_UNICODE -D_USE_MATH_DEFINES -D__CLANG__ -ID:/Programs/LLVM/clang15/include -ID:/Programs/Android/android-ndk-r25b/sources/cxx-stl/llvm-libc++/include -ID:/Programs/Android/android-ndk-r25b/sources/cxx-stl/system/include -ID:/Programs/LLVM/clang15/lib/clang/clang15.0.1/include -ID:/Projects/XCSoar/XCSoar/src/io -ID:/Projects/Binaries/XCSoar/dev-branch/include -ID:/Projects/link_libs/boost/boost-1.81.0/include/boost-1_81 -ID:/Projects/link_libs/zlib/zlib-1.2.12/include -ID:/Projects/link_libs/lua/lua-5.4.4/include -ID:/Projects/link_libs/png/png-1.6.37/include -ID:/Projects/link_libs/cares/cares-1.17.1/include/clang15 -ID:/Projects/link_libs/curl/curl-7.85.0/include -ID:/Projects/link_libs/sodium/sodium-1.0.18/include -ID:/Projects/XCSoar/XCSoar/src -ID:/Projects/XCSoar/XCSoar/src/Engine -ID:/Projects/link_libs/boost/boost-1.81.0/include/boost-1_81/boost/predef/other -ID:/Projects/Binaries/XCSoar/dev-branch/3rd_Party/glfw/glfw-3.3.2.bin.WIN64/include -ID:/Projects/link_libs/glm/glm-0.9.9/include -ID:/Projects/XCSoar/XCSoar/src/Blackboard -v -std=c++20 -fcoroutines-ts -MD -MT src/Blackboard/CMakeFiles/Blackboard.dir/BlackboardListener.cpp.obj -MF src\Blackboard\CMakeFiles\Blackboard.dir\BlackboardListener.cpp.obj.d -o src/Blackboard/CMakeFiles/Blackboard.dir/BlackboardListener.cpp.obj -c D:/Projects/XCSoar/XCSoar/src/Blackboard/BlackboardListener.cpp +D:\Programs\LLVM\clang15\bin\clang++.exe -DCURL_STATICLIB -DGIT_COMMIT_ID=\"76c88d4c9f\" -DGNU_CONST=[[gnu::const]] -DGNU_PURE=[[gnu::pure]] -DNOMINMAX -DSTRICT -DUNICODE -DUSE_GDI -DUSE_WIN32_RESOURCES -DUSE_WINUSER -DXCSOAR_VERSION=\"7.29\" -DZZIP_1_H -D_AMD64_ -D_AUG_CLANG -D_UNICODE -D_USE_MATH_DEFINES -D__CLANG__ -ID:/Programs/LLVM/clang15/include -ID:/Programs/LLVM/clang15/lib/clang/clang15.0.1/include -ID:/Projects/XCSoar/XCSoar/src/io -ID:/Projects/Binaries/XCSoar/dev-branch/include -ID:/Projects/link_libs/boost/boost-1.81.0/include/boost-1_81 -ID:/Projects/link_libs/zlib/zlib-1.2.12/include -ID:/Projects/link_libs/lua/lua-5.4.4/include -ID:/Projects/link_libs/png/png-1.6.37/include -ID:/Projects/link_libs/cares/cares-1.17.1/include/clang15 -ID:/Projects/link_libs/curl/curl-7.85.0/include -ID:/Projects/link_libs/sodium/sodium-1.0.18/include -ID:/Projects/XCSoar/XCSoar/src -ID:/Projects/XCSoar/XCSoar/src/Engine -ID:/Projects/link_libs/boost/boost-1.81.0/include/boost-1_81/boost/predef/other -ID:/Projects/Binaries/XCSoar/dev-branch/3rd_Party/glfw/glfw-3.3.2.bin.WIN64/include -ID:/Projects/link_libs/glm/glm-0.9.9/include -ID:/Projects/XCSoar/XCSoar/src/Terrain -v -std=c++20 -fcoroutines-ts -MD -MT src/Terrain/jasper/CMakeFiles/jasper.dir/jpc/jpc_bs.c.obj -MF src\Terrain\jasper\CMakeFiles\jasper.dir\jpc\jpc_bs.c.obj.d -o src/Terrain/jasper/CMakeFiles/jasper.dir/jpc/jpc_bs.c.obj -c D:/Projects/XCSoar/XCSoar/src/Terrain/jasper/jpc/jpc_bs.c +D:\Programs\LLVM\clang15\bin\clang.exe -DCURL_STATICLIB -DGIT_COMMIT_ID=\"76c88d4c9f\" -DGNU_CONST=[[gnu::const]] -DGNU_PURE=[[gnu::pure]] -DNOMINMAX -DSTRICT -DUNICODE -DUSE_GDI -DUSE_WIN32_RESOURCES -DUSE_WINUSER -DXCSOAR_VERSION=\"7.29\" -DZZIP_1_H -D_AMD64_ -D_AUG_CLANG -D_UNICODE -D_USE_MATH_DEFINES -D__CLANG__ -ID:/Programs/LLVM/clang15/include -ID:/Programs/LLVM/clang15/lib/clang/clang15.0.1/include -ID:/Projects/XCSoar/XCSoar/src/io -ID:/Projects/Binaries/XCSoar/dev-branch/include -ID:/Projects/link_libs/boost/boost-1.81.0/include/boost-1_81 -ID:/Projects/link_libs/zlib/zlib-1.2.12/include -ID:/Projects/link_libs/lua/lua-5.4.4/include -ID:/Projects/link_libs/png/png-1.6.37/include -ID:/Projects/link_libs/cares/cares-1.17.1/include/clang15 -ID:/Projects/link_libs/curl/curl-7.85.0/include -ID:/Projects/link_libs/sodium/sodium-1.0.18/include -ID:/Projects/XCSoar/XCSoar/src -ID:/Projects/XCSoar/XCSoar/src/Engine -ID:/Projects/link_libs/boost/boost-1.81.0/include/boost-1_81/boost/predef/other -ID:/Projects/Binaries/XCSoar/dev-branch/3rd_Party/glfw/glfw-3.3.2.bin.WIN64/include -ID:/Projects/link_libs/glm/glm-0.9.9/include -ID:/Projects/XCSoar/XCSoar/src/Terrain -v -fcoroutines-ts -MD -MT src/Terrain/jasper/CMakeFiles/jasper.dir/jpc/jpc_bs.c.obj -MF src\Terrain\jasper\CMakeFiles\jasper.dir\jpc\jpc_bs.c.obj.d -o src/Terrain/jasper/CMakeFiles/jasper.dir/jpc/jpc_bs.c.obj -c D:/Projects/XCSoar/XCSoar/src/Terrain/jasper/jpc/jpc_bs.c \ No newline at end of file diff --git a/build/cmake/Compile-XCSoar-MGW122.cmd b/build/cmake/Compile-XCSoar-MGW122.cmd new file mode 100644 index 00000000000..e419362be16 --- /dev/null +++ b/build/cmake/Compile-XCSoar-MGW122.cmd @@ -0,0 +1,8 @@ +@echo off +cd /D %~dp0../.. + +echo %CD% +PATH=%CD%;%CD%\build\cmake\python;%PATH% +python build/cmake/python/Start-CMake-XCSoar.py xcsoar mgw122 14 + +if errorlevel 1 pause diff --git a/build/cmake/Compile-XCSoar-MSVC.cmd b/build/cmake/Compile-XCSoar-MSVC.cmd new file mode 100644 index 00000000000..164f0764f71 --- /dev/null +++ b/build/cmake/Compile-XCSoar-MSVC.cmd @@ -0,0 +1,8 @@ +@echo off +cd /D %~dp0../.. + +echo %CD% +PATH=%CD%;%CD%\build\cmake\python;%PATH% +python build/cmake/python/Start-CMake-XCSoar.py xcsoar msvc2022 14 + +if errorlevel 1 pause diff --git a/build/cmake/Compile-XCSoar.cmd b/build/cmake/Compile-XCSoar.cmd new file mode 100644 index 00000000000..eee3a8c85f1 --- /dev/null +++ b/build/cmake/Compile-XCSoar.cmd @@ -0,0 +1,42 @@ +@echo off +cd /D %~dp0../.. + +echo Directory = '%CD%' +REM pause + +REM goto BULK_START + +set TOOLCHAIN=ninja +set TOOLCHAIN=mgw112 +set TOOLCHAIN=msvc2022 +REM set TOOLCHAIN=mgw122 +REM set TOOLCHAIN=clang15 + +echo %CD% +PATH=%CD%;%CD%\build\cmake\python;%PATH% +python build/cmake/python/Start-CMake-XCSoar.py xcsoar %TOOLCHAIN% 14 + +if errorlevel 1 pause + +exit /B 0 + + +:: 3 times one after another: +: BULK_START +python build/cmake/Start-CMake-XCSoar.py xcsoar clang14 6 +if errorlevel 1 goto ERROR +REM python build/cmake/Start-CMake-XCSoar.py xcsoar mgw112 6 +if errorlevel 1 goto ERROR +python build/cmake/Start-CMake-XCSoar.py xcsoar msvc2022 14 +if errorlevel 1 goto ERROR + +goto FINISH + +: ERROR +echo Error during the BULK_START build!!! + + + +: FINISH +pause +exit /B 0 diff --git a/build/cmake/LinuxGCC.cmake b/build/cmake/LinuxGCC.cmake new file mode 100644 index 00000000000..9826129f472 --- /dev/null +++ b/build/cmake/LinuxGCC.cmake @@ -0,0 +1,84 @@ +set(TARGET_NAME "XCSoarAug-Linux") # hardcoded yet + +message(STATUS "+++ System = Linux / GCC (${TOOLCHAIN}) on ${CMAKE_HOST_SYSTEM_NAME} !") + +set(LIB_PREFIX "lib" ) # "lib") +set(LIB_SUFFIX ".a") # "a") + + +set(UNIX ON) +add_compile_definitions(__LINGCC__) + +# include_directories("/usr/include/x86_64-linux-gnu") +# message(FATAL_ERROR "Stop????") + +#******************************************************************************** +if(AUGUST_SPECIAL) + add_compile_definitions(_AUG_GCC=1) +endif() +#******************************************************************************** +set(ENABLE_OPENGL ON) # better outside???? +set(ENABLE_SDL OFF) # better outside???? +set(USE_MEMORY_CANVAS OFF) # das ist hier auch falsch!!!! + +add_compile_definitions(BOOST_NO_IOSTREAM) +add_compile_definitions(BOOST_MATH_NO_LEXICAL_CAST) +add_compile_definitions(BOOST_UBLAS_NO_STD_CERR) +add_compile_definitions(BOOST_ERROR_CODE_HEADER_ONLY) +add_compile_definitions(BOOST_SYSTEM_NO_DEPRECATED) +add_compile_definitions(BOOST_NO_STD_LOCALE) +add_compile_definitions(BOOST_LEXICAL_CAST_ASSUME_C_LOCALE) +add_compile_definitions(BOOST_NO_CXX98_FUNCTION_BASE) +add_compile_definitions(HAVE_POSIX) +add_compile_definitions(HAVE_VASPRINTF) +add_compile_definitions(EYE_CANDY) +add_compile_definitions(_GLIBCXX_ASSERTIONS) +add_compile_definitions(ENABLE_ALSA) +add_compile_definitions(USE_FREETYPE) +add_compile_definitions(ENABLE_OPENGL) +add_compile_definitions(HAVE_GLES) +add_compile_definitions(HAVE_GLES2) +add_compile_definitions(GL_GLEXT_PROTOTYPES) +add_compile_definitions(USE_GLX) +add_compile_definitions(USE_X11) +add_compile_definitions(USE_POLL_EVENT) +add_compile_definitions(BOOST_JSON_STANDALONE) + +set(USE_POLL_EVENT ON) +set(ENABLE_OPENGL ON) + +include_directories( + ${SRC}/unix + ${SRC} + ${SRC}/Engine + lib/glm + /usr/include + /usr/include/x86_64-linux-gnu + ${LINK_LIBS}/boost/boost-1.80.0 +) + +# string(APPEND CMAKE_CXX_FLAGS " -Og -funit-at-a-time -ffast-math -g -std=c++20 -fno-threadsafe-statics -fmerge-all-constants -fcoroutines -fconserve-space -fno-operator-names -fvisibility=hidden -finput-charset=utf-8 -Wall -Wextra -Wwrite-strings -Wcast-qual -Wpointer-arith -Wsign-compare -Wundef -Wmissing-declarations -Wredundant-decls -Wmissing-noreturn -Wvla -Wno-format-truncation -Wno-missing-field-initializers -Wcast-align -Werror ") + +string(APPEND CMAKE_CXX_FLAGS " -Og -funit-at-a-time -ffast-math -g -std=c++20 -fno-threadsafe-statics -fmerge-all-constants -fcoroutines -fconserve-space -fno-operator-names -fvisibility=hidden -finput-charset=utf-8 -Wall -Wextra -Wwrite-strings -Wpointer-arith -Wsign-compare -Wmissing-declarations -Wmissing-noreturn -Wvla -Wno-format-truncation -Wno-missing-field-initializers -Wcast-align -Werror ") + + +# string(APPEND CMAKE_CXX_FLAGS "-Werror=redundant-decls -Werror=cast-qual") + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") + + +set(CMAKE_CXX_STANDARD_LIBRARIES "-static-libgcc -static-libstdc++ ${CMAKE_CXX_STANDARD_LIBRARIES}") +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static -static-libstdc++ -Wl,-Bstatic,--whole-archive -Wl,--no-whole-archive -v") +# set(FREEGLUT_LIB_DIR "${LINK_LIBS}/freeglut-MinGW-3.0.0-1/freeglut") + + set(SSL_LIB) + set(CRYPTO_LIB) # no extra (OpenSSL-)crypto lib on linux??! + +set(PERCENT_CHAR \%) +set(DOLLAR_CHAR $$) + +list(APPEND CMAKE_PROGRAM_PATH "/home/august/Projects/XCSoar/_build") + +include_directories(${SRC}/unix) +# message(FATAL_ERROR "Include ${SRC}/unix") + diff --git a/build/cmake/LinuxMinGW.cmake b/build/cmake/LinuxMinGW.cmake new file mode 100644 index 00000000000..61071037b5d --- /dev/null +++ b/build/cmake/LinuxMinGW.cmake @@ -0,0 +1,100 @@ +set(TARGET_NAME "XCSoarAug-MinGW") # hardcoded yet + +message(STATUS "+++ System = WIN32 / MinGW (${TOOLCHAIN})! on ${CMAKE_HOST_SYSTEM_NAME} ") + +set(LIB_PREFIX "lib" ) # "lib") +set(LIB_SUFFIX ".a") # "a") + +# August2111: warum? string(APPEND CMAKE_CXX_FLAGS " -U_REENTRANT") +add_compile_definitions(BOOST_NO_IOSTREAM) +add_compile_definitions(BOOST_MATH_NO_LEXICAL_CAST) +add_compile_definitions(BOOST_UBLAS_NO_STD_CERR) +add_compile_definitions(BOOST_ERROR_CODE_HEADER_ONLY) +add_compile_definitions(BOOST_SYSTEM_NO_DEPRECATED) +add_compile_definitions(BOOST_NO_STD_LOCALE) +add_compile_definitions(BOOST_LEXICAL_CAST_ASSUME_C_LOCALE) +add_compile_definitions(BOOST_NO_CXX98_FUNCTION_BASE) +add_compile_definitions(WINVER=0x0600) +add_compile_definitions(_WIN32_WINDOWS=0x0600) +add_compile_definitions(_WIN32_WINNT=0x0600) +add_compile_definitions(_WIN32_IE=0x0600) +add_compile_definitions(WIN32_LEAN_AND_MEAN) +add_compile_definitions(NOMINMAX) +add_compile_definitions(HAVE_STRUCT_POLLFD) +add_compile_definitions(HAVE_MSVCRT) +add_compile_definitions(UNICODE) # ??? +add_compile_definitions(_UNICODE) +add_compile_definitions(STRICT) +add_compile_definitions(EYE_CANDY) +add_compile_definitions(USE_WIN32_RESOURCES) +add_compile_definitions(_GLIBCXX_ASSERTIONS) + +add_compile_definitions(BOOST_JSON_STANDALONE) + + +# string(APPEND CMAKE_CXX_FLAGS " -Og -funit-at-a-time -ffast-math -g -std=c++20 -fno-threadsafe-statics -fmerge-all-constants -fcoroutines -fconserve-space -fno-operator-names -fvisibility=hidden -finput-charset=utf-8 -Wall -Wextra -Wwrite-strings -Wcast-qual -Wpointer-arith -Wsign-compare -Wundef -Wmissing-declarations -Wredundant-decls -Wmissing-noreturn -Wvla -Wno-format-truncation -Wno-missing-field-initializers -Wcast-align -Werror -I./src/unix -I./_build/include -isystem /home/august/Projects/link_libs/boost/boost-1.80.0 ") +string(APPEND CMAKE_CXX_FLAGS " -c -Og -funit-at-a-time -ffast-math -g -std=c++20 -fno-threadsafe-statics -fmerge-all-constants -fcoroutines -fconserve-space -fno-operator-names -finput-charset=utf-8 -Wall -Wextra -Wwrite-strings -Wcast-qual -Wpointer-arith -Wsign-compare -Wundef -Wmissing-declarations -Wredundant-decls -Wmissing-noreturn -Wvla -Wno-format-truncation -Wno-missing-field-initializers -Wcast-align -Werror -m64 -mwin32 -mwindows -mms-bitfields") + +# string(APPEND CMAKE_CXX_FLAGS " -v") + +include_directories( + ${SRC} + ${SRC}/Engine + /usr/lib/gcc/x86_64-w64-mingw32/10-win32/include/c++ + /usr/lib/gcc/x86_64-w64-mingw32/10-win32/include/c++/x86_64-w64-mingw32 + /usr/lib/gcc/x86_64-w64-mingw32/10-win32/include/c++/backward + /usr/lib/gcc/x86_64-w64-mingw32/10-win32/include + /usr/lib/gcc/x86_64-w64-mingw32/10-win32/include-fixed + /usr/lib/gcc/x86_64-w64-mingw32/10-win32/../../../../x86_64-w64-mingw32/include +) +# /home/august/Projects/XCsoar/output/WIN64/lib/x86_64-w64-mingw32/include + +if (${CMAKE_HOST_SYSTEM_NAME} STREQUAL Windows) + include_directories("D:/Programs/MinGW/${TOOLCHAIN}/include") + # later: include_directories("${PROJECTGROUP_SOURCE_DIR}/output/include") +endif() + + +#additional to make TARGET=WIN64: -isystem statt -I +include_directories( + /usr/include + /usr/include/x86_64-linux-gnu + ${LINK_LIBS}/boost/boost-1.80.0 +) + +####################################################################### + list(APPEND XCSOAR_LINK_LIBRARIES + msimg32 + winmm + # dl + pthread + stdc++ + user32 + gdi32 + gdiplus + ws2_32 + mswsock + kernel32 + # ?? msvcrt32 + shell32 + gcc_s + ) + +set(MINGW ON) +add_compile_definitions(__MINGW__) +#******************************************************************************** +if(AUGUST_SPECIAL) + add_compile_definitions(_AUG_MGW=1) +endif() +#******************************************************************************** +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") +set(CMAKE_CXX_STANDARD_LIBRARIES "-static-libgcc -static-libstdc++ -m64 -lwsock32 -lws2_32 -lgdi32 -lgdiplus -lcrypt32 ${CMAKE_CXX_STANDARD_LIBRARIES}") +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static -static-libstdc++ -Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive -v") + +if (${CMAKE_HOST_SYSTEM_NAME} STREQUAL Windows) + set(SSL_LIB) + set(CRYPTO_LIB Crypt32.lib BCrypt.lib) # no (OpenSSL-)crypto lib on windows! +endif() + +set(PERCENT_CHAR \%) +set(DOLLAR_CHAR $$) diff --git a/build/cmake/MakeAll.sh b/build/cmake/MakeAll.sh new file mode 100644 index 00000000000..a91de2e968a --- /dev/null +++ b/build/cmake/MakeAll.sh @@ -0,0 +1,67 @@ +#!/bin/bash + +if [ "$COMPLETE" == "" ]; then COMPLETE=y; fi + +BIN_NAME=output/ANDROID/bin/OpenSoar-unsigned.apk + +#delete all old Android packages: +rm -rv output/ANDROID/opt +rm -v $BIN_NAME + +echo "=============================================================================" +echo "Make Android v8a (64 bit):" +if [ "$COMPLETE" == "y" ]; then rm -rv output/ANDROID/arm64-v8a/opt/src; fi + +make DEBUG=n TARGET=ANDROIDAARCH64 +echo "Android arm64-v8a ready!" + +if [ -e $BIN_NAME ]; then +if [ "$EXPORT_ANDROID_ARM64" == "y" ]; then cp -v $BIN_NAME output/ANDROID/bin/OpenSoar-${PROGRAM_VERSION}-64.apk; fi + +if [ ! "$ANDROID_ARM64_ONLY" == "y" ]; then +echo "=============================================================================" +echo "Make Android v7a (32 bit):" +if [ "$COMPLETE" == "y" ]; then rm -rv output/ANDROID/armeabi-v7a/opt/src; fi +make DEBUG=n TARGET=ANDROID +echo "Android armeabi_v7a ready!" + +echo "=============================================================================" +echo "Make Android x64:" +if [ "$COMPLETE" == "y" ]; then rm -rv output/ANDROID/x86_64/opt/src; fi +make DEBUG=n TARGET=ANDROIDX64 +echo "Android x86_64 ready!" + +echo "=============================================================================" +echo "Make Android x86:" +if [ "$COMPLETE" == "y" ]; then rm -rv output/ANDROID/x86/opt/src; fi +make DEBUG=n TARGET=ANDROID86 +echo "Android x86 ready!" + +cp -v $BIN_NAME output/ANDROID/bin/OpenSoar-${PROGRAM_VERSION}.apk + +if [ ! "$ANDROID_ONLY" == "y" ]; then +echo "=============================================================================" +echo "Make Win64:" +if [ "$COMPLETE" == "y" ]; then rm -rv output/WIN64/opt/src; fi +make DEBUG=n TARGET=WIN64 +echo "Win64 ready!" +cp -v output/WIN64/bin/OpenSoar.exe output/WIN64/bin/OpenSoar-${PROGRAM_VERSION}.exe +echo "=============================================================================" +echo "Make Linux:" +if [ "$COMPLETE" == "y" ]; then rm -rv output/UNIX/opt/src; fi +make DEBUG=n TARGET=UNIX +echo "UNIX ready!" +cp -v output/UNIX/bin/OpenSoar output/UNIX/bin/OpenSoar-${PROGRAM_VERSION} + +# ANDROID_ONLY: +else +echo "ANDROID_ONLY = $ANDROID_ONLY" +fi + +else +echo "ANDROID_ARM64_ONLY = $ANDROID_ARM64_ONLY" +fi + +else +echo "'$BIN_NAME' not available!" +fi diff --git a/build/cmake/MakeAndroid.sh b/build/cmake/MakeAndroid.sh new file mode 100644 index 00000000000..33d3c29c34d --- /dev/null +++ b/build/cmake/MakeAndroid.sh @@ -0,0 +1,11 @@ +echo Make Android v7a (32 bit): +make DEBUG=n TARGET=ANDROID + +echo Make Android v8a (64 bit): +make DEBUG=n TARGET=ANDROIDAARCH64 + +echo Make Android x64: +make DEBUG=n TARGET=ANDROIDX64 + +echo Make Android x86: +make DEBUG=n TARGET=ANDROID86 diff --git a/build/cmake/MakeComplete.sh b/build/cmake/MakeComplete.sh new file mode 100644 index 00000000000..0f2d3c342ce --- /dev/null +++ b/build/cmake/MakeComplete.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +echo "Make Complete" +echo "=============" + +if [ "$GIT_REPOSITORY" == "" ]; then GIT_REPOSITORY=OpenSoaring ; fi +if [ "$GIT_BRANCH" == "" ]; then GIT_BRANCH=master ; fi +# or origin ; fi + +git fetch ${GIT_REPOSITORY} +git reset --hard ${GIT_REPOSITORY}/${GIT_BRANCH} +./git-clean-submodule.sh +. ./OpenSoar.config +echo "PROGRAM_VERSION = ${PROGRAM_VERSION}" +chmod -R 757 ./build/cmake + +export PROGRAM_VERSION=${PROGRAM_VERSION} + +if [ "$COMPILE" == "" ]; then COMPILE=y ; fi +if [ "$COMPLETE" == "" ]; then export COMPLETE=y ; fi + +if [ "$COMPILE" == "y" ]; then ./build/cmake/MakeAll.sh ; fi + diff --git a/build/cmake/MakeLinux.sh b/build/cmake/MakeLinux.sh new file mode 100644 index 00000000000..e2927761094 --- /dev/null +++ b/build/cmake/MakeLinux.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +git fetch OpenSoaring_OpenSoar +# git reset --hard august/weglide-tmp +# git reset --hard flaps3/cmake +git reset --hard OpenSoaring_OpenSoar/opensoar-dev +# git reset --hard OpenSoaring_OpenSoar/dev-branch +sudo chmod 757 -R ./build/cmake +make TARGET=UNIX DEBUG=n +output/UNIX/bin/xcsoar -fly -1000x500 + diff --git a/build/cmake/MinGW.cmake b/build/cmake/MinGW.cmake new file mode 100644 index 00000000000..5224feafa3c --- /dev/null +++ b/build/cmake/MinGW.cmake @@ -0,0 +1,86 @@ +set(TARGET_NAME "XCSoarAug-MinGW") # hardcoded yet + +message(STATUS "+++ System = WIN32 / MinGW (${TOOLCHAIN}) on ${CMAKE_HOST_SYSTEM_NAME} !!!") + +set(LIB_PREFIX "lib" ) # "lib") +set(LIB_SUFFIX ".a") # "a") + +add_compile_definitions(BOOST_ASIO_SEPARATE_COMPILATION) +add_compile_definitions(BOOST_MATH_DISABLE_DEPRECATED_03_WARNING=ON) + +# Bei Windows brauche ich das nicht, aber hilft das eventuell beim Cross-Compile unter Linux? +add_compile_definitions(BOOST_JSON_HEADER_ONLY) +add_compile_definitions(BOOST_JSON_STANDALONE) + + # add_compile_definitions(HAVE_MSVCRT) +add_compile_definitions(UNICODE) # ??? +add_compile_definitions(_UNICODE) +add_compile_definitions(STRICT) +add_compile_definitions(_USE_MATH_DEFINES) # necessary under C++17! +add_compile_definitions(ZZIP_1_H) # definition of uint32_t and Co.! +# string(APPEND CMAKE_CXX_FLAGS " -Og -funit-at-a-time -ffast-math -g -std=c++20 -fno-threadsafe-statics -fmerge-all-constants -fcoroutines -fconserve-space -fno-operator-names -fvisibility=hidden -finput-charset=utf-8 -Wall -Wextra -Wwrite-strings -Wcast-qual -Wpointer-arith -Wsign-compare -Wundef -Wmissing-declarations -Wredundant-decls -Wmissing-noreturn -Wvla -Wno-format-truncation -Wno-missing-field-initializers -Wcast-align -Werror -I./src/unix -I./_build/include -isystem /home/august/Projects/link_libs/boost/boost-1.80.0 ") +# string(APPEND CMAKE_CXX_FLAGS " -c -Og -funit-at-a-time -ffast-math -g -std=c++20 -fno-threadsafe-statics -fmerge-all-constants -fcoroutines -fconserve-space -fno-operator-names -finput-charset=utf-8 -Wall -Wextra -Wwrite-strings -Wcast-qual -Wpointer-arith -Wsign-compare -Wundef -Wmissing-declarations -Wredundant-decls -Wmissing-noreturn -Wvla -Wno-format-truncation -Wno-missing-field-initializers -Wcast-align -Werror -m64 -mwin32 -mwindows -mms-bitfields") +string(APPEND CMAKE_CXX_FLAGS " -std=c++20") # C++20 +string(APPEND CMAKE_CXX_FLAGS " -fcoroutines") # use CoRoutines +string(APPEND CMAKE_CXX_FLAGS " -Wno-cpp") # disable the warning 'Please include winsock2.h before windows.h' +if(VERBOSE_CXX) + string(APPEND CMAKE_CXX_FLAGS " -v") # verbose.. +endif() + +if (${CMAKE_HOST_SYSTEM_NAME} STREQUAL Windows) + include_directories("D:/Programs/MinGW/${TOOLCHAIN}/include") + # later: include_directories("${PROJECTGROUP_SOURCE_DIR}/output/include") + # include_directories(D:/Projects/link_libs/boost/boost-1.80.0/include/boost-1_80) + include_directories(${LINK_LIBS}/boost/boost-1.80.0/include/boost-1_80) +else() +include_directories( + /usr/include + /usr/include/x86_64-linux-gnu + /usr/lib/gcc/x86_64-w64-mingw32/10-win32/include + # later: include_directories("${PROJECTGROUP_SOURCE_DIR}/output/include") + include_directories("${PROJECTGROUP_SOURCE_DIR}/output/src/boost_1_80_0") +) + +endif() +####################################################################### + # list(APPEND XCSOAR_LINK_LIBRARIES + set(BASIC_LINK_LIBRARIES + msimg32 + winmm + # dl + pthread + stdc++ + user32 + gdi32 + gdiplus + ws2_32 + mswsock + kernel32 + # ?? msvcrt32 + shell32 + gcc_s + ) + +set(MINGW ON) +add_compile_definitions(__MINGW__) +#******************************************************************************** +if(AUGUST_SPECIAL) + add_compile_definitions(_AUG_MGW=1) +endif() +#******************************************************************************** +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") +set(CMAKE_CXX_STANDARD_LIBRARIES "-static-libgcc -static-libstdc++ -m64 -lwsock32 -lws2_32 -lgdi32 -lgdiplus -lcrypt32 ${CMAKE_CXX_STANDARD_LIBRARIES}") +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static -static-libstdc++ -Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive -v") + +if (${CMAKE_HOST_SYSTEM_NAME} STREQUAL Windows) + set(SSL_LIB) + set(CRYPTO_LIB Crypt32.lib BCrypt.lib) # no (OpenSSL-)crypto lib on windows! +endif() + +set(PERCENT_CHAR \%) +set(DOLLAR_CHAR $$) + +# if(EXISTS "D:/Programs") # on Windows - and on Flaps6 (August2111) +if (${CMAKE_HOST_SYSTEM_NAME} STREQUAL Windows) + list(APPEND CMAKE_PROGRAM_PATH "D:/Programs") +endif() diff --git a/build/cmake/WinClang.cmake b/build/cmake/WinClang.cmake new file mode 100644 index 00000000000..f5b8bcd68f6 --- /dev/null +++ b/build/cmake/WinClang.cmake @@ -0,0 +1,97 @@ +set(TARGET_NAME "XCSoarAug-Clang") # hardcoded + +message(STATUS "+++ System = WIN32 / Clang!") + +if(NOT TOOLCHAIN) +# set(TOOLCHAIN clang14) +endif() + +include_directories(D:/Programs/LLVM/${TOOLCHAIN}/include) + +# include_directories(D:/Programs/Android/android-ndk-r25b/sources/cxx-stl/llvm-libc++/include) +# include_directories(D:/Programs/Android/android-ndk-r25b/sources/cxx-stl/system/include) + +# include_directories(D:/Programs/LLVM/${TOOLCHAIN}/lib/clang/${TOOLCHAIN}.0.7/include) + +### message(FATAL_ERROR "Das ist WinClang!!!!") + +set(LIB_PREFIX "lib") +set(LIB_SUFFIX ".a") +# add_compile_definitions(BOOST_ASIO_SEPARATE_COMPILATION) +add_compile_definitions(BOOST_ASIO_SEPARATE_COMPILATION) +add_compile_definitions(BOOST_JSON_HEADER_ONLY) +add_compile_definitions(BOOST_JSON_STANDALONE) +add_compile_definitions(BOOST_MATH_DISABLE_DEPRECATED_03_WARNING=ON) + +add_compile_definitions(__CLANG__) +add_compile_definitions(_WIN32) # this should be by default? +# add_compile_definitions(HAVE_MSVCRT) +add_compile_definitions(_UNICODE) +add_compile_definitions(UNICODE) # ??? +add_compile_definitions(STRICT) +add_compile_definitions(_USE_MATH_DEFINES) # necessary under C++17! +# add_compile_definitions(USE_WIN32_RESOURCES) + +# add_compile_options(-v) # verbose compiler messages + +# +add_compile_options(-fcoroutines-ts) +# add_compile_options(-fcoroutines) +## add_compile_options(-fconserve-space) +## add_compile_options(-fno-operator-names) + +# gibt es nicht mehr: --- include_directories("${PROJECTGROUP_SOURCE_DIR}/temp/data") # temporary data! +if (ON OR WIN64) # momentan kein Flag verfügbar! + add_compile_definitions(WIN64) ## ???? + add_compile_definitions(_AMD64_) +else() + message(FATAL_ERROR "Error: WIN32 not implemented?") +endif() + +list(APPEND XCSOAR_LINK_LIBRARIES + wsock32 + ws2_32 + gdi32 + gdiplus + crypt32 +# winpthread +) +if (0) +list(APPEND XCSOAR_LINK_LIBRARIES + D:/Projects/link_libs/boost/boost-1.81.0/lib/clang15/libboost_container-clang15-mt-d-x64-1_81.lib + D:/Projects/link_libs/boost/boost-1.81.0/lib/clang15/libboost_json-clang15-mt-d-x64-1_81.lib +) +endif() + +add_compile_definitions(__CLANG__) + +add_compile_definitions(WIN32_LEAN_AND_MEAN) + # warning C4996: 'xxx': The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name: _wcsdup. See online help for details. + # xxx: wcscpy, wcsdup, strtok, strcpy, strdup, .... +add_compile_definitions(_CRT_SECURE_NO_WARNINGS) +add_compile_definitions(_CRT_NONSTDC_NO_DEPRECATE) +###### add_compile_definitions(__STDC_WANT_SECURE_LIB__=0) +###### add_compile_definitions(_CRT_SECURE_NO_DEPRECATE=0) +###### add_definitions(-Wdeprecated-declarations) +#******************************************************************************** +if(AUGUST_SPECIAL) + add_compile_definitions(_AUG_CLANG) + add_compile_definitions(__AUGUST__) +endif() +#******************************************************************************** +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_CXX_FLAGS}") +# list(APPEND CMAKE_CXX_FLAGS -msse4.1) +list(APPEND CMAKE_CXX_FLAGS -std=c++20) ## c++20 - only for cpp and not for c - "add_compile_options(-std=c++20)"! +# set(CMAKE_CXX_STANDARD_LIBRARIES "-static-libgcc -static-libstdc++ -m64 -lwsock32 -lws2_32 -lgdi32 -lgdiplus -lcrypt32 ${CMAKE_CXX_STANDARD_LIBRARIES}") +set(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIBRARIES} -m64") +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static -v") +# set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static -static-libstdc++ -Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive -v") +# list(APPEND CMAKE_EXE_LINKER_FLAGS -static -v) + + +set(SSL_LIB ) # no ssl lib on windows! == Use Schannel +set(CRYPTO_LIB Crypt32.lib BCrypt.lib) # no (OpenSSL-)crypto lib on windows! + +set(PERCENT_CHAR "%%" GLOBAL) +set(DOLLAR_CHAR "$$" GLOBAL) +### message(FATAL_ERROR "Stop clang") diff --git a/build/cmake/WinMSVC.cmake b/build/cmake/WinMSVC.cmake new file mode 100644 index 00000000000..78d3406759e --- /dev/null +++ b/build/cmake/WinMSVC.cmake @@ -0,0 +1,86 @@ +message(STATUS "+++ System = WIN32 / MSVC (${TOOLCHAIN})!") + +set(LIB_PREFIX "" ) # "lib") +set(LIB_SUFFIX ".lib") # "a") +# ??? add_compile_definitions(PROJECT_OUTPUT_FOLDER=${OUTPUT_FOLDER}) + +# only in DEBUG-Version--- +set(TARGET_IS_OPENVARIO ON) +# add special OpenVario functions +if (TARGET_IS_OPENVARIO) + add_compile_definitions(IS_OPENVARIO) +endif() +#------------------------------- +add_compile_definitions(__MSVC__) +#******************************************************************************** +set(AUGUST_SPECIAL ON) + +if(AUGUST_SPECIAL) + add_compile_definitions(__AUGUST__=1) + add_compile_definitions(_AUG_MSC) +endif() +#******************************************************************************** + +## add_compile_definitions(_UNICODE) +## add_compile_definitions(UNICODE) # ??? + +add_compile_definitions(NO_ERROR_CHECK) # EnumBitSet funktioniert m.E. noch nicht korrekt!!!! +add_compile_definitions(WIN32_LEAN_AND_MEAN) + # warning C4996: 'xxx': The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name: _wcsdup. See online help for details. + # xxx: wcscpy, wcsdup, strtok, strcpy, strdup, .... +add_compile_definitions(_CRT_SECURE_NO_WARNINGS) +add_compile_definitions(_SCL_SECURE_NO_WARNINGS) +# add_compile_definitions(/std:c++20) +# add_definitions(/std:c++20) +add_compile_options(/std:c++20) +add_compile_options(/Zc:__cplusplus) +add_compile_options(/utf-8) +#add_compile_definitions(/Zc:__cplusplus) +#add_compile_definitions(/utf-8) +# add_definitions(/Zc:wchar_t) + +# Disabling Warnings: +add_compile_options(/wd5030) +add_compile_options(/wd4455) # "suffix warning?" +add_compile_options(/wd4805) # "|": unsichere Kombination von Typ "bool" mit Typ "int" in einer Operation + + +add_compile_definitions(BOOST_ASIO_SEPARATE_COMPILATION) +add_compile_definitions(BOOST_JSON_HEADER_ONLY) +add_compile_definitions(BOOST_JSON_STANDALONE) +add_compile_definitions(BOOST_MATH_DISABLE_DEPRECATED_03_WARNING=ON) + +if (ON OR WIN64) # momentan kein Flag für 64bit verfügbar! + add_compile_definitions(WIN64) + add_compile_definitions(_AMD64_) +else() + message(FATAL_ERROR "Error: WIN32 not implemented?") +endif() +# set(FREEGLUT_LIB_DIR "${LINK_LIBS}/freeglut-MSVC-3.0.0-2/freeglut") +# set(SODIUM_LIB "${LINK_LIBS}/libsodium/x64/Release/v142/static/libsodium.lib") +add_compile_definitions(SODIUM_STATIC=1) # MSCV only... + +# see below add_compile_definitions(CURL_STATICLIB) +add_compile_definitions(LDAP_STATICLIB) + +set(BASIC_LINK_LIBRARIES + msimg32.lib + winmm.lib + ws2_32.lib + gdiplus +) + +set(SSL_LIB ) # no ssl lib on windowsfor curl necessary! +set(CRYPTO_LIB Crypt32.lib BCrypt.lib) + +set(USE_MEMORY_CANVAS OFF) + +set(PERCENT_CHAR %%) +set(DOLLAR_CHAR \$) + + +if(EXISTS "D:/Programs") # on Windows only - and at Flaps6 (August2111) + list(APPEND CMAKE_PROGRAM_PATH "D:/Programs") +else() + list(APPEND CMAKE_PROGRAM_PATH "C:/Program Files") +endif() diff --git a/build/cmake/WinMinGW.cmake b/build/cmake/WinMinGW.cmake new file mode 100644 index 00000000000..72eb264b86d --- /dev/null +++ b/build/cmake/WinMinGW.cmake @@ -0,0 +1,84 @@ +set(TARGET_NAME "XCSoarAug-MinGW") # hardcoded yet + +message(STATUS "+++ System = WIN32 / MinGW (${TOOLCHAIN}) on ${CMAKE_HOST_SYSTEM_NAME} !!!") + +set(LIB_PREFIX "lib" ) # "lib") +set(LIB_SUFFIX ".a") # "a") + +add_compile_definitions(BOOST_ASIO_SEPARATE_COMPILATION) +add_compile_definitions(BOOST_MATH_DISABLE_DEPRECATED_03_WARNING=ON) + # add_compile_definitions(HAVE_MSVCRT) +add_compile_definitions(_UNICODE) +add_compile_definitions(UNICODE) # ??? +add_compile_definitions(STRICT) +add_compile_definitions(_USE_MATH_DEFINES) # necessary under C++17! +## add_compile_definitions(ZZIP_1_H) # definition of uint32_t and Co.! +# string(APPEND CMAKE_CXX_FLAGS " -Og -funit-at-a-time -ffast-math -g -std=c++20 -fno-threadsafe-statics -fmerge-all-constants -fcoroutines -fconserve-space -fno-operator-names -fvisibility=hidden -finput-charset=utf-8 -Wall -Wextra -Wwrite-strings -Wcast-qual -Wpointer-arith -Wsign-compare -Wundef -Wmissing-declarations -Wredundant-decls -Wmissing-noreturn -Wvla -Wno-format-truncation -Wno-missing-field-initializers -Wcast-align -Werror -I./src/unix -I./_build/include -isystem /home/august/Projects/link_libs/boost/boost-1.80.0 ") +# string(APPEND CMAKE_CXX_FLAGS " -c -Og -funit-at-a-time -ffast-math -g -std=c++20 -fno-threadsafe-statics -fmerge-all-constants -fcoroutines -fconserve-space -fno-operator-names -finput-charset=utf-8 -Wall -Wextra -Wwrite-strings -Wcast-qual -Wpointer-arith -Wsign-compare -Wundef -Wmissing-declarations -Wredundant-decls -Wmissing-noreturn -Wvla -Wno-format-truncation -Wno-missing-field-initializers -Wcast-align -Werror -m64 -mwin32 -mwindows -mms-bitfields") +add_compile_options(/std:c++20) +add_compile_options(-fcoroutines) +add_compile_options(-Wcpp) + +# string(APPEND CMAKE_CXX_FLAGS " -std=c++20") # C++20 +# string(APPEND CMAKE_CXX_FLAGS " -fcoroutines") # use CoRoutines +# string(APPEND CMAKE_CXX_FLAGS " -Wcpp") # disable the warning 'Please include winsock2.h before windows.h' +add_compile_options(-v) # add_definitions(-v) + +if (${CMAKE_HOST_SYSTEM_NAME} STREQUAL Windows) + include_directories("D:/Programs/MinGW/${TOOLCHAIN}/include") + # later: include_directories("${PROJECTGROUP_SOURCE_DIR}/output/include") +endif() +####################################################################### +if(0) + list(APPEND XCSOAR_LINK_LIBRARIES + msimg32 + winmm + # dl + pthread + stdc++ + user32 + gdi32 + gdiplus + ws2_32 + mswsock + kernel32 + # ?? msvcrt32 + shell32 + gcc_s + ) +else() + list(APPEND XCSOAR_LINK_LIBRARIES + wsock32 + ws2_32 + gdi32 + gdiplus + crypt32 + winpthread + ) +endif() + +set(MINGW ON) +add_compile_definitions(__MINGW__) +#******************************************************************************** +if(AUGUST_SPECIAL) + add_compile_definitions(_AUG_MGW) +endif() +#******************************************************************************** +# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") +list (APPEND CMAKE_CXX_STANDARD_LIBRARIES -static-libgcc -static-libstdc++ -m64) +list (APPEND CMAKE_EXE_LINKER_FLAGS -static -static-libstdc++ -Wl,-Bstatic,--whole-archive -Wl,--no-whole-archive -v) +# set(CMAKE_CXX_STANDARD_LIBRARIES "-static-libgcc -static-libstdc++ -m64 -lwsock32 -lws2_32 -lgdi32 -lgdiplus -lcrypt32 ${CMAKE_CXX_STANDARD_LIBRARIES}") +# set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static -static-libstdc++ -Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive -v") + +if (${CMAKE_HOST_SYSTEM_NAME} STREQUAL Windows) + set(SSL_LIB) + set(CRYPTO_LIB Crypt32.lib BCrypt.lib) # no (OpenSSL-)crypto lib on windows! +endif() + +set(PERCENT_CHAR \%) +set(DOLLAR_CHAR $$) + +# if(EXISTS "D:/Programs") # on Windows - and on Flaps6 (August2111) +if (${CMAKE_HOST_SYSTEM_NAME} STREQUAL Windows) + list(APPEND CMAKE_PROGRAM_PATH "D:/Programs") +endif() diff --git a/build/cmake/opensoar.cmake b/build/cmake/opensoar.cmake new file mode 100644 index 00000000000..a051a139688 --- /dev/null +++ b/build/cmake/opensoar.cmake @@ -0,0 +1,4 @@ +set(DISPLAY_STRING "# OpenSoar CMake Macros and Functions") +message(STATUS "${DISPLAY_STRING}") +cmake_minimum_required(VERSION 3.15) + diff --git a/build/cmake/python/CMakeOpenSoar.py b/build/cmake/python/CMakeOpenSoar.py new file mode 100644 index 00000000000..dbb3dac3cfa --- /dev/null +++ b/build/cmake/python/CMakeOpenSoar.py @@ -0,0 +1,401 @@ +#!/usr/bin/env python3 + +import os, sys, subprocess + +Configuration = 'Release' +# Configuration = 'Debug' + +# Am 19.03.2020 aktuell! +# Am 16.04.2020 cmd2py angefangen! + +# if len(sys.argv) > 1: +# print(sys.argv[1]) +# os.chdir(sys.argv[1]) ## batch: cd /D %~dp0 +# print(os.getcwd()) +# else: +# print('No Parameter!') + +# my_env = [] # global! +# my_env = os.environ.copy() + +prev_batch = None +cmake_generator = None +program_dir = None +is_windows = False +build_system = 'unknown' +toolchain_file = None + +def gcc(toolchain, env): + global cmake_generator + global prev_batch + global program_dir + global toolchain_file + src_dir = os.getcwd() + if sys.platform.startswith('win'): + if toolchain == 'mingw' or toolchain.startswith('mgw'): + toolchain_file = src_dir.replace('\\','/') + '/build/cmake/toolchains/MinGW.toolchain' + # cmake_generator = '\"MinGW Makefiles\"' + print('src_dir = ',src_dir) + + cmake_generator = 'MinGW Makefiles' + return program_dir.replace('/', '\\') + '\\MinGW\\' + toolchain + '\\bin;' + env['PATH'] + else: + # cmake_generator ='Unix Makefiles' # normal Unix + cmake_generator ='Ninja' + env_path = env['PATH'] + return env_path + +def clang(toolchain, env): + global cmake_generator + global toolchain_file + + env_path = env['PATH'] + if sys.platform.startswith('win'): + # env_path = program_dir.replace('/', '\\') + '\\MinGW\\mgw122;' + env_path + # env_path = program_dir.replace('/', '\\') + '\\MinGW\\mgw122\\include;' + env_path + if toolchain == 'clangXX': + env_path = program_dir.replace('/', '\\') + '\\LLVM\\' + toolchain + '-llvm\\bin;' + env_path['PATH'] + #Android-Clang! + # env_path = program_dir.replace('/', '\\') + '\\LLVM\\clang14-android\\bin;' + env_path + # env_path = program_dir.replace('/', '\\') + '\\LLVM\\llvm\\bin;' + env_path + ### Android: env_path = program_dir + '/Android/android-ndk-r25b/toolchains/llvm/prebuilt/windows-x86_64/bin;' + env_path + # toolchain_file = src_dir.replace('\\','/') + '/build/cmake/toolchains/MinGW.toolchain' + elif toolchain == 'clang12': + # env_path = program_dir.replace('/', '\\') + '\\MinGW\\mgw112\\bin;' + env_path + env_path = program_dir.replace('/', '\\') + '\\LLVM\\' + toolchain + '\\bin;' + env_path # ['PATH'] + else: + env_path = program_dir.replace('/', '\\') + '\\LLVM\\' + toolchain + '\\bin;' + env_path # ['PATH'] + # env_path = program_dir.replace('/', '\\') + '\\MinGW\\mgw112\\bin;' + env_path + # toolchain_file = os.getcwd().replace('\\','/') + '/build/cmake/toolchains/Android/x86_64.toolchain' + toolchain_file = os.getcwd().replace('\\','/') + '/build/cmake/toolchains/WinClang.toolchain' + else: + env_path = env['PATH'] + # cmake_generator ='Unix Makefiles' + cmake_generator ='Ninja' + return env_path + +generator = { + 'mgw73' : 'MinGW Makefiles', + 'mgw82' : 'MinGW Makefiles', + 'mgw103' : 'MinGW Makefiles', + 'mgw112' : 'MinGW Makefiles', + 'mgw122' : 'MinGW Makefiles', + # 'ninja' : 'MinGW Makefiles', + 'ninja' : 'Ninja', + 'unix' : 'Unix Makefiles', + 'mingw' : 'MinGW Makefiles', + 'clang10' : 'Clang', + 'clang11' : 'Clang', + 'clang12' : 'Clang', + 'clang13' : 'Clang', + 'clang14' : 'Clang', + 'clang15' : 'Clang', + 'clang16' : 'Clang', + 'msvc2015' : 'Visual Studio 14', + 'msvc2017' : 'Visual Studio 15', + 'msvc2019' : 'Visual Studio 16', + 'msvc2022' : 'Visual Studio 17', +} + +def visual_studio(toolchain, env): + global prev_batch, cmake_generator + #prev_batch = 'C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/VC/Auxiliary/Build/vcvars64.bat' + if toolchain == 'msvc2022': + prev_batch = program_dir + '/Microsoft Visual Studio/2022/Preview/VC/Auxiliary/Build/vcvars64.bat' + else: + print('wrong toolchain: ', toolchain, '!') + exit(1) + cmake_generator = generator[toolchain] + # cmake_generator ='Visual Studio 16' + return env['PATH'] + + # map the inputs to the function blocks +compiler_setup = { + 'mgw73' : gcc, + 'mgw82' : gcc, + 'mgw103' : gcc, + 'mgw112' : gcc, + 'mgw122' : gcc, + # 'ninja' : gcc, + 'ninja' : clang, + 'unix' : gcc, + 'mingw' : gcc, + 'clang10' : clang, + 'clang11' : clang, + 'clang12' : clang, + 'clang13' : clang, + 'clang14' : clang, + 'clang15' : clang, + 'clang16' : clang, + 'msvc2015' : visual_studio, + 'msvc2017' : visual_studio, + 'msvc2019' : visual_studio, + 'msvc2022' : visual_studio, +} + +def create_opensoar(args): + #Current directory: + global program_dir + global is_windows + is_windows = False + + filename = sys.argv[0] + project_name = args[0] + branch = args[1] + toolchain = args[2] + + start_dir = os.path.dirname(filename) + if len(start_dir) > 0: + start_dir = start_dir.replace('build/cmake/python', ''); + if len(start_dir) == 0: + # start_dir = '' + start_dir = os.getcwd(); + # print('Filename: ', filename) + # print('Start CMake Creation of ', project_name, ' / ', branch, ' / ', toolchain) + print('Start CMake Creation of ', project_name, ' / ', branch, ' / ', toolchain) + print('====================================\n') + print('CurrDir :',os.getcwd()) + print('StartDir :',start_dir) +# os.chdir(start_dir) +# print('CurrDir :',os.getcwd()) + + my_env = os.environ.copy() + creation = 15 + if len(sys.argv) > 3: + creation = int(sys.argv[3]) + # creation = 14 # ohne CMake! + verbose = creation & 0x100 + print('creation-flag = ', str(creation)) # ohne CMake! + ### verbose = True + if True: # False: # + i = 0 + for arg in args: # sys.argv: + print(i, ': ', arg) + i = i + 1 + if verbose: + print('Debug-Stop') + input("Press Enter to continue...") + + if sys.platform.startswith('win'): + is_windows = True + project_dir = 'D:/Projects' + program_dir = 'D:/Programs' + # not necessary ?! install_bindir = 'bin' + # src_dir = start_dir # changed 05.12.2022 + # ATTENTION: this isn't finished yet!!! + src_dir = start_dir # changed 05.12.2022 + if branch: + binary_dir= project_dir + '/Binaries/OpenSoar/' + branch # changed 10.01.2023 + else: + binary_dir= project_dir + '/Binaries/OpenSoar/build' # changed 10.01.2023 + link_libs = project_dir + '/link_libs' # Windows on August2111/Flaps6!!! + # build_dir = binary_dir + '/'+ project_name + '/' + branch + '/' + toolchain + build_dir = binary_dir + '/'+ toolchain + + + # TODO(August2111): delete: third_party = binary_dir + 'D:/Projects/3rd_Party' # Windows! + third_party = binary_dir + '/3rd_Party' # Windows! + install_dir = program_dir + '/Install/' + project_name + else: + src_dir = start_dir + root_dir = my_env['HOME'] + project_dir = root_dir + '/Projects' + # program_dir = '/usr/bin' + # program_dir = '/usr/local/bin' + program_dir = root_dir + '/Programs' + # binary_dir = project_dir + '/Binaries' + binary_dir= start_dir + '/_build' # new from 02.02.2021, simular to OpenSoar upstream + # build_dir = binary_dir + '/'+ project_name+ '/' + toolchain + build_dir = binary_dir + '/'+ toolchain + link_libs = project_dir + '/link_libs' + # third_party = project_dir + '/3rd_Party' + third_party = binary_dir + '/3rd_Party' # Windows! + install_dir = program_dir + '/Install/' + project_name + + toolset = None + + python_exe = '' + try: + myprocess = subprocess.Popen(['python', '--version'], env = my_env) + myprocess.wait() + python_exe = 'python' + except: + print('"python" not callable') + try: + myprocess = subprocess.Popen(['python3', '--version'], env = my_env) + myprocess.wait() + python_exe = 'python3' + except: + print('"python3" not callable') + + if sys.platform.startswith('win'): + cmake_exe = (program_dir + '/CMake/bin/') + 'cmake.exe' + my_env['PATH'] = (program_dir + '/CMake/bin;').replace('/', '\\') + my_env['PATH'] + else: + cmake_exe = 'cmake' + + # wget https://github.com/Kitware/CMake/releases/download/v3.17.2/cmake-3.17.2.tar.gz + + try: + myprocess = subprocess.Popen([cmake_exe, '--version'], env = my_env) + myprocess.wait() + except: + print('"cmake" not callable!') + creation = 0 + + if not os.path.exists(build_dir): + os.makedirs(build_dir) + creation = creation | 1 + + my_env['PATH'] = compiler_setup[toolchain](toolchain, my_env) + print(my_env['PATH']) + + # compiler_setup[args[1]](args[1], my_env['PATH']) + + print('Creation-Flag: ', creation) + if prev_batch: + print(prev_batch) + #======================================================================== + if creation & 1: + print('Python Step 1 - Configure CMake') + if os.path.isfile(build_dir+ '/CMakeCache.txt'): + os.remove(build_dir+ '/CMakeCache.txt') + arguments = [] + # if prev_batch: + # arguments.append(prev_batch) + # arguments.append(' & ') + arguments.append(cmake_exe) + # if toolchain in ['clang10']: ## Clang! + # my_env['PATH'] = program_dir + '/llvm/bin;' ## Clang! + # my_env['PATH'] = my_env['PATH'] + program_dir + '/CMake/bin;' ## Clang! + # arguments.append(cmake_exe) # 'cmake') + # arguments.append('-H.') ## Clang! + arguments.append('-S') + arguments.append(src_dir) # curr_dir.replace('\\', '/')) + arguments.append('-B') + arguments.append(build_dir) + arguments.append('-G') + arguments.append(cmake_generator) + arguments.append('--debug-trycompile') + + if is_windows and toolchain.startswith('clang'): + compiler = toolchain + if is_windows and toolchain == 'ninja': + toolchain = 'clang15' + compiler = toolchain + + print('---') + if is_windows: + print('!!! COMPUTERNAME = ', my_env['COMPUTERNAME'], ', USERNAME = ', my_env['USERNAME'], '!!!') + if toolchain_file: + # input('Toolchain file: ', toolchain_file) + arguments.append('-DCMAKE_TOOLCHAIN_FILE:PATH=' + toolchain_file) + # if toolchain.starts('clang) + if build_system.startswith('android'): # build_system gibt es momentan noch nicht! + arguments.append('-DCMAKE_TOOLCHAIN_FILE:PATH=\"' + program_dir + '/Android/android-ndk-r25b/build/cmake/android.toolchain.cmake\"') + # else: arguments.append('-DCMAKE_TOOLCHAIN_FILE:PATH=\"' + src_dir.replace('\\','/') + '/.august/toolchains/mscv2019.toolchain\"') + else: + if toolchain == 'mingw': + arguments.append('-DCMAKE_TOOLCHAIN_FILE:PATH=' + src_dir.replace('\\','/') + '/build/cmake/toolchains/MinGW.toolchain') + else: + arguments.append('-DCMAKE_TOOLCHAIN_FILE:PATH=' + src_dir.replace('\\','/') + '/build/cmake/toolchains/LinuxGCC.toolchain') + print('!!! USER = ', my_env['USER'], '!!!') + + arguments.append('-DTOOLCHAIN=' + toolchain) + arguments.append('-DTHIRD_PARTY=' + third_party) + arguments.append('-DLINK_LIBS=' + link_libs) + arguments.append('-Wno-dev') + + arguments.append('-DCMAKE_INSTALL_PREFIX=' + install_dir) + if not toolset is None: + arguments.append('-T' + toolset) + ### arguments.append('-DCMAKE_INSTALL_BINDIR=' + install_bindir) + + ### try: + ### for cmake_def in project["cmake_definitions"]: + ### arguments.append(cmake_def) + ### except: + ### pass + + myprocess = subprocess.Popen(arguments, env = my_env, shell = False) + myprocess.wait() + if myprocess.returncode != 0: + creation = 0 + print('cmd with failure! (', myprocess, ')') + else: + if verbose: + print('Debug-Stop') + input("Press Enter to continue...") + + #======================================================================== + if creation & 2: + print('Python Step 2 - Build with cmake') + print('--------------------------------') + arguments = [] + arguments.append(cmake_exe) # 'cmake') + arguments.append('--build') + arguments.append(build_dir) + # if toolchain.startswith('msvc') or toolchain.startswith('mgw'): + arguments.append('--config') + arguments.append(Configuration) + # if False: # toolchain MinGW/GCC... + if not toolchain.startswith('msvc'): + #if not (toolchain.startswith('msvc') or toolchain.startswith('clang')): + arguments.append('--') # nachfolgende Befehle werden zum Build tool durchgereicht + arguments.append('-j') + arguments.append('8') # jobs... + myprocess = subprocess.Popen(arguments, env = my_env, shell = False) + myprocess.wait() + if myprocess.returncode != 0: + creation = 0 + print('cmd: (', arguments, ')') + print('cmd with failure! (', myprocess, ')') + else: + if verbose: + print('Debug-Stop') + input("Press Enter to continue...") + + #======================================================================== + if creation & 0x04: + print('Python Step 3 - Install') + arguments = [] + arguments.append(cmake_exe) # 'cmake') + arguments.append('--install') + arguments.append(build_dir) + myprocess = subprocess.Popen(arguments, env = my_env, shell = False) + myprocess.wait() + if myprocess.returncode != 0: + creation = 0 + print('cmd with failure! (', myprocess, ')') + else: + if verbose: + print('Debug-Stop') + input("Press Enter to continue...") + + #======================================================================== + if creation & 0x08: # ==>Run + print('Python Step 4 - Execute OpenSoar') + if toolchain.startswith('msvc'): + build_dir = build_dir + '/'+ Configuration + opensoar_app = project_name + '-MSVC.exe' + opensoar_app = project_name + '.exe' # jetzt so... + elif toolchain.startswith('mgw'): + opensoar_app = project_name + '-MinGW.exe' + opensoar_app = 'XCSoarAug-MinGW.exe' + elif toolchain.startswith('clang'): + opensoar_app = project_name + '-Clang.exe' + + arguments = [build_dir + '/' + opensoar_app, '-1400x700', '-fly', '-profile=D:/Data/OpenSoarData/August.prf', '-datapath=D:/Data/OpenSoarData'] + if not os.path.exists(arguments[0]): + print("App '", arguments[0], "' doesn't exist!") + creation = 0 + else: + # print('Command 4: ', arguments) + myprocess = subprocess.Popen(arguments, env = my_env, shell = False) + myprocess.wait() + if myprocess.returncode != 0: + creation = 0 + print('cmd with failure! (', myprocess, ')') + + if(not creation): + input('Error in cmake python script') diff --git a/build/cmake/python/CMakeXCSoar.py b/build/cmake/python/CMakeXCSoar.py new file mode 100644 index 00000000000..4db4733bffa --- /dev/null +++ b/build/cmake/python/CMakeXCSoar.py @@ -0,0 +1,384 @@ +#!/usr/bin/env python3 + +import os, sys, subprocess + +# Am 19.03.2020 aktuell! +# Am 16.04.2020 cmd2py angefangen! + +# if len(sys.argv) > 1: +# print(sys.argv[1]) +# os.chdir(sys.argv[1]) ## batch: cd /D %~dp0 +# print(os.getcwd()) +# else: +# print('No Parameter!') + +# my_env = [] # global! +# my_env = os.environ.copy() + +prev_batch = None +cmake_generator = None +program_dir = None +is_windows = False +build_system = 'unbekannt' +toolchain_file = None + +def gcc(toolchain, env): + global cmake_generator + global prev_batch + global program_dir + global toolchain_file + src_dir = 'D:/Projects/XCSoar/XCSoar' + if sys.platform.startswith('win'): + if toolchain == 'mingw' or toolchain.startswith('mgw'): + toolchain_file = src_dir.replace('\\','/') + '/build/cmake/toolchains/MinGW.toolchain' + # cmake_generator = '\"MinGW Makefiles\"' + cmake_generator = 'MinGW Makefiles' + return program_dir.replace('/', '\\') + '\\MinGW\\' + toolchain + '\\bin;' + env['PATH'] + else: + # cmake_generator ='Unix Makefiles' # normal Unix + cmake_generator ='Ninja' + env_path = env['PATH'] + return env_path + +def clang(toolchain, env): + global cmake_generator + + env_path = env['PATH'] + if sys.platform.startswith('win'): + # env_path = program_dir.replace('/', '\\') + '\\MinGW\\mgw122;' + env_path + # env_path = program_dir.replace('/', '\\') + '\\MinGW\\mgw122\\include;' + env_path + env_path = program_dir.replace('/', '\\') + '\\LLVM\\' + toolchain + '\\bin;' + env_path + #Android-Clang! +# env_path = program_dir.replace('/', '\\') + '\\LLVM\\clang14-android\\bin;' + env_path +# env_path = program_dir.replace('/', '\\') + '\\LLVM\\llvm\\bin;' + env_path + # program_dir + '/Android/android-ndk-r25b/toolchains/llvm/prebuilt/windows-x86_64/bin' + else: + env_path = env['PATH'] + # cmake_generator ='Unix Makefiles' + cmake_generator ='Ninja' + return env_path + +generator = { + 'mgw73' : 'MinGW Makefiles', + 'mgw82' : 'MinGW Makefiles', + 'mgw103' : 'MinGW Makefiles', + 'mgw112' : 'MinGW Makefiles', + 'mgw122' : 'MinGW Makefiles', + # 'ninja' : 'MinGW Makefiles', + 'ninja' : 'Ninja', + 'unix' : 'Unix Makefiles', + 'mingw' : 'MinGW Makefiles', + 'clang10' : 'Clang', + 'clang11' : 'Clang', + 'clang12' : 'Clang', + 'clang13' : 'Clang', + 'clang14' : 'Clang', + 'clang15' : 'Clang', + 'msvc2015' : 'Visual Studio 14', + 'msvc2017' : 'Visual Studio 15', + 'msvc2019' : 'Visual Studio 16', + 'msvc2022' : 'Visual Studio 17', +} + +def visual_studio(toolchain, env): + global prev_batch, cmake_generator + #prev_batch = 'C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/VC/Auxiliary/Build/vcvars64.bat' + if toolchain == 'msvc2022': + prev_batch = program_dir + '/Microsoft Visual Studio/2022/Preview/VC/Auxiliary/Build/vcvars64.bat' + else: + print('wrong toolchain: ', toolchain, '!') + exit(1) + cmake_generator = generator[toolchain] + # cmake_generator ='Visual Studio 16' + return env['PATH'] + + # map the inputs to the function blocks +compiler_setup = { + 'mgw73' : gcc, + 'mgw82' : gcc, + 'mgw103' : gcc, + 'mgw112' : gcc, + 'mgw122' : gcc, + # 'ninja' : gcc, + 'ninja' : clang, + 'unix' : gcc, + 'mingw' : gcc, + 'clang10' : clang, + 'clang11' : clang, + 'clang12' : clang, + 'clang13' : clang, + 'clang14' : clang, + 'clang15' : clang, + 'msvc2015' : visual_studio, + 'msvc2017' : visual_studio, + 'msvc2019' : visual_studio, + 'msvc2022' : visual_studio, +} + +def create_xcsoar(args): + #Current directory: + global program_dir + global is_windows + is_windows = False + + filename = sys.argv[0] + project_name = args[0] + branch = args[1] + toolchain = args[2] + + start_dir = os.path.dirname(filename) + if len(start_dir) > 0: + start_dir = start_dir.replace('build/cmake/python', ''); + if len(start_dir) == 0: + # start_dir = '' + start_dir = os.getcwd(); + # print('Filename: ', filename) # 'CMakeXCSoar_Flaps5.py') + # print('Start CMake Creation of ', project_name, ' / ', branch, ' / ', toolchain) + print('Start CMake Creation of ', project_name, ' / ', branch, ' / ', toolchain) + print('====================================\n') + print('CurrDir :',os.getcwd()) + print('StartDir :',start_dir) +# os.chdir(start_dir) +# print('CurrDir :',os.getcwd()) + + my_env = os.environ.copy() + creation = 15 + if len(sys.argv) > 3: + creation = int(sys.argv[3]) + # creation = 14 # ohne CMake! + verbose = creation & 0x100 + print('creation-flag = ', str(creation)) # ohne CMake! + ### verbose = True + if True: # False: # + i = 0 + for arg in args: # sys.argv: + print(i, ': ', arg) + i = i + 1 + if verbose: + print('Debug-Stop') + input("Press Enter to continue...") + + if sys.platform.startswith('win'): + is_windows = True + project_dir = 'D:/Projects' + program_dir = 'D:/Programs' + # not necessary ?! install_bindir = 'bin' + # src_dir = start_dir # changed 05.12.2022 + start_dir = project_dir + '/XCSoar/XCSoar' # changed 05.12.2022 + src_dir = start_dir # changed 05.12.2022 + ## binary_dir= start_dir + '/output' # new from 02.02.2021, simular to XCSoar upstream + binary_dir= start_dir + '/_build' # changed 05.12.2022 + if branch: + binary_dir= project_dir + '/Binaries/XCSoar/' + branch # changed 10.01.2023 + else: + binary_dir= project_dir + '/Binaries/XCSoar/build' # changed 10.01.2023 + link_libs = project_dir + '/link_libs' # Windows on August2111/Flaps6!!! + # build_dir = binary_dir + '/'+ project_name + '/' + branch + '/' + toolchain + build_dir = binary_dir + '/'+ toolchain + + + # TODO(August2111): delete: third_party = binary_dir + 'D:/Projects/3rd_Party' # Windows! + third_party = binary_dir + '/3rd_Party' # Windows! + install_dir = program_dir + '/Install/' + project_name + else: + src_dir = start_dir + root_dir = my_env['HOME'] + project_dir = root_dir + '/Projects' + # program_dir = '/usr/bin' + # program_dir = '/usr/local/bin' + program_dir = root_dir + '/Programs' + # binary_dir = project_dir + '/Binaries' + binary_dir= start_dir + '/_build' # new from 02.02.2021, simular to XCSoar upstream + # build_dir = binary_dir + '/'+ project_name+ '/' + toolchain + build_dir = binary_dir + '/'+ toolchain + link_libs = project_dir + '/link_libs' + # third_party = project_dir + '/3rd_Party' + third_party = binary_dir + '/3rd_Party' # Windows! + install_dir = program_dir + '/Install/' + project_name + + toolset = None + + python_exe = '' + try: + myprocess = subprocess.Popen(['python', '--version'], env = my_env) + myprocess.wait() + python_exe = 'python' + except: + print('"python" not callable') + try: + myprocess = subprocess.Popen(['python3', '--version'], env = my_env) + myprocess.wait() + python_exe = 'python3' + except: + print('"python3" not callable') + + if sys.platform.startswith('win'): + cmake_exe = (program_dir + '/CMake/bin/') + 'cmake.exe' + my_env['PATH'] = (program_dir + '/CMake/bin;').replace('/', '\\') + my_env['PATH'] + else: + cmake_exe = 'cmake' + + # wget https://github.com/Kitware/CMake/releases/download/v3.17.2/cmake-3.17.2.tar.gz + + try: + myprocess = subprocess.Popen([cmake_exe, '--version'], env = my_env) + myprocess.wait() + except: + print('"cmake" not callable!') + creation = 0 + + if not os.path.exists(build_dir): + os.makedirs(build_dir) + creation = creation | 1 + + my_env['PATH'] = compiler_setup[toolchain](toolchain, my_env) + print(my_env['PATH']) + + # compiler_setup[args[1]](args[1], my_env['PATH']) + + print('Creation-Flag: ', creation) + if prev_batch: + print(prev_batch) + #======================================================================== + if creation & 1: + print('Python Step 1 - Configure CMake') + if os.path.isfile(build_dir+ '/CMakeCache.txt'): + os.remove(build_dir+ '/CMakeCache.txt') + arguments = [] + # if prev_batch: + # arguments.append(prev_batch) + # arguments.append(' & ') + arguments.append(cmake_exe) + # if toolchain in ['clang10']: ## Clang! + # my_env['PATH'] = program_dir + '/llvm/bin;' ## Clang! + # my_env['PATH'] = my_env['PATH'] + program_dir + '/CMake/bin;' ## Clang! + # arguments.append(cmake_exe) # 'cmake') + # arguments.append('-H.') ## Clang! + arguments.append('-S') + arguments.append(src_dir) # curr_dir.replace('\\', '/')) + arguments.append('-B') + arguments.append(build_dir) + arguments.append('-G') + arguments.append(cmake_generator) + arguments.append('--debug-trycompile') + + if is_windows and toolchain.startswith('clang'): + compiler = toolchain + if is_windows and toolchain == 'ninja': + toolchain = 'clang15' + compiler = toolchain + + print('---') + if is_windows: + print('!!! COMPUTERNAME = ', my_env['COMPUTERNAME'], ', USERNAME = ', my_env['USERNAME'], '!!!') + if toolchain_file: + # input('Toolchain file: ', toolchain_file) + arguments.append('-DCMAKE_TOOLCHAIN_FILE:PATH=' + toolchain_file) + # if toolchain.starts('clang) + if build_system.startswith('android'): # build_system gibt es momentan nocjh nicht! + arguments.append('-DCMAKE_TOOLCHAIN_FILE:PATH=\"' + program_dir + '/Android/android-ndk-r25b/build/cmake/android.toolchain.cmake\"') + # else: arguments.append('-DCMAKE_TOOLCHAIN_FILE:PATH=\"' + src_dir.replace('\\','/') + '/.august/toolchains/mscv2019.toolchain\"') + else: + if toolchain == 'mingw': + arguments.append('-DCMAKE_TOOLCHAIN_FILE:PATH=' + src_dir.replace('\\','/') + '/build/cmake/toolchains/MinGW.toolchain') + else: + arguments.append('-DCMAKE_TOOLCHAIN_FILE:PATH=' + src_dir.replace('\\','/') + '/build/cmake/toolchains/LinuxGCC.toolchain') + print('!!! USER = ', my_env['USER'], '!!!') + + arguments.append('-DTOOLCHAIN=' + toolchain) + arguments.append('-DTHIRD_PARTY=' + third_party) + arguments.append('-DLINK_LIBS=' + link_libs) + arguments.append('-Wno-dev') + + arguments.append('-DCMAKE_INSTALL_PREFIX=' + install_dir) + if not toolset is None: + arguments.append('-T' + toolset) + ### arguments.append('-DCMAKE_INSTALL_BINDIR=' + install_bindir) + + ### try: + ### for cmake_def in project["cmake_definitions"]: + ### arguments.append(cmake_def) + ### except: + ### pass + + myprocess = subprocess.Popen(arguments, env = my_env, shell = False) + myprocess.wait() + if myprocess.returncode != 0: + creation = 0 + print('cmd with failure! (', myprocess, ')') + else: + if verbose: + print('Debug-Stop') + input("Press Enter to continue...") + + #======================================================================== + if creation & 2: + print('Python Step 2 - Build with cmake') + arguments = [] + arguments.append(cmake_exe) # 'cmake') +# arguments.append('-S') +# arguments.append(src_dir) + arguments.append('--build') + arguments.append(build_dir) + arguments.append('--config') + arguments.append('Release') + # if False: # toolchain MinGW/GCC... + if not toolchain.startswith('msvc'): + arguments.append('--') # nachfolgende Befehle werden zum Build tool durchgereicht + arguments.append('-j') + arguments.append('8') # jobs... + myprocess = subprocess.Popen(arguments, env = my_env, shell = False) + myprocess.wait() + if myprocess.returncode != 0: + creation = 0 + print('cmd with failure! (', myprocess, ')') + else: + if verbose: + print('Debug-Stop') + input("Press Enter to continue...") + + #======================================================================== + if creation & 0x04: + print('Python Step 3 - Install') + arguments = [] + arguments.append(cmake_exe) # 'cmake') + arguments.append('--install') + arguments.append(build_dir) + myprocess = subprocess.Popen(arguments, env = my_env, shell = False) + myprocess.wait() + if myprocess.returncode != 0: + creation = 0 + print('cmd with failure! (', myprocess, ')') + else: + if verbose: + print('Debug-Stop') + input("Press Enter to continue...") + + #======================================================================== + if creation & 0x08: # ==>Run + print('Python Step 4 - Execute XCSoar') + if toolchain.startswith('msvc'): + build_dir = build_dir + '/Release' + # build_dir = build_dir + '/Debug' + xcsoar_app = project_name + '-MSVC.exe' + elif toolchain.startswith('mgw'): + xcsoar_app = project_name + '-MinGW.exe' + elif toolchain.startswith('clang'): + xcsoar_app = project_name + '-Clang.exe' + + # XCSoarAug-MinGW.exe -1400x700' -fly -profile=D:\Data\XCSoarData\August.prf -datapath=D:/XCSoarData/Data + arguments = [build_dir + '/' + xcsoar_app, '-1400x700', '-fly', '-profile=D:/Data/OpenSoarData/August.prf', '-datapath=D:/Data/OpenSoarData'] + # arguments = [build_dir + '/' + xcsoar_app, '-1400x700', '-fly', '-profile=D:/Data/OpenSoarData/August2.prf', '-datapath=D:/Data/OpenSoarData'] + # arguments = [build_dir + '/' + xcsoar_app, '-1400x700', '-fly', '-profile=August5.prf'] + if not os.path.exists(arguments[0]): + print("App 'arguments[0]' doesn't exist!") + else: + # print('Command 4: ', arguments) + myprocess = subprocess.Popen(arguments, env = my_env, shell = False) + myprocess.wait() + if myprocess.returncode != 0: + creation = 0 + print('cmd with failure! (', myprocess, ')') + + if(not creation): + input('Error in cmake python script') \ No newline at end of file diff --git a/build/cmake/python/Start-CMake-OpenSoar.py b/build/cmake/python/Start-CMake-OpenSoar.py new file mode 100644 index 00000000000..a211899ab97 --- /dev/null +++ b/build/cmake/python/Start-CMake-OpenSoar.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python3 + +import os, sys +from CMakeOpenSoar import create_opensoar + +# ==================== +# ==================== +branch = 'dev-branch' +# ==================== +# ==================== + + +class ComputerDirectories(object): + def __init__(self, name, directories): + self.name = name + self.project_dir = directories["project_dir"] + self.third_party_dir = directories["third_party_dir"] + self.binary_dir = directories["binary_dir"] + self.program_dir = directories["program_dir"] + self.link_libs = directories["link_libs"] + +creation_flag = 15 +if len(sys.argv) > 1: + project = sys.argv[1] +else: + project = "OpenSoar" + +if len(sys.argv) > 2: + toolchain = sys.argv[2] +else: + toolchain = "msvc2022" + +if len(sys.argv) > 3: + creation_flag = sys.argv[3] + +# input("Press Enter to continue...") # == 'pause' + + +if sys.platform.startswith('win'): + if not toolchain in ['mgw73', 'mgw103', 'mgw112', 'mgw122', 'ninja', 'msvc2019', 'msvc2022', + 'clang10', 'clang11', 'clang12', 'clang13', 'clang14', 'clang15', 'clang16' ]: + toolchain = 'mgw112' # standard toolchain on windows +else: + if not toolchain in ['unix', 'mingw']: + # toolchain = 'unix' # standard toolchain on Linux + toolchain = 'mingw' # standard toolchain on Linux + +print('Project Name = ', project, 'toolchain = ', toolchain) + +arguments = [] +arguments.append('OpenSoar') # project_name +# arguments.append('master') # branch +# arguments.append('weglide_msvc_new') # branch +if branch: + arguments.append(branch) # branch +else: + arguments.append('no-branch') # branch + +arguments.append(toolchain) # build-toolchain +arguments.append(creation_flag) +# arguments.append('Arg2') + + +# arguments.append('Arg3') +# arguments.append('Arg4') + +print('Jetzt gehts los: ', arguments) +create_opensoar(arguments) + diff --git a/build/cmake/python/Start-CMake-XCSoar.py b/build/cmake/python/Start-CMake-XCSoar.py new file mode 100644 index 00000000000..a42dfc39e63 --- /dev/null +++ b/build/cmake/python/Start-CMake-XCSoar.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python3 + +import os, sys +from CMakeXCSoar import create_xcsoar + +# ==================== +# ==================== +branch = 'dev-branch' +# ==================== +# ==================== + + +class ComputerDirectories(object): + def __init__(self, name, directories): + self.name = name + self.project_dir = directories["project_dir"] + self.third_party_dir = directories["third_party_dir"] + self.binary_dir = directories["binary_dir"] + self.program_dir = directories["program_dir"] + self.link_libs = directories["link_libs"] + +creation_flag = 15 +if len(sys.argv) > 1: + project = sys.argv[1] +else: + project = "XCSoarAug" + +if len(sys.argv) > 2: + toolchain = sys.argv[2] +else: + toolchain = "msvc2022" + +if len(sys.argv) > 3: + creation_flag = sys.argv[3] + +# input("Press Enter to continue...") # == 'pause' + + +if sys.platform.startswith('win'): + if not toolchain in ['mgw73', 'mgw103', 'mgw112', 'mgw122', 'ninja', 'msvc2019', 'msvc2022', + 'clang10', 'clang11', 'clang12', 'clang13', 'clang14', 'clang15' ]: + toolchain = 'mgw112' # standard toolchain on windows +else: + if not toolchain in ['unix', 'mingw']: + # toolchain = 'unix' # standard toolchain on Linux + toolchain = 'mingw' # standard toolchain on Linux + +print('Project Name = ', project, 'toolchain = ', toolchain) + +arguments = [] +arguments.append('XCSoarAug') # project_name +# arguments.append('master') # branch +# arguments.append('weglide_msvc_new') # branch +if branch: + arguments.append(branch) # branch +else: + arguments.append('no-branch') # branch + +arguments.append(toolchain) # build-toolchain +arguments.append(creation_flag) +# arguments.append('Arg2') + + +# arguments.append('Arg3') +# arguments.append('Arg4') + +print('Jetzt gehts los: ', arguments) +create_xcsoar(arguments) + diff --git a/build/cmake/toolchains/Android/x86.toolchain b/build/cmake/toolchains/Android/x86.toolchain new file mode 100644 index 00000000000..e69de29bb2d diff --git a/build/cmake/toolchains/Android/x86_64.toolchain b/build/cmake/toolchains/Android/x86_64.toolchain new file mode 100644 index 00000000000..e110cda26bf --- /dev/null +++ b/build/cmake/toolchains/Android/x86_64.toolchain @@ -0,0 +1,23 @@ +# the name of the target operating system +SET(CMAKE_SYSTEM_NAME Windows) + +# which compilers to use for C and C++ + SET(CMAKE_C_COMPILER clang) + SET(CMAKE_CXX_COMPILER clang++) + # SET(CMAKE_RC_COMPILER llvm-windres) + SET(CMAKE_RC_COMPILER llvm-rc) + SET(CMAKE_AR_COMPILER llvm-ar) + # here is the target environment located + # SET(CMAKE_FIND_ROOT_PATH /usr/bin /usr/lib ) + +# adjust the default behaviour of the FIND_XXX() commands: +# search headers and libraries in the target environment, search +# programs in the host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + + +# set(CMAKE_C_COMPILER_WORKS 1) +# set(CMAKE_CXX_COMPILER_WORKS 1) + diff --git a/build/cmake/toolchains/LinuxGCC.toolchain b/build/cmake/toolchains/LinuxGCC.toolchain new file mode 100644 index 00000000000..0cc37ec4a8b --- /dev/null +++ b/build/cmake/toolchains/LinuxGCC.toolchain @@ -0,0 +1,17 @@ +# the name of the target operating system +# set(cmake_system_name unix) +set(cmake_system_name linux) + +# which compilers to use for c and c++ + set(cmake_c_compiler gcc) + set(cmake_cxx_compiler g++) + set(cmake_rc_compiler windres) + # here is the target environment located + set(cmake_find_root_path /usr/bin /usr/lib ) + +# adjust the default behaviour of the find_xxx() commands: +# search headers and libraries in the target environment, search +# programs in the host environment +set(cmake_find_root_path_mode_program never) +set(cmake_find_root_path_mode_library only) +set(cmake_find_root_path_mode_include only) diff --git a/build/cmake/toolchains/LinuxMinGW.toolchain b/build/cmake/toolchains/LinuxMinGW.toolchain new file mode 100644 index 00000000000..4e454012172 --- /dev/null +++ b/build/cmake/toolchains/LinuxMinGW.toolchain @@ -0,0 +1,31 @@ +# the name of the target operating system +SET(CMAKE_SYSTEM_NAME Windows) + +# which compilers to use for C and C++ + SET(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc) + SET(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++) + + SET(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres) + +if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL Windows) + set(WIN_HOST ON) +else() + # here is the target environment located + set(CMAKE_FIND_ROOT_PATH /usr/bin ) + # set(CMAKE_FIND_ROOT_PATH /usr/lib/gcc/x86_64-w64-mingw32/10-win32 ) + # set(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32 ) # /home/august/mingw-install +endif() + +set(MINGW ON) + +# adjust the default behaviour of the FIND_XXX() commands: +# search headers and libraries in the target environment, search +# programs in the host environment + +#set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +#set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +#set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +# because cross compiling no compiler check +SET (CMAKE_C_COMPILER_WORKS 1) +SET (CMAKE_CXX_COMPILER_WORKS 1) diff --git a/build/cmake/toolchains/MinGW.toolchain b/build/cmake/toolchains/MinGW.toolchain new file mode 100644 index 00000000000..4bd7bb4f46a --- /dev/null +++ b/build/cmake/toolchains/MinGW.toolchain @@ -0,0 +1,32 @@ +# the name of the target operating system +set(CMAKE_SYSTEM_NAME Windows) + +# which compilers to use for C and C++ + set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc) + set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++) + # set(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres) + +if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL Windows) + set(WIN_HOST ON) +else() + # here is the target environment located + set(CMAKE_FIND_ROOT_PATH /usr/bin ) + # set(CMAKE_FIND_ROOT_PATH /usr/lib/gcc/x86_64-w64-mingw32/10-win32 ) + # set(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32 ) # /home/august/mingw-install + + # because cross compiling no compiler check + set(CMAKE_C_COMPILER_WORKS 1) + set(CMAKE_CXX_COMPILER_WORKS 1) +endif() + +set(MINGW ON) + +# adjust the default behaviour of the FIND_XXX() commands: +# search headers and libraries in the target environment, search +# programs in the host environment + +#set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +#set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +#set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +set(CMAKE_INCLUDE_SYSTEM build/cmake/MinGW.cmake) diff --git a/build/cmake/toolchains/WinClang.toolchain b/build/cmake/toolchains/WinClang.toolchain new file mode 100644 index 00000000000..81baf1636d0 --- /dev/null +++ b/build/cmake/toolchains/WinClang.toolchain @@ -0,0 +1,32 @@ +# the name of the target operating system +set(CMAKE_SYSTEM_NAME Windows) + +### # which compilers to use for C and C++ +### set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc) +### set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++) +### # set(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres) + +if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL Windows) + set(WIN_HOST ON) +else() +### # here is the target environment located +### set(CMAKE_FIND_ROOT_PATH /usr/bin ) +### # set(CMAKE_FIND_ROOT_PATH /usr/lib/gcc/x86_64-w64-mingw32/10-win32 ) +### # set(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32 ) # /home/august/mingw-install +### +### # because cross compiling no compiler check +### set(CMAKE_C_COMPILER_WORKS 1) +### set(CMAKE_CXX_COMPILER_WORKS 1) +endif() + +### set(MINGW ON) + +# adjust the default behaviour of the FIND_XXX() commands: +# search headers and libraries in the target environment, search +# programs in the host environment + +#set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +#set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +#set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +set(CMAKE_INCLUDE_SYSTEM build/cmake/WinClang.cmake) diff --git a/build/cmake/toolchains/mscv2019.toolchain b/build/cmake/toolchains/mscv2019.toolchain new file mode 100644 index 00000000000..b70252a4102 --- /dev/null +++ b/build/cmake/toolchains/mscv2019.toolchain @@ -0,0 +1,17 @@ +# the name of the target operating system +SET(CMAKE_SYSTEM_NAME Windows) + +# which compilers to use for C and C++ +SET(CMAKE_C_COMPILER vc) +SET(CMAKE_CXX_COMPILER vc) +# SET(CMAKE_RC_COMPILER i586-mingw32msvc-windres) + +# here is the target environment located +SET(CMAKE_FIND_ROOT_PATH /usr/i586-mingw32msvc /home/alex/mingw-install ) + +# adjust the default behaviour of the FIND_XXX() commands: +# search headers and libraries in the target environment, search +# programs in the host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/build/cmake/toolchains/mscv2022.toolchain b/build/cmake/toolchains/mscv2022.toolchain new file mode 100644 index 00000000000..b70252a4102 --- /dev/null +++ b/build/cmake/toolchains/mscv2022.toolchain @@ -0,0 +1,17 @@ +# the name of the target operating system +SET(CMAKE_SYSTEM_NAME Windows) + +# which compilers to use for C and C++ +SET(CMAKE_C_COMPILER vc) +SET(CMAKE_CXX_COMPILER vc) +# SET(CMAKE_RC_COMPILER i586-mingw32msvc-windres) + +# here is the target environment located +SET(CMAKE_FIND_ROOT_PATH /usr/i586-mingw32msvc /home/alex/mingw-install ) + +# adjust the default behaviour of the FIND_XXX() commands: +# search headers and libraries in the target environment, search +# programs in the host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/build/cmake/xcsoar.cmake b/build/cmake/xcsoar.cmake new file mode 100644 index 00000000000..c731f56bc6e --- /dev/null +++ b/build/cmake/xcsoar.cmake @@ -0,0 +1,4 @@ +set(DISPLAY_STRING "# XCSoar CMake Macros and Functions") +message(STATUS "${DISPLAY_STRING}") +cmake_minimum_required(VERSION 3.15) + diff --git a/build/compile.mk b/build/compile.mk index 181a4006db2..b6fb065089f 100644 --- a/build/compile.mk +++ b/build/compile.mk @@ -1,5 +1,18 @@ ######## tools +# August2111: This part is for OpenSoar only: +#============================================ +# with changed .config a new ProgramVersion (and a new title.svg) is needed +output/include/ProgramVersion.h: OpenSoar.config + @$(NQ)echo " VERSION: $< ==> $@ " + $(Q)python3 $(topdir)/tools/python/replace.py $< Data/graphics/title.svg $(DATA)/temp/graphics/title.svg $@ + +# Version.o need the new PROGRAM_VERSION if it is available: +Version.o: %.cpp ProgramVersion.h + @$(NQ)echo " CPP $@" + $(Q)$(WRAPPED_CXX) $< -c -o $@ $(cxx-flags) +#================================================ + CCACHE := ifeq ($(USE_CCACHE),y) CCACHE := ccache$(EXE) @@ -99,8 +112,11 @@ $(ABI_OUTPUT_DIR)/%$(OBJ_SUFFIX): %.c | $(ABI_OUTPUT_DIR)/%/../dirstamp $(compil @$(NQ)echo " CC $@" $(Q)$(WRAPPED_CC) $< -c -o $@ $(cc-flags) +# switch verbose on (or off): +# cxx-flags += -v + $(ABI_OUTPUT_DIR)/%$(OBJ_SUFFIX): %.cpp | $(ABI_OUTPUT_DIR)/%/../dirstamp $(compile-depends) - @$(NQ)echo " CXX $@" + @$(NQ)echo " CPP $@" $(Q)$(WRAPPED_CXX) $< -c -o $@ $(cxx-flags) ifeq ($(IWYU),y) $(Q)iwyu $< $(cxx-flags) diff --git a/build/debug.mk b/build/debug.mk index fd9b8de1e2d..d0afc03dc54 100644 --- a/build/debug.mk +++ b/build/debug.mk @@ -15,7 +15,7 @@ endif TARGET_OPTIMIZE := -g HOST_OPTIMIZE := -g -# Enable fast floating point math. XCSoar does not rely on strict +# Enable fast floating point math. OpenSoar does not rely on strict # IEEE/ISO semantics, for example it is not interested in "errno" or # the difference between -0 and +0. This allows using non-conforming # vector units on some platforms, e.g. ARM NEON. diff --git a/build/dist.mk b/build/dist.mk index 655a324b707..e2658f1d745 100644 --- a/build/dist.mk +++ b/build/dist.mk @@ -1,7 +1,8 @@ -TARGET_DIST_NAME = XCSoar-$(FULL_VERSION)-$(TARGET) +TARGET_DIST_NAME = $(PROGRAM_NAME)-$(FULL_VERSION)-$(TARGET) TARGET_DIST_DIR = $(TARGET_OUTPUT_DIR)/dist -dist: $(XCSOAR_BIN) $(VALI_XCS_BIN) +# dist: $(XCSOAR_BIN) $(VALI_XCS_BIN) +dist: $(XCSOAR_BIN) rm -rf $(TARGET_DIST_DIR)/$(TARGET_DIST_NAME) $(MKDIR) -p $(TARGET_DIST_DIR)/$(TARGET_DIST_NAME) cp $^ COPYING \ diff --git a/build/doxygen.mk b/build/doxygen.mk index ef1f046e54c..59c20f72da4 100644 --- a/build/doxygen.mk +++ b/build/doxygen.mk @@ -4,4 +4,4 @@ DOXYGEN_OUTPUT_DIR = $(OUT)/doc doco: FORCE rm -rf $(DOXYGEN_OUTPUT_DIR) $(MKDIR) -p $(DOXYGEN_OUTPUT_DIR) - cd $(DOC) && doxygen XCSoar.doxyfile + cd $(DOC) && doxygen $(PROGRAM_NAME).doxyfile diff --git a/build/driver.mk b/build/driver.mk index 38fa3d86caa..430fe31947d 100644 --- a/build/driver.mk +++ b/build/driver.mk @@ -102,6 +102,7 @@ DRIVER_SOURCES = \ $(XCTRACER_SOURCES) \ $(THERMALEXPRESS_SOURCES) \ $(DRIVER_SRC_DIR)/AltairPro.cpp \ + $(DRIVER_SRC_DIR)/Anemoi.cpp \ $(DRIVER_SRC_DIR)/BorgeltB50.cpp \ $(DRIVER_SRC_DIR)/XCVario.cpp \ $(DRIVER_SRC_DIR)/CaiGpsNav.cpp \ @@ -113,6 +114,7 @@ DRIVER_SOURCES = \ $(DRIVER_SRC_DIR)/Eye.cpp \ $(DRIVER_SRC_DIR)/FlymasterF1.cpp \ $(DRIVER_SRC_DIR)/FlyNet.cpp \ + $(DRIVER_SRC_DIR)/FreeVario.cpp \ $(DRIVER_SRC_DIR)/Generic.cpp \ $(DRIVER_SRC_DIR)/LevilAHRS_G.cpp \ $(DRIVER_SRC_DIR)/Leonardo.cpp \ @@ -126,6 +128,8 @@ DRIVER_SOURCES = \ $(DRIVER_SRC_DIR)/Vaulter.cpp \ $(DRIVER_SRC_DIR)/KRT2.cpp \ $(DRIVER_SRC_DIR)/AirControlDisplay.cpp \ + $(DRIVER_SRC_DIR)/Larus.cpp \ + $(DRIVER_SRC_DIR)/AR62xx.cpp \ $(DRIVER_SRC_DIR)/ATR833/Device.cpp \ $(DRIVER_SRC_DIR)/ATR833/Register.cpp diff --git a/build/generate.mk b/build/generate.mk index c1581f2a0f2..99351228833 100644 --- a/build/generate.mk +++ b/build/generate.mk @@ -43,7 +43,13 @@ $(OUT)/include/InputEvents_Char2NE.cpp: $(SRC)/Input/InputQueue.hpp \ XCI_LIST = default XCI_HEADERS = $(patsubst %,$(OUT)/include/InputEvents_%.cpp,$(XCI_LIST)) -$(OUT)/include/InputEvents_default.cpp: $(topdir)/Data/Input/default.xci \ +ifeq ($(TARGET_IS_OPENVARIO),y) + GETTEXT_EVENTS = Data/Input/defaultOV.xci +else + GETTEXT_EVENTS = Data/Input/default.xci +endif + +$(OUT)/include/InputEvents_default.cpp: $(topdir)/$(GETTEXT_EVENTS) \ $(topdir)/tools/xci2cpp.pl \ | $(OUT)/include/dirstamp @$(NQ)echo " GEN $@" diff --git a/build/gettext.mk b/build/gettext.mk index 721ee5b6d5f..dc6dcee4bd7 100644 --- a/build/gettext.mk +++ b/build/gettext.mk @@ -6,14 +6,19 @@ MSGCAT = msgcat MSGFMT = msgfmt MSGMERGE = msgmerge -GETTEXT_PACKAGE = xcsoar +GETTEXT_PACKAGE = $(PROGRAM_NAME_LC) GETTEXT_SOURCES = $(XCSOAR_SOURCES) \ $(LIBINFOBOX_SOURCES) \ $(LIBMAPWINDOW_SOURCES) \ $(LIBCOMPUTER_SOURCES) \ $(wildcard $(SRC)/Dialogs/Device/Vega/*Parameters.hpp) \ $(SRC)/Weather/Rasp/RaspStore.cpp -GETTEXT_EVENTS = Data/Input/default.xci + +ifeq ($(TARGET_IS_OPENVARIO),y) + GETTEXT_EVENTS = Data/Input/defaultOV.xci +else + GETTEXT_EVENTS = Data/Input/default.xci +endif $(OUT)/po/cpp.pot: $(GETTEXT_SOURCES) | $(OUT)/po/dirstamp @$(NQ)echo " GEN $@" diff --git a/build/install.mk b/build/install.mk index 0b517748241..4f6ba33906a 100644 --- a/build/install.mk +++ b/build/install.mk @@ -6,16 +6,19 @@ prefix = $(DESTDIR)/usr install-mo: mo install -d -m 0755 $(patsubst %,$(prefix)/share/locale/%/LC_MESSAGES,$(LINGUAS)) for i in $(LINGUAS); do \ - install -m 0644 $(OUT)/po/$$i.mo $(prefix)/share/locale/$$i/LC_MESSAGES/xcsoar.mo; \ + install -m 0644 $(OUT)/po/$$i.mo $(prefix)/share/locale/$$i/LC_MESSAGES/$(PROGRAM_NAME_LC).mo; \ done install-bin: all + @$(NQ)echo " INSTALL Passiert hier irgend etwas????" install -d -m 0755 $(prefix)/bin - install -m 0755 $(TARGET_BIN_DIR)/xcsoar $(TARGET_BIN_DIR)/vali-xcs $(prefix)/bin + install -m 0755 $(TARGET_BIN_DIR)/$(PROGRAM_NAME) $(prefix)/bin + +# install -m 0755 $(TARGET_BIN_DIR)/$(PROGRAM_NAME) $(TARGET_BIN_DIR)/vali-xcs $(prefix)/bin install-manual: manual - install -d -m 0755 $(prefix)/share/doc/xcsoar - install -m 0644 $(MANUAL_PDF) $(prefix)/share/doc/xcsoar + install -d -m 0755 $(prefix)/share/doc/$(PROGRAM_NAME) + install -m 0644 $(MANUAL_PDF) $(prefix)/share/doc/$(PROGRAM_NAME) install: install-bin install-mo install-manual diff --git a/build/ios.mk b/build/ios.mk index 7638b4ea73d..925388316c7 100644 --- a/build/ios.mk +++ b/build/ios.mk @@ -5,18 +5,18 @@ TARGET_LDLIBS += -framework UIKit IPA_TMPDIR = $(TARGET_OUTPUT_DIR)/ipa ifeq ($(TESTING),y) -IPA_NAME = xcsoar-testing.ipa -IOS_APP_DIR_NAME = XCSoar.testing.app -IOS_APP_BUNDLE_INENTIFIER = XCSoar-testing -IOS_APP_DISPLAY_NAME = XCSoar Testing +IPA_NAME = $(PROGRAM_NAME_LC)-testing.ipa +IOS_APP_DIR_NAME = $(PROGRAM_NAME).testing.app +IOS_APP_BUNDLE_INENTIFIER = $(PROGRAM_NAME)-testing +IOS_APP_DISPLAY_NAME = $(PROGRAM_NAME) Testing IOS_ICON_SVG = $(topdir)/Data/iOS/iOS-Icon_red.svg IOS_SPLASH_BASE_IMG=$(DATA)/graphics/logo_red_320.png IOS_GRAPHICS_DIR=$(DATA)/ios-graphics-testing else -IPA_NAME = xcsoar.ipa -IOS_APP_DIR_NAME = XCSoar.app -IOS_APP_BUNDLE_INENTIFIER = XCSoar -IOS_APP_DISPLAY_NAME = XCSoar +IPA_NAME = $(PROGRAM_NAME_LC).ipa +IOS_APP_DIR_NAME = $(PROGRAM_NAME).app +IOS_APP_BUNDLE_INENTIFIER = $(PROGRAM_NAME) +IOS_APP_DISPLAY_NAME = $(PROGRAM_NAME) IOS_ICON_SVG = $(topdir)/Data/iOS/iOS-Icon.svg IOS_SPLASH_BASE_IMG=$(DATA)/graphics/logo_320.png IOS_GRAPHICS_DIR=$(DATA)/ios-graphics @@ -104,11 +104,11 @@ else endif -$(TARGET_OUTPUT_DIR)/$(IPA_NAME): $(TARGET_BIN_DIR)/xcsoar $(TARGET_OUTPUT_DIR)/Info.plist $(IOS_GRAPHICS) +$(TARGET_OUTPUT_DIR)/$(IPA_NAME): $(TARGET_BIN_DIR)/$(PROGRAM_NAME_LC) $(TARGET_OUTPUT_DIR)/Info.plist $(IOS_GRAPHICS) @$(NQ)echo " IPA $@" $(Q)rm -rf $(IPA_TMPDIR) $(Q)$(MKDIR) -p $(IPA_TMPDIR)/Payload/$(IOS_APP_DIR_NAME) - $(Q)cp $(TARGET_BIN_DIR)/xcsoar $(IPA_TMPDIR)/Payload/$(IOS_APP_DIR_NAME)/XCSoar + $(Q)cp $(TARGET_BIN_DIR)/$(PROGRAM_NAME_LC) $(IPA_TMPDIR)/Payload/$(IOS_APP_DIR_NAME)/$(PROGRAM_NAME) $(Q)cp $(TARGET_OUTPUT_DIR)/Info.plist $(IPA_TMPDIR)/Payload/$(IOS_APP_DIR_NAME) $(Q)cp $(IOS_GRAPHICS) $(IPA_TMPDIR)/Payload/$(IOS_APP_DIR_NAME) $(Q)cd $(IPA_TMPDIR) && $(ZIP) -r ../$(IPA_NAME) ./* diff --git a/build/kobo.mk b/build/kobo.mk index e2c9f5e555e..e74da723e03 100644 --- a/build/kobo.mk +++ b/build/kobo.mk @@ -144,7 +144,7 @@ $(CLARAHD_DRIVERS_DOWNLOAD): | $(DOWNLOAD_DIR)/dirstamp # /mnt/onboard/.kobo/KoboRoot.tgz is a file that is picked up by # /etc/init.d/rcS, extracted to / on each boot; we can use it to -# install XCSoar +# install OpenSoar $(TARGET_OUTPUT_DIR)/KoboRoot.tgz: $(XCSOAR_BIN) \ $(KOBO_MENU_BIN) $(KOBO_POWER_OFF_BIN) \ $(BITSTREAM_VERA_FILES) \ diff --git a/build/libdata.mk b/build/libdata.mk index 0150f8a6f46..c617cbcda61 100644 --- a/build/libdata.mk +++ b/build/libdata.mk @@ -3,6 +3,9 @@ DATA_RESOURCES = \ $(MO_FILES) \ + output/data/COPYING.gz \ + output/data/AUTHORS.gz \ + output/data/OpenSoar-News.md.gz \ $(TEXT_COMPRESSED) \ Data/other/egm96s.dem DATA_SOURCES += $(foreach file,$(DATA_RESOURCES),$(DATA)/$(notdir $(file)).c) diff --git a/build/libutil.mk b/build/libutil.mk index 7a5ea62d64a..c7d47f92edb 100644 --- a/build/libutil.mk +++ b/build/libutil.mk @@ -11,19 +11,10 @@ UTIL_SOURCES = \ $(UTIL_SRC_DIR)/ASCII.cxx \ $(UTIL_SRC_DIR)/TruncateString.cpp \ $(UTIL_SRC_DIR)/EscapeBackslash.cpp \ - $(UTIL_SRC_DIR)/ConvertString.cpp \ $(UTIL_SRC_DIR)/StaticString.cxx \ $(UTIL_SRC_DIR)/StringBuilder.cxx \ $(UTIL_SRC_DIR)/StringCompare.cxx \ $(UTIL_SRC_DIR)/StringStrip.cxx \ $(UTIL_SRC_DIR)/StringUtil.cpp -ifeq ($(HAVE_MSVCRT),y) -UTIL_SOURCES += \ - $(UTIL_SRC_DIR)/WASCII.cxx \ - $(UTIL_SRC_DIR)/WStringCompare.cpp \ - $(UTIL_SRC_DIR)/WStringStrip.cxx \ - $(UTIL_SRC_DIR)/WStringUtil.cpp -endif - $(eval $(call link-library,util,UTIL)) diff --git a/build/lua.mk b/build/lua.mk index 8d3743c7eb7..b000350f0ad 100644 --- a/build/lua.mk +++ b/build/lua.mk @@ -9,6 +9,14 @@ else $(eval $(call pkg-config-library,LIBLUA,lua5.4)) endif +ifeq ($(USE_XCSOAR_ONLY),y) +LIBLUA_CPPFLAGS += -DPROGRAM_NAME_LC=\"xcsoar\" +else +# August2111: use "xcsoar" instead of "opensoar" to make it aligned... +LIBLUA_CPPFLAGS += -DPROGRAM_NAME_LC=\"xcsoar\" +# LIBLUA_CPPFLAGS += -DPROGRAM_NAME_LC=\"opensoar\" +endif + LUA_SOURCES = \ $(SRC)/lua/Ptr.cpp \ $(SRC)/lua/Error.cxx \ diff --git a/build/main.mk b/build/main.mk index fe96c3660ba..8fc1d8e6f62 100644 --- a/build/main.mk +++ b/build/main.mk @@ -1,8 +1,11 @@ -ifeq ($(HAVE_POSIX),y) -PROGRAM_NAME = xcsoar -else -PROGRAM_NAME = XCSoar -endif +### PROGRAM_NAME_LC = opensoar +### PROGRAM_NAME_CC = OpenSoar +### +### ifeq ($(HAVE_POSIX),y) +### PROGRAM_NAME = $(PROGRAM_NAME_CC) # all programs CamelCase +### else +### PROGRAM_NAME = $(PROGRAM_NAME_CC) +### endif DIALOG_SOURCES = \ $(SRC)/Dialogs/Inflate.cpp \ @@ -151,6 +154,28 @@ DIALOG_SOURCES = \ $(SRC)/Dialogs/dlgCredits.cpp \ $(SRC)/Dialogs/dlgQuickMenu.cpp \ +ifeq ($(TARGET_IS_OPENVARIO),y) + # $(SRC)/OpenVario/OpenVarioBaseMenu.cpp # for exe only... +DIALOG_SOURCES += \ + $(SRC)/Dialogs/ProcessDialog.cpp \ + \ + $(SRC)/OpenVario/SystemSettingsWidget.cpp \ + $(SRC)/OpenVario/DisplaySettingsWidget.cpp \ + $(SRC)/OpenVario/FileMenuWidget.cpp \ + $(SRC)/OpenVario/ExtraWidget.cpp \ + \ + $(SRC)/OpenVario/System/SystemMenuWidget.cpp \ + \ + $(SRC)/OpenVario/System/OpenVarioDevice.cpp \ + $(SRC)/OpenVario/System/OpenVarioTools.cpp \ + \ + $(SRC)/OpenVario/System/Setting/RotationWidget.cpp \ + $(SRC)/OpenVario/System/Setting/WifiWidget.cpp \ + \ + $(SRC)/OpenVario/System/WifiDialogOV.cpp \ + $(SRC)/OpenVario/System/WifiSupplicantOV.cpp +endif + ifeq ($(HAVE_PCM_PLAYER),y) DIALOG_SOURCES += \ $(SRC)/Dialogs/Settings/Panels/AudioVarioConfigPanel.cpp \ @@ -610,9 +635,12 @@ XCSOAR_SOURCES += \ else XCSOAR_SOURCES += \ $(SRC)/CommandLine.cpp \ - $(SRC)/XCSoar.cpp + $(SRC)/OpenSoar.cpp + +# $(SRC)/XCSoar.cpp endif + ifeq ($(HAVE_HTTP),y) XCSOAR_SOURCES += \ $(SRC)/Dialogs/DownloadFilePicker.cpp \ diff --git a/build/options.mk b/build/options.mk index 640d7d57c7a..9f3e07a8ba8 100644 --- a/build/options.mk +++ b/build/options.mk @@ -55,7 +55,7 @@ ifeq ($(GREYSCALE),y) TARGET_CPPFLAGS += -DGREYSCALE endif -# When enabled, the Androidpackage org.xcsoar.testing is created, with +# When enabled, the Androidpackage de.opensoar.testing is created, with # a red Activity icon, to allow simultaneous installation of "stable" # and "testing". # In the stable branch, this should default to "n". diff --git a/build/osx.mk b/build/osx.mk index 943ec9d4240..284a9acd9f3 100644 --- a/build/osx.mk +++ b/build/osx.mk @@ -13,23 +13,23 @@ DMG_TMPDIR = $(TARGET_OUTPUT_DIR)/dmg MKISOFS ?= mkisofs ifeq ($(TESTING),y) -DMG_NAME = XCSoar-testing.dmg -OSX_APP_LABEL = XCSoar Testing +DMG_NAME = $(PROGRAM_NAME)-testing.dmg +OSX_APP_LABEL = $(PROGRAM_NAME) Testing OSX_LOGO = $(DATA)/graphics/logo_red_1024.icns -OSX_APP_BUNDLE_INENTIFIER = XCSoar-Testing.app +OSX_APP_BUNDLE_INENTIFIER = $(PROGRAM_NAME)-Testing.app else -DMG_NAME = XCSoar.dmg -OSX_APP_LABEL = XCSoar +DMG_NAME = $(PROGRAM_NAME).dmg +OSX_APP_LABEL = $(PROGRAM_NAME) OSX_LOGO = $(DATA)/graphics/logo_1024.icns -OSX_APP_BUNDLE_INENTIFIER = XCSoar.app +OSX_APP_BUNDLE_INENTIFIER = $(PROGRAM_NAME).app endif -$(TARGET_OUTPUT_DIR)/$(DMG_NAME): $(TARGET_BIN_DIR)/xcsoar Data/OSX/Info.plist.in.xml $(OSX_LOGO) +$(TARGET_OUTPUT_DIR)/$(DMG_NAME): $(TARGET_BIN_DIR)/$(PROGRAM_NAME_LC) Data/OSX/Info.plist.in.xml $(OSX_LOGO) @$(NQ)echo " DMG $@" $(Q)rm -rf $(DMG_TMPDIR) $(Q)$(MKDIR) -p $(DMG_TMPDIR)/$(OSX_APP_BUNDLE_INENTIFIER)/Contents/MacOS $(Q)sed -e "s,VERSION_PLACEHOLDER,$(FULL_VERSION)," -e 's/OSX_APP_LABEL_PLACEHOLDER/$(OSX_APP_LABEL)/g' < Data/OSX/Info.plist.in.xml > $(DMG_TMPDIR)/$(OSX_APP_BUNDLE_INENTIFIER)/Contents/Info.plist - $(Q)cp $(TARGET_BIN_DIR)/xcsoar $(DMG_TMPDIR)/$(OSX_APP_BUNDLE_INENTIFIER)/Contents/MacOS/ + $(Q)cp $(TARGET_BIN_DIR)/$(PROGRAM_NAME_LC) $(DMG_TMPDIR)/$(OSX_APP_BUNDLE_INENTIFIER)/Contents/MacOS/ $(Q)$(MKDIR) -p $(DMG_TMPDIR)/$(OSX_APP_BUNDLE_INENTIFIER)/Contents/Resources $(Q)cp $(OSX_LOGO) $(DMG_TMPDIR)/$(OSX_APP_BUNDLE_INENTIFIER)/Contents/Resources/logo_1024.icns $(Q)rm -f $@ diff --git a/build/ov.mk b/build/ov.mk index bc672150e6e..ce61508defc 100644 --- a/build/ov.mk +++ b/build/ov.mk @@ -1,13 +1,212 @@ +CONFIG = $(topdir)/OpenSoar.config +include $(CONFIG) + +# w/o VERSION.txt: +ifeq ($(PROGRAM_VERSION),"") + # take the version from XCSoar VERSION.txt + PROGRAM_VERSION = $(strip $(shell cat $(topdir)/VERSION.txt)) +endif +EXTRA_CPPFLAGS+= -DPROGRAM_VERSION=\"$(PROGRAM_VERSION)\" + +EXTRA_CPPFLAGS += -DIS_OPENVARIO +EXTRA_CPPFLAGS += -DOPENVARIO_BASEMENU +ifeq ($(TARGET_IS_OVDEVICE),y) + EXTRA_CPPFLAGS+= -DIS_OPENVARIO_CB2 +endif + +DIALOG_SOURCES = \ + $(SRC)/Dialogs/Inflate.cpp \ + $(SRC)/Dialogs/Message.cpp \ + $(SRC)/Dialogs/LockScreen.cpp \ + $(SRC)/Dialogs/Error.cpp \ + $(SRC)/Dialogs/ListPicker.cpp \ + $(SRC)/Dialogs/ProgressDialog.cpp \ + $(SRC)/Dialogs/CoDialog.cpp \ + $(SRC)/Dialogs/JobDialog.cpp \ + $(SRC)/Dialogs/WidgetDialog.cpp \ + $(SRC)/Dialogs/FileManager.cpp \ + $(SRC)/Dialogs/Device/PortDataField.cpp \ + $(SRC)/Dialogs/Device/PortPicker.cpp \ + $(SRC)/Dialogs/Device/DeviceEditWidget.cpp \ + $(SRC)/Dialogs/Device/DeviceListDialog.cpp \ + $(SRC)/Dialogs/Device/PortMonitor.cpp \ + $(SRC)/Dialogs/Device/ManageCAI302Dialog.cpp \ + $(SRC)/Dialogs/Device/CAI302/UnitsEditor.cpp \ + $(SRC)/Dialogs/Device/CAI302/WaypointUploader.cpp \ + $(SRC)/Dialogs/Device/ManageFlarmDialog.cpp \ + $(SRC)/Dialogs/Device/BlueFly/BlueFlyConfigurationDialog.cpp \ + $(SRC)/Dialogs/Device/ManageI2CPitotDialog.cpp \ + $(SRC)/Dialogs/Device/LX/ManageLXNAVVarioDialog.cpp \ + $(SRC)/Dialogs/Device/LX/LXNAVVarioConfigWidget.cpp \ + $(SRC)/Dialogs/Device/LX/ManageNanoDialog.cpp \ + $(SRC)/Dialogs/Device/LX/NanoConfigWidget.cpp \ + $(SRC)/Dialogs/Device/LX/ManageLX16xxDialog.cpp \ + $(SRC)/Dialogs/Device/Vega/VegaParametersWidget.cpp \ + $(SRC)/Dialogs/Device/Vega/VegaConfigurationDialog.cpp \ + $(SRC)/Dialogs/Device/Vega/VegaDemoDialog.cpp \ + $(SRC)/Dialogs/Device/Vega/SwitchesDialog.cpp \ + $(SRC)/Dialogs/Device/FLARM/ConfigWidget.cpp \ + $(SRC)/Dialogs/MapItemListDialog.cpp \ + $(SRC)/Dialogs/MapItemListSettingsDialog.cpp \ + $(SRC)/Dialogs/MapItemListSettingsPanel.cpp \ + $(SRC)/Dialogs/ColorListDialog.cpp \ + $(SRC)/Dialogs/Airspace/dlgAirspace.cpp \ + $(SRC)/Dialogs/Airspace/dlgAirspacePatterns.cpp \ + $(SRC)/Dialogs/Airspace/dlgAirspaceDetails.cpp \ + $(SRC)/Dialogs/Airspace/AirspaceList.cpp \ + $(SRC)/Dialogs/Airspace/AirspaceCRendererSettingsDialog.cpp \ + $(SRC)/Dialogs/Airspace/AirspaceCRendererSettingsPanel.cpp \ + $(SRC)/Dialogs/Airspace/dlgAirspaceWarnings.cpp \ + $(SRC)/Dialogs/Settings/WindSettingsPanel.cpp \ + $(SRC)/Dialogs/Settings/WindSettingsDialog.cpp \ + $(SRC)/Dialogs/Settings/dlgBasicSettings.cpp \ + $(SRC)/Dialogs/Settings/dlgConfiguration.cpp \ + $(SRC)/Dialogs/Settings/dlgConfigInfoboxes.cpp \ + $(SRC)/Dialogs/Traffic/TrafficList.cpp \ + $(SRC)/Dialogs/Traffic/FlarmTrafficDetails.cpp \ + $(SRC)/Dialogs/Traffic/TeamCodeDialog.cpp \ + $(SRC)/Dialogs/dlgAnalysis.cpp \ + $(SRC)/Dialogs/dlgChecklist.cpp \ + $(SRC)/Dialogs/ProfileListDialog.cpp \ + $(SRC)/Dialogs/Plane/PlaneListDialog.cpp \ + $(SRC)/Dialogs/Plane/PlaneDetailsDialog.cpp \ + $(SRC)/Dialogs/Plane/PlanePolarDialog.cpp \ + $(SRC)/Dialogs/Plane/PolarShapeEditWidget.cpp \ + $(SRC)/Dialogs/DataField.cpp \ + $(SRC)/Dialogs/ComboPicker.cpp \ + $(SRC)/Dialogs/FilePicker.cpp \ + $(SRC)/Dialogs/HelpDialog.cpp \ + $(SRC)/Dialogs/dlgInfoBoxAccess.cpp \ + $(SRC)/Dialogs/ReplayDialog.cpp \ + $(SRC)/Dialogs/dlgSimulatorPrompt.cpp \ + $(SRC)/Dialogs/SimulatorPromptWindow.cpp \ + $(SRC)/Dialogs/StartupDialog.cpp \ + $(SRC)/Dialogs/ProfilePasswordDialog.cpp \ + \ + $(SRC)/Dialogs/dlgStatus.cpp \ + $(SRC)/Dialogs/StatusPanels/StatusPanel.cpp \ + $(SRC)/Dialogs/StatusPanels/FlightStatusPanel.cpp \ + $(SRC)/Dialogs/StatusPanels/SystemStatusPanel.cpp \ + $(SRC)/Dialogs/StatusPanels/TaskStatusPanel.cpp \ + $(SRC)/Dialogs/StatusPanels/RulesStatusPanel.cpp \ + $(SRC)/Dialogs/StatusPanels/TimesStatusPanel.cpp \ + \ + $(SRC)/Dialogs/Waypoint/WaypointInfoWidget.cpp \ + $(SRC)/Dialogs/Waypoint/WaypointCommandsWidget.cpp \ + $(SRC)/Dialogs/Waypoint/dlgWaypointDetails.cpp \ + $(SRC)/Dialogs/Waypoint/Manager.cpp \ + $(SRC)/Dialogs/Waypoint/dlgWaypointEdit.cpp \ + $(SRC)/Dialogs/Waypoint/WaypointList.cpp \ + $(SRC)/Dialogs/Waypoint/NearestWaypoint.cpp \ + \ + $(SRC)/Dialogs/Settings/Panels/AirspaceConfigPanel.cpp \ + $(SRC)/Dialogs/Settings/Panels/GaugesConfigPanel.cpp \ + $(SRC)/Dialogs/Settings/Panels/VarioConfigPanel.cpp \ + $(SRC)/Dialogs/Settings/Panels/GlideComputerConfigPanel.cpp \ + $(SRC)/Dialogs/Settings/Panels/WindConfigPanel.cpp \ + $(SRC)/Dialogs/Settings/Panels/InfoBoxesConfigPanel.cpp \ + $(SRC)/Dialogs/Settings/Panels/InterfaceConfigPanel.cpp \ + $(SRC)/Dialogs/Settings/Panels/LayoutConfigPanel.cpp \ + $(SRC)/Dialogs/Settings/Panels/LoggerConfigPanel.cpp \ + $(SRC)/Dialogs/Settings/Panels/MapDisplayConfigPanel.cpp \ + $(SRC)/Dialogs/Settings/Panels/PagesConfigPanel.cpp \ + $(SRC)/Dialogs/Settings/Panels/RouteConfigPanel.cpp \ + $(SRC)/Dialogs/Settings/Panels/SafetyFactorsConfigPanel.cpp \ + $(SRC)/Dialogs/Settings/Panels/SiteConfigPanel.cpp \ + $(SRC)/Dialogs/Settings/Panels/SymbolsConfigPanel.cpp \ + $(SRC)/Dialogs/Settings/Panels/TaskRulesConfigPanel.cpp \ + $(SRC)/Dialogs/Settings/Panels/TaskDefaultsConfigPanel.cpp \ + $(SRC)/Dialogs/Settings/Panels/ScoringConfigPanel.cpp \ + $(SRC)/Dialogs/Settings/Panels/TerrainDisplayConfigPanel.cpp \ + $(SRC)/Dialogs/Settings/Panels/UnitsConfigPanel.cpp \ + $(SRC)/Dialogs/Settings/Panels/TimeConfigPanel.cpp \ + $(SRC)/Dialogs/Settings/Panels/WaypointDisplayConfigPanel.cpp \ + $(SRC)/Dialogs/Settings/Panels/TrackingConfigPanel.cpp \ + $(SRC)/Dialogs/Settings/Panels/CloudConfigPanel.cpp \ + $(SRC)/Dialogs/Settings/Panels/WeatherConfigPanel.cpp \ + $(SRC)/Dialogs/Settings/Panels/WeGlideConfigPanel.cpp \ + \ + $(SRC)/Dialogs/Task/Widgets/ObservationZoneEditWidget.cpp \ + $(SRC)/Dialogs/Task/Widgets/CylinderZoneEditWidget.cpp \ + $(SRC)/Dialogs/Task/Widgets/LineSectorZoneEditWidget.cpp \ + $(SRC)/Dialogs/Task/Widgets/SectorZoneEditWidget.cpp \ + $(SRC)/Dialogs/Task/Widgets/KeyholeZoneEditWidget.cpp \ + $(SRC)/Dialogs/Task/Manager/TaskMapButtonRenderer.cpp \ + $(SRC)/Dialogs/Task/Manager/TaskManagerDialog.cpp \ + $(SRC)/Dialogs/Task/Manager/TaskClosePanel.cpp \ + $(SRC)/Dialogs/Task/Manager/TaskEditPanel.cpp \ + $(SRC)/Dialogs/Task/Manager/TaskPropertiesPanel.cpp \ + $(SRC)/Dialogs/Task/Manager/TaskMiscPanel.cpp \ + $(SRC)/Dialogs/Task/Manager/TaskActionsPanel.cpp \ + $(SRC)/Dialogs/Task/Manager/TaskListPanel.cpp \ + $(SRC)/Dialogs/Task/Manager/WeGlideTasksPanel.cpp \ + $(SRC)/Dialogs/Task/OptionalStartsDialog.cpp \ + $(SRC)/Dialogs/Task/TaskPointDialog.cpp \ + $(SRC)/Dialogs/Task/MutateTaskPointDialog.cpp \ + $(SRC)/Dialogs/Task/dlgTaskHelpers.cpp \ + $(SRC)/Dialogs/Task/TargetDialog.cpp \ + $(SRC)/Dialogs/Task/AlternatesListDialog.cpp \ + \ + $(SRC)/Dialogs/Tracking/CloudEnableDialog.cpp \ + \ + $(SRC)/Dialogs/NumberEntry.cpp \ + $(SRC)/Dialogs/TextEntry.cpp \ + $(SRC)/Dialogs/KnobTextEntry.cpp \ + $(SRC)/Dialogs/TouchTextEntry.cpp \ + $(SRC)/Dialogs/TimeEntry.cpp \ + $(SRC)/Dialogs/DateEntry.cpp \ + $(SRC)/Dialogs/GeoPointEntry.cpp \ + $(SRC)/Dialogs/Weather/WeatherDialog.cpp \ + $(SRC)/Dialogs/Weather/RASPDialog.cpp \ + $(SRC)/Dialogs/dlgCredits.cpp \ + $(SRC)/Dialogs/dlgQuickMenu.cpp \ + \ + $(SRC)/Dialogs/DownloadFilePicker.cpp \ + +## ifeq ($(HAVE_HTTP),y) +DIALOG_SOURCES += \ + $(SRC)/Dialogs/DownloadFilePicker.cpp \ + $(SRC)/Repository/Glue.cpp \ + +## $(SRC)/Renderer/NOAAListRenderer.cpp \ +## $(SRC)/Weather/PCMet/Images.cpp \ +## $(SRC)/Weather/PCMet/Overlays.cpp \ +## $(SRC)/Weather/NOAAGlue.cpp \ +## $(SRC)/Weather/METARParser.cpp \ +## $(SRC)/Weather/NOAAFormatter.cpp \ +## $(SRC)/Weather/NOAADownloader.cpp \ +## $(SRC)/Weather/NOAAStore.cpp \ +## $(SRC)/Weather/NOAAUpdater.cpp +## endif + OV_MENU_SOURCES = \ + $(DIALOG_SOURCES) \ + $(SRC)/OpenVario/OpenVarioBaseMenu.cpp \ + \ + $(SRC)/OpenVario/SystemSettingsWidget.cpp \ + $(SRC)/OpenVario/DisplaySettingsWidget.cpp \ + $(SRC)/OpenVario/FileMenuWidget.cpp \ + $(SRC)/OpenVario/ExtraWidget.cpp \ + \ + $(SRC)/OpenVario/System/SystemMenuWidget.cpp \ + \ + $(SRC)/OpenVario/System/OpenVarioDevice.cpp \ + $(SRC)/OpenVario/System/OpenVarioTools.cpp \ + \ + $(SRC)/OpenVario/System/Setting/RotationWidget.cpp \ + $(SRC)/OpenVario/System/Setting/WifiWidget.cpp \ + \ + $(SRC)/OpenVario/System/WifiDialogOV.cpp \ + $(SRC)/OpenVario/System/WifiSupplicantOV.cpp \ + \ $(SRC)/Version.cpp \ $(SRC)/Asset.cpp \ - $(SRC)/LocalPath.cpp \ - $(SRC)/FlightInfo.cpp \ $(SRC)/Formatter/HexColor.cpp \ $(SRC)/Formatter/TimeFormatter.cpp \ $(SRC)/Hardware/CPU.cpp \ $(SRC)/Hardware/DisplayDPI.cpp \ $(SRC)/Hardware/RotateDisplay.cpp \ + $(SRC)/Hardware/DisplayGlue.cpp \ $(SRC)/Screen/Layout.cpp \ $(SRC)/ui/control/TerminalWindow.cpp \ $(SRC)/Look/TerminalLook.cpp \ @@ -15,8 +214,6 @@ OV_MENU_SOURCES = \ $(SRC)/Look/ButtonLook.cpp \ $(SRC)/Look/CheckBoxLook.cpp \ $(SRC)/Renderer/TwoTextRowsRenderer.cpp \ - $(SRC)/Renderer/FlightListRenderer.cpp \ - $(SRC)/Logger/FlightParser.cpp \ $(SRC)/Gauge/LogoView.cpp \ $(SRC)/Dialogs/DialogSettings.cpp \ $(SRC)/Dialogs/WidgetDialog.cpp \ @@ -27,17 +224,78 @@ OV_MENU_SOURCES = \ $(SRC)/Dialogs/KnobTextEntry.cpp \ $(SRC)/Dialogs/TouchTextEntry.cpp \ $(SRC)/Dialogs/ProcessDialog.cpp \ - $(SRC)/Dialogs/Error.cpp \ + $(SRC)/Profile/Map.cpp \ + $(SRC)/Profile/File.cpp \ + $(SRC)/Profile/NumericValue.cpp \ $(TEST_SRC_DIR)/Fonts.cpp \ - $(TEST_SRC_DIR)/FakeLanguage.cpp \ - $(TEST_SRC_DIR)/FakeLogFile.cpp \ - $(SRC)/Kobo/FakeSymbols.cpp \ - $(SRC)/OV/System.cpp \ - $(SRC)/OV/OpenVarioMenu.cpp -OV_MENU_DEPENDS = DBUS WIDGET FORM DATA_FIELD SCREEN EVENT RESOURCE ASYNC LIBNET OS IO THREAD TIME MATH UTIL + $(SRC)/Language/Language.cpp \ + \ + $(SRC)/LocalPath.cpp \ + $(SRC)/LogFile.cpp \ + $(SRC)/Form/DigitEntry.cpp \ + $(SRC)/Renderer/TextRowRenderer.cpp \ + $(SRC)/net/http/DownloadManager.cpp \ + $(SRC)/Profile/Map.cpp \ + $(SRC)/Profile/File.cpp \ + $(SRC)/Profile/NumericValue.cpp \ + $(SRC)/Profile/Profile.cpp \ + $(SRC)/Profile/ProfileMap.cpp \ + \ + $(SRC)/ProgressWindow.cpp \ + \ + $(SRC)/ResourceLoader.cpp \ + $(SRC)/Repository/Parser.cpp \ + $(SRC)/ResourceLoader.cpp \ + $(SRC)/event/Call.cxx \ + $(SRC)/Math/FastTrig.cpp \ + $(SRC)/ui/window/ContainerWindow.cpp \ + $(SRC)/Operation/Operation.cpp \ + \ + $(SRC)/UtilsSettings.cpp \ + \ + +# $(SRC)/Operation/ConsoleOperationEnvironment.cpp + +OV_MENU_DEPENDS = WIDGET FORM DATA_FIELD SCREEN EVENT RESOURCE ASYNC LIBNET OS IO THREAD TIME MATH UTIL \ + LANGUAGE \ + LIBMAPWINDOW \ + GETTEXT \ + PROFILE \ + LOOK \ + LIBHTTP \ + CO OPERATION UNITS \ + DBUS + +# $(TEST_SRC_DIR)/Fonts.cpp +# $(SRC)/Language/Language.cpp # $(TEST_SRC_DIR)/FakeLanguage.cpp +# $(SRC)/LocalPath.cpp +# $(SRC)/LogFile.cpp # $(TEST_SRC_DIR)/FakeLogFile.cpp + + +### $(SRC)/Profile/Profile.cpp \ +### $(SRC)/Profile/Map.cpp \ +### $(SRC)/Profile/ProfileMap.cpp \ +### $(SRC)/Profile/File.cpp \ +### $(SRC)/Profile/NumericValue.cpp \ +### $(SRC)/Profile/Current.cpp \ + +### $(SRC)/Dialogs/ComboPicker.cpp \ +### $(SRC)/Dialogs/ListPicker.cpp \ +### $(SRC)/Dialogs/FilePicker.cpp \ +### $(SRC)/Dialogs/NumberEntry.cpp \ +### $(SRC)/Dialogs/TextEntry.cpp \ +### $(SRC)/Dialogs/KnobTextEntry.cpp \ +### $(SRC)/Dialogs/TouchTextEntry.cpp \ +### $(SRC)/Dialogs/TimeEntry.cpp \ +### $(SRC)/Dialogs/DateEntry.cpp \ +### $(SRC)/Dialogs/GeoPointEntry.cpp \ +### \ +### $(SRC)/Dialogs/DataField.cpp + + OV_MENU_STRIP = y -$(eval $(call link-program,OpenVarioMenu,OV_MENU)) +$(eval $(call link-program,OpenVarioBaseMenu,OV_MENU)) ifeq ($(TARGET),UNIX) OPTIONAL_OUTPUTS += $(OV_MENU_BIN) diff --git a/build/resource.mk b/build/resource.mk index e1b8e1cc138..ce0333128ef 100644 --- a/build/resource.mk +++ b/build/resource.mk @@ -1,6 +1,10 @@ include build/rsvg.mk include build/imagemagick.mk +# TODO(August2111): what is with setting in main.mk? +# PROGRAM_NAME = XCSoar +# PROGRAM_NAME = OpenSoar + USE_WIN32_RESOURCES = $(call bool_and,$(HAVE_WIN32),$(call bool_not,$(ENABLE_SDL))) ifeq ($(USE_WIN32_RESOURCES),y) @@ -82,15 +86,24 @@ $(ICNS_SPLASH_1024): %.icns: %.png ####### version -SVG_TITLE = Data/graphics/title.svg Data/graphics/title_red.svg -PNG_TITLE_110 = $(patsubst Data/graphics/%.svg,$(DATA)/graphics/%_110.png,$(SVG_TITLE)) +SVG_TITLE = Data/graphics/title.svg +# Data/graphics/title_red.svg +SVG_TMP_TITLE = $(DATA)/temp/graphics/title.svg $(DATA)/temp/graphics/title_red.svg +# convert to title +$(DATA)/temp/graphics/%.svg: $(SVG_TITLE) $(topdir)/OpenSoar.config + @$(NQ)echo " TMP_SVG: $< == $@" + $(Q)$(MKDIR) -p $(DATA)/temp/graphics + $(Q)$(MKDIR) -p $(OUT)/include + $(Q)python3 $(topdir)/tools/python/replace.py $(topdir)/OpenSoar.config $< $@ $(OUT)/include/ProgramVersion.h + +PNG_TITLE_110 = $(patsubst $(DATA)/temp/graphics/%.svg,$(DATA)/graphics/%_110.png,$(SVG_TMP_TITLE)) BMP_TITLE_110 = $(PNG_TITLE_110:.png=.bmp) -PNG_TITLE_320 = $(patsubst Data/graphics/%.svg,$(DATA)/graphics/%_320.png,$(SVG_TITLE)) +PNG_TITLE_320 = $(patsubst $(DATA)/temp/graphics/%.svg,$(DATA)/graphics/%_320.png,$(SVG_TMP_TITLE)) BMP_TITLE_320 = $(PNG_TITLE_320:.png=.bmp) # render from SVG to PNG -$(eval $(call rsvg-convert,$(PNG_TITLE_110),$(DATA)/graphics/%_110.png,Data/graphics/%.svg,--width=110)) -$(eval $(call rsvg-convert,$(PNG_TITLE_320),$(DATA)/graphics/%_320.png,Data/graphics/%.svg,--width=320)) +$(eval $(call rsvg-convert,$(PNG_TITLE_110),$(DATA)/graphics/%_110.png,$(DATA)/temp/graphics/%.svg,--width=110)) +$(eval $(call rsvg-convert,$(PNG_TITLE_320),$(DATA)/graphics/%_320.png,$(DATA)/temp/graphics/%.svg,--width=320)) # convert to uncompressed 8-bit BMP $(eval $(call convert-to-bmp-white,$(BMP_TITLE_110) $(BMP_TITLE_320),%.bmp,%.png)) @@ -167,7 +180,8 @@ endif ####### -TEXT_FILES = AUTHORS COPYING NEWS.txt +# TEXT_FILES = AUTHORS COPYING NEWS.txt +TEXT_FILES = AUTHORS COPYING OpenSoar-News.md TEXT_COMPRESSED = $(patsubst %,$(DATA)/%.gz,$(TEXT_FILES)) $(TEXT_COMPRESSED): $(DATA)/%.gz: % | $(DATA)/dirstamp @@ -181,12 +195,20 @@ $(TARGET_OUTPUT_DIR)/resources.txt: Data/resources.txt | $(TARGET_OUTPUT_DIR)/di @$(NQ)echo " CPP $@" $(Q)cat $< |$(CC) -E -o $@ -I$(OUT)/include $(TARGET_CPPFLAGS) $(OPENGL_CPPFLAGS) $(GDI_CPPFLAGS) - +ifeq ($(TARGET_IS_ANDROID),y) + +$(TARGET_OUTPUT_DIR)/include/MakeResource.hpp: $(TARGET_OUTPUT_DIR)/resources.txt tools/GenerateMakeResource.pl | $(TARGET_OUTPUT_DIR)/include/dirstamp + @$(NQ)echo " GEN $@" + $(Q)$(PERL) tools/GenerateMakeResource.pl <$< >$(TARGET_OUTPUT_DIR)/$(ANDROID_APK_LIB_ABI)/MakeResource.hpp.tmp + $(Q)mv -n $(TARGET_OUTPUT_DIR)/$(ANDROID_APK_LIB_ABI)/MakeResource.hpp.tmp $@ + +else + $(TARGET_OUTPUT_DIR)/include/MakeResource.hpp: $(TARGET_OUTPUT_DIR)/resources.txt tools/GenerateMakeResource.pl | $(TARGET_OUTPUT_DIR)/include/dirstamp @$(NQ)echo " GEN $@" $(Q)$(PERL) tools/GenerateMakeResource.pl <$< >$@.tmp $(Q)mv $@.tmp $@ -ifeq ($(TARGET_IS_ANDROID),n) ifeq ($(USE_WIN32_RESOURCES),y) RESOURCE_FILES += $(BMP_BITMAPS) @@ -221,9 +243,12 @@ ifeq ($(TARGET_IS_ANDROID),n) ifeq ($(USE_WIN32_RESOURCES),y) -$(TARGET_OUTPUT_DIR)/XCSoar.rc: $(TARGET_OUTPUT_DIR)/resources.txt Data/XCSoar.rc tools/GenerateWindowsResources.pl +# old (10.03.2024): RESOURCE_TEXT = Data/$(PROGRAM_NAME).rc +# old (10.03.2024): RESOURCE_BINARY = $(TARGET_OUTPUT_DIR)/$(notdir $(RESOURCE_TEXT:.rc=.rsc)) +# old (10.03.2024): RESOURCE_FILES += $(patsubst po/%.po,$(OUT)/po/%.mo,$(wildcard po/*.po)) +$(TARGET_OUTPUT_DIR)/OpenSoar.rc: $(TARGET_OUTPUT_DIR)/resources.txt Data/OpenSoar.rc tools/GenerateWindowsResources.pl @$(NQ)echo " GEN $@" - $(Q)cp Data/XCSoar.rc $@.tmp + $(Q)cp Data/OpenSoar.rc $@.tmp $(Q)$(PERL) tools/GenerateWindowsResources.pl $< >>$@.tmp $(Q)mv $@.tmp $@ @@ -232,14 +257,15 @@ $(TARGET_OUTPUT_DIR)/include/resource.h: $(TARGET_OUTPUT_DIR)/include/MakeResour $(Q)$(PERL) -ne 'print "#define $$1 $$2\n" if /^MAKE_RESOURCE\((\w+), \S+, (\d+)\);/;' $< >$@.tmp $(Q)mv $@.tmp $@ -RESOURCE_BINARY = $(TARGET_OUTPUT_DIR)/XCSoar.rsc +RESOURCE_BINARY = $(TARGET_OUTPUT_DIR)/OpenSoar.rsc -$(TARGET_OUTPUT_DIR)/XCSoar.rsc: %.rsc: %.rc $(TARGET_OUTPUT_DIR)/include/resource.h $(RESOURCE_FILES) | $(TARGET_OUTPUT_DIR)/%/../dirstamp $(BUILD_TOOLCHAIN_TARGET) +$(TARGET_OUTPUT_DIR)/OpenSoar.rsc: %.rsc: %.rc $(TARGET_OUTPUT_DIR)/include/resource.h $(RESOURCE_FILES) | $(TARGET_OUTPUT_DIR)/%/../dirstamp $(BUILD_TOOLCHAIN_TARGET) @$(NQ)echo " WINDRES $@" $(Q)$(WINDRES) $(WINDRESFLAGS) --include-dir output/data --include-dir Data -o $@ $< else # USE_WIN32_RESOURCES +# old (10.03.2024): $(TARGET_OUTPUT_DIR)/resources.c: $(TARGET_OUTPUT_DIR)/$(PROGRAM_NAME).rc $(OUT)/include/resource.h $(RESOURCE_FILES) tools/LinkResources.pl tools/BinToC.pm | $(TARGET_OUTPUT_DIR)/resources/dirstamp $(TARGET_OUTPUT_DIR)/resources.c: export TARGET_IS_ANDROID:=$(TARGET_IS_ANDROID) $(TARGET_OUTPUT_DIR)/resources.c: export ENABLE_OPENGL:=$(OPENGL) $(TARGET_OUTPUT_DIR)/resources.c: $(TARGET_OUTPUT_DIR)/resources.txt $(RESOURCE_FILES) tools/LinkResources.pl tools/BinToC.pm | $(TARGET_OUTPUT_DIR)/resources/dirstamp diff --git a/build/targets.mk b/build/targets.mk index 52764edb01c..709b1af1cad 100644 --- a/build/targets.mk +++ b/build/targets.mk @@ -3,11 +3,33 @@ TARGETS = PC WIN64 \ WAYLAND \ FUZZER \ PI PI2 CUBIE KOBO NEON \ + OPENVARIO OPENVARIO_CB2 \ ANDROID ANDROID7 ANDROID86 \ ANDROIDAARCH64 ANDROIDX64 \ ANDROIDFAT \ OSX64 IOS32 IOS64 +ifeq ($(TARGET),OPENVARIO) + # the OpenVario is a linux target + # but has special functions, menus,... + override TARGET = UNIX + TARGET_IS_OPENVARIO = y +else + TARGET_IS_OPENVARIO = n +endif + +ifeq ($(TARGET),OPENVARIO_CB2) + # the OpenVario is a linux target + # but has special functions, menus,... + # in difference to OPENVARIO it is really compiled for OpenVario device + override TARGET = UNIX + TARGET_IS_OPENVARIO = y + TARGET_IS_OVDEVICE = y +else + TARGET_IS_OVDEVICE = n +endif + + ifeq ($(TARGET),) ifeq ($(HOST_IS_UNIX),y) ifeq ($(HOST_IS_DARWIN),y) @@ -421,9 +443,19 @@ ifeq ($(HAVE_POSIX),y) TARGET_CPPFLAGS += -DHAVE_VASPRINTF endif +ifeq ($(TARGET_IS_OPENVARIO),y) + override TARGET_FLAVOR = OPENVARIO + TARGET_CPPFLAGS += -DIS_OPENVARIO + # TARGET_CPPFLAGS += -isystem /usr/include/dbus-1.0 -isystem /usr/lib/x86_64-linux-gnu/dbus-1.0/include +endif + +ifeq ($(TARGET_IS_OVDEVICE),y) + TARGET_CPPFLAGS += -DIS_OPENVARIO_CB2 +endif + ifeq ($(HAVE_MSVCRT),y) TARGET_CPPFLAGS += -DHAVE_MSVCRT - TARGET_CPPFLAGS += -DUNICODE -D_UNICODE + # TARGET_CPPFLAGS += -DUNICODE -D_UNICODE TARGET_CPPFLAGS += -DSTRICT endif diff --git a/build/vali.mk b/build/vali.mk index 8e9724dac5f..6b60b84f323 100644 --- a/build/vali.mk +++ b/build/vali.mk @@ -1,5 +1,6 @@ # Rules for VALI-XCS.exe, the non-interactive G record validation tool +ifeq ($(PROGRAM_NAME),xcsoar) VALI_XCS_SOURCES = \ $(SRC)/Logger/GRecord.cpp \ $(SRC)/util/MD5.cpp \ @@ -9,3 +10,5 @@ VALI_XCS_DEPENDS = IO OS UTIL VALI_XCS_STRIP = y $(eval $(call link-program,vali-xcs,VALI_XCS)) + +endif \ No newline at end of file diff --git a/build/version.mk b/build/version.mk index 521cf094251..fc0fae6ed77 100644 --- a/build/version.mk +++ b/build/version.mk @@ -1,14 +1,33 @@ -VERSION = $(strip $(shell cat $(topdir)/VERSION.txt)) -FULL_VERSION = $(VERSION) +CONFIG = $(topdir)/OpenSoar.config +include $(CONFIG) -VERSION_CPPFLAGS = -DXCSOAR_VERSION=\"$(VERSION)\" +# w/o VERSION.txt: +ifeq ($(PROGRAM_VERSION),"") + # take the version from XCSoar VERSION.txt + PROGRAM_VERSION = $(strip $(shell cat $(topdir)/VERSION.txt)) +endif + +$(info PROGRAM_NAME is $(PROGRAM_NAME)) +$(info PROGRAM_VERSION is $(PROGRAM_VERSION)) + +FULL_VERSION = $(PROGRAM_VERSION) + +VERSION_CPPFLAGS = -DPROGRAM_VERSION=\"$(PROGRAM_VERSION)\" + +GIT_COMMIT_ID := $(shell git rev-parse --short --verify HEAD ) +GIT_TAG=tags/opensoar-$(PROGRAM_VERSION) +$(info GIT_TAG is $(GIT_TAG) ) +RELEASE_COMMIT_ID := $(shell git rev-parse --short --verify $(GIT_TAG)^0 ) + +$(info GIT_COMMIT_ID is $(GIT_COMMIT_ID) ) +$(info RELEASE_COMMIT_ID is $(RELEASE_COMMIT_ID) ) -GIT_COMMIT_ID := $(shell git rev-parse --short --verify HEAD 2>$(NUL)) -RELEASE_COMMIT_ID := $(shell git rev-parse --short --verify "v$(VERSION)^{commit}" 2>$(NUL)) # only append the commit id for unreleased builds (no release tag) -ifneq ($(GIT_COMMIT_ID),$(RELEASE_COMMIT_ID)) VERSION_CPPFLAGS += -DGIT_COMMIT_ID=\"$(GIT_COMMIT_ID)\" FULL_VERSION := $(FULL_VERSION)~$(GIT_COMMIT_ID) +ifneq ($(GIT_COMMIT_ID),$(RELEASE_COMMIT_ID) ) + $(info Git commits: HEAD = $(GIT_COMMIT_ID) vs. RELEASE = $(RELEASE_COMMIT_ID) ) + VERSION_CPPFLAGS += -DRELEASE_COMMIT_ID=\"$(RELEASE_COMMIT_ID)\" endif $(call SRC_TO_OBJ,$(SRC)/Version.cpp): $(topdir)/VERSION.txt diff --git a/build/warnings.mk b/build/warnings.mk index edc2a47e403..0ff06fde78e 100644 --- a/build/warnings.mk +++ b/build/warnings.mk @@ -2,7 +2,13 @@ WARNINGS = -Wall -Wextra WARNINGS += -Wwrite-strings -Wcast-qual -Wpointer-arith -Wsign-compare WARNINGS += -Wundef WARNINGS += -Wmissing-declarations -WARNINGS += -Wredundant-decls + +ifeq ($(TARGET),PC) + WARNINGS += -Wno-builtin-macro-redefined + WARNINGS += -Wno-redundant-decls +else + WARNINGS += -Wredundant-decls +endif CXX_WARNINGS = $(WARNINGS) CXX_WARNINGS += -Wmissing-noreturn diff --git a/ide/msvc/OpenSoar.vcxproj.user.in b/ide/msvc/OpenSoar.vcxproj.user.in new file mode 100644 index 00000000000..21c897d4cc7 --- /dev/null +++ b/ide/msvc/OpenSoar.vcxproj.user.in @@ -0,0 +1,11 @@ + + + + -fly -1400x700 -profile=@OPENSOARDATA@/August.prf -datapath=@OPENSOARDATA@ + WindowsLocalDebugger + + + -fly -1400x700 -profile=@OPENSOARDATA@/August.prf -datapath=@OPENSOARDATA@ + WindowsLocalDebugger + + \ No newline at end of file diff --git a/ide/msvc/XCSoar.vcxproj.user.in b/ide/msvc/XCSoar.vcxproj.user.in new file mode 100644 index 00000000000..c7134100cc0 --- /dev/null +++ b/ide/msvc/XCSoar.vcxproj.user.in @@ -0,0 +1,11 @@ + + + + -fly -1400x700 -profile=@XCSOARDATA@/August.prf -datapath=@XCSOARDATA@ + WindowsLocalDebugger + + + -fly -1400x700 -profile=@XCSOARDATA@/August.prf -datapath=@XCSOARDATA@ + WindowsLocalDebugger + + \ No newline at end of file diff --git a/ide/xcsoar.natvis b/ide/xcsoar.natvis new file mode 100644 index 00000000000..45fc8189e0b --- /dev/null +++ b/ide/xcsoar.natvis @@ -0,0 +1,30 @@ + + + + + + + + + {the_data._Elems, na} + the_data._Elems + + ((std::array<$T1,$T2>)the_data) + the_data._Elems, na + $T2 + + + + + {data, na} + + data, na + size + + + + + ScreenGlobalInit! + + + diff --git a/lib/lua/patches/ios_no_system.diff b/lib/lua/patches/ios_no_system.diff index bca42e56f03..b679a635ade 100644 --- a/lib/lua/patches/ios_no_system.diff +++ b/lib/lua/patches/ios_no_system.diff @@ -1,7 +1,7 @@ -Index: lua-5.4.4/src/loslib.c +Index: lua-5.4.6/src/loslib.c =================================================================== ---- lua-5.4.4.orig/src/loslib.c -+++ lua-5.4.4/src/loslib.c +--- lua-5.4.6.orig/src/loslib.c ++++ lua-5.4.6/src/loslib.c @@ -21,6 +21,9 @@ #include "lauxlib.h" #include "lualib.h" @@ -13,7 +13,7 @@ Index: lua-5.4.4/src/loslib.c /* ** {================================================================== @@ -139,6 +142,7 @@ - + #endif +#if !defined(__APPLE__) || !TARGET_OS_IPHONE @@ -28,7 +28,7 @@ Index: lua-5.4.4/src/loslib.c static int os_remove (lua_State *L) { -@@ -408,7 +413,9 @@ static const luaL_Reg syslib[] = { +@@ -406,7 +411,9 @@ static const luaL_Reg syslib[] = { {"clock", os_clock}, {"date", os_date}, {"difftime", os_difftime}, @@ -38,7 +38,7 @@ Index: lua-5.4.4/src/loslib.c {"exit", os_exit}, {"getenv", os_getenv}, {"remove", os_remove}, -@@ -427,4 +434,3 @@ LUAMOD_API int luaopen_os (lua_State *L) +@@ -425,4 +432,3 @@ LUAMOD_API int luaopen_os (lua_State *L) luaL_newlib(L, syslib); return 1; } diff --git a/po/CMakeLists.txt b/po/CMakeLists.txt new file mode 100644 index 00000000000..9165b47d961 --- /dev/null +++ b/po/CMakeLists.txt @@ -0,0 +1,61 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + +# get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) +set(TARGET_NAME po-Files) + +# include(CMakeSource.cmake) +# organize the files in subdirectories + +find_program(PYTHON_APP NAMES python REQUIRED) + +set (SOURCE_FILES) + +# set(PO_FILES "${PROJECTGROUP_SOURCE_DIR}/po/de.po") +file(GLOB PO_FILES "*.po") +set(SCRIPT_FILES ) +set(MO_C_FILES) +set(output_dir ${OUTPUT_FOLDER}/data) +get_filename_component(_python_dir ${PYTHON_APP} DIRECTORY) +set(MSGFMT "${_python_dir}/Tools/i18n/msgfmt.py") + +if (1) # only if a po_file changed... + foreach(po_file ${PO_FILES}) + get_filename_component(lang_name ${po_file} NAME_WE) + ## message(STATUS "po_file = ${po_file} ") + set(out_file ${output_dir}/${lang_name}.mo.c) + set(_mo_file ${output_dir}/temp/${lang_name}.mo) + # add_custom_command(TARGET ${TARGET_NAME} POST_BUILD + add_custom_command(OUTPUT ${out_file} + COMMAND ${CMAKE_COMMAND} -E make_directory ${output_dir}/temp + COMMAND ${PYTHON_APP} ${MSGFMT} --output-file=${_mo_file} ${po_file} + COMMAND ${PYTHON_APP} tools/python/bin2c.py ${_mo_file} ${output_dir} + WORKING_DIRECTORY ${PROJECTGROUP_SOURCE_DIR} + COMMENT "${lang_name} ==> ${out_file}" + DEPENDS ${po_file} + ) + list(APPEND MO_C_FILES ${out_file}) + endforeach() +endif() +#! add_custom_target(${TARGET_NAME} +### add_custom_target(TARGET ${TARGET_NAME} PRE_BUILD +### COMMAND ${CMAKE_COMMAND} -E make_directory ${output_dir}/temp +### WORKING_DIRECTORY ${PROJECTGROUP_SOURCE_DIR} +### COMMENT Make dir '${output_dir}' +### ) + +if(MSVC) + source_group("po-Files" FILES ${PO_FILES}) +endif() + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} ${MO_C_FILES} ${PO_FILES}) +set_target_properties(${TARGET_NAME} PROPERTIES + LINKER_LANGUAGE C + FOLDER Data +) + +add_dependencies(${TARGET_NAME} Data) + + diff --git a/po/de.po b/po/de.po index 626d4385147..3c62a6bcb86 100644 --- a/po/de.po +++ b/po/de.po @@ -8237,12 +8237,14 @@ msgstr "Wind - Geschwindigkeit" #: src/InfoBoxes/Content/Factory.cpp:324 src/InfoBoxes/Content/Factory.cpp:921 #, no-c-format msgid "" -"Wind speed estimated by XCSoar. Manual adjustment is possible with the " -"connected InfoBox dialogue. Pressing the up/down cursor keys to cycle " -"through settings, adjust the values with left/right cursor keys." -msgstr "" -"Von XCSoar geschätzte Windgeschwindigkeit. Manuelles einstellen ist mit dem " -"InfoBox Dialog möglich. Pfeiltaste hoch/runter wechselt durch die " +"Wind speed estimated by XCSoar or external sensor (if available). " +"Manual adjustment is possible with the connected InfoBox dialogue. " +"Pressing the up/down cursor keys to cycle through settings, adjust " +"the values with left/right cursor keys." +msgstr "" +"Von XCSoar oder einem externen Sensor (wenn verfügbar) geschätzte " +"Windgeschwindigkeit. Manuelles Einstellen ist mit dem InfoBox Dialog " +"möglich: Pfeiltaste hoch/runter wechselt durch die " "Einstellungen, links und rechts verändert die Werte." #: src/InfoBoxes/Content/Factory.cpp:331 @@ -8253,11 +8255,13 @@ msgstr "Wind - Richtung" #: src/InfoBoxes/Content/Factory.cpp:333 #, no-c-format msgid "" -"Wind bearing estimated by XCSoar. Manual adjustment is possible with the " -"connected InfoBox dialogue. Pressing the up/down cursor keys to cycle " -"through settings, adjust the values with left/right cursor keys." +"Wind bearing estimated by XCSoar or external sensor (if available). " +"Manual adjustment is possible with the connected InfoBox dialogue. " +"Pressing the up/down cursor keys to cycle through settings, adjust " +"the values with left/right cursor keys." msgstr "" -"Von XCSoar geschätzte Windrichtung. Manuelles einstellen ist mit dem InfoBox " +"Von XCSoar oder einem externen Sensor (wenn verfügbar) geschätzte " +"Windrichtung. Manuelles Einstellen ist mit dem InfoBox " "Dialog möglich. Pfeiltaste hoch/runter wechselt durch die Einstellungen, " "links und rechts verändert die Werte." @@ -9698,7 +9702,7 @@ msgstr "Contest Durchschnittsgeschwindigkeit" #: src/InfoBoxes/Content/Factory.cpp:995 #, no-c-format msgid "Cont Speed" -msgstr "Const Geschw" +msgstr "Cont Geschw" #: src/InfoBoxes/Content/Factory.cpp:996 #, no-c-format @@ -9875,7 +9879,7 @@ msgstr "Alternative 2 - Gleitzahl" #: src/InfoBoxes/Content/Factory.cpp:1078 #, no-c-format msgid "Altn2 GR" -msgstr "Altn1 benö GZ" +msgstr "Altn2 benö GZ" #: src/InfoBoxes/Content/Factory.cpp:1079 #, no-c-format diff --git a/src/ActionInterface.cpp b/src/ActionInterface.cpp index 6852528b7af..7c73772b4e1 100644 --- a/src/ActionInterface.cpp +++ b/src/ActionInterface.cpp @@ -260,7 +260,7 @@ ActionInterface::SendUIState() noexcept void ActionInterface::SetActiveFrequency(const RadioFrequency freq, - const TCHAR *freq_name, + const char *freq_name, bool to_devices) noexcept { assert(freq.IsDefined()); @@ -289,7 +289,7 @@ ActionInterface::SetActiveFrequency(const RadioFrequency freq, void ActionInterface::SetStandbyFrequency(const RadioFrequency freq, - const TCHAR *freq_name, + const char *freq_name, bool to_devices) noexcept { assert(freq.IsDefined()); diff --git a/src/ActionInterface.hpp b/src/ActionInterface.hpp index 71a0195e5a6..306dbce509c 100644 --- a/src/ActionInterface.hpp +++ b/src/ActionInterface.hpp @@ -101,7 +101,7 @@ SendUIState() noexcept; * @param to_devices send the new setting to all devices? */ void -SetActiveFrequency(RadioFrequency freq, const TCHAR *freq_name, +SetActiveFrequency(RadioFrequency freq, const char *freq_name, bool to_devices=true) noexcept; /** @@ -111,7 +111,7 @@ SetActiveFrequency(RadioFrequency freq, const TCHAR *freq_name, * @param to_devices send the new setting to all devices? */ void -SetStandbyFrequency(RadioFrequency freq, const TCHAR *freq_name, +SetStandbyFrequency(RadioFrequency freq, const char *freq_name, bool to_devices=true) noexcept; /** diff --git a/src/Airspace/AirspaceParser.cpp b/src/Airspace/AirspaceParser.cpp index 4a36a968990..7be96e6384f 100644 --- a/src/Airspace/AirspaceParser.cpp +++ b/src/Airspace/AirspaceParser.cpp @@ -18,7 +18,6 @@ #include "lib/fmt/RuntimeError.hxx" #include "io/BufferedReader.hxx" #include "io/StringConverter.hpp" -#include "util/ConvertString.hpp" #include "util/StaticString.hxx" #include "util/StringCompare.hxx" #include "util/StringSplit.hxx" @@ -121,10 +120,10 @@ struct TempAirspace } // General - tstring name; + std::string name; RadioFrequency radio_frequency; AirspaceClass asclass; - tstring astype; + std::string astype; std::optional base; std::optional top; AirspaceActivity days_of_operation; @@ -425,6 +424,7 @@ ReadAltitude(StringParser<> &input) return altitude; default: + altitude = {0, 0, 0, AltitudeReference::STD}; // otherwise not initialized break; } @@ -898,7 +898,8 @@ ParseLineTNP(Airspaces &airspace_database, unsigned line_number, } else if (input.SkipMatchIgnoreCase("BASE="sv)) { temp_area.base = ReadAltitude(input); } else if (input.SkipMatchIgnoreCase("RADIO="sv)) { - temp_area.radio_frequency = RadioFrequency::Parse(ReadRadioFrequency(input.c_str())); + temp_area.radio_frequency = RadioFrequency:: + Parse(ReadRadioFrequency(input.c_str())); } else if (input.SkipMatchIgnoreCase("ACTIVE="sv)) { if (input.MatchAllIgnoreCase("WEEKEND")) temp_area.days_of_operation.SetWeekend(); @@ -973,7 +974,7 @@ ParseAirspaceFile(Airspaces &airspaces, } if (filetype == AirspaceFileType::UNKNOWN) - throw std::runtime_error(WideToUTF8Converter(_("Unknown airspace filetype"))); + throw std::runtime_error(_("Unknown airspace filetype")); // Process final area (if any) temp_area.Commit(airspaces); diff --git a/src/Airspace/CMakeLists.txt b/src/Airspace/CMakeLists.txt new file mode 100644 index 00000000000..c73add87267 --- /dev/null +++ b/src/Airspace/CMakeLists.txt @@ -0,0 +1,56 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +# project(${TARGET_NAME} CXX) # Your project name + +include(CMakeSource.cmake) +# organize the files in subdirectories +include(CMakeSource.cmake) +set(SOURCE_FILES ) +# foreach(source_file ${_SOURCES}) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) +### ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +### message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +# include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(${CMAKE_SOURCE_DIR}) +include_directories(${CMAKE_SOURCE_DIR}/Engine) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) + +target_link_libraries(${TARGET_NAME} PUBLIC io Engine) + +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/Airspace/CMakeSource.cmake b/src/Airspace/CMakeSource.cmake new file mode 100644 index 00000000000..ac0c17e330e --- /dev/null +++ b/src/Airspace/CMakeSource.cmake @@ -0,0 +1,15 @@ + +set(_SOURCES + Airspace/ActivePredicate.cpp + Airspace/AirspaceComputerSettings.cpp + Airspace/AirspaceGlue.cpp + Airspace/AirspaceParser.cpp + Airspace/AirspaceVisibility.cpp + Airspace/NearestAirspace.cpp + Airspace/ProtectedAirspaceWarningManager.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake +) + diff --git a/src/Android/BMP085Device.cpp b/src/Android/BMP085Device.cpp index 8439e05eb5c..4443d2492f6 100644 --- a/src/Android/BMP085Device.cpp +++ b/src/Android/BMP085Device.cpp @@ -12,10 +12,10 @@ static jmethodID bmp085_ctor; void BMP085Device::Initialise(JNIEnv *env) noexcept { - bmp085_class.Find(env, "org/xcsoar/GlueBMP085"); + bmp085_class.Find(env, "de/opensoar/GlueBMP085"); bmp085_ctor = env->GetMethodID(bmp085_class, "", - "(Lorg/xcsoar/IOIOConnectionHolder;IIILorg/xcsoar/SensorListener;)V"); + "(Lde/opensoar/IOIOConnectionHolder;IIILde/opensoar/SensorListener;)V"); } void diff --git a/src/Android/Battery.cpp b/src/Android/Battery.cpp index 43d08a2823e..0dae682eaa1 100644 --- a/src/Android/Battery.cpp +++ b/src/Android/Battery.cpp @@ -3,12 +3,12 @@ #include "Hardware/PowerGlobal.hpp" #include "Hardware/PowerInfo.hpp" -#include "org_xcsoar_BatteryReceiver.h" +#include "de_opensoar_BatteryReceiver.h" #include "util/Compiler.h" gcc_visibility_default JNIEXPORT void JNICALL -Java_org_xcsoar_BatteryReceiver_setBatteryPercent([[maybe_unused]] JNIEnv *env, [[maybe_unused]] jclass cls, +Java_de_opensoar_BatteryReceiver_setBatteryPercent([[maybe_unused]] JNIEnv *env, [[maybe_unused]] jclass cls, jint value, jint plugged) { auto &info = Power::global_info; diff --git a/src/Android/BluetoothHelper.cpp b/src/Android/BluetoothHelper.cpp index bf50bc8a9e4..e6d68707daf 100644 --- a/src/Android/BluetoothHelper.cpp +++ b/src/Android/BluetoothHelper.cpp @@ -32,14 +32,14 @@ BluetoothHelper::Initialise(JNIEnv *env) noexcept { assert(env != nullptr); - if (!cls.FindOptional(env, "org/xcsoar/BluetoothHelper")) + if (!cls.FindOptional(env, "de/opensoar/BluetoothHelper")) /* Android < 2.0 doesn't have Bluetooth support */ return false; ctor = env->GetMethodID(cls, "", "(Landroid/content/Context;" - "Lorg/xcsoar/PermissionManager;" + "Lde/opensoar/PermissionManager;" ")V"); if (Java::DiscardException(env)) { /* need to check for Java exceptions again because the first @@ -53,23 +53,23 @@ BluetoothHelper::Initialise(JNIEnv *env) noexcept getNameFromAddress_method = env->GetMethodID(cls, "getNameFromAddress", "(Ljava/lang/String;)Ljava/lang/String;"); connectSensor_method = env->GetMethodID(cls, "connectSensor", - "(Ljava/lang/String;Lorg/xcsoar/SensorListener;)" - "Lorg/xcsoar/BluetoothSensor;"); + "(Ljava/lang/String;Lde/opensoar/SensorListener;)" + "Lde/opensoar/BluetoothSensor;"); connect_method = env->GetMethodID(cls, "connect", "(Ljava/lang/String;)" - "Lorg/xcsoar/AndroidPort;"); + "Lde/opensoar/AndroidPort;"); createServer_method = env->GetMethodID(cls, "createServer", - "()Lorg/xcsoar/AndroidPort;"); + "()Lde/opensoar/AndroidPort;"); hm10connect_method = env->GetMethodID(cls, "connectHM10", "(Ljava/lang/String;)" - "Lorg/xcsoar/AndroidPort;"); + "Lde/opensoar/AndroidPort;"); addDetectDeviceListener_method = env->GetMethodID(cls, "addDetectDeviceListener", - "(Lorg/xcsoar/DetectDeviceListener;)V"); + "(Lde/opensoar/DetectDeviceListener;)V"); removeDetectDeviceListener_method = env->GetMethodID(cls, "removeDetectDeviceListener", - "(Lorg/xcsoar/DetectDeviceListener;)V"); + "(Lde/opensoar/DetectDeviceListener;)V"); return true; } diff --git a/src/Android/CMakeLists.txt b/src/Android/CMakeLists.txt new file mode 100644 index 00000000000..ec1682560d9 --- /dev/null +++ b/src/Android/CMakeLists.txt @@ -0,0 +1,64 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +# project(${TARGET_NAME} CXX) # Your project name + +# organize the files in subdirectories +include(CMakeSource.cmake) +set(SOURCE_FILES ) + +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) +### ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +### message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +# include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(${CMAKE_SOURCE_DIR}) +include_directories(${CMAKE_SOURCE_DIR}/Engine) + +if(ANDROID) +set(_BUILD_CONDITION ) +else() +set(_BUILD_CONDITION EXCLUDE_FROM_ALL ) +endif() +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${_BUILD_CONDITION} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) + +target_link_libraries(${TARGET_NAME} PUBLIC io Engine) + +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES + FOLDER _Main + EXCLUDE_FROM_ALL TRUE +) + +# add_dependencies(${TARGET_NAME} _Main) diff --git a/src/Android/CMakeSource.cmake b/src/Android/CMakeSource.cmake new file mode 100644 index 00000000000..27432100969 --- /dev/null +++ b/src/Android/CMakeSource.cmake @@ -0,0 +1,68 @@ + +set(_SOURCES + ${SRC}/java/Global.cxx + ${SRC}/java/Object.cxx + ${SRC}/java/String.cxx + ${SRC}/java/Exception.cxx + ${SRC}/java/File.cxx + ${SRC}/java/Path.cxx + ${SRC}/java/InputStream.cxx + ${SRC}/java/URL.cxx + ${SRC}/java/Closeable.cxx + + ${SRC}/Device/AndroidSensors.cpp + ${SRC}/Device/Port/AndroidPort.cpp + ${SRC}/Device/Port/AndroidBluetoothPort.cpp + ${SRC}/Device/Port/AndroidIOIOUartPort.cpp + ${SRC}/Device/Port/AndroidUsbSerialPort.cpp + + NativeView.cpp + Environment.cpp + Bitmap.cpp + Product.cpp + InternalSensors.cpp + SoundUtil.cpp + TextUtil.cpp + EventBridge.cpp + NativePortListener.cpp + NativeInputListener.cpp + PortBridge.cpp + Sensor.cpp + BluetoothHelper.cpp + NativeDetectDeviceListener.cpp + NativeSensorListener.cpp + Battery.cpp + GliderLink.cpp + DownloadManager.cpp + Vibrator.cpp + Context.cpp + BMP085Device.cpp + I2CbaroDevice.cpp + NunchuckDevice.cpp + VoltageDevice.cpp + IOIOHelper.cpp + UsbSerialHelper.cpp + TextEntryDialog.cpp + FileProvider.cpp + Main.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake +) + +# # # jetzt nicht mehr so ;-) +# # # jetzt nicht mehr so ;-) +# # # jetzt nicht mehr so ;-) add_library(${LIB_TARGET_NAME} ${XCSOAR_LIB_TYPE} +# # # jetzt nicht mehr so ;-) ${SOURCE_FILES} +# # # jetzt nicht mehr so ;-) ${HEADER_FILES} +# # # jetzt nicht mehr so ;-) ${CMAKE_CURRENT_LIST_DIR}/CMakeSource.cmake +# # # jetzt nicht mehr so ;-) ${SCRIPT_FILES} +# # # jetzt nicht mehr so ;-) ) +# # # jetzt nicht mehr so ;-) # message(FATAL_ERROR "Stop!") +# # # jetzt nicht mehr so ;-) +# # # jetzt nicht mehr so ;-) set_target_properties(${LIB_TARGET_NAME} PROPERTIES FOLDER Libs) +# # # jetzt nicht mehr so ;-) +# # # jetzt nicht mehr so ;-) target_link_libraries(${LIB_TARGET_NAME} PUBLIC IO) +# # # jetzt nicht mehr so ;-) +# # # jetzt nicht mehr so ;-) endif() diff --git a/src/Android/DownloadManager.cpp b/src/Android/DownloadManager.cpp index 5ae73886d47..28ddeab4bd6 100644 --- a/src/Android/DownloadManager.cpp +++ b/src/Android/DownloadManager.cpp @@ -13,7 +13,7 @@ #include "io/CopyFile.hxx" #include "util/Macros.hpp" #include "util/StringAPI.hxx" -#include "org_xcsoar_DownloadUtil.h" +#include "de_opensoar_DownloadUtil.h" #include @@ -41,7 +41,7 @@ AndroidDownloadManager::Initialise(JNIEnv *env) noexcept assert(util_class == nullptr); assert(env != nullptr); - if (!util_class.FindOptional(env, "org/xcsoar/DownloadUtil")) + if (!util_class.FindOptional(env, "de/opensoar/DownloadUtil")) return false; ctor = env->GetMethodID(util_class, "", @@ -113,7 +113,7 @@ AndroidDownloadManager::OnDownloadComplete(Path path_relative, } JNIEXPORT void JNICALL -Java_org_xcsoar_DownloadUtil_onDownloadAdded(JNIEnv *env, [[maybe_unused]] jobject obj, +Java_de_opensoar_DownloadUtil_onDownloadAdded(JNIEnv *env, [[maybe_unused]] jobject obj, jlong j_handler, jstring j_path, jlong size, jlong position) { @@ -124,7 +124,7 @@ Java_org_xcsoar_DownloadUtil_onDownloadAdded(JNIEnv *env, [[maybe_unused]] jobje } JNIEXPORT void JNICALL -Java_org_xcsoar_DownloadUtil_onDownloadComplete(JNIEnv *env, [[maybe_unused]] jobject obj, +Java_de_opensoar_DownloadUtil_onDownloadComplete(JNIEnv *env, [[maybe_unused]] jobject obj, jlong ptr, jstring j_tmp_path, jstring j_relative_path, diff --git a/src/Android/EventBridge.cpp b/src/Android/EventBridge.cpp index f8a160d29f5..d346d4269af 100644 --- a/src/Android/EventBridge.cpp +++ b/src/Android/EventBridge.cpp @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -#include "org_xcsoar_EventBridge.h" +#include "de_opensoar_EventBridge.h" #include "Product.hpp" #include "ui/event/Queue.hpp" #include "ui/event/Idle.hpp" @@ -52,10 +52,10 @@ IsCursorKey(unsigned key_code) gcc_visibility_default void -Java_org_xcsoar_EventBridge_onKeyDown([[maybe_unused]] JNIEnv *env, [[maybe_unused]] jclass cls, jint key_code) +Java_de_opensoar_EventBridge_onKeyDown([[maybe_unused]] JNIEnv *env, [[maybe_unused]] jclass cls, jint key_code) { if (event_queue == nullptr) - /* XCSoar not yet initialised */ + /* OpenSoar not yet initialised */ return; if (!has_cursor_keys && IsCursorKey(key_code)) @@ -69,10 +69,10 @@ Java_org_xcsoar_EventBridge_onKeyDown([[maybe_unused]] JNIEnv *env, [[maybe_unus gcc_visibility_default void -Java_org_xcsoar_EventBridge_onKeyUp([[maybe_unused]] JNIEnv *env, [[maybe_unused]] jclass cls, jint key_code) +Java_de_opensoar_EventBridge_onKeyUp([[maybe_unused]] JNIEnv *env, [[maybe_unused]] jclass cls, jint key_code) { if (event_queue == nullptr) - /* XCSoar not yet initialised */ + /* OpenSoar not yet initialised */ return; event_queue->Inject(Event(Event::KEY_UP, TranslateKeyCode(key_code))); @@ -81,11 +81,11 @@ Java_org_xcsoar_EventBridge_onKeyUp([[maybe_unused]] JNIEnv *env, [[maybe_unused gcc_visibility_default void -Java_org_xcsoar_EventBridge_onMouseDown([[maybe_unused]] JNIEnv *env, [[maybe_unused]] jclass cls, +Java_de_opensoar_EventBridge_onMouseDown([[maybe_unused]] JNIEnv *env, [[maybe_unused]] jclass cls, jint x, jint y) { if (event_queue == nullptr) - /* XCSoar not yet initialised */ + /* OpenSoar not yet initialised */ return; event_queue->Inject(Event(Event::MOUSE_DOWN, PixelPoint(x, y))); @@ -94,11 +94,11 @@ Java_org_xcsoar_EventBridge_onMouseDown([[maybe_unused]] JNIEnv *env, [[maybe_un gcc_visibility_default void -Java_org_xcsoar_EventBridge_onMouseUp([[maybe_unused]] JNIEnv *env, [[maybe_unused]] jclass cls, +Java_de_opensoar_EventBridge_onMouseUp([[maybe_unused]] JNIEnv *env, [[maybe_unused]] jclass cls, jint x, jint y) { if (event_queue == nullptr) - /* XCSoar not yet initialised */ + /* OpenSoar not yet initialised */ return; event_queue->Inject(Event(Event::MOUSE_UP, PixelPoint(x, y))); @@ -107,11 +107,11 @@ Java_org_xcsoar_EventBridge_onMouseUp([[maybe_unused]] JNIEnv *env, [[maybe_unus gcc_visibility_default void -Java_org_xcsoar_EventBridge_onMouseMove([[maybe_unused]] JNIEnv *env, [[maybe_unused]] jclass cls, +Java_de_opensoar_EventBridge_onMouseMove([[maybe_unused]] JNIEnv *env, [[maybe_unused]] jclass cls, jint x, jint y) { if (event_queue == nullptr) - /* XCSoar not yet initialised */ + /* OpenSoar not yet initialised */ return; event_queue->Purge(Event::MOUSE_MOTION); @@ -121,10 +121,10 @@ Java_org_xcsoar_EventBridge_onMouseMove([[maybe_unused]] JNIEnv *env, [[maybe_un gcc_visibility_default void -Java_org_xcsoar_EventBridge_onPointerDown([[maybe_unused]] JNIEnv *env, [[maybe_unused]] jclass cls) +Java_de_opensoar_EventBridge_onPointerDown([[maybe_unused]] JNIEnv *env, [[maybe_unused]] jclass cls) { if (event_queue == nullptr) - /* XCSoar not yet initialised */ + /* OpenSoar not yet initialised */ return; event_queue->Inject(Event::POINTER_DOWN); @@ -133,10 +133,10 @@ Java_org_xcsoar_EventBridge_onPointerDown([[maybe_unused]] JNIEnv *env, [[maybe_ gcc_visibility_default void -Java_org_xcsoar_EventBridge_onPointerUp([[maybe_unused]] JNIEnv *env, [[maybe_unused]] jclass cls) +Java_de_opensoar_EventBridge_onPointerUp([[maybe_unused]] JNIEnv *env, [[maybe_unused]] jclass cls) { if (event_queue == nullptr) - /* XCSoar not yet initialised */ + /* OpenSoar not yet initialised */ return; event_queue->Inject(Event::POINTER_UP); diff --git a/src/Android/FileProvider.cpp b/src/Android/FileProvider.cpp index 60b0c6b3ab8..e43f9f08053 100644 --- a/src/Android/FileProvider.cpp +++ b/src/Android/FileProvider.cpp @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The XCSoar Project -#include "org_xcsoar_FileProvider.h" +#include "de_opensoar_FileProvider.h" #include "Engine/Waypoint/Waypoints.hpp" #include "system/Path.hpp" #include "java/String.hxx" @@ -12,7 +12,7 @@ #include JNIEXPORT jstring JNICALL -Java_org_xcsoar_FileProvider_getWaypointFileForUri(JNIEnv *env, jclass, +Java_de_opensoar_FileProvider_getWaypointFileForUri(JNIEnv *env, jclass, jint id, jstring _filename) { auto w = data_components->waypoints->LookupId(id); diff --git a/src/Android/GliderLink.cpp b/src/Android/GliderLink.cpp index f5bb7e235a4..e9ab38bff53 100644 --- a/src/Android/GliderLink.cpp +++ b/src/Android/GliderLink.cpp @@ -16,10 +16,10 @@ GliderLink::Initialise(JNIEnv *env) noexcept assert(!gl_cls.IsDefined()); assert(env != nullptr); - gl_cls.Find(env, "org/xcsoar/GliderLinkReceiver"); + gl_cls.Find(env, "de/opensoar/GliderLinkReceiver"); gl_ctor_id = env->GetMethodID(gl_cls, "", - "(Landroid/content/Context;Lorg/xcsoar/SensorListener;)V"); + "(Landroid/content/Context;Lde/opensoar/SensorListener;)V"); } void diff --git a/src/Android/I2CbaroDevice.cpp b/src/Android/I2CbaroDevice.cpp index 18e3a5327e4..d17e880ef7b 100644 --- a/src/Android/I2CbaroDevice.cpp +++ b/src/Android/I2CbaroDevice.cpp @@ -12,10 +12,10 @@ static jmethodID i2cbaro_ctor; void I2CbaroDevice::Initialise(JNIEnv *env) noexcept { - i2cbaro_class.Find(env, "org/xcsoar/GlueI2Cbaro"); + i2cbaro_class.Find(env, "de/opensoar/GlueI2Cbaro"); i2cbaro_ctor = env->GetMethodID(i2cbaro_class, "", - "(Lorg/xcsoar/IOIOConnectionHolder;IIIIILorg/xcsoar/SensorListener;)V"); + "(Lde/opensoar/IOIOConnectionHolder;IIIIILde/opensoar/SensorListener;)V"); } void diff --git a/src/Android/IOIOHelper.cpp b/src/Android/IOIOHelper.cpp index 61fb2806f7c..544d7133b8b 100644 --- a/src/Android/IOIOHelper.cpp +++ b/src/Android/IOIOHelper.cpp @@ -17,7 +17,7 @@ IOIOHelper::Initialise(JNIEnv *env) assert(!cls.IsDefined()); assert(env != nullptr); - if (!cls.FindOptional(env, "org/xcsoar/IOIOHelper")) + if (!cls.FindOptional(env, "de/opensoar/IOIOHelper")) return false; ctor = env->GetMethodID(cls, "", "()V"); @@ -29,7 +29,7 @@ IOIOHelper::Initialise(JNIEnv *env) } openUart_method = env->GetMethodID(cls, "openUart", - "(II)Lorg/xcsoar/AndroidPort;"); + "(II)Lde/opensoar/AndroidPort;"); shutdown_method = env->GetMethodID(cls, "shutdown", "()V"); return true; diff --git a/src/Android/InternalSensors.cpp b/src/Android/InternalSensors.cpp index 07286b242c3..39f69f8a90d 100644 --- a/src/Android/InternalSensors.cpp +++ b/src/Android/InternalSensors.cpp @@ -26,17 +26,17 @@ InternalSensors::Initialise(JNIEnv *env) assert(!sensors_cls.IsDefined()); assert(env != nullptr); - gps_cls.Find(env, "org/xcsoar/InternalGPS"); + gps_cls.Find(env, "de/opensoar/InternalGPS"); gps_ctor_id = env->GetMethodID(gps_cls, "", "(Landroid/content/Context;" - "Lorg/xcsoar/PermissionManager;" - "Lorg/xcsoar/SensorListener;)V"); + "Lde/opensoar/PermissionManager;" + "Lde/opensoar/SensorListener;)V"); - sensors_cls.Find(env, "org/xcsoar/NonGPSSensors"); + sensors_cls.Find(env, "de/opensoar/NonGPSSensors"); sensors_ctor_id = env->GetMethodID(sensors_cls, "", - "(Landroid/content/Context;Lorg/xcsoar/SensorListener;)V"); + "(Landroid/content/Context;Lde/opensoar/SensorListener;)V"); mid_sensors_getSubscribableSensors = env->GetMethodID(sensors_cls, "getSubscribableSensors", "()[I"); diff --git a/src/Android/Main.cpp b/src/Android/Main.cpp index 5bbcff18bf6..b90e100ffbf 100644 --- a/src/Android/Main.cpp +++ b/src/Android/Main.cpp @@ -45,7 +45,7 @@ #include "java/URL.hxx" #include "java/Closeable.hxx" #include "util/Compiler.h" -#include "org_xcsoar_NativeView.h" +#include "de_opensoar_NativeView.h" #include "io/async/GlobalAsioThread.hpp" #include "io/async/AsioThread.hpp" #include "net/http/Init.hpp" @@ -60,6 +60,9 @@ #include "NunchuckDevice.hpp" #include "VoltageDevice.hpp" +#include "UIGlobals.hpp" + + #include #include @@ -117,7 +120,7 @@ InitNative(JNIEnv *env) noexcept gcc_visibility_default void -Java_org_xcsoar_NativeView_initNative(JNIEnv *env, [[maybe_unused]] jclass cls) +Java_de_opensoar_NativeView_initNative(JNIEnv *env, [[maybe_unused]] jclass cls) { static std::once_flag init_native_flag; @@ -126,7 +129,7 @@ Java_org_xcsoar_NativeView_initNative(JNIEnv *env, [[maybe_unused]] jclass cls) gcc_visibility_default void -Java_org_xcsoar_NativeView_deinitNative(JNIEnv *env, +Java_de_opensoar_NativeView_deinitNative(JNIEnv *env, [[maybe_unused]] jclass cls) { AndroidTextEntryDialog::Deinitialise(env); @@ -152,7 +155,7 @@ Java_org_xcsoar_NativeView_deinitNative(JNIEnv *env, gcc_visibility_default void -Java_org_xcsoar_NativeView_onConfigurationChangedNative([[maybe_unused]] JNIEnv *env, +Java_de_opensoar_NativeView_onConfigurationChangedNative([[maybe_unused]] JNIEnv *env, [[maybe_unused]] jclass cls, jboolean night_mode) { @@ -173,7 +176,7 @@ Java_org_xcsoar_NativeView_onConfigurationChangedNative([[maybe_unused]] JNIEnv gcc_visibility_default JNIEXPORT jstring JNICALL -Java_org_xcsoar_NativeView_onReceiveXCTrackTask(JNIEnv *env, +Java_de_opensoar_NativeView_onReceiveXCTrackTask(JNIEnv *env, [[maybe_unused]] jclass cls, jstring data) try { @@ -183,126 +186,158 @@ try { return env->NewStringUTF(GetFullMessage(std::current_exception()).c_str()); } +#define ANDROID_RERUN +/** ReRun hat 2 grosse Probleme zur Zeit: +* - startet man OpenSoar mit einer SD-Card, befindet sich der Data-Ordner (und +* auch der Cache) dort, bei einem ReRun vesucht er aber, z.B. die Maps und +* Wegpunkte(oder Airspaces) von Data-Ordner des Android zu lesen, der ist +* aber leer... +* - Bei Start Von OpenSoar werden die Log-Files auf dem Telefon angelegt, +* nicht wie alles andere auf der SD-Card... (das ist ein ähnliches Verhalten +* wie bei einem 'Umlegen' des datapath bei anderen Systemen +* - Das Quickmenü hat im 1.Fall 12 Zeilen, im 2.Fall nur noch 11 - als ob das +* Fenster ein wenig kleiner geworden ist +* - Ich habe noch keine Moeglichkeit gefunden, auf die 2.Seite des Quickmenus +* zu gelangen -> mit Touch geht es leider (noch) nicht!!! +*/ gcc_visibility_default JNIEXPORT void JNICALL -Java_org_xcsoar_NativeView_runNative(JNIEnv *env, jobject obj, +Java_de_opensoar_NativeView_runNative(JNIEnv *env, jobject obj, jobject _context, jobject _permission_manager, jint width, jint height, jint xdpi, jint ydpi, jstring product) try { - const std::scoped_lock shutdown_lock{shutdown_mutex}; - - InitThreadDebug(); - - const bool have_bluetooth = BluetoothHelper::Initialise(env); - const bool have_usb_serial = UsbSerialHelper::Initialise(env); - const bool have_ioio = IOIOHelper::Initialise(env); - - context = new Context(env, _context); - AtScopeExit() { - delete context; - context = nullptr; - }; - - permission_manager = env->NewGlobalRef(_permission_manager); - AtScopeExit(env) { env->DeleteGlobalRef(permission_manager); }; - - const ScopeGlobalAsioThread global_asio_thread; - const Net::ScopeInit net_init(asio_thread->GetEventLoop()); - - InitialiseDataPath(); - AtScopeExit() { DeinitialiseDataPath(); }; - - LogFormat(_T("Starting XCSoar %s"), XCSoar_ProductToken); - - TextUtil::Initialise(env); - AtScopeExit(env) { TextUtil::Deinitialise(env); }; - - assert(native_view == nullptr); - native_view = new NativeView(env, obj, width, height, xdpi, ydpi, - product); - AtScopeExit() { - delete native_view; - native_view = nullptr; - }; - - SoundUtil::Initialise(env); - AtScopeExit(env) { SoundUtil::Deinitialise(env); }; - - Vibrator::Initialise(env); - vibrator = Vibrator::Create(env, *context); - - AtScopeExit() { - delete vibrator; - vibrator = nullptr; - }; - - if (have_bluetooth) { - try { - bluetooth_helper = new BluetoothHelper(env, *context, - permission_manager); - } catch (...) { - LogError(std::current_exception(), "Failed to initialise Bluetooth"); +#ifdef ANDROID_RERUN + bool rerun = false; + + do { + // rerun = false; + UI::TopWindow::SetExitValue(0); +#endif + const std::scoped_lock shutdown_lock{shutdown_mutex}; + + InitThreadDebug(); + + const bool have_bluetooth = BluetoothHelper::Initialise(env); + const bool have_usb_serial = UsbSerialHelper::Initialise(env); + const bool have_ioio = IOIOHelper::Initialise(env); + + context = new Context(env, _context); + AtScopeExit() { + delete context; + context = nullptr; + }; + + permission_manager = env->NewGlobalRef(_permission_manager); + AtScopeExit(env) { env->DeleteGlobalRef(permission_manager); }; + + const ScopeGlobalAsioThread global_asio_thread; + const Net::ScopeInit net_init(asio_thread->GetEventLoop()); + + InitialiseDataPath(); + AtScopeExit() { DeinitialiseDataPath(); }; + + LogFormat("Starting OpenSoar %s", OpenSoar_ProductToken); + + TextUtil::Initialise(env); + AtScopeExit(env) { TextUtil::Deinitialise(env); }; + + assert(native_view == nullptr); + native_view = new NativeView(env, obj, width, height, xdpi, ydpi, product); + AtScopeExit() { + delete native_view; + native_view = nullptr; + }; + + SoundUtil::Initialise(env); + AtScopeExit(env) { SoundUtil::Deinitialise(env); }; + + Vibrator::Initialise(env); + vibrator = Vibrator::Create(env, *context); + + AtScopeExit() { + delete vibrator; + vibrator = nullptr; + }; + + if (have_bluetooth) { + try { + bluetooth_helper = + new BluetoothHelper(env, *context, permission_manager); + } catch (...) { + LogError(std::current_exception(), "Failed to initialise Bluetooth"); + } } - } - - AtScopeExit() { - delete bluetooth_helper; - bluetooth_helper = nullptr; - }; - - if (have_usb_serial) { - try { - usb_serial_helper = new UsbSerialHelper(env, *context); - } catch (...) { - LogError(std::current_exception(), "Failed to initialise USB serial support"); + + AtScopeExit() { + delete bluetooth_helper; + bluetooth_helper = nullptr; + }; + + if (have_usb_serial) { + try { + usb_serial_helper = new UsbSerialHelper(env, *context); + } catch (...) { + LogError(std::current_exception(), + "Failed to initialise USB serial support"); + } } - } - - AtScopeExit() { - delete usb_serial_helper; - usb_serial_helper = nullptr; - }; - - if (have_ioio) { - try { - ioio_helper = new IOIOHelper(env); - } catch (...) { - LogError(std::current_exception(), "Failed to initialise IOIO"); + + AtScopeExit() { + delete usb_serial_helper; + usb_serial_helper = nullptr; + }; + + if (have_ioio) { + try { + ioio_helper = new IOIOHelper(env); + } catch (...) { + LogError(std::current_exception(), "Failed to initialise IOIO"); + } } - } - AtScopeExit() { - delete ioio_helper; - ioio_helper = nullptr; - }; + AtScopeExit() { + delete ioio_helper; + ioio_helper = nullptr; + }; - ScreenGlobalInit screen_init; - AtScopeExit() { Fonts::Deinitialize(); }; + ScreenGlobalInit screen_init; + AtScopeExit() { Fonts::Deinitialize(); }; - AllowLanguage(); - AtScopeExit() { DisallowLanguage(); }; + AllowLanguage(); + AtScopeExit() { DisallowLanguage(); }; - InitLanguage(); + InitLanguage(); - AtScopeExit() { - if (CommonInterface::main_window != nullptr) { - CommonInterface::main_window->Destroy(); - delete CommonInterface::main_window; - CommonInterface::main_window = nullptr; - } - }; + AtScopeExit() { + if (CommonInterface::main_window != nullptr) { + CommonInterface::main_window->Destroy(); + delete CommonInterface::main_window; + CommonInterface::main_window = nullptr; + } + }; - { - const ScopeUnlock shutdown_unlock{shutdown_mutex}; + { + const ScopeUnlock shutdown_unlock{shutdown_mutex}; - if (Startup(screen_init.GetDisplay())) - CommonInterface::main_window->RunEventLoop(); - } + if (Startup(screen_init.GetDisplay())) + CommonInterface::main_window->RunEventLoop(); + } - Shutdown(); + Shutdown(); +#ifdef ANDROID_RERUN + unsigned ret = UI::TopWindow::GetExitValue(); + rerun = (ret == EXIT_RESTART); + // if (rerun) { + // env->DeleteGlobalRef(permission_manager); + // DeinitialiseDataPath(); + // } + } while (rerun); +#endif + +// Shutdown(); } catch (...) { /* if an error occurs, rethrow the C++ exception as Java exception, to be displayed by the Java glue code */ @@ -313,7 +348,7 @@ try { gcc_visibility_default JNIEXPORT void JNICALL -Java_org_xcsoar_NativeView_resizedNative(JNIEnv *env, jobject obj, +Java_de_opensoar_NativeView_resizedNative(JNIEnv *env, jobject obj, jint width, jint height) { const std::scoped_lock shutdown_lock{shutdown_mutex}; @@ -332,7 +367,7 @@ Java_org_xcsoar_NativeView_resizedNative(JNIEnv *env, jobject obj, gcc_visibility_default JNIEXPORT void JNICALL -Java_org_xcsoar_NativeView_surfaceDestroyedNative(JNIEnv *env, jobject obj) +Java_de_opensoar_NativeView_surfaceDestroyedNative(JNIEnv *env, jobject obj) { const std::scoped_lock shutdown_lock{shutdown_mutex}; @@ -342,7 +377,7 @@ Java_org_xcsoar_NativeView_surfaceDestroyedNative(JNIEnv *env, jobject obj) gcc_visibility_default JNIEXPORT void JNICALL -Java_org_xcsoar_NativeView_pauseNative(JNIEnv *env, jobject obj) +Java_de_opensoar_NativeView_pauseNative(JNIEnv *env, jobject obj) { const std::scoped_lock shutdown_lock{shutdown_mutex}; @@ -359,7 +394,7 @@ Java_org_xcsoar_NativeView_pauseNative(JNIEnv *env, jobject obj) gcc_visibility_default JNIEXPORT void JNICALL -Java_org_xcsoar_NativeView_resumeNative(JNIEnv *env, jobject obj) +Java_de_opensoar_NativeView_resumeNative(JNIEnv *env, jobject obj) { const std::scoped_lock shutdown_lock{shutdown_mutex}; @@ -376,7 +411,7 @@ Java_org_xcsoar_NativeView_resumeNative(JNIEnv *env, jobject obj) gcc_visibility_default JNIEXPORT void JNICALL -Java_org_xcsoar_NativeView_setHapticFeedback([[maybe_unused]] JNIEnv *env, [[maybe_unused]] jobject obj, +Java_de_opensoar_NativeView_setHapticFeedback([[maybe_unused]] JNIEnv *env, [[maybe_unused]] jobject obj, jboolean on) { GlobalSettings::haptic_feedback = on; diff --git a/src/Android/NativeDetectDeviceListener.cpp b/src/Android/NativeDetectDeviceListener.cpp index 41e702501c5..dc1a1690d98 100644 --- a/src/Android/NativeDetectDeviceListener.cpp +++ b/src/Android/NativeDetectDeviceListener.cpp @@ -6,7 +6,7 @@ #include "Main.hpp" #include "java/Class.hxx" #include "java/String.hxx" -#include "org_xcsoar_NativeDetectDeviceListener.h" +#include "de_opensoar_NativeDetectDeviceListener.h" namespace NativeDetectDeviceListener { static Java::TrivialClass cls; @@ -15,7 +15,7 @@ static jfieldID ptr_field; } // namespace NativeDetectDeviceListener JNIEXPORT void JNICALL -Java_org_xcsoar_NativeDetectDeviceListener_onDeviceDetected(JNIEnv *env, jobject obj, +Java_de_opensoar_NativeDetectDeviceListener_onDeviceDetected(JNIEnv *env, jobject obj, jint type, jstring _address, jstring _name, @@ -39,7 +39,7 @@ Java_org_xcsoar_NativeDetectDeviceListener_onDeviceDetected(JNIEnv *env, jobject void NativeDetectDeviceListener::Initialise(JNIEnv *env) noexcept { - cls.Find(env, "org/xcsoar/NativeDetectDeviceListener"); + cls.Find(env, "de/opensoar/NativeDetectDeviceListener"); ctor = env->GetMethodID(cls, "", "(J)V"); ptr_field = env->GetFieldID(cls, "ptr", "J"); } diff --git a/src/Android/NativeInputListener.cpp b/src/Android/NativeInputListener.cpp index 535b29aaa95..b34274a49b1 100644 --- a/src/Android/NativeInputListener.cpp +++ b/src/Android/NativeInputListener.cpp @@ -5,7 +5,7 @@ #include "io/DataHandler.hpp" #include "java/Array.hxx" #include "java/Class.hxx" -#include "org_xcsoar_NativeInputListener.h" +#include "de_opensoar_NativeInputListener.h" #include @@ -16,7 +16,7 @@ static jfieldID ptr_field; } // namespace NativeInputListener JNIEXPORT void JNICALL -Java_org_xcsoar_NativeInputListener_dataReceived(JNIEnv *env, jobject obj, +Java_de_opensoar_NativeInputListener_dataReceived(JNIEnv *env, jobject obj, jbyteArray data, jint length) { jlong ptr = env->GetLongField(obj, NativeInputListener::ptr_field); @@ -33,7 +33,7 @@ Java_org_xcsoar_NativeInputListener_dataReceived(JNIEnv *env, jobject obj, void NativeInputListener::Initialise(JNIEnv *env) { - cls.Find(env, "org/xcsoar/NativeInputListener"); + cls.Find(env, "de/opensoar/NativeInputListener"); ctor = env->GetMethodID(cls, "", "(J)V"); ptr_field = env->GetFieldID(cls, "ptr", "J"); diff --git a/src/Android/NativePortListener.cpp b/src/Android/NativePortListener.cpp index 7be0d2d5be0..dcecb7f79d6 100644 --- a/src/Android/NativePortListener.cpp +++ b/src/Android/NativePortListener.cpp @@ -5,7 +5,7 @@ #include "Device/Port/Listener.hpp" #include "java/Class.hxx" #include "java/String.hxx" -#include "org_xcsoar_NativePortListener.h" +#include "de_opensoar_NativePortListener.h" #include @@ -16,7 +16,7 @@ static jfieldID ptr_field; } // namespace NativePortListener JNIEXPORT void JNICALL -Java_org_xcsoar_NativePortListener_portStateChanged(JNIEnv *env, jobject obj) +Java_de_opensoar_NativePortListener_portStateChanged(JNIEnv *env, jobject obj) { jlong ptr = env->GetLongField(obj, NativePortListener::ptr_field); if (ptr == 0) @@ -28,7 +28,7 @@ Java_org_xcsoar_NativePortListener_portStateChanged(JNIEnv *env, jobject obj) } JNIEXPORT void JNICALL -Java_org_xcsoar_NativePortListener_portError(JNIEnv *env, jobject obj, +Java_de_opensoar_NativePortListener_portError(JNIEnv *env, jobject obj, jstring msg) { jlong ptr = env->GetLongField(obj, NativePortListener::ptr_field); @@ -43,7 +43,7 @@ Java_org_xcsoar_NativePortListener_portError(JNIEnv *env, jobject obj, void NativePortListener::Initialise(JNIEnv *env) { - cls.Find(env, "org/xcsoar/NativePortListener"); + cls.Find(env, "de/opensoar/NativePortListener"); ctor = env->GetMethodID(cls, "", "(J)V"); ptr_field = env->GetFieldID(cls, "ptr", "J"); diff --git a/src/Android/NativeSensorListener.cpp b/src/Android/NativeSensorListener.cpp index f110b0c9556..1aed7fcc957 100644 --- a/src/Android/NativeSensorListener.cpp +++ b/src/Android/NativeSensorListener.cpp @@ -11,7 +11,7 @@ #include "java/String.hxx" #include "time/SystemClock.hxx" #include "util/Compiler.h" -#include "org_xcsoar_NativeSensorListener.h" +#include "de_opensoar_NativeSensorListener.h" namespace NativeSensorListener { static Java::TrivialClass cls; @@ -22,7 +22,7 @@ static jfieldID ptr_field; void NativeSensorListener::Initialise(JNIEnv *env) noexcept { - cls.Find(env, "org/xcsoar/NativeSensorListener"); + cls.Find(env, "de/opensoar/NativeSensorListener"); ctor = env->GetMethodID(cls, "", "(J)V"); ptr_field = env->GetFieldID(cls, "ptr", "J"); } @@ -42,7 +42,7 @@ NativeSensorListener::Create(JNIEnv *env, gcc_visibility_default JNIEXPORT void JNICALL -Java_org_xcsoar_NativeSensorListener_onConnected(JNIEnv *env, jobject obj, +Java_de_opensoar_NativeSensorListener_onConnected(JNIEnv *env, jobject obj, jint connected) { jlong ptr = env->GetLongField(obj, NativeSensorListener::ptr_field); @@ -55,7 +55,7 @@ Java_org_xcsoar_NativeSensorListener_onConnected(JNIEnv *env, jobject obj, gcc_visibility_default JNIEXPORT void JNICALL -Java_org_xcsoar_NativeSensorListener_onLocationSensor(JNIEnv *env, jobject obj, +Java_de_opensoar_NativeSensorListener_onLocationSensor(JNIEnv *env, jobject obj, jlong time, jint n_satellites, jdouble longitude, jdouble latitude, jboolean hasAltitude, @@ -82,7 +82,7 @@ Java_org_xcsoar_NativeSensorListener_onLocationSensor(JNIEnv *env, jobject obj, gcc_visibility_default JNIEXPORT void JNICALL -Java_org_xcsoar_NativeSensorListener_onAccelerationSensor1(JNIEnv *env, jobject obj, +Java_de_opensoar_NativeSensorListener_onAccelerationSensor1(JNIEnv *env, jobject obj, jdouble acceleration) { jlong ptr = env->GetLongField(obj, NativeSensorListener::ptr_field); @@ -95,7 +95,7 @@ Java_org_xcsoar_NativeSensorListener_onAccelerationSensor1(JNIEnv *env, jobject gcc_visibility_default JNIEXPORT void JNICALL -Java_org_xcsoar_NativeSensorListener_onAccelerationSensor(JNIEnv *env, jobject obj, +Java_de_opensoar_NativeSensorListener_onAccelerationSensor(JNIEnv *env, jobject obj, jfloat ddx, jfloat ddy, jfloat ddz) { @@ -109,7 +109,7 @@ Java_org_xcsoar_NativeSensorListener_onAccelerationSensor(JNIEnv *env, jobject o gcc_visibility_default JNIEXPORT void JNICALL -Java_org_xcsoar_NativeSensorListener_onRotationSensor(JNIEnv *env, jobject obj, +Java_de_opensoar_NativeSensorListener_onRotationSensor(JNIEnv *env, jobject obj, jfloat dtheta_x, jfloat dtheta_y, jfloat dtheta_z) { @@ -123,7 +123,7 @@ Java_org_xcsoar_NativeSensorListener_onRotationSensor(JNIEnv *env, jobject obj, gcc_visibility_default JNIEXPORT void JNICALL -Java_org_xcsoar_NativeSensorListener_onMagneticFieldSensor(JNIEnv *env, jobject obj, +Java_de_opensoar_NativeSensorListener_onMagneticFieldSensor(JNIEnv *env, jobject obj, jfloat h_x, jfloat h_y, jfloat h_z) { @@ -137,7 +137,7 @@ Java_org_xcsoar_NativeSensorListener_onMagneticFieldSensor(JNIEnv *env, jobject gcc_visibility_default JNIEXPORT void JNICALL -Java_org_xcsoar_NativeSensorListener_onBarometricPressureSensor(JNIEnv *env, +Java_de_opensoar_NativeSensorListener_onBarometricPressureSensor(JNIEnv *env, jobject obj, jfloat pressure, jfloat sensor_noise_variance) @@ -152,7 +152,7 @@ Java_org_xcsoar_NativeSensorListener_onBarometricPressureSensor(JNIEnv *env, gcc_visibility_default JNIEXPORT void JNICALL -Java_org_xcsoar_NativeSensorListener_onPressureAltitudeSensor(JNIEnv *env, +Java_de_opensoar_NativeSensorListener_onPressureAltitudeSensor(JNIEnv *env, jobject obj, jfloat altitude) { @@ -165,7 +165,7 @@ Java_org_xcsoar_NativeSensorListener_onPressureAltitudeSensor(JNIEnv *env, } JNIEXPORT void JNICALL -Java_org_xcsoar_NativeSensorListener_onI2CbaroSensor(JNIEnv *env, jobject obj, +Java_de_opensoar_NativeSensorListener_onI2CbaroSensor(JNIEnv *env, jobject obj, jint index, jint sensorType, jint pressure) @@ -181,7 +181,7 @@ Java_org_xcsoar_NativeSensorListener_onI2CbaroSensor(JNIEnv *env, jobject obj, gcc_visibility_default JNIEXPORT void JNICALL -Java_org_xcsoar_NativeSensorListener_onEngineSensors(JNIEnv *env, +Java_de_opensoar_NativeSensorListener_onEngineSensors(JNIEnv *env, jobject obj, jboolean has_cht_temp, jint cht_temp, @@ -205,7 +205,7 @@ Java_org_xcsoar_NativeSensorListener_onEngineSensors(JNIEnv *env, gcc_visibility_default JNIEXPORT void JNICALL -Java_org_xcsoar_NativeSensorListener_onVarioSensor(JNIEnv *env, +Java_de_opensoar_NativeSensorListener_onVarioSensor(JNIEnv *env, jobject obj, jfloat vario) { @@ -219,7 +219,7 @@ Java_org_xcsoar_NativeSensorListener_onVarioSensor(JNIEnv *env, gcc_visibility_default JNIEXPORT void JNICALL -Java_org_xcsoar_NativeSensorListener_onHeartRateSensor(JNIEnv *env, +Java_de_opensoar_NativeSensorListener_onHeartRateSensor(JNIEnv *env, jobject obj, jint bpm) { @@ -232,7 +232,7 @@ Java_org_xcsoar_NativeSensorListener_onHeartRateSensor(JNIEnv *env, } JNIEXPORT void JNICALL -Java_org_xcsoar_NativeSensorListener_onVoltageValues(JNIEnv *env, jobject obj, +Java_de_opensoar_NativeSensorListener_onVoltageValues(JNIEnv *env, jobject obj, jint temp_adc, jint voltage_index, jint volt_adc) @@ -247,7 +247,7 @@ Java_org_xcsoar_NativeSensorListener_onVoltageValues(JNIEnv *env, jobject obj, gcc_visibility_default JNIEXPORT void JNICALL -Java_org_xcsoar_NativeSensorListener_onNunchukValues(JNIEnv *env, jobject obj, +Java_de_opensoar_NativeSensorListener_onNunchukValues(JNIEnv *env, jobject obj, jint joy_x, jint joy_y, jint acc_x, jint acc_y, jint acc_z, @@ -263,7 +263,7 @@ Java_org_xcsoar_NativeSensorListener_onNunchukValues(JNIEnv *env, jobject obj, gcc_visibility_default JNIEXPORT void JNICALL -Java_org_xcsoar_NativeSensorListener_onGliderLinkTraffic(JNIEnv *env, +Java_de_opensoar_NativeSensorListener_onGliderLinkTraffic(JNIEnv *env, jobject obj, jlong gid, jstring callsign, @@ -289,7 +289,7 @@ Java_org_xcsoar_NativeSensorListener_onGliderLinkTraffic(JNIEnv *env, gcc_visibility_default JNIEXPORT void JNICALL -Java_org_xcsoar_NativeSensorListener_onTemperature(JNIEnv *env, +Java_de_opensoar_NativeSensorListener_onTemperature(JNIEnv *env, jobject obj, jdouble temperature_kelvin) { @@ -303,7 +303,7 @@ Java_org_xcsoar_NativeSensorListener_onTemperature(JNIEnv *env, gcc_visibility_default JNIEXPORT void JNICALL -Java_org_xcsoar_NativeSensorListener_onBatteryPercent(JNIEnv *env, +Java_de_opensoar_NativeSensorListener_onBatteryPercent(JNIEnv *env, jobject obj, jdouble battery_percent) { @@ -317,7 +317,7 @@ Java_org_xcsoar_NativeSensorListener_onBatteryPercent(JNIEnv *env, gcc_visibility_default JNIEXPORT void JNICALL -Java_org_xcsoar_NativeSensorListener_onSensorStateChanged(JNIEnv *env, +Java_de_opensoar_NativeSensorListener_onSensorStateChanged(JNIEnv *env, jobject obj) { jlong ptr = env->GetLongField(obj, NativeSensorListener::ptr_field); @@ -330,7 +330,7 @@ Java_org_xcsoar_NativeSensorListener_onSensorStateChanged(JNIEnv *env, gcc_visibility_default JNIEXPORT void JNICALL -Java_org_xcsoar_NativeSensorListener_onSensorError(JNIEnv *env, +Java_de_opensoar_NativeSensorListener_onSensorError(JNIEnv *env, jobject obj, jstring msg) { diff --git a/src/Android/NativeView.cpp b/src/Android/NativeView.cpp index 6f2671d2b6a..af32e1d2d0a 100644 --- a/src/Android/NativeView.cpp +++ b/src/Android/NativeView.cpp @@ -33,7 +33,7 @@ jmethodID NativeView::bitmapConfigValueOf_method; void NativeView::Initialise(JNIEnv *env) { - cls.Find(env, "org/xcsoar/NativeView"); + cls.Find(env, "de/opensoar/NativeView"); ptr_field = env->GetFieldID(cls, "ptr", "J"); textureNonPowerOfTwo_field = diff --git a/src/Android/NunchuckDevice.cpp b/src/Android/NunchuckDevice.cpp index eecf6eec56e..88504708d8e 100644 --- a/src/Android/NunchuckDevice.cpp +++ b/src/Android/NunchuckDevice.cpp @@ -12,10 +12,10 @@ static jmethodID nunchuck_ctor; void NunchuckDevice::Initialise(JNIEnv *env) noexcept { - nunchuck_class.Find(env, "org/xcsoar/GlueNunchuck"); + nunchuck_class.Find(env, "de/opensoar/GlueNunchuck"); nunchuck_ctor = env->GetMethodID(nunchuck_class, "", - "(Lorg/xcsoar/IOIOConnectionHolder;IILorg/xcsoar/SensorListener;)V"); + "(Lde/opensoar/IOIOConnectionHolder;IILde/opensoar/SensorListener;)V"); } void diff --git a/src/Android/PortBridge.cpp b/src/Android/PortBridge.cpp index a69a472572f..882cc22f0f2 100644 --- a/src/Android/PortBridge.cpp +++ b/src/Android/PortBridge.cpp @@ -21,12 +21,12 @@ jmethodID PortBridge::write_method; void PortBridge::Initialise(JNIEnv *env) { - Java::Class cls(env, "org/xcsoar/AndroidPort"); + Java::Class cls(env, "de/opensoar/AndroidPort"); setListener_method = env->GetMethodID(cls, "setListener", - "(Lorg/xcsoar/PortListener;)V"); + "(Lde/opensoar/PortListener;)V"); setInputListener_method = env->GetMethodID(cls, "setInputListener", - "(Lorg/xcsoar/InputListener;)V"); + "(Lde/opensoar/InputListener;)V"); getState_method = env->GetMethodID(cls, "getState", "()I"); drain_method = env->GetMethodID(cls, "drain", "()Z"); getBaudRate_method = env->GetMethodID(cls, "getBaudRate", "()I"); diff --git a/src/Android/ReceiveTask.cpp b/src/Android/ReceiveTask.cpp index 624b1facc88..29529db0d9f 100644 --- a/src/Android/ReceiveTask.cpp +++ b/src/Android/ReceiveTask.cpp @@ -43,7 +43,7 @@ ReceiveXCTrackTask(std::string_view data) received_task = std::move(task); } - /* if XCSoar is already running, post a TASK_RECEIVED event so + /* if OpenSoar is already running, post a TASK_RECEIVED event so MainWindow::OnTaskReceived() opens the task manager */ if (UI::event_queue != nullptr) UI::event_queue->Inject(UI::Event::TASK_RECEIVED); diff --git a/src/Android/Sensor.cpp b/src/Android/Sensor.cpp index 09e004cd281..3835111142f 100644 --- a/src/Android/Sensor.cpp +++ b/src/Android/Sensor.cpp @@ -11,7 +11,7 @@ static jmethodID getState_method; void Initialise(JNIEnv *env) noexcept { - Java::Class cls(env, "org/xcsoar/AndroidSensor"); + Java::Class cls(env, "de/opensoar/AndroidSensor"); getState_method = env->GetMethodID(cls, "getState", "()I"); } diff --git a/src/Android/SoundUtil.cpp b/src/Android/SoundUtil.cpp index b7f7f5bdee6..ce35af2019e 100644 --- a/src/Android/SoundUtil.cpp +++ b/src/Android/SoundUtil.cpp @@ -19,7 +19,7 @@ SoundUtil::Initialise(JNIEnv *env) assert(!cls.IsDefined()); assert(env != nullptr); - cls.Find(env, "org/xcsoar/SoundUtil"); + cls.Find(env, "de/opensoar/SoundUtil"); play_method = env->GetStaticMethodID(cls, "play", "(Landroid/content/Context;" "Ljava/lang/String;)Z"); @@ -45,7 +45,7 @@ SoundUtil::Play(JNIEnv *env, jobject context, const char *name) bool SoundUtil::PlayExternal(JNIEnv *env, jobject context, const char *path) { - AllocatedPath absolutePath = LocalPath(_T(path)); + AllocatedPath absolutePath = LocalPath(path); Java::String paramName(env, absolutePath.c_str()); return env->CallStaticBooleanMethod(cls, playExternal_method, context, paramName.Get()); diff --git a/src/Android/TextEntryDialog.cpp b/src/Android/TextEntryDialog.cpp index 3f0507fb36c..19f2ff10f2a 100644 --- a/src/Android/TextEntryDialog.cpp +++ b/src/Android/TextEntryDialog.cpp @@ -10,7 +10,7 @@ #include "java/Closeable.hxx" #include "java/Env.hxx" #include "java/String.hxx" -#include "org_xcsoar_TextEntryDialog.h" +#include "de_opensoar_TextEntryDialog.h" #include "UIGlobals.hpp" #include @@ -39,7 +39,7 @@ AndroidTextEntryDialog::Initialise(JNIEnv *env) noexcept assert(text_entry_dialog_class == nullptr); assert(env != nullptr); - text_entry_dialog_class.Find(env, "org/xcsoar/TextEntryDialog"); + text_entry_dialog_class.Find(env, "de/opensoar/TextEntryDialog"); ctor = env->GetMethodID(text_entry_dialog_class, "", "(JLandroid/content/Context;Ljava/lang/String;Ljava/lang/String;I)V"); @@ -52,7 +52,7 @@ AndroidTextEntryDialog::Deinitialise(JNIEnv *env) noexcept } JNIEXPORT void JNICALL -Java_org_xcsoar_TextEntryDialog_onResult(JNIEnv *env, [[maybe_unused]] jobject obj, +Java_de_opensoar_TextEntryDialog_onResult(JNIEnv *env, [[maybe_unused]] jobject obj, jlong ptr, jstring value) { auto &dialog = *(AndroidTextEntryDialog *)(std::size_t)ptr; diff --git a/src/Android/TextUtil.cpp b/src/Android/TextUtil.cpp index 498248fd279..6660b5cb88b 100644 --- a/src/Android/TextUtil.cpp +++ b/src/Android/TextUtil.cpp @@ -23,7 +23,7 @@ TextUtil::Initialise(JNIEnv *_env) noexcept { env = _env; - cls.Find(_env, "org/xcsoar/TextUtil"); + cls.Find(_env, "de/opensoar/TextUtil"); midTextUtil = _env->GetMethodID(cls, "", "(IIIZ)V"); midGetFontMetrics = _env->GetMethodID(cls, "getFontMetrics", "([I)V"); diff --git a/src/Android/UsbSerialHelper.cpp b/src/Android/UsbSerialHelper.cpp index 7cc57f8a419..076602fd567 100644 --- a/src/Android/UsbSerialHelper.cpp +++ b/src/Android/UsbSerialHelper.cpp @@ -22,7 +22,7 @@ UsbSerialHelper::Initialise(JNIEnv *env) noexcept assert(!cls.IsDefined()); assert(env != nullptr); - if (!cls.FindOptional(env, "org/xcsoar/UsbSerialHelper")) { + if (!cls.FindOptional(env, "de/opensoar/UsbSerialHelper")) { /* Android < 3.1 doesn't have Usb Host support */ return false; } @@ -38,14 +38,14 @@ UsbSerialHelper::Initialise(JNIEnv *env) noexcept close_method = env->GetMethodID(cls, "close", "()V"); connect_method = env->GetMethodID(cls, "connect", - "(Ljava/lang/String;I)Lorg/xcsoar/AndroidPort;"); + "(Ljava/lang/String;I)Lde/opensoar/AndroidPort;"); addDetectDeviceListener_method = env->GetMethodID(cls, "addDetectDeviceListener", - "(Lorg/xcsoar/DetectDeviceListener;)V"); + "(Lde/opensoar/DetectDeviceListener;)V"); removeDetectDeviceListener_method = env->GetMethodID(cls, "removeDetectDeviceListener", - "(Lorg/xcsoar/DetectDeviceListener;)V"); + "(Lde/opensoar/DetectDeviceListener;)V"); return true; } diff --git a/src/Android/VoltageDevice.cpp b/src/Android/VoltageDevice.cpp index 6be82b75e5e..d29207f4e49 100644 --- a/src/Android/VoltageDevice.cpp +++ b/src/Android/VoltageDevice.cpp @@ -12,10 +12,10 @@ static jmethodID voltage_ctor; void VoltageDevice::Initialise(JNIEnv *env) noexcept { - voltage_class.Find(env, "org/xcsoar/GlueVoltage"); + voltage_class.Find(env, "de/opensoar/GlueVoltage"); voltage_ctor = env->GetMethodID(voltage_class, "", - "(Lorg/xcsoar/IOIOConnectionHolder;ILorg/xcsoar/SensorListener;)V"); + "(Lde/opensoar/IOIOConnectionHolder;ILde/opensoar/SensorListener;)V"); } void diff --git a/src/Atmosphere/CMakeLists.txt b/src/Atmosphere/CMakeLists.txt new file mode 100644 index 00000000000..bd834cc6445 --- /dev/null +++ b/src/Atmosphere/CMakeLists.txt @@ -0,0 +1,49 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + ### hide: message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/Atmosphere/CMakeSource.cmake b/src/Atmosphere/CMakeSource.cmake new file mode 100644 index 00000000000..cece4fb97fb --- /dev/null +++ b/src/Atmosphere/CMakeSource.cmake @@ -0,0 +1,10 @@ +set(_SOURCES + Atmosphere/AirDensity.cpp + Atmosphere/CuSonde.cpp + Atmosphere/Pressure.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake +) + diff --git a/src/Audio/CMakeLists.txt b/src/Audio/CMakeLists.txt new file mode 100644 index 00000000000..0b7e1f84f97 --- /dev/null +++ b/src/Audio/CMakeLists.txt @@ -0,0 +1,49 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/Audio/CMakeSource.cmake b/src/Audio/CMakeSource.cmake new file mode 100644 index 00000000000..e7d0fe49da1 --- /dev/null +++ b/src/Audio/CMakeSource.cmake @@ -0,0 +1,33 @@ +set(_SOURCES + Audio/Settings.cpp + Audio/Sound.cpp + Audio/VarioSettings.cpp + + Audio/GlobalPCMMixer.cpp +) + + +if(UNIX) + list(APPEND _SOURCES + Audio/VarioGlue.cpp + Audio/ToneSynthesiser.cpp + Audio/VarioSynthesiser.cpp + Audio/PCMPlayer.cpp + Audio/GlobalPCMResourcePlayer.cpp + Audio/GlobalPCMMixer.cpp + Audio/GlobalVolumeController.cpp + Audio/MixerPCMPlayer.cpp + Audio/PCMBufferDataSource.cpp + Audio/PCMMixerDataSource.cpp + Audio/PCMMixer.cpp + Audio/PCMResourcePlayer.cpp + Audio/VolumeController.cpp + Audio/ALSAEnv.cpp + Audio/ALSAPCMPlayer.cpp + ) +endif() + +set(SCRIPT_FILES + CMakeSource.cmake +) + diff --git a/src/Audio/GlobalPCMMixer.cpp b/src/Audio/GlobalPCMMixer.cpp index cc436637aaa..ee12c0db1a9 100644 --- a/src/Audio/GlobalPCMMixer.cpp +++ b/src/Audio/GlobalPCMMixer.cpp @@ -2,14 +2,31 @@ // Copyright The XCSoar Project #include "GlobalPCMMixer.hpp" -#include "PCMPlayerFactory.hpp" #include "PCMMixer.hpp" +#ifndef _WIN32 +#include "PCMPlayerFactory.hpp" +#endif + +// #define EXTERNAL_AUDIO_INIT + +#ifdef EXTERNAL_AUDIO_INIT +# include "GlobalPCMResourcePlayer.hpp" +# include "GlobalVolumeController.hpp" + +# include "event/Loop.hxx" +#endif #include #include PCMMixer *pcm_mixer = nullptr; +#ifdef EXTERNAL_AUDIO_INIT + ScopeGlobalPCMMixer *global_pcm_mixer = nullptr; + ScopeGlobalPCMResourcePlayer *global_pcm_resouce_player = nullptr; + ScopeGlobalVolumeController *global_volume_controller = nullptr; +#endif +#ifndef _WIN32 void InitialisePCMMixer(EventLoop &event_loop) { @@ -28,3 +45,22 @@ DeinitialisePCMMixer() delete pcm_mixer; pcm_mixer = nullptr; } + +#endif + +#ifdef EXTERNAL_AUDIO_INIT +void InitAudio(EventLoop *_loop) { + // How I get this variables to live up to the end? + EventLoop *loop = _loop; + global_pcm_mixer = new ScopeGlobalPCMMixer(*loop); + global_pcm_resouce_player = new ScopeGlobalPCMResourcePlayer; + global_volume_controller = new ScopeGlobalVolumeController; +} + +void ShutdownAudio() { + // How I get this variables to live up to the end? + delete global_pcm_mixer; + delete global_pcm_resouce_player; + delete global_volume_controller; +} +#endif diff --git a/src/Audio/GlobalPCMMixer.hpp b/src/Audio/GlobalPCMMixer.hpp index 6f75f683656..ec9fe8aefda 100644 --- a/src/Audio/GlobalPCMMixer.hpp +++ b/src/Audio/GlobalPCMMixer.hpp @@ -3,10 +3,15 @@ #pragma once - #include "Features.hpp" class EventLoop; +// #define EXTERNAL_AUDIO_INIT + +#ifdef EXTERNAL_AUDIO_INIT +void InitAudio(EventLoop *loop); +void ShutdownAudio(); +#endif #ifdef HAVE_PCM_MIXER class PCMMixer; diff --git a/src/Audio/PCMMixer.cpp b/src/Audio/PCMMixer.cpp index b18e4eeac57..cf5de47a909 100644 --- a/src/Audio/PCMMixer.cpp +++ b/src/Audio/PCMMixer.cpp @@ -26,8 +26,8 @@ PCMMixer::Start(PCMDataSource &source) if (src_sample_rate != mixer_sample_rate) { /* Resampling is not supported yet */ - LogFormat(_T("Cannot playback PCM data source with sample rate of %u Hz, ") - _T("because the mixer sample rate is %u Hz"), + LogFormat("Cannot playback PCM data source with sample rate of %u Hz, " + "because the mixer sample rate is %u Hz", src_sample_rate, mixer_sample_rate); return false; @@ -36,8 +36,8 @@ PCMMixer::Start(PCMDataSource &source) const std::lock_guard protect{lock}; if (!mixer_data_source.AddSource(source)) { - LogFormat(_T("Cannot handle PCM data source to mixer, because the mixer ") - _T("capacity is exceeded")); + LogFormat("Cannot handle PCM data source to mixer, because the mixer " + "capacity is exceeded"); return false; } diff --git a/src/Audio/PCMResourcePlayer.cpp b/src/Audio/PCMResourcePlayer.cpp index 8e9aa6ec86d..9413ab634df 100644 --- a/src/Audio/PCMResourcePlayer.cpp +++ b/src/Audio/PCMResourcePlayer.cpp @@ -17,13 +17,13 @@ PCMResourcePlayer::PCMResourcePlayer() : } bool -PCMResourcePlayer::PlayResource(const TCHAR *resource_name) +PCMResourcePlayer::PlayResource(const char *resource_name) { PCMBufferDataSource::PCMData pcm_data = FromBytesStrict( - ResourceLoader::Load(resource_name, _T("WAVE"))); + ResourceLoader::Load(resource_name, "WAVE")); if (pcm_data.data() == nullptr) { - LogFormat(_T("PCM resource \"%s\" not found!"), resource_name); + LogFormat("PCM resource \"%s\" not found!", resource_name); return false; } diff --git a/src/Audio/PCMResourcePlayer.hpp b/src/Audio/PCMResourcePlayer.hpp index d103d81045c..773ff7438f9 100644 --- a/src/Audio/PCMResourcePlayer.hpp +++ b/src/Audio/PCMResourcePlayer.hpp @@ -28,5 +28,5 @@ class PCMResourcePlayer { PCMResourcePlayer(PCMResourcePlayer &) = delete; PCMResourcePlayer &operator=(PCMResourcePlayer &) = delete; - bool PlayResource(const TCHAR *resource_name); + bool PlayResource(const char *resource_name); }; diff --git a/src/Audio/Sound.cpp b/src/Audio/Sound.cpp index 651ee7b5fd4..55ee41c90bb 100644 --- a/src/Audio/Sound.cpp +++ b/src/Audio/Sound.cpp @@ -19,20 +19,20 @@ #endif bool -PlayResource(const TCHAR *resource_name) +PlayResource(const char *resource_name) { #ifdef ANDROID - if (_tcsstr(resource_name, _T(".wav"))) + if (strstr(resource_name, ".wav")) return SoundUtil::PlayExternal(Java::GetEnv(), context->Get(), resource_name); return SoundUtil::Play(Java::GetEnv(), context->Get(), resource_name); #elif defined(_WIN32) - if (_tcsstr(resource_name, TEXT(".wav"))) + if (strstr(resource_name, TEXT(".wav"))) return sndPlaySound(resource_name, SND_ASYNC | SND_NODEFAULT); - ResourceLoader::Data data = ResourceLoader::Load(resource_name, _T("WAVE")); + ResourceLoader::Data data = ResourceLoader::Load(resource_name, "WAVE"); return data.data() != nullptr && sndPlaySound((LPCTSTR)data.data(), SND_MEMORY | SND_ASYNC | SND_NODEFAULT); diff --git a/src/Audio/Sound.hpp b/src/Audio/Sound.hpp index 1de754d49cf..e8c7b822bd9 100644 --- a/src/Audio/Sound.hpp +++ b/src/Audio/Sound.hpp @@ -5,4 +5,4 @@ #include -bool PlayResource(const TCHAR *resource_name); +bool PlayResource(const char *resource_name); diff --git a/src/Audio/VarioGlue.cpp b/src/Audio/VarioGlue.cpp index 176b83d8363..41a08212c7f 100644 --- a/src/Audio/VarioGlue.cpp +++ b/src/Audio/VarioGlue.cpp @@ -75,9 +75,19 @@ AudioVarioGlue::Configure(const VarioSoundSettings &settings) settings.max_frequency); synthesiser->SetPeriods(settings.min_period_ms, settings.max_period_ms); synthesiser->SetDeadBandRange(settings.min_dead, settings.max_dead); +#ifdef ANDROID player->Start(*synthesiser); - } else + } else { player->Stop(); + } +#else + } else { + /* WorkAround: don't stop the player on Linux: player->Stop(); + * this never cannot switching on the sound! */ + synthesiser->SetVolume(0); + } + player->Start(*synthesiser); +#endif } void diff --git a/src/Blackboard/CMakeLists.txt b/src/Blackboard/CMakeLists.txt new file mode 100644 index 00000000000..0b7e1f84f97 --- /dev/null +++ b/src/Blackboard/CMakeLists.txt @@ -0,0 +1,49 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/Blackboard/CMakeSource.cmake b/src/Blackboard/CMakeSource.cmake new file mode 100644 index 00000000000..e1d1ad8c841 --- /dev/null +++ b/src/Blackboard/CMakeSource.cmake @@ -0,0 +1,14 @@ +set(_SOURCES + Blackboard/BlackboardListener.cpp + Blackboard/DeviceBlackboard.cpp + Blackboard/InterfaceBlackboard.cpp + Blackboard/LiveBlackboard.cpp + Blackboard/ProxyBlackboardListener.cpp + Blackboard/RateLimitedBlackboardListener.cpp + Blackboard/ScopeCalculatedListener.cpp + Blackboard/ScopeGPSListener.cpp +) +set(SCRIPT_FILES + CMakeSource.cmake +) + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 00000000000..90eda4e107f --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,24 @@ +cmake_minimum_required(VERSION 3.18) + +set(TARGET_NAME libOpenSoar) +# set(TARGET_NAME libXCSoar) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR} -- ${TARGET_NAME}!") +endif() + +include(CMakeSource.cmake) + +if (${XCSOAR_LIB_TYPE} STREQUAL "WITHOUT") + set(XCSOAR_LIB_TYPE STATIC) +endif() + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) + +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER _Main) + +target_link_libraries(${TARGET_NAME} PUBLIC Dialogs Math WeGlide) +add_dependencies(${TARGET_NAME} util Data) diff --git a/src/CMakeSource.cmake b/src/CMakeSource.cmake new file mode 100644 index 00000000000..0f348e13a8e --- /dev/null +++ b/src/CMakeSource.cmake @@ -0,0 +1,76 @@ +# Location ./XCSoarAug/src/CMakeSource.cmake + +# file(GLOB_RECURSE SOURCE_FILES ${PROJECTGROUP_SOURCE_DIR}/src/*.cpp) +# file(GLOB_RECURSE HEADER_FILES ${PROJECTGROUP_SOURCE_DIR}/src/*.h*) +file(GLOB HEADER_FILES *.h*) + +set(BASIC_SOURCES + ${SRC}/ActionInterface.cpp + ${SRC}/ApplyExternalSettings.cpp + ${SRC}/ApplyVegaSwitches.cpp + ${SRC}/Asset.cpp + ${SRC}/BallastDumpManager.cpp + ${SRC}/BatteryTimer.cpp + ${SRC}/BackendComponents.cpp + ${SRC}/DataComponents.cpp + ${SRC}/Components.cpp + ${SRC}/CommandLine.cpp + ${SRC}/DataGlobals.cpp + ${SRC}/NetComponents.cpp + + ${SRC}/FlightStatistics.cpp + ${SRC}/HorizonWidget.cpp + ${SRC}/Interface.cpp + ${SRC}/LocalPath.cpp + ${SRC}/MainWindow.cpp + ${SRC}/ProcessTimer.cpp + ${SRC}/ProgressWindow.cpp + ${SRC}/ProgressGlue.cpp + ${SRC}/Protection.cpp + ${SRC}/RadioFrequency.cpp + ${SRC}/ResourceLoader.cpp + ${SRC}/Simulator.cpp + ${SRC}/Startup.cpp + ${SRC}/UIActions.cpp + + ${SRC}/Pan.cpp + ${SRC}/TransponderCode.cpp + + ${SRC}/PageSettings.cpp + ${SRC}/PageState.cpp + ${SRC}/PageActions.cpp + ${SRC}/StatusMessage.cpp + ${SRC}/PopupMessage.cpp + ${SRC}/Message.cpp + + ${SRC}/LogFile.cpp + ${SRC}/DrawThread.cpp + + ${SRC}/UIReceiveBlackboard.cpp + ${SRC}/UIGlobals.cpp + ${SRC}/UIState.cpp + ${SRC}/UISettings.cpp + ${SRC}/DisplaySettings.cpp + ${SRC}/MapSettings.cpp + ${SRC}/SystemSettings.cpp + + ${SRC}/MergeThread.cpp + ${SRC}/CalculationThread.cpp + ${SRC}/DisplayMode.cpp + + ${SRC}/UtilsSettings.cpp + ${SRC}/UtilsSystem.cpp + ${SRC}/Version.cpp + + ${SRC}/RateLimiter.cpp + ${SRC}/TeamActions.cpp + + ${SRC}/Version.cpp +) + +set(SOURCE_FILES ${BASIC_SOURCES} ) +set(SCRIPT_FILES CMakeSource.cmake + ../ide/xcsoar.natvis +) + +file(GLOB ICON_FILES ${PROJECTGROUP_SOURCE_DIR}/Data/icons/*.svg) diff --git a/src/Cloud/CMakeLists.txt b/src/Cloud/CMakeLists.txt new file mode 100644 index 00000000000..69892236a1a --- /dev/null +++ b/src/Cloud/CMakeLists.txt @@ -0,0 +1,35 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) + +target_link_libraries(${TARGET_NAME} PUBLIC IGC Formatter util io) # json) + +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/Cloud/CMakeSource.cmake b/src/Cloud/CMakeSource.cmake new file mode 100644 index 00000000000..1cd3076e50b --- /dev/null +++ b/src/Cloud/CMakeSource.cmake @@ -0,0 +1,7 @@ +set(_SOURCES +# no sources up to now in Win32 or Linux... +) + +set(SCRIPT_FILES + CMakeSource.cmake +) diff --git a/src/Compatibility/path.h b/src/Compatibility/path.h index e164f2b803c..5288bf9f897 100644 --- a/src/Compatibility/path.h +++ b/src/Compatibility/path.h @@ -18,11 +18,12 @@ #endif /* !_WIN32 */ static inline bool -IsDirSeparator(TCHAR ch) +IsDirSeparator(char ch) { #ifdef _WIN32 - return ch == _T('\\'); + // at Windows both separators are possible!!! + return ch == DIR_SEPARATOR || ch == '/'; #else - return ch == _T('/'); + return ch == DIR_SEPARATOR; #endif } diff --git a/src/Computer/CMakeLists.txt b/src/Computer/CMakeLists.txt new file mode 100644 index 00000000000..808596c0c37 --- /dev/null +++ b/src/Computer/CMakeLists.txt @@ -0,0 +1,59 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() +### create_test_sourcelist() + +if (1) +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +target_link_libraries(${TARGET_NAME} PUBLIC Task system) + +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} + util + Math # include/MathTables.h! +) diff --git a/src/Computer/CMakeSource.cmake b/src/Computer/CMakeSource.cmake new file mode 100644 index 00000000000..2efe48ba707 --- /dev/null +++ b/src/Computer/CMakeSource.cmake @@ -0,0 +1,53 @@ +set(_SOURCES + Computer/AutoQNH.cpp + Computer/AverageVarioComputer.cpp + Computer/BasicComputer.cpp + Computer/CirclingComputer.cpp + Computer/ClimbAverageCalculator.cpp + Computer/ConditionMonitor/ConditionMonitor.cpp + Computer/ConditionMonitor/ConditionMonitorAATTime.cpp + Computer/ConditionMonitor/ConditionMonitorFinalGlide.cpp + Computer/ConditionMonitor/ConditionMonitorGlideTerrain.cpp + Computer/ConditionMonitor/ConditionMonitorLandableReachable.cpp + Computer/ConditionMonitor/ConditionMonitors.cpp + Computer/ConditionMonitor/ConditionMonitorSunset.cpp + Computer/ConditionMonitor/ConditionMonitorWind.cpp + Computer/ConditionMonitor/AirspaceEnterMonitor.cpp + Computer/ConditionMonitor/MoreConditionMonitors.cpp + Computer/ContestComputer.cpp + Computer/CuComputer.cpp + Computer/Events.cpp + Computer/FlyingComputer.cpp + Computer/GlideComputer.cpp + Computer/GlideComputerAirData.cpp + Computer/GlideComputerBlackboard.cpp + Computer/GlideComputerInterface.cpp + Computer/GlideRatioCalculator.cpp + Computer/GlideRatioComputer.cpp + Computer/GroundSpeedComputer.cpp + Computer/LiftDatabaseComputer.cpp + Computer/LogComputer.cpp + Computer/RouteComputer.cpp + Computer/Settings.cpp + Computer/StatsComputer.cpp + Computer/TaskComputer.cpp + Computer/ThermalBandComputer.cpp + Computer/ThermalBase.cpp + Computer/ThermalLocator.cpp + Computer/ThermalRecency.cpp + Computer/TraceComputer.cpp + Computer/WarningComputer.cpp + Computer/WaveComputer.cpp + Computer/Wind/CirclingWind.cpp + Computer/Wind/Computer.cpp + Computer/Wind/MeasurementList.cpp + Computer/Wind/Settings.cpp + Computer/Wind/Store.cpp + Computer/Wind/WindEKF.cpp + Computer/Wind/WindEKFGlue.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake +) + diff --git a/src/Computer/GlideRatioCalculator.cpp b/src/Computer/GlideRatioCalculator.cpp index c0ffce451b4..5745f9ece76 100644 --- a/src/Computer/GlideRatioCalculator.cpp +++ b/src/Computer/GlideRatioCalculator.cpp @@ -17,22 +17,22 @@ GlideRatioCalculator::Initialize(const ComputerSettings &settings) unsigned bsize; switch (settings.average_eff_time) { - case ae15seconds: + case AverageEffTime::ae15seconds: bsize = 15; // useless, LDinst already there break; - case ae30seconds: + case AverageEffTime::ae30seconds: bsize = 30; // limited useful break; - case ae60seconds: + case AverageEffTime::ae60seconds: bsize = 60; // starting to be valuable break; - case ae90seconds: + case AverageEffTime::ae90seconds: bsize = 90; // good interval break; - case ae2minutes: + case AverageEffTime::ae2minutes: bsize = 120; // other software's interval break; - case ae3minutes: + case AverageEffTime::ae3minutes: bsize = 180; // probably too long interval break; #ifndef __clang__ diff --git a/src/Computer/Settings.cpp b/src/Computer/Settings.cpp index 8e220ff1bb4..cea1fa361f4 100644 --- a/src/Computer/Settings.cpp +++ b/src/Computer/Settings.cpp @@ -49,7 +49,7 @@ ComputerSettings::SetDefaults() circling.SetDefaults(); wave.SetDefaults(); - average_eff_time = ae30seconds; + average_eff_time = AverageEffTime::ae30seconds; set_system_time_from_gps = false; utc_offset = RoughTimeDelta::FromSeconds(GetTimeZoneOffset()); forecast_temperature = Temperature::FromCelsius(25); diff --git a/src/Computer/Settings.hpp b/src/Computer/Settings.hpp index d7bb9718658..d45ca14d7b6 100644 --- a/src/Computer/Settings.hpp +++ b/src/Computer/Settings.hpp @@ -169,13 +169,13 @@ struct CirclingSettings { } }; -enum AverageEffTime { - ae15seconds, - ae30seconds, - ae60seconds, - ae90seconds, - ae2minutes, - ae3minutes, +enum class AverageEffTime : uint8_t{ + ae15seconds = 15, + ae30seconds = 30, + ae60seconds = 60, + ae90seconds = 90, + ae2minutes = 120, + ae3minutes = 180, }; struct ComputerSettings { diff --git a/src/CrossSection/AirspaceXSRenderer.cpp b/src/CrossSection/AirspaceXSRenderer.cpp index f2a26afa358..02dc3b3428f 100644 --- a/src/CrossSection/AirspaceXSRenderer.cpp +++ b/src/CrossSection/AirspaceXSRenderer.cpp @@ -168,7 +168,7 @@ AirspaceIntersectionVisitorSlice::Render(const AbstractAirspace &as) const max_x -= Layout::GetTextPadding(); /* draw the airspace name */ - const TCHAR *name = as.GetName(); + const char *name = as.GetName(); if (name != nullptr && !StringIsEmpty(name) && min_x < max_x) { canvas.SetBackgroundTransparent(); canvas.SetTextColor(COLOR_BLACK); diff --git a/src/CrossSection/CMakeLists.txt b/src/CrossSection/CMakeLists.txt new file mode 100644 index 00000000000..8007a8ccd1a --- /dev/null +++ b/src/CrossSection/CMakeLists.txt @@ -0,0 +1,54 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories + + +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) + +add_dependencies(${TARGET_NAME} util) + diff --git a/src/CrossSection/CMakeSource.cmake b/src/CrossSection/CMakeSource.cmake new file mode 100644 index 00000000000..f2a372d296f --- /dev/null +++ b/src/CrossSection/CMakeSource.cmake @@ -0,0 +1,12 @@ +set(_SOURCES + CrossSection/AirspaceXSRenderer.cpp + CrossSection/CrossSectionRenderer.cpp + CrossSection/CrossSectionWidget.cpp + CrossSection/CrossSectionWindow.cpp + CrossSection/TerrainXSRenderer.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake +) + diff --git a/src/CrossSection/CrossSectionRenderer.cpp b/src/CrossSection/CrossSectionRenderer.cpp index 8188c8f5788..e2dfbaac374 100644 --- a/src/CrossSection/CrossSectionRenderer.cpp +++ b/src/CrossSection/CrossSectionRenderer.cpp @@ -44,8 +44,8 @@ CrossSectionRenderer::Paint(Canvas &canvas, const PixelRect rc) const { ChartRenderer chart(chart_look, canvas, rc); - chart.SetXLabel(_T("D"), Units::GetDistanceName()); - chart.SetYLabel(_T("h"), Units::GetAltitudeName()); + chart.SetXLabel("D", Units::GetDistanceName()); + chart.SetYLabel("h", Units::GetAltitudeName()); chart.Begin(); diff --git a/src/Device/CMakeLists.txt b/src/Device/CMakeLists.txt new file mode 100644 index 00000000000..4fb8a09d376 --- /dev/null +++ b/src/Device/CMakeLists.txt @@ -0,0 +1,59 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories + +if(MSVC) + # in device driver could be found characters f.e. fro german codepage + # (f.e. VOLKSLOGGER) - surpress this warnings: + add_compile_options(/wd4828) # "|": unsichere Kombination von Typ "bool" mit Typ "int" in einer Operation +endif() + +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) + +target_link_libraries(${TARGET_NAME} PUBLIC Job NMEA) + +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/Device/CMakeSource.cmake b/src/Device/CMakeSource.cmake new file mode 100644 index 00000000000..eed6e0736a2 --- /dev/null +++ b/src/Device/CMakeSource.cmake @@ -0,0 +1,140 @@ +set(_SOURCES + Device/Config.cpp + Device/Factory.cpp + Device/Declaration.cpp + Device/Descriptor.cpp + Device/device.cpp + Device/Dispatcher.cpp + Device/DataEditor.cpp + Device/Driver.cpp + Device/Driver/AirControlDisplay.cpp + Device/Driver/AltairPro.cpp + Device/Driver/Anemoi.cpp + Device/Driver/ATR833/Register.cpp + Device/Driver/ATR833/Device.cpp + Device/Driver/BlueFly/Misc.cpp + Device/Driver/BlueFly/Parser.cpp + Device/Driver/BlueFly/Register.cpp + Device/Driver/BlueFly/Settings.cpp + Device/Driver/BorgeltB50.cpp + Device/Driver/CAI302/Declare.cpp + Device/Driver/CAI302/Logger.cpp + Device/Driver/CAI302/Manage.cpp + Device/Driver/CAI302/Mode.cpp + Device/Driver/CAI302/Parser.cpp + Device/Driver/CAI302/PocketNav.cpp + Device/Driver/CAI302/Protocol.cpp + Device/Driver/CAI302/Register.cpp + Device/Driver/CAI302/Settings.cpp + Device/Driver/CaiGpsNav.cpp + Device/Driver/CaiLNav.cpp + Device/Driver/Condor.cpp + Device/Driver/CProbe.cpp + Device/Driver/EW.cpp + Device/Driver/EWMicroRecorder.cpp + Device/Driver/Eye.cpp + Device/Driver/FLARM/BinaryProtocol.cpp + Device/Driver/FLARM/CRC16.cpp + Device/Driver/FLARM/Declare.cpp + Device/Driver/FLARM/Device.cpp + Device/Driver/FLARM/Logger.cpp + Device/Driver/FLARM/Mode.cpp + Device/Driver/FLARM/Parser.cpp + Device/Driver/FLARM/Register.cpp + Device/Driver/FLARM/Settings.cpp + Device/Driver/FLARM/StaticParser.cpp + Device/Driver/FLARM/TextProtocol.cpp + Device/Driver/FlymasterF1.cpp + Device/Driver/FlyNet.cpp + Device/Driver/Flytec/Logger.cpp + Device/Driver/Flytec/Parser.cpp + Device/Driver/Flytec/Register.cpp + Device/Driver/FreeVario.cpp + Device/Driver/Generic.cpp + Device/Driver/ILEC.cpp + Device/Driver/IMI/Declare.cpp + Device/Driver/IMI/Internal.cpp + Device/Driver/IMI/Logger.cpp + Device/Driver/IMI/Protocol/Checksum.cpp + Device/Driver/IMI/Protocol/Communication.cpp + Device/Driver/IMI/Protocol/Conversion.cpp + Device/Driver/IMI/Protocol/IGC.cpp + Device/Driver/IMI/Protocol/MessageParser.cpp + Device/Driver/IMI/Protocol/Protocol.cpp + Device/Driver/IMI/Register.cpp + Device/Driver/KRT2.cpp + Device/Driver/AR62xx.cpp + Device/Driver/Larus.cpp + Device/Driver/Leonardo.cpp + Device/Driver/LevilAHRS_G.cpp + Device/Driver/LX/Convert.cpp + Device/Driver/LX/Declare.cpp + Device/Driver/LX/Logger.cpp + Device/Driver/LX/LXN.cpp + Device/Driver/LX/Mode.cpp + Device/Driver/LX/NanoDeclare.cpp + Device/Driver/LX/NanoLogger.cpp + Device/Driver/LX/Parser.cpp + Device/Driver/LX/Protocol.cpp + Device/Driver/LX/Register.cpp + Device/Driver/LX/Settings.cpp + Device/Driver/NmeaOut.cpp + Device/Driver/OpenVario.cpp + Device/Driver/PosiGraph.cpp + Device/Driver/ThermalExpress/Driver.cpp + Device/Driver/Vaulter.cpp + Device/Driver/Vega/Misc.cpp + Device/Driver/Vega/Parser.cpp + Device/Driver/Vega/Register.cpp + Device/Driver/Vega/Settings.cpp + Device/Driver/Vega/Volatile.cpp + Device/Driver/Volkslogger/Database.cpp + Device/Driver/Volkslogger/dbbconv.cpp + Device/Driver/Volkslogger/Declare.cpp + Device/Driver/Volkslogger/grecord.cpp + Device/Driver/Volkslogger/Logger.cpp + Device/Driver/Volkslogger/Parser.cpp + Device/Driver/Volkslogger/Protocol.cpp + Device/Driver/Volkslogger/Register.cpp + Device/Driver/Volkslogger/Util.cpp + Device/Driver/Volkslogger/vlapi2.cpp + Device/Driver/Volkslogger/vlapihlp.cpp + Device/Driver/Volkslogger/vlconv.cpp + Device/Driver/Westerboer.cpp + Device/Driver/XCOM760.cpp + Device/Driver/XCTracer/Parser.cpp + Device/Driver/XCTracer/Register.cpp + Device/Driver/XCVario.cpp + Device/Driver/Zander.cpp + Device/MultipleDevices.cpp + Device/Parser.cpp + Device/Port/BufferedPort.cpp + Device/Port/ConfiguredPort.cpp + Device/Port/DumpPort.cpp + Device/Port/K6BtPort.cpp + Device/Port/NullPort.cpp + Device/Port/Port.cpp + Device/Port/SocketPort.cpp + Device/Port/TCPClientPort.cpp + Device/Port/TCPPort.cpp + Device/Port/UDPPort.cpp + Device/Register.cpp + Device/Simulator.cpp + Device/Util/LineSplitter.cpp + Device/Util/NMEAReader.cpp + Device/Util/NMEAWriter.cpp +) +if(UNIX) + list(APPEND _SOURCES + Device/Port/TTYEnumerator.cpp + Device/Port/TTYPort.cpp + ) +elseif(WIN32) + list(APPEND _SOURCES + Device/Port/SerialPort.cpp + ) +endif() + +set(SCRIPT_FILES + CMakeSource.cmake +) diff --git a/src/Device/Config.cpp b/src/Device/Config.cpp index 2ab618df021..162486ddb3f 100644 --- a/src/Device/Config.cpp +++ b/src/Device/Config.cpp @@ -29,9 +29,10 @@ DeviceConfig::IsAvailable() const noexcept case PortType::RFCOMM: case PortType::BLE_HM10: case PortType::BLE_SENSOR: + case PortType::USB_SERIAL: + return IsAndroid() || true; // IsWindows() case PortType::RFCOMM_SERVER: case PortType::GLIDER_LINK: - case PortType::ANDROID_USB_SERIAL: return IsAndroid(); case PortType::IOIOUART: @@ -82,7 +83,7 @@ DeviceConfig::ShouldReopenOnTimeout() const noexcept case PortType::BLE_SENSOR: case PortType::BLE_HM10: case PortType::RFCOMM_SERVER: - case PortType::ANDROID_USB_SERIAL: + case PortType::USB_SERIAL: case PortType::IOIOUART: case PortType::DROIDSOAR_V2: case PortType::NUNCHUCK: @@ -112,7 +113,7 @@ DeviceConfig::ShouldReopenOnTimeout() const noexcept } bool -DeviceConfig::MaybeBluetooth(PortType port_type, [[maybe_unused]] const TCHAR *path) noexcept +DeviceConfig::MaybeBluetooth(PortType port_type, [[maybe_unused]] const char *path) noexcept { /* note: RFCOMM_SERVER is not considered here because this function is used to check for the K6-Bt protocol, but the K6-Bt @@ -122,7 +123,7 @@ DeviceConfig::MaybeBluetooth(PortType port_type, [[maybe_unused]] const TCHAR *p return true; #ifdef HAVE_POSIX - if (port_type == PortType::SERIAL && _tcsstr(path, _T("/rfcomm")) != nullptr) + if (port_type == PortType::SERIAL && strstr(path, "/rfcomm") != nullptr) return true; #endif @@ -140,7 +141,7 @@ DeviceConfig::MaybeBluetooth() const noexcept return true; #ifdef HAVE_POSIX - if (port_type == PortType::SERIAL && path.Contains(_T("/rfcomm"))) + if (port_type == PortType::SERIAL && path.Contains("/rfcomm")) return true; #endif @@ -177,6 +178,7 @@ DeviceConfig::Clear() noexcept i2c_addr = 0; press_use = PressureUse::STATIC_ONLY; path.clear(); + port_name.clear(); bluetooth_mac.clear(); driver_name.clear(); enabled = true; @@ -187,10 +189,11 @@ DeviceConfig::Clear() noexcept #ifndef NDEBUG dump_port = false; #endif +// dump_port = true; } -const TCHAR * -DeviceConfig::GetPortName(TCHAR *buffer, size_t max_size) const noexcept +const char * +DeviceConfig::GetPortName(char *buffer, size_t max_size) const noexcept { switch (port_type) { case PortType::DISABLED: @@ -200,7 +203,7 @@ DeviceConfig::GetPortName(TCHAR *buffer, size_t max_size) const noexcept return path.c_str(); case PortType::BLE_SENSOR: { - const TCHAR *name = bluetooth_mac.c_str(); + const char *name = bluetooth_mac.c_str(); #ifdef ANDROID if (bluetooth_helper != nullptr) { const char *name2 = @@ -208,15 +211,17 @@ DeviceConfig::GetPortName(TCHAR *buffer, size_t max_size) const noexcept if (name2 != nullptr) name = name2; } +#elif defined(_WIN32) + name = port_name; #endif - StringFormat(buffer, max_size, _T("%s: %s"), + StringFormat(buffer, max_size, "%s: %s", _("BLE sensor"), name); return buffer; } case PortType::BLE_HM10: { - const TCHAR *name = bluetooth_mac.c_str(); + const char *name = bluetooth_mac.c_str(); #ifdef ANDROID if (bluetooth_helper != nullptr) { const char *name2 = @@ -224,15 +229,17 @@ DeviceConfig::GetPortName(TCHAR *buffer, size_t max_size) const noexcept if (name2 != nullptr) name = name2; } +#elif defined(_WIN32) + name = port_name; #endif - StringFormat(buffer, max_size, _T("%s: %s"), + StringFormat(buffer, max_size, "%s: %s", _("BLE port"), name); return buffer; } case PortType::RFCOMM: { - const TCHAR *name = bluetooth_mac.c_str(); + const char *name = bluetooth_mac.c_str(); #ifdef ANDROID if (bluetooth_helper != nullptr) { const char *name2 = @@ -240,9 +247,11 @@ DeviceConfig::GetPortName(TCHAR *buffer, size_t max_size) const noexcept if (name2 != nullptr) name = name2; } +#elif defined(_WIN32) + name = port_name; #endif - StringFormat(buffer, max_size, _T("Bluetooth %s"), name); + StringFormat(buffer, max_size, "Bluetooth %s", name); return buffer; } @@ -250,20 +259,20 @@ DeviceConfig::GetPortName(TCHAR *buffer, size_t max_size) const noexcept return _("Bluetooth server"); case PortType::IOIOUART: - StringFormat(buffer, max_size, _T("IOIO UART %d"), ioio_uart_id); + StringFormat(buffer, max_size, "IOIO UART %d", ioio_uart_id); return buffer; case PortType::DROIDSOAR_V2: - return _T("DroidSoar V2"); + return "DroidSoar V2"; case PortType::NUNCHUCK: - return _T("Nunchuck"); + return "Nunchuck"; case PortType::I2CPRESSURESENSOR: - return _T("IOIO i2c pressure sensor"); + return "IOIO i2c pressure sensor"; case PortType::IOIOVOLTAGE: - return _T("IOIO voltage sensor"); + return "IOIO voltage sensor"; case PortType::AUTO: return _("GPS Intermediate Driver"); @@ -275,25 +284,25 @@ DeviceConfig::GetPortName(TCHAR *buffer, size_t max_size) const noexcept return _("GliderLink traffic receiver"); case PortType::TCP_CLIENT: - StringFormat(buffer, max_size, _T("TCP client %s:%u"), + StringFormat(buffer, max_size, "TCP client %s:%u", ip_address.c_str(), tcp_port); return buffer; case PortType::TCP_LISTENER: - StringFormat(buffer, max_size, _T("TCP port %d"), tcp_port); + StringFormat(buffer, max_size, "TCP port %d", tcp_port); return buffer; case PortType::UDP_LISTENER: - StringFormat(buffer, max_size, _T("UDP port %d"), tcp_port); + StringFormat(buffer, max_size, "UDP port %d", tcp_port); return buffer; case PortType::PTY: - StringFormat(buffer, max_size, _T("Pseudo-terminal %s"), path.c_str()); + StringFormat(buffer, max_size, "Pseudo-terminal %s", path.c_str()); return buffer; - case PortType::ANDROID_USB_SERIAL: - StringFormat(buffer, max_size, _T("%s: %s"), - _("USB serial"), path.c_str()); + case PortType::USB_SERIAL: + StringFormat(buffer, max_size, "%s: %s", + _("USB serial"), port_name.c_str()); return buffer; } diff --git a/src/Device/Config.hpp b/src/Device/Config.hpp index 41146e78838..c5d11e6a23b 100644 --- a/src/Device/Config.hpp +++ b/src/Device/Config.hpp @@ -101,7 +101,7 @@ struct DeviceConfig { /** * USB serial port on Android. */ - ANDROID_USB_SERIAL, + USB_SERIAL, }; /** @@ -124,10 +124,15 @@ struct DeviceConfig { unsigned bulk_baud_rate; /** - * The path name of the serial port, e.g. "COM4:" or "/dev/ttyUSB0". + * The path name of the serial port, e.g. "COM4" or "/dev/ttyUSB0". */ StaticString<64> path; + /** + * The path name of the bluetooth port, e.g. "COM15 (Larus1234)". + */ + StaticString<128> port_name; + /** * The Bluetooth MAC address of the peer. */ @@ -259,7 +264,7 @@ struct DeviceConfig { */ static constexpr bool UsesSpeed(PortType port_type) noexcept { return port_type == PortType::SERIAL || port_type == PortType::AUTO || - port_type == PortType::ANDROID_USB_SERIAL || + port_type == PortType::USB_SERIAL || port_type == PortType::IOIOUART; } @@ -309,7 +314,7 @@ struct DeviceConfig { case PortType::IOIOUART: case PortType::PTY: case PortType::UDP_LISTENER: - case PortType::ANDROID_USB_SERIAL: + case PortType::USB_SERIAL: break; } @@ -317,7 +322,7 @@ struct DeviceConfig { } [[gnu::pure]] - static bool MaybeBluetooth(PortType port_type, const TCHAR *path) noexcept; + static bool MaybeBluetooth(PortType port_type, const char *path) noexcept; [[gnu::pure]] bool MaybeBluetooth() const noexcept; @@ -345,7 +350,6 @@ struct DeviceConfig { static constexpr bool UsesDriver(PortType port_type) noexcept { switch (port_type) { case PortType::DISABLED: - case PortType::BLE_SENSOR: case PortType::GLIDER_LINK: case PortType::DROIDSOAR_V2: case PortType::NUNCHUCK: @@ -354,6 +358,13 @@ struct DeviceConfig { case PortType::INTERNAL: return false; + case PortType::BLE_SENSOR: +#ifdef _WIN32 + return true; +#else + return false; +#endif + case PortType::SERIAL: case PortType::BLE_HM10: case PortType::RFCOMM: @@ -364,7 +375,7 @@ struct DeviceConfig { case PortType::IOIOUART: case PortType::PTY: case PortType::UDP_LISTENER: - case PortType::ANDROID_USB_SERIAL: + case PortType::USB_SERIAL: return true; } @@ -400,12 +411,12 @@ struct DeviceConfig { return UsesTCPPort(port_type); } - constexpr bool IsDriver(const TCHAR *name) const noexcept { + constexpr bool IsDriver(const char *name) const noexcept { return UsesDriver() && driver_name.equals(name); } bool IsVega() const noexcept { - return IsDriver(_T("Vega")); + return IsDriver("Vega"); } constexpr bool IsAndroidInternalGPS() const noexcept { @@ -456,5 +467,5 @@ struct DeviceConfig { * Generates a human-readable (localised) port name. */ [[gnu::pure]] - const TCHAR *GetPortName(TCHAR *buffer, size_t max_size) const noexcept; + const char *GetPortName(char *buffer, size_t max_size) const noexcept; }; diff --git a/src/Device/Declaration.hpp b/src/Device/Declaration.hpp index 5f71e8f7416..6bde2da857f 100644 --- a/src/Device/Declaration.hpp +++ b/src/Device/Declaration.hpp @@ -59,12 +59,12 @@ struct Declaration { } [[gnu::pure]] - const TCHAR *GetName(const unsigned i) const { + const char *GetName(const unsigned i) const { return turnpoints[i].waypoint.name.c_str(); } [[gnu::pure]] - const TCHAR *GetShortName(const unsigned i) const { + const char *GetShortName(const unsigned i) const { return turnpoints[i].waypoint.shortname.c_str(); } diff --git a/src/Device/Descriptor.cpp b/src/Device/Descriptor.cpp index fc6fa0986b7..ddaaf6e7898 100644 --- a/src/Device/Descriptor.cpp +++ b/src/Device/Descriptor.cpp @@ -16,7 +16,6 @@ #include "NMEA/Info.hpp" #include "thread/Mutex.hxx" #include "util/StringAPI.hxx" -#include "util/ConvertString.hpp" #include "util/Exception.hxx" #include "Logger/NMEALogger.hpp" #include "Language/Language.hpp" @@ -196,8 +195,8 @@ try { port = std::move(_port); parser.Reset(); - parser.SetReal(!StringIsEqual(driver->name, _T("Condor"))); - if (config.IsDriver(_T("Condor"))) + parser.SetReal(!StringIsEqual(driver->name, "Condor")); + if (config.IsDriver("Condor")) parser.DisableGeoid(); if (driver->CreateOnPort != nullptr) { @@ -341,6 +340,8 @@ DeviceDescriptor::OpenBluetoothSensor() java_sensor = new Java::GlobalCloseable(factory.OpenBluetoothSensor(config, *this)); return true; +#elif defined(_WIN32) + return true; #else return false; #endif @@ -355,27 +356,26 @@ try { const std::lock_guard lock{mutex}; error_message.clear(); } - - if (config.port_type == DeviceConfig::PortType::INTERNAL) + switch (config.port_type) { + case DeviceConfig::PortType::INTERNAL: return OpenInternalSensors(); - - if (config.port_type == DeviceConfig::PortType::DROIDSOAR_V2) + case DeviceConfig::PortType::DROIDSOAR_V2: return OpenDroidSoarV2(); - - if (config.port_type == DeviceConfig::PortType::I2CPRESSURESENSOR) - return OpenI2Cbaro(); - - if (config.port_type == DeviceConfig::PortType::NUNCHUCK) - return OpenNunchuck(); - - if (config.port_type == DeviceConfig::PortType::IOIOVOLTAGE) - return OpenVoltage(); - - if (config.port_type == DeviceConfig::PortType::GLIDER_LINK) - return OpenGliderLink(); - - if (config.port_type == DeviceConfig::PortType::BLE_SENSOR) - return OpenBluetoothSensor(); + case DeviceConfig::PortType::I2CPRESSURESENSOR: + return OpenI2Cbaro(); + case DeviceConfig::PortType::NUNCHUCK: + return OpenNunchuck(); + case DeviceConfig::PortType::IOIOVOLTAGE: + return OpenVoltage(); + case DeviceConfig::PortType::GLIDER_LINK: + return OpenGliderLink(); +#ifndef _WIN32 + case DeviceConfig::PortType::BLE_SENSOR: + return OpenBluetoothSensor(); +#endif + default: + break; + } reopen_clock.Update(); @@ -387,18 +387,18 @@ try { } catch (...) { const auto e = std::current_exception(); - TCHAR name_buffer[64]; - const TCHAR *name = config.GetPortName(name_buffer, 64); + char name_buffer[64]; + const char *name = config.GetPortName(name_buffer, 64); - LogError(e, WideToUTF8Converter(name)); - - const auto _msg = GetFullMessage(e); - if (const UTF8ToWideConverter what{_msg.c_str()}; what.IsValid()) { - LockSetErrorMessage(what); + LogError(e, name); + + // const std::string_view _msg(GetFullMessage(e)); + const auto what = GetFullMessage(e); + if (what.c_str() != nullptr) { StaticString<256> msg; - msg.Format(_T("%s: %s (%s)"), _("Unable to open port"), name, - (const TCHAR *)what); + LockSetErrorMessage(what.c_str()); + msg.Format("%s: %s (%s)", _("Unable to open port"), name, what.c_str()); env.SetErrorMessage(msg); } @@ -406,11 +406,11 @@ try { } if (port == nullptr) { - TCHAR name_buffer[64]; - const TCHAR *name = config.GetPortName(name_buffer, 64); + char name_buffer[64]; + const char *name = config.GetPortName(name_buffer, 64); StaticString<256> msg; - msg.Format(_T("%s: %s."), _("Unable to open port"), name); + msg.Format("%s: %s.", _("Unable to open port"), name); env.SetErrorMessage(msg); return false; } @@ -436,11 +436,10 @@ try { const auto e = std::current_exception(); LogError(e); - const auto _msg = GetFullMessage(e); - - if (const UTF8ToWideConverter msg{_msg.c_str()}; msg.IsValid()) { - LockSetErrorMessage(msg); - env.SetErrorMessage(msg); + const auto msg = GetFullMessage(e); + if (msg.c_str() != nullptr) { + LockSetErrorMessage(msg.c_str()); + env.SetErrorMessage(msg.c_str()); } return false; @@ -465,8 +464,8 @@ DeviceDescriptor::Open(OperationEnvironment &env) assert(!IsOccupied()); assert(open_job == nullptr); - TCHAR buffer[64]; - LogFormat(_T("Opening device %s"), config.GetPortName(buffer, 64)); + char buffer[64]; + LogFormat("Opening device %s", config.GetPortName(buffer, 64)); #ifdef ANDROID /* reset the Kalman filter */ @@ -554,8 +553,8 @@ DeviceDescriptor::AutoReopen(OperationEnvironment &env) !reopen_clock.CheckUpdate(std::chrono::seconds(30))) return; - TCHAR buffer[64]; - LogFormat(_T("Reconnecting to device %s"), config.GetPortName(buffer, 64)); + char buffer[64]; + LogFormat("Reconnecting to device %s", config.GetPortName(buffer, 64)); InputEvents::processGlideComputer(GCE_COMMPORT_RESTART); Reopen(env); @@ -584,7 +583,7 @@ DeviceDescriptor::EnableNMEA(OperationEnvironment &env) noexcept return success; } -const TCHAR * +const char * DeviceDescriptor::GetDisplayName() const noexcept { return driver != nullptr @@ -593,7 +592,7 @@ DeviceDescriptor::GetDisplayName() const noexcept } bool -DeviceDescriptor::IsDriver(const TCHAR *name) const noexcept +DeviceDescriptor::IsDriver(const char *name) const noexcept { return driver != nullptr ? StringIsEqual(driver->name, name) @@ -627,7 +626,7 @@ DeviceDescriptor::IsManageable() const noexcept if (driver->IsManageable()) return true; - if (StringIsEqual(driver->name, _T("LX")) && device != nullptr) { + if (StringIsEqual(driver->name, "LX") && device != nullptr) { const LXDevice &lx = *(const LXDevice *)device; return lx.IsManageable(); } @@ -770,21 +769,6 @@ DeviceDescriptor::WriteNMEA(const char *line, } } -#ifdef _UNICODE -bool -DeviceDescriptor::WriteNMEA(const TCHAR *line, - OperationEnvironment &env) noexcept -{ - assert(line != nullptr); - - if (port == nullptr) - return false; - - WideToACPConverter narrow{line}; - return narrow.IsValid() && WriteNMEA(narrow, env); -} -#endif - bool DeviceDescriptor::PutMacCready(double value, OperationEnvironment &env) noexcept @@ -931,7 +915,7 @@ DeviceDescriptor::PutPilotEvent(OperationEnvironment &env) noexcept bool DeviceDescriptor::PutActiveFrequency(RadioFrequency frequency, - const TCHAR *name, + const char *name, OperationEnvironment &env) noexcept { assert(InMainThread()); @@ -957,7 +941,7 @@ DeviceDescriptor::PutActiveFrequency(RadioFrequency frequency, bool DeviceDescriptor::PutStandbyFrequency(RadioFrequency frequency, - const TCHAR *name, + const char *name, OperationEnvironment &env) noexcept { assert(InMainThread()); @@ -1065,13 +1049,13 @@ DoDeclare(const struct Declaration &declaration, OperationEnvironment &env) { StaticString<60> text; - text.Format(_T("%s: %s."), _("Sending declaration"), driver.display_name); + text.Format("%s: %s.", _("Sending declaration"), driver.display_name); env.SetText(text); bool result = device != nullptr && device->Declare(declaration, home, env); if (flarm) { - text.Format(_T("%s: FLARM."), _("Sending declaration")); + text.Format("%s: FLARM.", _("Sending declaration")); env.SetText(text); result |= DeclareToFLARM(declaration, port, driver, device, home, env); @@ -1099,7 +1083,7 @@ DeviceDescriptor::Declare(const struct Declaration &declaration, } else { /* enable the "muxed FLARM" hack? */ const bool flarm = blackboard.IsFLARM(index) && - !IsDriver(_T("FLARM")); + !IsDriver("FLARM"); return DoDeclare(declaration, *port, *driver, device, flarm, home, env); @@ -1118,14 +1102,14 @@ DeviceDescriptor::ReadFlightList(RecordedFlightList &flight_list, StaticString<60> text; if (driver->HasPassThrough() && second_device != nullptr) { - text.Format(_T("%s: %s."), _("Reading flight list"), + text.Format("%s: %s.", _("Reading flight list"), second_driver->display_name); env.SetText(text); device->EnablePassThrough(env); return second_device->ReadFlightList(flight_list, env); } else { - text.Format(_T("%s: %s."), _("Reading flight list"), driver->display_name); + text.Format("%s: %s.", _("Reading flight list"), driver->display_name); env.SetText(text); return device->ReadFlightList(flight_list, env); @@ -1149,14 +1133,14 @@ DeviceDescriptor::DownloadFlight(const RecordedFlightInfo &flight, if (driver->HasPassThrough() && (second_device != nullptr)) { - text.Format(_T("%s: %s."), _("Downloading flight log"), + text.Format("%s: %s.", _("Downloading flight log"), second_driver->display_name); env.SetText(text); device->EnablePassThrough(env); return second_device->DownloadFlight(flight, path, env); } else { - text.Format(_T("%s: %s."), _("Downloading flight log"), + text.Format("%s: %s.", _("Downloading flight log"), driver->display_name); env.SetText(text); @@ -1242,23 +1226,12 @@ DeviceDescriptor::OnCalculatedUpdate(const MoreData &basic, } inline void -DeviceDescriptor::LockSetErrorMessage(const TCHAR *msg) noexcept +DeviceDescriptor::LockSetErrorMessage(const char *msg) noexcept { const std::lock_guard lock{mutex}; error_message = msg; } -#ifdef _UNICODE - -inline void -DeviceDescriptor::LockSetErrorMessage(const char *msg) noexcept -{ - if (const UTF8ToWideConverter tmsg(msg); tmsg.IsValid()) - LockSetErrorMessage(tmsg); -} - -#endif - void DeviceDescriptor::OnJobFinished() noexcept { @@ -1291,8 +1264,8 @@ void DeviceDescriptor::PortError(const char *msg) noexcept { { - TCHAR buffer[64]; - LogFormat(_T("Error on device %s: %s"), + char buffer[64]; + LogFormat("Error on device %s: %s", config.GetPortName(buffer, 64), msg); } diff --git a/src/Device/Descriptor.hpp b/src/Device/Descriptor.hpp index b314304e10f..d88151ce011 100644 --- a/src/Device/Descriptor.hpp +++ b/src/Device/Descriptor.hpp @@ -18,7 +18,7 @@ #include "thread/Mutex.hxx" #include "thread/Debug.hpp" #include "time/FloatDuration.hxx" -#include "util/tstring.hpp" +#include #include "util/StaticFifoBuffer.hxx" #ifdef HAVE_INTERNAL_GPS @@ -231,7 +231,7 @@ class DeviceDescriptor final * If this device has failed, then this attribute may contain an * error message. */ - tstring error_message; + std::string error_message; /** * Number of port failures since the device was last reset. @@ -292,7 +292,7 @@ class DeviceDescriptor final [[gnu::pure]] PortState GetState() const noexcept; - tstring GetErrorMessage() const noexcept { + std::string GetErrorMessage() const noexcept { const std::lock_guard lock{mutex}; return error_message; } @@ -420,12 +420,12 @@ class DeviceDescriptor final */ bool EnableNMEA(OperationEnvironment &env) noexcept; - const TCHAR *GetDisplayName() const noexcept; + const char *GetDisplayName() const noexcept; /** * Compares the driver's name. */ - bool IsDriver(const TCHAR *name) const noexcept; + bool IsDriver(const char *name) const noexcept; [[gnu::pure]] bool CanDeclare() const noexcept; @@ -434,11 +434,11 @@ class DeviceDescriptor final bool IsLogger() const noexcept; bool IsCondor() const noexcept { - return IsDriver(_T("Condor")); + return IsDriver("Condor"); } bool IsVega() const noexcept { - return IsDriver(_T("Vega")); + return IsDriver("Vega"); } bool IsNMEAOut() const noexcept; @@ -529,10 +529,6 @@ class DeviceDescriptor final void ForwardLine(const char *line); bool WriteNMEA(const char *line, OperationEnvironment &env) noexcept; -#ifdef _UNICODE - bool WriteNMEA(const TCHAR *line, OperationEnvironment &env) noexcept; -#endif - bool PutMacCready(double mac_cready, OperationEnvironment &env) noexcept; bool PutBugs(double bugs, OperationEnvironment &env) noexcept; bool PutBallast(double fraction, double overload, @@ -540,10 +536,10 @@ class DeviceDescriptor final bool PutVolume(unsigned volume, OperationEnvironment &env) noexcept; bool PutPilotEvent(OperationEnvironment &env) noexcept; bool PutActiveFrequency(RadioFrequency frequency, - const TCHAR *name, + const char *name, OperationEnvironment &env) noexcept; bool PutStandbyFrequency(RadioFrequency frequency, - const TCHAR *name, + const char *name, OperationEnvironment &env) noexcept; bool PutTransponderCode(TransponderCode code, OperationEnvironment &env) noexcept; bool PutQNH(AtmosphericPressure pres, @@ -581,11 +577,7 @@ class DeviceDescriptor final const DerivedInfo &calculated) noexcept; private: - void LockSetErrorMessage(const TCHAR *msg) noexcept; -#ifdef _UNICODE void LockSetErrorMessage(const char *msg) noexcept; -#endif - void OnJobFinished() noexcept; /* virtual methods from class PortListener */ diff --git a/src/Device/Driver.cpp b/src/Device/Driver.cpp index c4cfaa2fcf3..76399405b84 100644 --- a/src/Device/Driver.cpp +++ b/src/Device/Driver.cpp @@ -66,7 +66,7 @@ AbstractDevice::PutPilotEvent([[maybe_unused]] OperationEnvironment &env) bool AbstractDevice::PutActiveFrequency([[maybe_unused]] RadioFrequency frequency, - [[maybe_unused]] const TCHAR *name, + [[maybe_unused]] const char *name, [[maybe_unused]] OperationEnvironment &env) { return true; @@ -74,7 +74,7 @@ AbstractDevice::PutActiveFrequency([[maybe_unused]] RadioFrequency frequency, bool AbstractDevice::PutStandbyFrequency([[maybe_unused]] RadioFrequency frequency, - [[maybe_unused]] const TCHAR *name, + [[maybe_unused]] const char *name, [[maybe_unused]] OperationEnvironment &env) { return true; diff --git a/src/Device/Driver.hpp b/src/Device/Driver.hpp index f24fa17988b..6e925fab66a 100644 --- a/src/Device/Driver.hpp +++ b/src/Device/Driver.hpp @@ -115,7 +115,7 @@ class Device { * @return true on success */ virtual bool PutActiveFrequency(RadioFrequency frequency, - const TCHAR *name, + const char *name, OperationEnvironment &env) = 0; /** @@ -126,7 +126,7 @@ class Device { * @return true on success */ virtual bool PutStandbyFrequency(RadioFrequency frequency, - const TCHAR *name, + const char *name, OperationEnvironment &env) = 0; /** @@ -249,10 +249,10 @@ class AbstractDevice : public Device { bool PutVolume(unsigned volume, OperationEnvironment &env) override; bool PutPilotEvent(OperationEnvironment &env) override; bool PutActiveFrequency(RadioFrequency frequency, - const TCHAR *name, + const char *name, OperationEnvironment &env) override; bool PutStandbyFrequency(RadioFrequency frequency, - const TCHAR *name, + const char *name, OperationEnvironment &env) override; bool PutTransponderCode(TransponderCode code, OperationEnvironment &env) override; @@ -351,12 +351,12 @@ struct DeviceRegister { * The internal name of the driver, i.e. the one that is stored in * the profile. */ - const TCHAR *name; + const char *name; /** * The human-readable name of this driver. */ - const TCHAR *display_name; + const char *display_name; /** * A bit set describing the features of this driver. diff --git a/src/Device/Driver/AR62xx.cpp b/src/Device/Driver/AR62xx.cpp new file mode 100644 index 00000000000..c12c9bf156d --- /dev/null +++ b/src/Device/Driver/AR62xx.cpp @@ -0,0 +1,638 @@ +/* +Copyright_License { + + XCSoar Glide Computer - http://www.xcsoar.org/ + Copyright (C) 2000-2023 The XCSoar Project + A detailed list of copyright holders can be found in the file "AUTHORS". + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +} +*/ + +/** + * The driver is derived from the KRT2-driver. + * This version has implemented two methods yet: + * setting the active frequency + * setting the passive frequency + * But it can be added: + * setting/reading the volume of the radio + * setting/reading dual scan on/off (listening on both channels) + * being noticed of frequency change on the radio itself + * setting/reading squelsh settings + * setting/reading vox settigns of the intercom + * + */ + +#include "Device/Driver/AR62xx.hpp" +#include "Device/Driver.hpp" +#include "Device/Port/Port.hpp" +#include "NMEA/Info.hpp" +#include "RadioFrequency.hpp" +#include "thread/Cond.hxx" +#include "thread/Mutex.hxx" +#include "util/CharUtil.hxx" +#include "util/StaticFifoBuffer.hxx" +#include "util/Compiler.h" +#include "LogFile.hpp" + +#include + +#include + +/* + * Some constants and expressions + * Becker AR62xx radios have a binary protocol + */ +constexpr uint8_t HEADER_ID = 0xA5; + +/* Some defines */ +#define PROTID 0x14; +#define MAX_CMD_LEN 128 +#define ACTIVE_STATION 1 +#define PASSIVE_STATION 0 + +union IntConvertStruct { + uint16_t int_val16; + uint8_t int_val8[2]; +}; + +struct Radio { + double active_frequency; + /* active station frequency, MHz(25KHz mode) or channel (8.33KHz mode) + MHz are represented as floating point and the channel too is shown + as floating point on the display + */ + double passive_frequency; + /* passive station frequency, MHz(25KHz mode) or channel (8.33KHz mode) + MHz are represented as floating point and the channel too is shown + as floating point on the display + */ +}; + +/** + * AR62xx device class. + * + * This class provides the interface to communicate with the AR62xx radio. + * The driver retransmits messages in case of a failure. + */ +class AR62xxDevice final : public AbstractDevice { + //!< Command timeout: + static constexpr auto CMD_TIMEOUT = std::chrono::milliseconds(250); + static constexpr unsigned NR_RETRIES = 3; //!< No. retries to send command + + static constexpr char STX = 0x02; /* Command start character */ + static constexpr char ACK = 0x06; /* Command acknowledged character */ + static constexpr char NAK = 0x15; /* Command not acknowledged character */ + static constexpr char NO_RSP = 0; /* No response received yet */ + + //! Struct containing active and passive frequency (from LK8000) + Radio radio_para; + //! Port the radio is connected to (from KRT2.cpp) + Port &port; + //! Expected message length just receiving (from KRT2.cpp) + // (at least currently) unused for AR62xx driver + // size_t expected_msg_length{}; + //! Buffer for messages from radio (from KRT2.cpp) + StaticFifoBuffer rx_buf; + //! Last response received from the radio (frome KRT2.cpp) + uint8_t response; + //! Condition to signal a response was received from radio (from KRT2.cpp) + Cond rx_cond; + //! Mutex to be locked to access response (from KRT2.cpp) + Mutex response_mutex; + +public: + /** + * Constructor of the radio device class. + * + * @param _port Port the radio is connected to. + */ + explicit AR62xxDevice(Port &_port); + +private: + IntConvertStruct crc; + IntConvertStruct s_frequency; + bool b_sending = false; + + /** + * Sends a message to the radio. + * + * @param msg Message to be send to the radio. + * Doing the real work. + */ + bool + Send(const uint8_t *msg, unsigned msg_size, OperationEnvironment &env); + + /* + * Creates the correct index for a given readable frequency + */ + int + Frq2Idx(double f_freq) noexcept; + + /* + * Creates a correct frequency-number given by the index + */ + double + Idx2Freq(uint16_t u_freq_idx); + + /* + * This function sets the station name and frequency on the AR62xx + */ + int + SetAR620xStation(uint8_t *command, int active_passive, + double f_frequency, const char* station) noexcept; + + /* + * Parses the messages which XCSoar receives from the radio. + */ + bool + AR620xParseString(const char *msg_string, size_t len); + + /* + * this function converts a AR62xx answer sting to a NMEA sequence + */ + int + AR620xConvertAnswer(uint8_t *sz_command, int len, uint16_t crc); + + /* + * Creates a correct frequency-number to show + */ + uint16_t + Freq2Idx(double a) noexcept; + + /* + * Not unsed in the Moment + * Used for function detection inside the binary string received + */ +/* + uint32_t + Bitshift(int n) noexcept; +*/ + /* + * Used for creating the binary string to send + */ + uint16_t + CRCBitwise(uint8_t *data, size_t len) noexcept; + +public: + /** + * Sets the active frequency on the radio. + */ + virtual bool PutActiveFrequency(RadioFrequency frequency, + const char *name, + OperationEnvironment &env) override; + + /** + * Sets the standby frequency on the radio. + */ + virtual bool PutStandbyFrequency(RadioFrequency frequency, + const char *name, + OperationEnvironment &env) override; + + /** + * Receives and handles data from the radio. + * + * The function parses messages send by the radio. + * Because all control characters (e.g. HEADER_ID, PROTOKOLL_ID, STX, ACK, + * NAK, ...) + * can be part of the payload of the messages, it is important + * to separate the messages to distinguish control characters + * from payload characters. + * + * If a response to a command is received, the function notifies + * the sender. This could trigger a retransmission in case of a + * failure. + */ + virtual bool DataReceived(std::span s, + struct NMEAInfo &info) noexcept override; +}; + +/* + * Constructor + * Port on which the radio is connected + */ +AR62xxDevice::AR62xxDevice(Port &_port) : port(_port) +{ + AR62xxDevice::response = ACK; +} + +/** + * Receives and handles data from the radio. + * + * The function parses messages send by the radio. + * Because all control characters (e.g. HEADER_ID, PROTOKOLL_ID, STX, ACK, + * NAK, ...) + * can be part of the payload of the messages, it is important + * to separate the messages to distinguish control characters + * from payload characters. + * + * If a response to a command is received, the function notifies + * the sender. This could trigger a retransmission in case of a + * failure. + * + * The initial frequency settings of the radio a delivered by this method + * and stored in the data struct "info" every time connection is established + */ +bool +AR62xxDevice::DataReceived(std::span s, + struct NMEAInfo &info) noexcept +{ + assert(!s.empty()); + + const auto *data = s.data(); + const auto *const end = data + s.size(); + size_t nbytes = std::min(s.size(), size_t(end - data)); + bool done_ok = AR620xParseString((const char *)data, nbytes); + info.alive.Update(info.clock); + return done_ok; + +} + +/** + * Writes the message to the serial port on which the radio is connected + */ +bool +AR62xxDevice::Send(const uint8_t *msg, + [[maybe_unused]] unsigned msg_size, + OperationEnvironment &env) +{ + //! Number of tries to send a message i.e. 3 retries, taken from KRT2-driver + unsigned retries = NR_RETRIES; + + assert(msg_size > 0); + + do { + { + const std::lock_guard lock(response_mutex); + response = NO_RSP; + } + b_sending = true; + + /* Send the message */ + port.FullWrite(reinterpret_cast (msg), env, CMD_TIMEOUT); + // TODO(August2111): const char* or better with std::span... + response = ACK; + + /* Wait for the response */ + uint8_t _response; + { + std::unique_lock lock(response_mutex); + rx_cond.wait_for(lock, std::chrono::milliseconds(CMD_TIMEOUT)); + _response = response; + } + b_sending = false; + if (_response == ACK) { + /* ACK received, finish, all went well */ + return true; + } + + /* No ACK received, retry, possibly an error occured */ + retries--; + } while (retries); + + return false; +} + +/* + * Not used in the moment + * Helper for Bit shifting, AR62xx have a binary protocol + */ +/* +inline uint32_t +AR62xxDevice::Bitshift(int n) noexcept +{ + return (1 << (n)); +} +*/ +/* + * Creates the correct index for a given readable frequency + * Because the return value can be a channel number or a frequency in MHZ, + * depending on use in 25Khz or 8.33Khz mode, + * the developer in LK8000 might have used "index" for that value + */ +inline int +AR62xxDevice::Frq2Idx(double f_freq) noexcept +{ + return (int)(((f_freq)-118.0) * 3040/(137.00-118.0)+0.5); +} + +/* + * Creates a correct frequency-number to show + * Because the return value can be a channel number or a frequency in MHZ, + * depending on use in 25Khz or 8.33Khz mode, + * the developer in LK8000 might have used "index" for that value + */ +double +AR62xxDevice::Idx2Freq(uint16_t u_freq_idx) +{ + double f_freq= 118.000 + (u_freq_idx & 0xFFF0) * (137.000-118.000)/3040.0; + switch(u_freq_idx & 0xF){ + case 0: f_freq += 0.000; break; + case 1: f_freq += 0.005; break; + case 2: f_freq += 0.010; break; + case 3: f_freq += 0.015; break; + case 4: f_freq += 0.025; break; + case 5: f_freq += 0.030; break; + case 6: f_freq += 0.035; break; + case 7: f_freq += 0.040; break; + case 8: f_freq += 0.050; break; + case 9: f_freq += 0.055; break; + case 10: f_freq += 0.060; break; + case 11: f_freq += 0.065; break; + case 12: f_freq += 0.075; break; + case 13: f_freq += 0.080; break; + case 14: f_freq += 0.085; break; + case 15: f_freq += 0.090; break; + } + return (f_freq); +} + +/* + * Creates the correct index for a given readable frequency or channel + * Because the return value can be a channel number or a frequency in MHZ, + * depending on use in 25Khz or 8.33Khz mode, + * the developer in LK8000 might have used "index" for that value + */ +uint16_t +AR62xxDevice::Freq2Idx(double f_freq) noexcept +{ + uint16_t u_fre_idx= Frq2Idx(f_freq); + u_fre_idx &= 0xFFF0; + uint8_t uiFrac = ((int)(f_freq*1000.0+0.5)) - (((int)(f_freq *10.0))*100); + + switch(uiFrac) { + case 0: u_fre_idx += 0; break; + case 5: u_fre_idx += 1; break; + case 10: u_fre_idx += 2; break; + case 15: u_fre_idx += 3; break; + case 25: u_fre_idx += 4; break; + case 30: u_fre_idx += 5; break; + case 35: u_fre_idx += 6; break; + case 40: u_fre_idx += 7; break; + case 50: u_fre_idx += 8; break; + case 55: u_fre_idx += 9; break; + case 60: u_fre_idx += 10; break; + case 65: u_fre_idx += 11; break; + case 75: u_fre_idx += 12; break; + case 80: u_fre_idx += 13; break; + case 85: u_fre_idx += 14; break; + case 90: u_fre_idx += 15; break; + case 100: u_fre_idx += 0; break; + default: break; + } + return (u_fre_idx); +} + +/* + * Creates the binary value for the message for the radio + */ +uint16_t +AR62xxDevice::CRCBitwise(uint8_t *data, + size_t len) noexcept +{ + uint16_t crc = 0x0000; + size_t j; + int i; + for (j=len; j>0; j--) { + crc ^= (uint16_t)(*data++) << 8; + for (i=0; i<8; i++) { + if (crc & 0x8000) crc = (crc<<1) ^ 0x8005; + else crc <<= 1; + } + } + return (crc); +} + +/** + * This function sets the station name and frequency on the AR62xx + * + * active_passive Active or passive station switch + * f_frequency station frequency + * station station name string + * + * The AR62xx always sends and receives both frequencies/channels. + * The one which remains unchanged is controlled by the "active_passive"-flag + * + * station is not used in the moment, AR62xx does not read it yet + */ +int +AR62xxDevice::SetAR620xStation(uint8_t *command, + int active_passive, + double f_frequency, + [[maybe_unused]] const char *station) noexcept +{ + unsigned int len = 0; + + assert(station !=NULL); + assert(command !=NULL); + + if(command == NULL ) { + return false; + } + + /* converting both actual frequencies active and passive */ + IntConvertStruct active_freq_idx; + active_freq_idx.int_val16 = Freq2Idx(radio_para.active_frequency); + IntConvertStruct passive_freq_idx; + passive_freq_idx.int_val16 = Freq2Idx(radio_para.passive_frequency); + command [len++] = HEADER_ID ; + command [len++] = PROTID ; + command [len++] = 5; + + /* converting the frequency to be changed */ + switch (active_passive) { + case ACTIVE_STATION: + active_freq_idx.int_val16 = Freq2Idx(f_frequency); + break; + default: + case PASSIVE_STATION: + passive_freq_idx.int_val16 = Freq2Idx(f_frequency); + break; + } + + command [len++] = 22; /* setting frequencies-command byte in the protocol */ + command [len++] = active_freq_idx.int_val8[1]; + command [len++] = active_freq_idx.int_val8[0]; + command [len++] = passive_freq_idx.int_val8[1]; + command [len++] = passive_freq_idx.int_val8[0]; + crc.int_val16 = CRCBitwise(command, len); /* Creating the binary value */ + command [len++] = crc.int_val8[1]; + command [len++] = crc.int_val8[0]; + return len; +} + +/* + * Parses the messages which XCSoar receives from the radio. + */ +bool +AR62xxDevice::AR620xParseString(const char *msg_string, + size_t len) +{ + size_t cnt = 0; + uint16_t cal_crc = 0; + static uint16_t rec_buf_len = 0; + int command_length = 0; + #define REC_BUFSIZE 127 + static uint8_t command[REC_BUFSIZE]; + + if(msg_string == NULL) return 0; + if(len == 0) return 0; + + while (cnt < len) { + if((uint8_t)msg_string[cnt] == HEADER_ID) rec_buf_len =0; + if(rec_buf_len >= REC_BUFSIZE) rec_buf_len =0; + assert(rec_buf_len < REC_BUFSIZE); + + command[rec_buf_len++] = (uint8_t) msg_string[cnt++]; + if(rec_buf_len == 2){ + if(!(command[rec_buf_len-1] == 0x14)){ + rec_buf_len = 0; + } + } + + if(rec_buf_len >= 3){ + command_length = command[2]; + if(rec_buf_len >= (command_length+5) ) {// all received + crc.int_val8[1] = command[command_length+3]; + crc.int_val8[0] = command[command_length+4]; + cal_crc =CRCBitwise(command, command_length+3); + if(cal_crc == crc.int_val16 || crc.int_val16 == 0) { + if(!b_sending) { + AR620xConvertAnswer(command, command_length+5, cal_crc); + } + } + rec_buf_len = 0; + } + } + } + return true; +} + +/* + * This function converts a AR62xx answer string to a readable number + * + * sz_command AR620x binary code to be converted, representing the state + * of a function (act. freq., pass. freq.) + * len length of the AR620x binary code to be converted + */ +int +AR62xxDevice::AR620xConvertAnswer(uint8_t *sz_command, + int len, + uint16_t crc) +{ + + if(sz_command == NULL) return 0; + if(len == 0) return 0; + + static uint16_t ui_last_channel_crc = 0; + static uint16_t ui_version_crc = 0; + +#ifdef RADIO_VOLTAGE + static uint16_t ui_voltage_crc = 0; +#endif + + assert(sz_command !=NULL); + + switch ((unsigned char)(sz_command[3] & 0x7F)){ + case 0: + if(ui_version_crc!= crc) { + ui_version_crc = crc; + } + break; +#ifdef RADIO_VOLTAGE + case 21: /* actual voltage of the radio */ + if(ui_voltage_crc != crc) { + ui_voltage_crc = crc; + GPS_INFO.ExtBatt2_Voltage = 8.5 + sz_command[4] * 0.1; + } + break; +#endif + case 22: /* Frequency/channel settings, always for active and passive */ + if(ui_last_channel_crc != crc) { + ui_last_channel_crc = crc; + s_frequency.int_val8[1] = sz_command[4] ; + s_frequency.int_val8[0] = sz_command[5] ; + radio_para.active_frequency = Idx2Freq(s_frequency.int_val16); + + s_frequency.int_val8[1] = sz_command[6]; + s_frequency.int_val8[0] = sz_command[7] ; + radio_para.passive_frequency = Idx2Freq(s_frequency.int_val16); + } + break; + default: + break; + } + return 0; /* return the number of converted characters */ +} + +/** + * Sets the active frequency on the radio. + * same as in KRT2.cpp + */ +bool +AR62xxDevice::PutActiveFrequency(RadioFrequency frequency, + const char* name, + OperationEnvironment &env) +{ + unsigned int ufreq = frequency.GetKiloHertz(); + double freq = ufreq / 1000.0; + int len; + uint8_t sz_tmp[MAX_CMD_LEN] = {}; + len = SetAR620xStation(sz_tmp ,ACTIVE_STATION, freq, name); + /* len seems to be the same as sizeof(szTmp)*/ + bool is_sent = Send((uint8_t *) &sz_tmp, len, env); + return is_sent; +} + +/** + * Sets the standby (passive) frequency on the radio. + * same as in KRT2.cpp + */ +bool +AR62xxDevice::PutStandbyFrequency(RadioFrequency frequency, + const char *name, + OperationEnvironment &env) +{ + unsigned int ufreq = frequency.GetKiloHertz(); + double freq = ufreq / 1000.0; + int len; + uint8_t sz_tmp[MAX_CMD_LEN] = {}; + len = SetAR620xStation(sz_tmp ,PASSIVE_STATION, freq, name); + bool is_sent = Send((uint8_t *) &sz_tmp, len, env); + return is_sent; +} + +/* + * Assign the selected port on Object construction + * same as in KRT2.cpp + */ +static Device * +AR62xxCreateOnPort([[maybe_unused]] const DeviceConfig &config, + Port &comPort) +{ + Device *dev = new AR62xxDevice(comPort); + return dev; +} + +/* + * Driver registration in XCSoar, connect to a serial port + * same as in KRT2.cpp + */ +const struct DeviceRegister ar62xx_driver = { + "AR62xx", + "Becker AR62xx", + DeviceRegister::NO_TIMEOUT | DeviceRegister::RAW_GPS_DATA, + AR62xxCreateOnPort, +}; diff --git a/src/Device/Driver/AR62xx.hpp b/src/Device/Driver/AR62xx.hpp new file mode 100644 index 00000000000..1e5540e7709 --- /dev/null +++ b/src/Device/Driver/AR62xx.hpp @@ -0,0 +1,26 @@ +/* +Copyright_License { + + XCSoar Glide Computer - http://www.xcsoar.org/ + Copyright (C) 2000-2023 The XCSoar Project + A detailed list of copyright holders can be found in the file "AUTHORS". + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +} +*/ + +#pragma once + +extern const struct DeviceRegister ar62xx_driver; diff --git a/src/Device/Driver/ATR833/Device.cpp b/src/Device/Driver/ATR833/Device.cpp index ca2194569cc..eb0aa24fad0 100644 --- a/src/Device/Driver/ATR833/Device.cpp +++ b/src/Device/Driver/ATR833/Device.cpp @@ -140,7 +140,7 @@ ATR833Device::HandleMessage(std::span src, bool ATR833Device::PutActiveFrequency(RadioFrequency frequency, - [[maybe_unused]] const TCHAR *name, + [[maybe_unused]] const char *name, OperationEnvironment &env) { ATRBuffer buffer(SETACTIVE); @@ -151,7 +151,7 @@ ATR833Device::PutActiveFrequency(RadioFrequency frequency, bool ATR833Device::PutStandbyFrequency(RadioFrequency frequency, - [[maybe_unused]] const TCHAR *name, + [[maybe_unused]] const char *name, OperationEnvironment &env) { ATRBuffer buffer(SETSTANDBY); diff --git a/src/Device/Driver/ATR833/Device.hpp b/src/Device/Driver/ATR833/Device.hpp index 87d2123409b..c8116315df5 100644 --- a/src/Device/Driver/ATR833/Device.hpp +++ b/src/Device/Driver/ATR833/Device.hpp @@ -22,10 +22,10 @@ class ATR833Device final : public AbstractDevice { bool DataReceived(std::span s, NMEAInfo &info) noexcept override; bool PutActiveFrequency(RadioFrequency frequency, - const TCHAR *name, + const char *name, OperationEnvironment &env) override; bool PutStandbyFrequency(RadioFrequency frequency, - const TCHAR *name, + const char *name, OperationEnvironment &env) override; bool EnableNMEA(OperationEnvironment &env) override; void OnSysTicker() override; diff --git a/src/Device/Driver/ATR833/Register.cpp b/src/Device/Driver/ATR833/Register.cpp index 86b29421704..b156a004ff0 100644 --- a/src/Device/Driver/ATR833/Register.cpp +++ b/src/Device/Driver/ATR833/Register.cpp @@ -11,8 +11,8 @@ ATR833CreateOnPort([[maybe_unused]] const DeviceConfig &config, Port &com_port) } const DeviceRegister atr833_driver = { - _T("ATR833"), - _T("ATR833"), + "ATR833", + "ATR833", DeviceRegister::RAW_GPS_DATA, ATR833CreateOnPort, }; diff --git a/src/Device/Driver/AirControlDisplay.cpp b/src/Device/Driver/AirControlDisplay.cpp index 7ea3df3c3f4..f7666c51005 100644 --- a/src/Device/Driver/AirControlDisplay.cpp +++ b/src/Device/Driver/AirControlDisplay.cpp @@ -91,7 +91,7 @@ ParsePAAVS(NMEAInputLine &line, NMEAInfo &info) unsigned code_value; if (line.ReadChecked(code_value)) { StaticString<16> buffer; - buffer.Format(_T("%04u"), code_value); + buffer.Format("%04u", code_value); TransponderCode parsed_code = TransponderCode::Parse(buffer); if (!parsed_code.IsDefined()) @@ -120,10 +120,11 @@ class ACDDevice : public AbstractDevice { OperationEnvironment &env) override; bool PutVolume(unsigned volume, OperationEnvironment &env) override; bool PutStandbyFrequency(RadioFrequency frequency, - const TCHAR *name, + const char *name, OperationEnvironment &env) override; bool PutTransponderCode(TransponderCode code, OperationEnvironment &env) override; void OnSensorUpdate(const MoreData &basic) override; + void OnCalculatedUpdate(const MoreData &basic, const DerivedInfo &calculated) override; }; bool @@ -147,7 +148,7 @@ ACDDevice::PutVolume(unsigned volume, OperationEnvironment &env) bool ACDDevice::PutStandbyFrequency(RadioFrequency frequency, - [[maybe_unused]] const TCHAR *name, + [[maybe_unused]] const char *name, OperationEnvironment &env) { char buffer[100]; @@ -201,6 +202,19 @@ ACDDevice::OnSensorUpdate(const MoreData &basic) } } +void +ACDDevice::OnCalculatedUpdate(const MoreData &basic,[[maybe_unused]] const DerivedInfo &calculated) +{ + NullOperationEnvironment env; + + if (basic.settings.qnh_available.IsValid()){ + char buffer[100]; + unsigned qnh = basic.settings.qnh.GetPascal(); + sprintf(buffer,"PAAVC,S,ALT,QNH,%u",qnh); + PortWriteNMEA(port, buffer, env); + } +} + static Device * AirControlDisplayCreateOnPort([[maybe_unused]] const DeviceConfig &config, Port &com_port) { @@ -208,8 +222,8 @@ AirControlDisplayCreateOnPort([[maybe_unused]] const DeviceConfig &config, Port } const struct DeviceRegister acd_driver = { - _T("ACD"), - _T("Air Control Display"), + "ACD", + "Air Control Display", DeviceRegister::RECEIVE_SETTINGS | DeviceRegister::SEND_SETTINGS, AirControlDisplayCreateOnPort, }; diff --git a/src/Device/Driver/AltairPro.cpp b/src/Device/Driver/AltairPro.cpp index b3b051cc137..514179b9a1e 100644 --- a/src/Device/Driver/AltairPro.cpp +++ b/src/Device/Driver/AltairPro.cpp @@ -11,7 +11,6 @@ #include "NMEA/InputLine.hpp" #include "Units/System.hpp" #include "Waypoint/Waypoint.hpp" -#include "util/ConvertString.hpp" #include "util/TruncateString.hpp" #include "util/Macros.hpp" #include "time/TimeoutClock.hpp" @@ -35,11 +34,6 @@ class AltairProDevice : public AbstractDevice { bool PropertySetGet(const char *name, const char *value, std::span dest, OperationEnvironment &env); -#ifdef _UNICODE - bool PropertySetGet(const char *name, const TCHAR *value, - std::span dest, - OperationEnvironment &env); -#endif public: AltairProDevice(Port &_port):port(_port){} @@ -61,7 +55,7 @@ ReadAltitude(NMEAInputLine &line, double &value_r) if (!available) return false; - if (unit == _T('f') || unit == _T('F')) + if (unit == 'f' || unit == 'F') value = Units::ToSysUnit(value, Unit::FEET); value_r = value; @@ -224,20 +218,6 @@ AltairProDevice::PropertySetGet(const char *name, const char *value, return false; } -#ifdef _UNICODE -bool -AltairProDevice::PropertySetGet(const char *name, const TCHAR *_value, - std::span dest, - OperationEnvironment &env) -{ - const WideToACPConverter value{_value}; - if (!value.IsValid()) - throw std::runtime_error("Invalid string"); - - return PropertySetGet(name, value, dest, env); -} -#endif - void AltairProDevice::PutTurnPoint(const char *propertyName, const Waypoint *waypoint, @@ -251,8 +231,8 @@ AltairProDevice::PutTurnPoint(const char *propertyName, char NoS, EoW; if (waypoint != nullptr){ - if (WideToACPConverter wp_name{waypoint->name.c_str()}; wp_name.IsValid()) - CopyTruncateString(Name, ARRAY_SIZE(Name), wp_name); + if (waypoint->name.c_str()) + CopyTruncateString(Name, ARRAY_SIZE(Name), waypoint->name.c_str()); else throw std::runtime_error("Invalid string"); @@ -306,8 +286,8 @@ AltairProCreateOnPort([[maybe_unused]] const DeviceConfig &config, Port &com_por } const struct DeviceRegister altair_pro_driver = { - _T("Altair RU"), - _T("Altair Recording Unit"), + "Altair RU", + "Altair Recording Unit", DeviceRegister::DECLARE, AltairProCreateOnPort, }; diff --git a/src/Device/Driver/Anemoi.cpp b/src/Device/Driver/Anemoi.cpp new file mode 100644 index 00000000000..055a46ccf7a --- /dev/null +++ b/src/Device/Driver/Anemoi.cpp @@ -0,0 +1,486 @@ +/* +Copyright_License { + + XCSoar Glide Computer - http://www.xcsoar.org/ + Copyright (C) 2000-2022 The XCSoar Project + A detailed list of copyright holders can be found in the file "AUTHORS". + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +} +*/ + +/** +* see Documentation https:// +*/ + +#include "Device/Driver/Anemoi.hpp" +#include "Device/Driver.hpp" +#include "Device/Port/Port.hpp" +#include "NMEA/Info.hpp" +#include "RadioFrequency.hpp" +#include "thread/Cond.hxx" +#include "thread/Mutex.hxx" +#include "util/CharUtil.hxx" +#include "util/StaticFifoBuffer.hxx" +#include "util/Compiler.h" +// #include "NMEA/Checksum.hpp" // aug: or whereis it? +#include "Units/System.hpp" + +#include +#include + +using std::string_view_literals::operator""sv; + +/** + * Device driver for Anemoi Wind. + * @see http://www..pdf + */ + +#define WITH_PORT 0 +class AnemoiDevice final : public AbstractDevice { + // unused up to now: Port &port; + + static constexpr std::byte StartByte{'$'}; //!< Command start character. + + //! Expected length of the message just receiving. + // size_t expected_msg_length{}; + size_t expected_msg_length{}; + //! Buffer which receives the messages send from the radio. + StaticFifoBuffer rx_buf; + + //! Mutex to be locked to access response. + Mutex response_mutex; + +private: + /** + * Calculates the length of the message just receiving. + * + * @param data Pointer to the first character of the message. + * @param length Number of characters received. + * @return Expected message length. + */ + static size_t ExpectedMsgLength(const std::byte *data, size_t length); + /** + * Calculates the length of the command message just receiving. + * + * @param code Command code received after the '$' character. + * @return Expected message length after the code character. + */ + static size_t ExpectedMsgLengthSentence(std::byte code); + + /** + * Handle the anemoi sentence. + * + */ + static bool HandleSentence(const std::byte *data, unsigned msg_size, + struct NMEAInfo & info); + + static int16_t ReadInteger16(const std::byte **data); + static int8_t ReadByte(const std::byte **data); + + static bool ParseAttitude(const std::byte *data, struct NMEAInfo &info); + static bool ParseWind(const std::byte *data, struct NMEAInfo &info); + static bool ParseData(const std::byte *data, struct NMEAInfo &info); + + bool active; + ~AnemoiDevice() { active = false; } + +public: + AnemoiDevice([[maybe_unused]] Port &_port) : active(true) {} + // port is unused: AnemoiDevice(Port &_port) : port(_port) {} + + /* virtual methods from class Device */ + virtual bool DataReceived(std::span s, + struct NMEAInfo &info) noexcept override; +}; + +bool +AnemoiDevice::DataReceived(std::span s, + struct NMEAInfo &info) noexcept +{ + assert(!s.empty()); + if (!active) + return false; + const auto *data = s.data(); + const auto *const end = data + s.size(); + do { + // Append new data to the buffer, as much as fits in there + auto range = rx_buf.Write(); + if (rx_buf.IsFull()) { + // Overflow: reset buffer to recover quickly + rx_buf.Clear(); + expected_msg_length = 0; + continue; + } + size_t nbytes = size_t(end - data); + if (nbytes > range.size()) + return true; // do nothing, avoid buffer overflow + // size_t nbytes = std::min(range.size(), size_t(end - data)); + std::copy_n(data, nbytes, range.begin()); + data += nbytes; + rx_buf.Append(nbytes); + + for (;;) { + // Read data from buffer to handle the messages + if (!active) + return false; + range = rx_buf.Read(); + if (range.empty()) + break; + + if (range.size() < expected_msg_length) + break; + + expected_msg_length = ExpectedMsgLength(range.data(), range.size()); + if (!active) + return false; + if (range.size() >= expected_msg_length) { + switch (*(const std::byte *)range.data()) { + case StartByte: // Startbyte + { + const std::lock_guard lock{response_mutex}; + HandleSentence(range.data(), expected_msg_length, info); + } + break; + default: + break; + } + // Message handled -> remove message + rx_buf.Consume(expected_msg_length); + expected_msg_length = 0; + // Received something from the radio -> the connection is alive + info.alive.Update(info.clock); + } + } + + } while (data < end); + return true; +} + +/** + The expected length of a received message may change, + when the first character is STX and the second character + is not received yet. +*/ +size_t +AnemoiDevice::ExpectedMsgLength(const std::byte *data, + size_t length) +{ + size_t expected_length; + + assert(data != nullptr); + assert(length > 0); + + if (data[0] == StartByte) { + if (length > 1) { + expected_length = ExpectedMsgLengthSentence(data[1]); + if (expected_length > 0) + expected_length += 4; + } else { + // minimum 2 chars + expected_length = 4; + } + } else + expected_length = 1; + + return expected_length; +} + +size_t +AnemoiDevice::ExpectedMsgLengthSentence(std::byte code) +{ + size_t expected_length; + + switch ((char)code) { + case 'S': + // Sensor health sentence + expected_length = 2; + break; + case 'w': + case 'W': + // Wind sentence + expected_length = 8; + break; + case 'a': + case 'A': + // + expected_length = 7; + break; + case 'd': + case 'D': + // + expected_length = 12; + break; + case 'M': + // + expected_length = 4; + break; + default: + // Received unknown code + expected_length = 0; + break; + } + + return expected_length; +} + +/* + * crc8.c + * + * + * + */ +static const uint8_t CRC_TABLE[256] = { + 0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15, 0x38, 0x3F, 0x36, 0x31, + 0x24, 0x23, 0x2A, 0x2D, 0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65, + 0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D, 0xE0, 0xE7, 0xEE, 0xE9, + 0xFC, 0xFB, 0xF2, 0xF5, 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD, + 0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85, 0xA8, 0xAF, 0xA6, 0xA1, + 0xB4, 0xB3, 0xBA, 0xBD, 0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2, + 0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA, 0xB7, 0xB0, 0xB9, 0xBE, + 0xAB, 0xAC, 0xA5, 0xA2, 0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A, + 0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32, 0x1F, 0x18, 0x11, 0x16, + 0x03, 0x04, 0x0D, 0x0A, 0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42, + 0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A, 0x89, 0x8E, 0x87, 0x80, + 0x95, 0x92, 0x9B, 0x9C, 0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4, + 0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC, 0xC1, 0xC6, 0xCF, 0xC8, + 0xDD, 0xDA, 0xD3, 0xD4, 0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C, + 0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44, 0x19, 0x1E, 0x17, 0x10, + 0x05, 0x02, 0x0B, 0x0C, 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34, + 0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B, 0x76, 0x71, 0x78, 0x7F, + 0x6A, 0x6D, 0x64, 0x63, 0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B, + 0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13, 0xAE, 0xA9, 0xA0, 0xA7, + 0xB2, 0xB5, 0xBC, 0xBB, 0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83, + 0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB, 0xE6, 0xE1, 0xE8, 0xEF, + 0xFA, 0xFD, 0xF4, 0xF3}; + +static uint8_t crc8ccitt(const void *data, size_t size) { + + uint8_t val = 0; + uint8_t *pos = reinterpret_cast(const_cast(data)); + uint8_t *end = pos + size; + while (pos < end) { + val = CRC_TABLE[val ^ *pos]; + pos++; + } + return val; +} + +int16_t +AnemoiDevice::ReadInteger16(const std::byte **data) +{ + // read 2 bytes + uint16_t value = + *reinterpret_cast(const_cast((*data)++)); + value <<= 8; + value |= + *reinterpret_cast(const_cast((*data)++)); + + return (int16_t)value; +} + +int8_t +AnemoiDevice::ReadByte(const std::byte **data) +{ + // read 1 byte + return + *reinterpret_cast(const_cast((*data)++)); +} + +bool +AnemoiDevice::ParseAttitude(const std::byte *data, struct NMEAInfo & info) +{ +// Attitude sentence + auto value = ReadInteger16(&data); + // Roll respect to Earth system - Phi [°] (i.e. +110) + if (value >= -180 && value <= +180) { + info.attitude.bank_angle_available.Update(info.clock); + info.attitude.bank_angle = Angle::Degrees(value); + } + value = ReadByte(&data); + // Pitch angle respect to Earth system - Theta [°] (i.e.+020) + if (value >= -90 && value <= +90) { + info.attitude.pitch_angle_available.Update(info.clock); + info.attitude.pitch_angle = Angle::Degrees(value); + } + value = ReadInteger16(&data); + // (True?) Heading + if (value >= 0 && value <= 360) { + info.attitude.heading = Angle::Degrees(value); + info.attitude.heading_available.Update(info.clock); + } + + value = ReadInteger16(&data); + // Circle diameter - no vbariable in XCSoar up to now + if (value >= 0 && value <= 1000) { +// info.attitude.heading = Angle::Degrees(value); +// info.attitude.heading_available.Update(info.clock); + } + + return true; +} + +bool +AnemoiDevice::ParseWind(const std::byte *data, struct NMEAInfo & info) +{ +// Wind sentence + // Live wind: + bool data_valid = true; + auto winddir = ReadInteger16(&data); + if (winddir < 0 || winddir > +360) { + data_valid = false; + } + uint8_t windspeed = ReadByte(&data); +// if (windspeed < 0 || windspeed > 200) { + if (windspeed > 200) { + data_valid = false; + } + if (data_valid) { + info.ProvideExternalWind( + SpeedVector(Angle::Degrees(winddir), + Units::ToSysUnit(windspeed, Unit::KILOMETER_PER_HOUR))); + // TODO(August2111): this is really a workaround: + // for the update thread is needed... + info.location_available.Update(info.clock); + } + + // Average wind: + data_valid = true; + winddir = ReadInteger16(&data); + if (winddir < 0 || winddir > +360) { + data_valid = false; + } + windspeed = ReadByte(&data); + // if (windspeed < 0 || windspeed > 200) { + if (windspeed > 200) { + data_valid = false; + } + if (data_valid) info.ProvideExternalInstantaneousWind( + SpeedVector(Angle::Degrees(winddir), + Units::ToSysUnit(windspeed, Unit::KILOMETER_PER_HOUR))); + + // Heading + auto heading = ReadInteger16(&data); + if (heading >= 0 && heading <= +360) { + info.attitude.heading = Angle::Degrees(heading); + info.attitude.heading_available.Update(info.clock); + } + + return true; // No other parser necessary +} + +bool +AnemoiDevice::ParseData(const std::byte *data, struct NMEAInfo & info) +{ +// Data sentence + // vGND (km/h): + auto value = ReadInteger16(&data); + if (value >= 0 && value < 500) { + info.ground_speed = Units::ToSysUnit(value, Unit::KILOMETER_PER_HOUR); + info.ground_speed_available.Update(info.clock); + } + + // vTAS (km/h): + value = ReadInteger16(&data); + if (value >= 0 && value < 500) { + info.true_airspeed = Units::ToSysUnit(value, Unit::KILOMETER_PER_HOUR); + info.airspeed_available.Update(info.clock); + info.airspeed_real = true; + } + + // track (deg): + value = ReadInteger16(&data); + if (value >= 0 && value < 500) { + info.track = Angle::Degrees(value); + info.track_available.Update(info.clock); + } + + // heading (deg): + value = ReadInteger16(&data); + if (value >= 0 && value <= +360) { + info.attitude.heading = Angle::Degrees(value); + info.attitude.heading_available.Update(info.clock); + } + + // Temperature (°C): + value = ReadByte(&data); + if (value >= -50 && value <= +100) { + info.temperature.FromCelsius(value); + info.temperature_available = true; + } + + // Pitot calibration (%): + value = ReadByte(&data); + if (value >= 0 && value <= 100) { + // info.attitude.heading = Angle::Degrees(value); + // info.attitude.heading_available.Update(info.clock); + } + + // FL: + value = ReadInteger16(&data); + if (value >= 0 && value <= 300) { + info.baro_altitude = Units::ToSysUnit(value, Unit::FLIGHT_LEVEL); + info.baro_altitude_available.Update(info.clock); + // info.attitude.heading = Angle::Degrees(value); + // info.attitude.heading_available.Update(info.clock); + } + + return true; // No other parser necessary +} + +bool +AnemoiDevice::HandleSentence(const std::byte *data, unsigned msg_size, + struct NMEAInfo & info) +{ + if (crc8ccitt((const void *)data, msg_size)) { + printf("ERROR\n"); + return false; +} + if (*data++ != StartByte) + return false; + + switch (*data++) { + // Attitude sentence + case std::byte('a'): + case std::byte('A'): + return ParseAttitude(data, info); + // Wind sentence: + case std::byte('w'): + case std::byte('W'): + return ParseWind(data, info); + // Data sentence: + case std::byte('d'): + case std::byte('D'): + return ParseData(data, info); + default: + return false; + //break; + } +} + + +static Device * +AnemoiCreateOnPort([[maybe_unused]] const DeviceConfig &config, Port &com_port) +{ + return new AnemoiDevice(com_port); +} + +const struct DeviceRegister anemoi_driver = { + "Anemoi", + "Anemoi", +// DeviceRegister::RECEIVE_SETTINGS | DeviceRegister::SEND_SETTINGS, + DeviceRegister::NO_TIMEOUT | DeviceRegister::RAW_GPS_DATA, + AnemoiCreateOnPort, +}; diff --git a/src/Device/Driver/Anemoi.hpp b/src/Device/Driver/Anemoi.hpp new file mode 100644 index 00000000000..cbd2cec4d11 --- /dev/null +++ b/src/Device/Driver/Anemoi.hpp @@ -0,0 +1,26 @@ +/* +Copyright_License { + + XCSoar Glide Computer - http://www.xcsoar.org/ + Copyright (C) 2000-2022 The XCSoar Project + A detailed list of copyright holders can be found in the file "AUTHORS". + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +} +*/ + +#pragma once + +extern const struct DeviceRegister anemoi_driver; diff --git a/src/Device/Driver/BlueFly/Register.cpp b/src/Device/Driver/BlueFly/Register.cpp index 33ea49a12d9..b576a3b1f32 100644 --- a/src/Device/Driver/BlueFly/Register.cpp +++ b/src/Device/Driver/BlueFly/Register.cpp @@ -11,8 +11,8 @@ BlueFlyCreateOnPort([[maybe_unused]] const DeviceConfig &config, Port &com_port) } const struct DeviceRegister bluefly_driver = { - _T("BlueFly"), - _T("BlueFly Vario"), + "BlueFly", + "BlueFly Vario", DeviceRegister::MANAGE, BlueFlyCreateOnPort, }; diff --git a/src/Device/Driver/BorgeltB50.cpp b/src/Device/Driver/BorgeltB50.cpp index eaaefcb4d89..1033c61ec7b 100644 --- a/src/Device/Driver/BorgeltB50.cpp +++ b/src/Device/Driver/BorgeltB50.cpp @@ -152,8 +152,8 @@ B50CreateOnPort([[maybe_unused]] const DeviceConfig &config, Port &com_port) } const struct DeviceRegister b50_driver = { - _T("Borgelt B50"), - _T("Borgelt B50/B800"), + "Borgelt B50", + "Borgelt B50/B800", DeviceRegister::RECEIVE_SETTINGS | DeviceRegister::SEND_SETTINGS, B50CreateOnPort, }; diff --git a/src/Device/Driver/CAI302/Declare.cpp b/src/Device/Driver/CAI302/Declare.cpp index a5383325dea..fe6fcf26188 100644 --- a/src/Device/Driver/CAI302/Declare.cpp +++ b/src/Device/Driver/CAI302/Declare.cpp @@ -9,27 +9,11 @@ #include #include -#ifdef _UNICODE -#include -#endif - static void -convert_string(char *dest, size_t size, const TCHAR *src) +convert_string(char *dest, size_t size, const char *src) { -#ifdef _UNICODE - size_t length = _tcslen(src); - if (length >= size) - length = size - 1; - - int length2 = ::WideCharToMultiByte(CP_ACP, 0, src, length, dest, size, - nullptr, nullptr); - if (length2 < 0) - length2 = 0; - dest[length2] = '\0'; -#else strncpy(dest, src, size - 1); dest[size - 1] = '\0'; -#endif } static void diff --git a/src/Device/Driver/CAI302/Manage.cpp b/src/Device/Driver/CAI302/Manage.cpp index 71c7c23ecd9..b9cf1112d9e 100644 --- a/src/Device/Driver/CAI302/Manage.cpp +++ b/src/Device/Driver/CAI302/Manage.cpp @@ -202,10 +202,10 @@ CAI302Device::ReadNavpoint(unsigned index, CAI302::Navpoint &navpoint, } static void -ToASCII(char *dest, size_t dest_size, const TCHAR *src) +ToASCII(char *dest, size_t dest_size, const char *src) { char *end = dest + dest_size - 1; - while (*src != _T('\0') && dest < end) + while (*src != '\0' && dest < end) if (IsPrintableASCII(*src)) *dest++ = (char)*src++; diff --git a/src/Device/Driver/CAI302/Register.cpp b/src/Device/Driver/CAI302/Register.cpp index 74ae351fa4f..f5c7dcca274 100644 --- a/src/Device/Driver/CAI302/Register.cpp +++ b/src/Device/Driver/CAI302/Register.cpp @@ -11,8 +11,8 @@ CAI302CreateOnPort(const DeviceConfig &config, Port &port) } const struct DeviceRegister cai302_driver = { - _T("CAI 302"), - _T("Cambridge CAI302"), + "CAI 302", + "Cambridge CAI302", DeviceRegister::BULK_BAUD_RATE | DeviceRegister::DECLARE | DeviceRegister::LOGGER | DeviceRegister::MANAGE | DeviceRegister::RECEIVE_SETTINGS | DeviceRegister::SEND_SETTINGS, diff --git a/src/Device/Driver/CProbe.cpp b/src/Device/Driver/CProbe.cpp index cd418fb49f8..1c14d288d57 100644 --- a/src/Device/Driver/CProbe.cpp +++ b/src/Device/Driver/CProbe.cpp @@ -124,8 +124,8 @@ CProbeCreateOnPort([[maybe_unused]] const DeviceConfig &config, [[maybe_unused]] } const struct DeviceRegister c_probe_driver = { - _T("CProbe"), - _T("Compass C-Probe"), + "CProbe", + "Compass C-Probe", 0, CProbeCreateOnPort, }; diff --git a/src/Device/Driver/CaiGpsNav.cpp b/src/Device/Driver/CaiGpsNav.cpp index f0afb29cfcd..ae3f02f4246 100644 --- a/src/Device/Driver/CaiGpsNav.cpp +++ b/src/Device/Driver/CaiGpsNav.cpp @@ -50,8 +50,8 @@ CaiGpsNavCreateOnPort([[maybe_unused]] const DeviceConfig &config, Port &com_por } const struct DeviceRegister gps_nav_driver = { - _T("CAI GPS-NAV"), - _T("Cambridge CAI GPS-NAV"), + "CAI GPS-NAV", + "Cambridge CAI GPS-NAV", 0, CaiGpsNavCreateOnPort, }; diff --git a/src/Device/Driver/CaiLNav.cpp b/src/Device/Driver/CaiLNav.cpp index d1beb0f894d..ab07e5a1200 100644 --- a/src/Device/Driver/CaiLNav.cpp +++ b/src/Device/Driver/CaiLNav.cpp @@ -139,8 +139,8 @@ CaiLNavCreateOnPort([[maybe_unused]] const DeviceConfig &config, Port &com_port) } const struct DeviceRegister cai_lnav_driver = { - _T("cai_lnav"), - _T("Cambridge L-Nav"), + "cai_lnav", + "Cambridge L-Nav", DeviceRegister::NO_TIMEOUT, CaiLNavCreateOnPort, }; diff --git a/src/Device/Driver/Condor.cpp b/src/Device/Driver/Condor.cpp index dfe1b0d8201..dd993b6d0dd 100644 --- a/src/Device/Driver/Condor.cpp +++ b/src/Device/Driver/Condor.cpp @@ -82,8 +82,8 @@ CondorCreateOnPort([[maybe_unused]] const DeviceConfig &config, [[maybe_unused]] } const struct DeviceRegister condor_driver = { - _T("Condor"), - _T("Condor Soaring Simulator"), + "Condor", + "Condor Soaring Simulator", 0, CondorCreateOnPort, }; diff --git a/src/Device/Driver/EW.cpp b/src/Device/Driver/EW.cpp index 4cb6b8b61f1..ac43099b39f 100644 --- a/src/Device/Driver/EW.cpp +++ b/src/Device/Driver/EW.cpp @@ -14,7 +14,6 @@ #include "NMEA/Checksum.hpp" #include "Operation/Operation.hpp" #include "util/TruncateString.hpp" -#include "util/ConvertString.hpp" #include "util/ScopeExit.hxx" #include @@ -23,10 +22,6 @@ #include #include "Waypoint/Waypoint.hpp" -#ifdef _UNICODE -#include -#endif - // Additional sentance for EW support class EWDevice : public AbstractDevice { @@ -86,22 +81,10 @@ EWDevice::TryConnect(OperationEnvironment &env) } static void -convert_string(char *dest, size_t size, const TCHAR *src) +convert_string(char *dest, size_t size, const char *src) { -#ifdef _UNICODE - size_t length = _tcslen(src); - if (length >= size) - length = size - 1; - - int length2 = ::WideCharToMultiByte(CP_ACP, 0, src, length, dest, size, - nullptr, nullptr); - if (length2 < 0) - length2 = 0; - dest[length2] = '\0'; -#else strncpy(dest, src, size - 1); dest[size - 1] = '\0'; -#endif } bool @@ -213,12 +196,11 @@ EWDevice::AddWaypoint(const Waypoint &way_point, OperationEnvironment &env) return false; // copy at most 6 chars - const WideToUTF8Converter name_utf8(way_point.name.c_str()); - if (!name_utf8.IsValid()) + if (way_point.name.empty()) return false; char IDString[12]; - char *end = CopyTruncateString(IDString, 7, name_utf8); + char *end = CopyTruncateString(IDString, 7, way_point.name.c_str()); // fill up with spaces std::fill(end, IDString + 6, ' '); @@ -281,8 +263,8 @@ EWCreateOnPort([[maybe_unused]] const DeviceConfig &config, Port &com_port) } const struct DeviceRegister ew_driver = { - _T("EW Logger"), - _T("EW Logger"), + "EW Logger", + "EW Logger", DeviceRegister::DECLARE, EWCreateOnPort, }; diff --git a/src/Device/Driver/EWMicroRecorder.cpp b/src/Device/Driver/EWMicroRecorder.cpp index 937302e6752..3fad3f9b3ee 100644 --- a/src/Device/Driver/EWMicroRecorder.cpp +++ b/src/Device/Driver/EWMicroRecorder.cpp @@ -58,7 +58,7 @@ ReadAltitude(NMEAInputLine &line, double &value_r) if (!available) return false; - if (unit == _T('f') || unit == _T('F')) + if (unit == 'f' || unit == 'F') value = Units::ToSysUnit(value, Unit::FEET); value_r = value; @@ -179,11 +179,11 @@ CleanString(char *p) * Clean a string and write it to the Port. */ static void -WriteCleanString(Port &port, const TCHAR *p, +WriteCleanString(Port &port, const char *p, OperationEnvironment &env, std::chrono::steady_clock::duration timeout) { - NarrowString<256> buffer; + StaticString<256> buffer; buffer.SetASCII(p); CleanString(buffer.buffer()); @@ -202,7 +202,7 @@ WriteLabel(Port &port, const char *name, OperationEnvironment &env) * Write a name/value pair to the EW microRecorder. */ static void -WritePair(Port &port, const char *name, const TCHAR *value, +WritePair(Port &port, const char *name, const char *value, OperationEnvironment &env) { WriteLabel(port, name, env); @@ -215,14 +215,14 @@ WriteGeoPoint(Port &port, const GeoPoint &value, OperationEnvironment &env) { int DegLat, DegLon; double tmp, MinLat, MinLon; - TCHAR NoS, EoW; + char NoS, EoW; // prepare latitude tmp = (double)value.latitude.Degrees(); - NoS = _T('N'); + NoS = 'N'; if (tmp < 0) { - NoS = _T('S'); + NoS = 'S'; tmp = -tmp; } @@ -231,10 +231,10 @@ WriteGeoPoint(Port &port, const GeoPoint &value, OperationEnvironment &env) // prepare long tmp = (double)value.longitude.Degrees(); - EoW = _T('E'); + EoW = 'E'; if (tmp < 0) { - EoW = _T('W'); + EoW = 'W'; tmp = -tmp; } @@ -293,7 +293,7 @@ DeclareInner(Port &port, const Declaration &declaration, port.FullWrite("\r\nFLIGHT DECLARATION\r\n-------------------\r\n\r\n", env, std::chrono::seconds(1)); - WritePair(port, "Description", _T("XCSoar task declaration"), env); + WritePair(port, "Description", "XCSoar task declaration", env); for (unsigned i = 0; i < 11; i++) { if (i+1>= declaration.Size()) { @@ -343,8 +343,8 @@ EWMicroRecorderCreateOnPort([[maybe_unused]] const DeviceConfig &config, Port &c } const struct DeviceRegister ew_microrecorder_driver = { - _T("EW MicroRecorder"), - _T("EW microRecorder"), + "EW MicroRecorder", + "EW microRecorder", DeviceRegister::DECLARE, EWMicroRecorderCreateOnPort, }; diff --git a/src/Device/Driver/Eye.cpp b/src/Device/Driver/Eye.cpp index 5ccc9f7094e..88cbb40c867 100644 --- a/src/Device/Driver/Eye.cpp +++ b/src/Device/Driver/Eye.cpp @@ -159,8 +159,8 @@ EyeCreateOnPort(const DeviceConfig &, Port &) } const struct DeviceRegister eye_driver = { - _T("EYE"), - _T("EYE sensor-box (experimental)"), + "EYE", + "EYE sensor-box (experimental)", 0, EyeCreateOnPort, }; diff --git a/src/Device/Driver/FLARM/Declare.cpp b/src/Device/Driver/FLARM/Declare.cpp index eff682185b2..8c7b525ef13 100644 --- a/src/Device/Driver/FLARM/Declare.cpp +++ b/src/Device/Driver/FLARM/Declare.cpp @@ -4,7 +4,6 @@ #include "Device.hpp" #include "Device/Declaration.hpp" #include "Operation/Operation.hpp" -#include "util/ConvertString.hpp" #include "TextProtocol.hpp" bool @@ -103,12 +102,12 @@ FlarmDevice::DeclareInternal(const Declaration &declaration, * parameter of CopyCleanFlarmString() allows us to trim off excess characters * so that a dodgy waypoint configuration doesn't cause an overflow. */ - NarrowString<90> buffer; - const WideToUTF8Converter shortName(declaration.GetShortName(i)); + StaticString<90> buffer; buffer.Format("%02d%05.0f%c,%03d%05.0f%c,", DegLat, (double)MinLat, NoS, DegLon, (double)MinLon, EoW); - CopyCleanFlarmString(buffer.buffer() + buffer.length(), shortName, 6); + CopyCleanFlarmString(buffer.buffer() + buffer.length(), + declaration.GetShortName(i), 6); if (!SetConfig("ADDWP", buffer, env)) return false; diff --git a/src/Device/Driver/FLARM/Device.cpp b/src/Device/Driver/FLARM/Device.cpp index 557ace4b608..6e9a2aba6aa 100644 --- a/src/Device/Driver/FLARM/Device.cpp +++ b/src/Device/Driver/FLARM/Device.cpp @@ -3,7 +3,6 @@ #include "Device.hpp" #include "Device/Port/Port.hpp" -#include "util/ConvertString.hpp" #include "util/StaticString.hxx" #include "util/TruncateString.hpp" #include "util/Macros.hpp" @@ -94,80 +93,80 @@ FlarmDevice::SetBaudRate(unsigned baud_id, OperationEnvironment &env) } bool -FlarmDevice::GetPilot(TCHAR *buffer, size_t length, OperationEnvironment &env) +FlarmDevice::GetPilot(char *buffer, size_t length, OperationEnvironment &env) { return GetConfig("PILOT", buffer, length, env); } bool -FlarmDevice::SetPilot(const TCHAR *pilot_name, OperationEnvironment &env) +FlarmDevice::SetPilot(const char *pilot_name, OperationEnvironment &env) { return SetConfig("PILOT", pilot_name, env); } bool -FlarmDevice::GetCoPilot(TCHAR *buffer, size_t length, +FlarmDevice::GetCoPilot(char *buffer, size_t length, OperationEnvironment &env) { return GetConfig("COPIL", buffer, length, env); } bool -FlarmDevice::SetCoPilot(const TCHAR *copilot_name, OperationEnvironment &env) +FlarmDevice::SetCoPilot(const char *copilot_name, OperationEnvironment &env) { return SetConfig("COPIL", copilot_name, env); } bool -FlarmDevice::GetPlaneType(TCHAR *buffer, size_t length, +FlarmDevice::GetPlaneType(char *buffer, size_t length, OperationEnvironment &env) { return GetConfig("GLIDERTYPE", buffer, length, env); } bool -FlarmDevice::SetPlaneType(const TCHAR *plane_type, OperationEnvironment &env) +FlarmDevice::SetPlaneType(const char *plane_type, OperationEnvironment &env) { return SetConfig("GLIDERTYPE", plane_type, env); } bool -FlarmDevice::GetPlaneRegistration(TCHAR *buffer, size_t length, +FlarmDevice::GetPlaneRegistration(char *buffer, size_t length, OperationEnvironment &env) { return GetConfig("GLIDERID", buffer, length, env); } bool -FlarmDevice::SetPlaneRegistration(const TCHAR *registration, +FlarmDevice::SetPlaneRegistration(const char *registration, OperationEnvironment &env) { return SetConfig("GLIDERID", registration, env); } bool -FlarmDevice::GetCompetitionId(TCHAR *buffer, size_t length, +FlarmDevice::GetCompetitionId(char *buffer, size_t length, OperationEnvironment &env) { return GetConfig("COMPID", buffer, length, env); } bool -FlarmDevice::SetCompetitionId(const TCHAR *competition_id, +FlarmDevice::SetCompetitionId(const char *competition_id, OperationEnvironment &env) { return SetConfig("COMPID", competition_id, env); } bool -FlarmDevice::GetCompetitionClass(TCHAR *buffer, size_t length, +FlarmDevice::GetCompetitionClass(char *buffer, size_t length, OperationEnvironment &env) { return GetConfig("COMPCLASS", buffer, length, env); } bool -FlarmDevice::SetCompetitionClass(const TCHAR *competition_class, +FlarmDevice::SetCompetitionClass(const char *competition_class, OperationEnvironment &env) { return SetConfig("COMPCLASS", competition_class, env); @@ -177,10 +176,10 @@ bool FlarmDevice::GetConfig(const char *setting, char *buffer, size_t length, OperationEnvironment &env) { - NarrowString<90> request; + StaticString<90> request; request.Format("PFLAC,R,%s", setting); - NarrowString<90> expected_answer(request); + StaticString<90> expected_answer(request); expected_answer[6u] = 'A'; expected_answer.push_back(','); @@ -210,10 +209,10 @@ bool FlarmDevice::SetConfig(const char *setting, const char *value, OperationEnvironment &env) { - NarrowString<90> buffer; + StaticString<90> buffer; buffer.Format("PFLAC,S,%s,%s", setting, value); - NarrowString<90> expected_answer(buffer); + StaticString<90> expected_answer(buffer); expected_answer[6u] = 'A'; Send(buffer, env); @@ -221,42 +220,6 @@ FlarmDevice::SetConfig(const char *setting, const char *value, return ExpectChecksum(port, NMEAChecksum(expected_answer), env); } -#ifdef _UNICODE - -bool -FlarmDevice::GetConfig(const char *setting, TCHAR *buffer, size_t length, - OperationEnvironment &env) -{ - char narrow_buffer[90]; - if (!GetConfig(setting, narrow_buffer, ARRAY_SIZE(narrow_buffer), env)) - return false; - - if (StringIsEmpty(narrow_buffer)) { - *buffer = _T('\0'); - return true; - } - - UTF8ToWideConverter wide(narrow_buffer); - if (!wide.IsValid()) - return false; - - CopyTruncateString(buffer, length, wide); - return true; -} - -bool -FlarmDevice::SetConfig(const char *setting, const TCHAR *value, - OperationEnvironment &env) -{ - WideToUTF8Converter narrow_value(value); - if (!narrow_value.IsValid()) - return false; - - return SetConfig(setting, narrow_value, env); -} - -#endif - void FlarmDevice::Restart(OperationEnvironment &env) { diff --git a/src/Device/Driver/FLARM/Device.hpp b/src/Device/Driver/FLARM/Device.hpp index c88762dbb0b..71dd9207d2d 100644 --- a/src/Device/Driver/FLARM/Device.hpp +++ b/src/Device/Driver/FLARM/Device.hpp @@ -83,23 +83,23 @@ class FlarmDevice: public AbstractDevice OperationEnvironment &env) override; bool PutPilotEvent(OperationEnvironment &env) override; - bool GetPilot(TCHAR *buffer, size_t length, OperationEnvironment &env); - bool SetPilot(const TCHAR *pilot_name, OperationEnvironment &env); - bool GetCoPilot(TCHAR *buffer, size_t length, OperationEnvironment &env); - bool SetCoPilot(const TCHAR *copilot_name, OperationEnvironment &env); - bool GetPlaneType(TCHAR *buffer, size_t length, OperationEnvironment &env); - bool SetPlaneType(const TCHAR *plane_type, OperationEnvironment &env); - bool GetPlaneRegistration(TCHAR *buffer, size_t length, + bool GetPilot(char *buffer, size_t length, OperationEnvironment &env); + bool SetPilot(const char *pilot_name, OperationEnvironment &env); + bool GetCoPilot(char *buffer, size_t length, OperationEnvironment &env); + bool SetCoPilot(const char *copilot_name, OperationEnvironment &env); + bool GetPlaneType(char *buffer, size_t length, OperationEnvironment &env); + bool SetPlaneType(const char *plane_type, OperationEnvironment &env); + bool GetPlaneRegistration(char *buffer, size_t length, OperationEnvironment &env); - bool SetPlaneRegistration(const TCHAR *registration, + bool SetPlaneRegistration(const char *registration, OperationEnvironment &env); - bool GetCompetitionId(TCHAR *buffer, size_t length, + bool GetCompetitionId(char *buffer, size_t length, OperationEnvironment &env); - bool SetCompetitionId(const TCHAR *competition_id, + bool SetCompetitionId(const char *competition_id, OperationEnvironment &env); - bool GetCompetitionClass(TCHAR *buffer, size_t length, + bool GetCompetitionClass(char *buffer, size_t length, OperationEnvironment &env); - bool SetCompetitionClass(const TCHAR *competition_class, + bool SetCompetitionClass(const char *competition_class, OperationEnvironment &env); bool GetStealthMode(bool &enabled, OperationEnvironment &env); @@ -124,14 +124,6 @@ class FlarmDevice: public AbstractDevice OperationEnvironment &env); bool SetConfig(const char *setting, const char *value, OperationEnvironment &env); - -#ifdef _UNICODE - bool GetConfig(const char *setting, TCHAR *buffer, size_t length, - OperationEnvironment &env); - bool SetConfig(const char *setting, const TCHAR *value, - OperationEnvironment &env); -#endif - bool DeclareInternal(const Declaration &declaration, OperationEnvironment &env); diff --git a/src/Device/Driver/FLARM/Register.cpp b/src/Device/Driver/FLARM/Register.cpp index bfef1807328..5e317faf5e2 100644 --- a/src/Device/Driver/FLARM/Register.cpp +++ b/src/Device/Driver/FLARM/Register.cpp @@ -11,7 +11,7 @@ FlarmCreateOnPort([[maybe_unused]] const DeviceConfig &config, Port &com_port) } const struct DeviceRegister flarm_driver = { - _T("FLARM"), _T("FLARM"), + "FLARM", "FLARM", DeviceRegister::DECLARE | DeviceRegister::LOGGER | DeviceRegister::MANAGE, FlarmCreateOnPort, }; diff --git a/src/Device/Driver/FlyNet.cpp b/src/Device/Driver/FlyNet.cpp index f5c5f9e9824..777fd27f446 100644 --- a/src/Device/Driver/FlyNet.cpp +++ b/src/Device/Driver/FlyNet.cpp @@ -96,8 +96,8 @@ FlyNetCreateOnPort([[maybe_unused]] const DeviceConfig &config, [[maybe_unused]] } const struct DeviceRegister flynet_driver = { - _T("FlyNet"), - _T("FlyNet Vario"), + "FlyNet", + "FlyNet Vario", 0, FlyNetCreateOnPort, }; diff --git a/src/Device/Driver/FlymasterF1.cpp b/src/Device/Driver/FlymasterF1.cpp index 10dafc72f00..fb00ae50baa 100644 --- a/src/Device/Driver/FlymasterF1.cpp +++ b/src/Device/Driver/FlymasterF1.cpp @@ -90,8 +90,8 @@ FlymasterF1CreateOnPort([[maybe_unused]] const DeviceConfig &config, Port &port) } const struct DeviceRegister flymaster_f1_driver = { - _T("FlymasterF1"), - _T("Flymaster F1"), + "FlymasterF1", + "Flymaster F1", 0, FlymasterF1CreateOnPort, }; diff --git a/src/Device/Driver/Flytec/Register.cpp b/src/Device/Driver/Flytec/Register.cpp index 3a808ef4e15..0f275b4f699 100644 --- a/src/Device/Driver/Flytec/Register.cpp +++ b/src/Device/Driver/Flytec/Register.cpp @@ -11,7 +11,7 @@ FlytecCreateOnPort([[maybe_unused]] const DeviceConfig &config, Port &com_port) } const struct DeviceRegister flytec_driver = { - _T("Flytec"), _T("Flytec 5030 / Brauniger"), + "Flytec", "Flytec 5030 / Brauniger", 0 /* DeviceRegister::LOGGER deactivated until current firmware supports this */, FlytecCreateOnPort, }; diff --git a/src/Device/Driver/FreeVario.cpp b/src/Device/Driver/FreeVario.cpp new file mode 100755 index 00000000000..289d6578b36 --- /dev/null +++ b/src/Device/Driver/FreeVario.cpp @@ -0,0 +1,400 @@ +#include "Device/Config.hpp" +#include "Device/Driver/FreeVario.hpp" +#include "Device/Driver.hpp" +#include "Device/Port/Port.hpp" +#include "Device/Util/NMEAWriter.hpp" +#include "Message.hpp" +#include "NMEA/Checksum.hpp" +#include "NMEA/Info.hpp" +#include "NMEA/Derived.hpp" +#include "NMEA/MoreData.hpp" +#include "NMEA/InputLine.hpp" +#include "Units/System.hpp" +#include "Operation/Operation.hpp" +// #include "Operation/PopupOperationEnvironment.hpp" +#include "LogFile.hpp" +#include "Interface.hpp" +#include "CalculationThread.hpp" +#include "Protection.hpp" +#include "Input/InputEvents.hpp" +#include + +using std::string_view_literals::operator""sv; + +/* + * Commands via NMEA from FreeVario Device to XCSoar: + * + * $PFV,M,S, - set MC External to defined value + * $PFV,M,U - set MC External up by 0.1 + * $PFV,M,D - set MC External down by 0.1 + * + * $PFV,F,C - set Vario FlightMode to Circle + * $PFV,F,S - set Vario FlightMode to SpeedToFly + * + * $PFV,Q,S, - set QNH to defined value + * $PFV,B,S, - set Bugs to percent by capacity 0 - 100 + * $PFV,S,S, - set Mute status and gives it back to sound board + * $PFV,A,S, - set attenuation and gives it back to sound board + * + * Commands for NMEA compatibility with OpenVario especially variod + * + * $POV,C,STF*4B -- if this command is received it is resend to NMEA + * Device 1 and Device 2 to sent variod to speed to fly + * audio mode + * $POV,C,VAR*4F -- if this command is received it is resend to NMEA + * Device 1 and Device 2 to set variod to vario audio mode + * + */ + +class FreeVarioDevice : public AbstractDevice { + Port &port; + +public: + explicit FreeVarioDevice(Port &_port):port(_port){} + bool ParseNMEA(const char *line,NMEAInfo &info) override; + static bool PFVParser(NMEAInputLine &line, NMEAInfo &info, Port &port); + bool POVParserAndForward(NMEAInputLine &line); + bool SendCmd(double value, const char *cmd, OperationEnvironment &env); + bool PutMacCready(double mc, OperationEnvironment &env) override; + bool PutBugs(double bugs, OperationEnvironment &env) override; + bool PutQNH(const AtmosphericPressure &pres, + OperationEnvironment &env) override; + void OnCalculatedUpdate(const MoreData &basic, + const DerivedInfo &calculated) override; + void OnSensorUpdate(const MoreData &basic) override; +}; + +/** + * Parse NMEA messsage and check if it is a valid FreeVario message + * Is true when a valid message or false if no valid message + */ +bool +FreeVarioDevice::POVParserAndForward(NMEAInputLine &line) +{ + NullOperationEnvironment env; + // PopupOperationEnvironment env; + bool messageValid = false; + + while (!line.IsEmpty() ) { + char command = line.ReadOneChar(); + char buff[4] ; + + line.Read(buff,4); + // TODO(August2111): I don't know, why this command should be + // mirrored in the driver to the eventSendNMEAPort(1) and (2) + // what is the sense for this + // From FreeVario device is coming a '$POV,C,XXX command + + if (command == 'C') { + char buffer[64]; + sprintf(buffer, "POV,C,%s", buff); + PortWriteNMEA(port, buffer, env); + } +#ifdef FREEVARIO_EVENT + // TODO(August2111): in the moment this output is not allowed + // with build-native it shows ' error: undefined reference to + // 'InputEvents::eventXXX(char const*)', but I don't know why yet + // info.switch_state.flight_mode = SwitchState::FlightMode::CIRCLING; + StaticString<4> bufferAsString; + bufferAsString.SetUTF8(buff); + if ('C' == command && bufferAsString == "STF") { + messageValid = true; + InputEvents::eventSendNMEAPort1("POV,C,STF*4B"); + InputEvents::eventSendNMEAPort2("POV,C,STF*4B"); + InputEvents::eventStatusMessage("Speed to Fly Mode"); + } + if ('C' == command && bufferAsString == "VAR") { + messageValid = true; + InputEvents::eventSendNMEAPort1("POV,C,VAR*4F"); + InputEvents::eventSendNMEAPort2("POV,C,VAR*4F"); + InputEvents::eventStatusMessage("Vario Mode"); + } +#endif + } + return messageValid; +} + +/** + * Parse NMEA message and check if it is a valid FreeVario message + * Is true when a valid message or false if no valid message + */ +bool +FreeVarioDevice::PFVParser(NMEAInputLine &line, NMEAInfo &info, Port &port) +{ + NullOperationEnvironment env; + bool validMessage = false; + + while (!line.IsEmpty()) { + + char type = line.ReadOneChar(); + char subCommand = line.ReadOneChar(); + + if (subCommand == '\0') + return validMessage; // from now the string is invalid... + + switch (type) { + case '\0': // from now the string is invalid or finished + return validMessage; + case 'M': { + if (subCommand == 'S') { + double mcIn; + if (line.ReadChecked(mcIn)) { + info.settings.ProvideMacCready(mcIn, info.clock); + validMessage = true; + } + } + + else if (subCommand == 'U') { + double new_mc = std::min(info.settings.mac_cready + 0.1, 5.0); + info.settings.ProvideMacCready(new_mc, info.clock); + validMessage = true; + } + + else if (subCommand == 'D') { + double new_mc = std::max(info.settings.mac_cready - 0.1, 0.0); + info.settings.ProvideMacCready(new_mc, info.clock); + validMessage = true; + } + break; + } + case 'B': { + if (subCommand == 'S') { + double bugsIn; + if (line.ReadChecked(bugsIn)) { + info.settings.ProvideBugs((100 - bugsIn) / 100., info.clock); + validMessage = true; + } + } + break; + } + + case 'Q': { + if (subCommand == 'S') { + double qnhIn; + if (line.ReadChecked(qnhIn)) { + AtmosphericPressure pres = info.static_pressure.HectoPascal(qnhIn); + info.settings.ProvideQNH(pres, info.clock); + validMessage = true; + } + } + break; + } + + case 'F': { + if (subCommand == 'S') { + info.switch_state.flight_mode = SwitchState::FlightMode::CRUISE; + validMessage = true; + } else if (subCommand == 'C') { + info.switch_state.flight_mode = SwitchState::FlightMode::CIRCLING; + validMessage = true; + } + break; + } + + case 'S': { + if (subCommand == 'S') { + char nmeaOutbuffer[80]; + int soundState; + bool stateOK = line.ReadChecked(soundState); + if (stateOK) + sprintf(nmeaOutbuffer, "PFV,MUT,%d", soundState); + PortWriteNMEA(port, nmeaOutbuffer, env); + validMessage = true; + } + break; + } + + case 'A': { + if (subCommand == 'S') { + char nmeaOutbuffer[80]; + int attenState; + bool stateOK = line.ReadChecked(attenState); + if (stateOK) + sprintf(nmeaOutbuffer, "PFV,ATT,%d", attenState); + PortWriteNMEA(port, nmeaOutbuffer, env); + validMessage = true; + } + break; + } + default: + // Just break on default + break; + } + } + + return validMessage; + } + +/** + * Parse incoming NMEA messages to check for PFV messages + */ +bool +FreeVarioDevice::ParseNMEA(const char *_line, NMEAInfo &info) +{ + NullOperationEnvironment env; + + if (VerifyNMEAChecksum(_line)) { + NMEAInputLine line(_line); + const auto type = line.ReadView(); + if (type == "$PFV"sv) { + return PFVParser(line, info, port); + } else if (type == "$POV"sv) { + return POVParserAndForward(line); // no info and port necessary + } + } + return false; +} + +/* + * Send total_energy_vario to FreeVario device on every sensor update. + * Is needed to have a good refresh rate on the external device showing the + * vario values + */ +void +FreeVarioDevice::OnSensorUpdate(const MoreData &basic) +{ + NullOperationEnvironment env; + char nmeaOutbuffer[80]; + + if (basic.total_energy_vario_available.IsValid()) { + sprintf(nmeaOutbuffer,"PFV,VAR,%f", basic.total_energy_vario); + PortWriteNMEA(port, nmeaOutbuffer, env); + } + + // TODO(August2111): basic.netto_variable has no timestamp unfortunately? + // if (basic.netto_vario_available.IsValid()) { + sprintf(nmeaOutbuffer,"PFV,VAN,%f", basic.netto_vario); + PortWriteNMEA(port, nmeaOutbuffer, env); + // } +} + + +/* + * Always send the calculated updated values to the FreeVario to have a good + * refresh rate on the external device + */ +void +FreeVarioDevice::OnCalculatedUpdate(const MoreData &basic, + const DerivedInfo &calculated) +{ + NullOperationEnvironment env; + + char nmeaOutbuffer[80]; + + if (basic.baro_altitude_available.IsValid()){ + sprintf(nmeaOutbuffer,"PFV,HIG,%f", basic.baro_altitude); + PortWriteNMEA(port, nmeaOutbuffer, env); + } else if (basic.gps_altitude_available.IsValid()){ + sprintf(nmeaOutbuffer,"PFV,HIG,%f", basic.gps_altitude); + PortWriteNMEA(port, nmeaOutbuffer, env); + } else { + sprintf(nmeaOutbuffer,"PFV,HIG,%f", 0.0); + PortWriteNMEA(port, nmeaOutbuffer, env); + } + + if (calculated.altitude_agl_valid){ + sprintf(nmeaOutbuffer,"PFV,HAG,%f", calculated.altitude_agl); + PortWriteNMEA(port, nmeaOutbuffer, env); + } + + bool tempAvil = basic.temperature_available; + if (tempAvil){ + double temp = basic.temperature.ToCelsius(); + sprintf(nmeaOutbuffer,"PFV,TEM,%f", temp); + PortWriteNMEA(port, nmeaOutbuffer, env); + } + + double trueAirspeedKmh = ((basic.true_airspeed * 60 * 60) / 1000); + sprintf(nmeaOutbuffer,"PFV,TAS,%f", trueAirspeedKmh); + PortWriteNMEA(port, nmeaOutbuffer, env); + + if (basic.ground_speed_available.IsValid()){ + double groundSpeed = ((basic.ground_speed * 60 * 60) / 1000);; + sprintf(nmeaOutbuffer,"PFV,GRS,%f", groundSpeed); + PortWriteNMEA(port, nmeaOutbuffer, env); + } else { + sprintf(nmeaOutbuffer,"PFV,GRS,%d", -1); + PortWriteNMEA(port, nmeaOutbuffer, env); + } + + double stfKmh = ((calculated.V_stf * 60 * 60) / 1000); + sprintf(nmeaOutbuffer,"PFV,STF,%f", stfKmh); + PortWriteNMEA(port, nmeaOutbuffer, env); + + if (calculated.circling){ + sprintf(nmeaOutbuffer,"PFV,MOD,%s", "C"); + PortWriteNMEA(port, nmeaOutbuffer, env); + } else { + sprintf(nmeaOutbuffer,"PFV,MOD,%s", "S"); + PortWriteNMEA(port, nmeaOutbuffer, env); + } + + // vario average last 30 secs + sprintf(nmeaOutbuffer,"PFV,VAA,%f",calculated.average); + PortWriteNMEA(port, nmeaOutbuffer, env); + + if (basic.settings.mac_cready_available.IsValid()){ + double externalMC = basic.settings.mac_cready; + sprintf(nmeaOutbuffer,"PFV,MCE,%0.2f", (double)externalMC); + PortWriteNMEA(port, nmeaOutbuffer, env); + } + + if (basic.settings.qnh_available.IsValid()){ + double qnhHp = basic.settings.qnh.GetHectoPascal(); + sprintf(nmeaOutbuffer,"PFV,QNH,%f",qnhHp); + PortWriteNMEA(port, nmeaOutbuffer, env); + } +} + +/* + * Send the internal xcsoar mc value to FreeVario device to + * be informed about MC changes doen in XCSoar + */ +bool +FreeVarioDevice::SendCmd(double value, const char *cmd, + OperationEnvironment &env) +{ + if (!EnableNMEA(env)) { + return false; + } + char nmeaOutbuffer[80]; + sprintf(nmeaOutbuffer, cmd, value); + PortWriteNMEA(port, nmeaOutbuffer, env); + return true; +} + +bool +FreeVarioDevice::PutMacCready(double mc, OperationEnvironment &env) +{ + return SendCmd(mc, "PFV,MCI,%0.2f", env); +} + +bool +FreeVarioDevice::PutBugs(double bugs,OperationEnvironment &env) +{ + double bugsAsPercentage = (1 - bugs) * 100; + return SendCmd(bugsAsPercentage, "PFV,BUG,%f", env); +} + +bool +FreeVarioDevice::PutQNH(const AtmosphericPressure &pres, + OperationEnvironment &env) +{ + return SendCmd(pres.GetHectoPascal(), "PFV,QNH,%f", env); +} + + +static Device * +FreeVarioCreateOnPort([[maybe_unused]] const DeviceConfig &config, + Port &com_port) +{ + return new FreeVarioDevice(com_port); +} + +const struct DeviceRegister free_vario_driver = { + "FreeVario", + "FreeVario", + DeviceRegister::SEND_SETTINGS| + DeviceRegister::RECEIVE_SETTINGS, + FreeVarioCreateOnPort, +}; diff --git a/src/Device/Driver/FreeVario.hpp b/src/Device/Driver/FreeVario.hpp new file mode 100755 index 00000000000..ffc9512aa83 --- /dev/null +++ b/src/Device/Driver/FreeVario.hpp @@ -0,0 +1,6 @@ +#ifndef XCSOAR_DEVICE_DRIVER_FREEVARIO_HPP +#define XCSOAR_DEVICE_DRIVER_FREEVARIO_HPP + +extern const struct DeviceRegister free_vario_driver; + +#endif diff --git a/src/Device/Driver/Generic.cpp b/src/Device/Driver/Generic.cpp index b19a46315d3..56ead1db6c1 100644 --- a/src/Device/Driver/Generic.cpp +++ b/src/Device/Driver/Generic.cpp @@ -14,8 +14,8 @@ GenericCreateOnPort([[maybe_unused]] const DeviceConfig &config, [[maybe_unused] } const struct DeviceRegister generic_driver = { - _T("Generic"), - _T("Generic"), + "Generic", + "Generic", 0, GenericCreateOnPort, }; diff --git a/src/Device/Driver/ILEC.cpp b/src/Device/Driver/ILEC.cpp index 0ad9aeff9b9..702d68b2dfa 100644 --- a/src/Device/Driver/ILEC.cpp +++ b/src/Device/Driver/ILEC.cpp @@ -70,8 +70,8 @@ ILECCreateOnPort([[maybe_unused]] const DeviceConfig &config, [[maybe_unused]] P } const struct DeviceRegister ilec_driver = { - _T("ILEC SN10"), - _T("ILEC SN10"), + "ILEC SN10", + "ILEC SN10", 0, ILECCreateOnPort, }; diff --git a/src/Device/Driver/IMI/Internal.cpp b/src/Device/Driver/IMI/Internal.cpp index 31fa3e658bb..4b976fb781a 100644 --- a/src/Device/Driver/IMI/Internal.cpp +++ b/src/Device/Driver/IMI/Internal.cpp @@ -37,7 +37,7 @@ ReadAltitude(NMEAInputLine &line, double &value_r) if (!available) return false; - if (unit == _T('f') || unit == _T('F')) + if (unit == 'f' || unit == 'F') value = Units::ToSysUnit(value, Unit::FEET); value_r = value; diff --git a/src/Device/Driver/IMI/Protocol/Conversion.cpp b/src/Device/Driver/IMI/Protocol/Conversion.cpp index 9a74b4b6ae7..ae6b845c716 100644 --- a/src/Device/Driver/IMI/Protocol/Conversion.cpp +++ b/src/Device/Driver/IMI/Protocol/Conversion.cpp @@ -7,23 +7,16 @@ #include "Engine/Waypoint/Waypoint.hpp" #include "time/Calendar.hxx" -#ifdef _UNICODE -#include -#endif - static constexpr unsigned IMI_SECONDS_IN_MINUTE = 60; static constexpr unsigned IMI_SECONDS_IN_HOUR = 60*60; static constexpr unsigned IMI_SECONDS_IN_DAY = 24*60*60; void -IMI::ConvertToChar(const TCHAR* unicode, char* ascii, int outSize) +IMI::ConvertToChar(const char* dest, char* ascii, int outSize) { -#ifdef _UNICODE - WideCharToMultiByte(CP_ACP, 0, unicode, -1, ascii, outSize, "?", nullptr); -#else - strncpy(ascii, unicode, outSize - 1); + // this is only a copy (n) function) + strncpy(ascii, dest, outSize - 1); ascii[outSize - 1] = 0; -#endif } IMI::AngleConverter::AngleConverter(Angle angle) diff --git a/src/Device/Driver/IMI/Protocol/Conversion.hpp b/src/Device/Driver/IMI/Protocol/Conversion.hpp index 74d45755f04..6276a73eebe 100644 --- a/src/Device/Driver/IMI/Protocol/Conversion.hpp +++ b/src/Device/Driver/IMI/Protocol/Conversion.hpp @@ -31,7 +31,7 @@ struct AngleConverter { }; void -ConvertToChar(const TCHAR* unicode, char* ascii, int outSize); +ConvertToChar(const char* dest, char* ascii, int outSize); BrokenDateTime ConvertToDateTime(IMIDATETIMESEC in); diff --git a/src/Device/Driver/IMI/Protocol/Protocol.cpp b/src/Device/Driver/IMI/Protocol/Protocol.cpp index 448548c6c50..0f650cc0811 100644 --- a/src/Device/Driver/IMI/Protocol/Protocol.cpp +++ b/src/Device/Driver/IMI/Protocol/Protocol.cpp @@ -130,7 +130,7 @@ IMI::DeclarationWrite(Port &port, const Declaration &decl, sizeof(imiDecl.header.gid)); ConvertToChar(decl.competition_id, imiDecl.header.cid, sizeof(imiDecl.header.cid)); - ConvertToChar(_T("XCSOARTASK"), imiDecl.header.tskName, + ConvertToChar("XCSOARTASK", imiDecl.header.tskName, sizeof(imiDecl.header.tskName)); ConvertWaypoint(decl.turnpoints[0].waypoint, imiDecl.wp[0]); diff --git a/src/Device/Driver/IMI/Register.cpp b/src/Device/Driver/IMI/Register.cpp index 5f59e809ca9..6a3c8312a0d 100644 --- a/src/Device/Driver/IMI/Register.cpp +++ b/src/Device/Driver/IMI/Register.cpp @@ -11,8 +11,8 @@ IMICreateOnPort([[maybe_unused]] const DeviceConfig &config, Port &com_port) } const struct DeviceRegister imi_driver = { - _T("IMI ERIXX"), - _T("IMI ERIXX"), + "IMI ERIXX", + "IMI ERIXX", DeviceRegister::DECLARE | DeviceRegister::LOGGER, IMICreateOnPort, }; diff --git a/src/Device/Driver/KRT2.cpp b/src/Device/Driver/KRT2.cpp index 5bc161b7d4d..e38e6ba0e91 100644 --- a/src/Device/Driver/KRT2.cpp +++ b/src/Device/Driver/KRT2.cpp @@ -102,7 +102,7 @@ class KRT2Device final : public AbstractDevice { * @param name Name of the radio station. * @return Name of the radio station (printable ASCII, MAX_NAME_LENGTH characters). */ - static void GetStationName(char *station_name, const TCHAR *name); + static void GetStationName(char *station_name, const char *name); /** * Sends the frequency to the radio. * @@ -116,7 +116,7 @@ class KRT2Device final : public AbstractDevice { */ bool PutFrequency(std::byte cmd, RadioFrequency frequency, - const TCHAR *name, + const char *name, OperationEnvironment &env); void LockSetResponse(std::byte _response) noexcept { @@ -156,13 +156,13 @@ class KRT2Device final : public AbstractDevice { * Sets the active frequency on the radio. */ virtual bool PutActiveFrequency(RadioFrequency frequency, - const TCHAR *name, + const char *name, OperationEnvironment &env) override; /** * Sets the standby frequency on the radio. */ virtual bool PutStandbyFrequency(RadioFrequency frequency, - const TCHAR *name, + const char *name, OperationEnvironment &env) override; /** * Receives and handles data from the radio. @@ -251,14 +251,14 @@ KRT2Device::DataReceived(std::span s, } inline void -KRT2Device::GetStationName(char *station_name, const TCHAR *name) +KRT2Device::GetStationName(char *station_name, const char *name) { if(name == nullptr) - name = _T(""); + name = ""; size_t s_idx = 0; //!< Source name index size_t d_idx = 0; //!< Destination name index - TCHAR c; //!< Character at source name index + char c; //!< Character at source name index while ((c = name[s_idx++])) { // KRT2 supports printable ASCII only @@ -376,7 +376,7 @@ KRT2Device::HandleMessage(std::span src, bool KRT2Device::PutFrequency(std::byte cmd, RadioFrequency frequency, - const TCHAR *name, + const char *name, OperationEnvironment &env) { stx_msg msg; @@ -392,7 +392,7 @@ KRT2Device::PutFrequency(std::byte cmd, bool KRT2Device::PutActiveFrequency(RadioFrequency frequency, - const TCHAR *name, + const char *name, OperationEnvironment &env) { return PutFrequency(ACTIVE_FREQUENCY, frequency, name, env); @@ -400,7 +400,7 @@ KRT2Device::PutActiveFrequency(RadioFrequency frequency, bool KRT2Device::PutStandbyFrequency(RadioFrequency frequency, - const TCHAR *name, + const char *name, OperationEnvironment &env) { return PutFrequency(STANDBY_FREQUENCY, frequency, name, env); @@ -413,8 +413,8 @@ KRT2CreateOnPort([[maybe_unused]] const DeviceConfig &config, Port &comPort) } const DeviceRegister krt2_driver = { - _T("KRT2"), - _T("KRT2"), + "KRT2", + "KRT2", DeviceRegister::NO_TIMEOUT | DeviceRegister::RAW_GPS_DATA, KRT2CreateOnPort, diff --git a/src/Device/Driver/LX/Declare.cpp b/src/Device/Driver/LX/Declare.cpp index 39c9f99de2d..720a23b1189 100644 --- a/src/Device/Driver/LX/Declare.cpp +++ b/src/Device/Driver/LX/Declare.cpp @@ -16,9 +16,9 @@ * len characters with last char = '\0' */ static void -copy_space_padded(char dest[], const TCHAR src[], unsigned int len) +copy_space_padded(char dest[], const char src[], unsigned int len) { - const unsigned slen = _tcslen(src); + const unsigned slen = strlen(src); for(unsigned i = 0; i < (len - 1); i++) { if (i < slen) dest[i] = (char)std::max((src[i] & 0x7f), 0x20); @@ -95,7 +95,7 @@ LoadTask(LX::Declaration &lx_driver_Declaration, const Declaration &declaration) lx_driver_Declaration.tptypes[i] = 3; lx_driver_Declaration.Latitudes[i] = 0; lx_driver_Declaration.Longitudes[i] = 0; - copy_space_padded(lx_driver_Declaration.WaypointNames[i], _T("TAKEOFF"), + copy_space_padded(lx_driver_Declaration.WaypointNames[i], "TAKEOFF", sizeof(lx_driver_Declaration.WaypointNames[i])); @@ -113,7 +113,7 @@ LoadTask(LX::Declaration &lx_driver_Declaration, const Declaration &declaration) lx_driver_Declaration.tptypes[i] = 2; lx_driver_Declaration.Longitudes[i] = 0; lx_driver_Declaration.Latitudes[i] = 0; - copy_space_padded(lx_driver_Declaration.WaypointNames[i], _T("LANDING"), + copy_space_padded(lx_driver_Declaration.WaypointNames[i], "LANDING", sizeof(lx_driver_Declaration.WaypointNames[i])); } else { // unused @@ -131,7 +131,7 @@ static void LoadContestClass(LX::ContestClass &lx_driver_ContestClass, [[maybe_unused]] const Declaration &declaration) { - copy_space_padded(lx_driver_ContestClass.contest_class, _T(""), + copy_space_padded(lx_driver_ContestClass.contest_class, "", sizeof(lx_driver_ContestClass.contest_class)); } diff --git a/src/Device/Driver/LX/Internal.hpp b/src/Device/Driver/LX/Internal.hpp index 46f213e3682..ee7c460b38c 100644 --- a/src/Device/Driver/LX/Internal.hpp +++ b/src/Device/Driver/LX/Internal.hpp @@ -151,7 +151,7 @@ class LXDevice: public AbstractDevice is_v7 = is_sVario = is_nano = is_lx16xx = is_forwarded_nano = false; } - void IdDeviceByName(NarrowString<16> productName) noexcept + void IdDeviceByName(StaticString<16> productName) noexcept { is_v7 = productName.equals("V7"); is_sVario = productName.equals("NINC") || productName.equals("S8x"); diff --git a/src/Device/Driver/LX/NanoDeclare.cpp b/src/Device/Driver/LX/NanoDeclare.cpp index 42eb7af79a7..0b5b5e2ebf2 100644 --- a/src/Device/Driver/LX/NanoDeclare.cpp +++ b/src/Device/Driver/LX/NanoDeclare.cpp @@ -10,14 +10,13 @@ #include "time/TimeoutClock.hpp" #include "time/BrokenDateTime.hpp" #include "Operation/Operation.hpp" -#include "util/ConvertString.hpp" static bool NanoWriteDecl(Port &port, OperationEnvironment &env, PortNMEAReader &reader, unsigned row, unsigned n_rows, const char *content) { - NarrowString<256> buffer; + StaticString<256> buffer; buffer.Format("$PLXVC,DECL,W,%u,%u,%s", row, n_rows, content); PortWriteNMEA(port, buffer, env); @@ -35,7 +34,7 @@ NanoWriteDeclFormat(Port &port, OperationEnvironment &env, unsigned row, unsigned n_rows, const char *fmt, Args&&... args) { - NarrowString<256> buffer; + StaticString<256> buffer; buffer.Format(fmt, args...); return NanoWriteDecl(port, env, reader, row, n_rows, buffer); } @@ -45,14 +44,13 @@ static bool NanoWriteDeclString(Port &port, OperationEnvironment &env, PortNMEAReader &reader, unsigned row, unsigned n_rows, - const char *prefix, const TCHAR *value) + const char *prefix, const char *value) { - WideToUTF8Converter narrow_value(value); - if (!narrow_value.IsValid()) + if (!value) return false; return NanoWriteDeclFormat(port, env, reader, row, n_rows, - "%s%s", prefix, (const char *)narrow_value); + "%s%s", prefix, value); } static bool diff --git a/src/Device/Driver/LX/NanoLogger.cpp b/src/Device/Driver/LX/NanoLogger.cpp index c48019cda5d..f935a00e506 100644 --- a/src/Device/Driver/LX/NanoLogger.cpp +++ b/src/Device/Driver/LX/NanoLogger.cpp @@ -147,7 +147,7 @@ ParseLogbookContent(const char *_line, RecordedFlightInfo &info) unsigned n; return line.ReadChecked(n) && - ReadFilename(line, info) > 0 && + ReadFilename(line, info) && ReadDate(line, info.date) && ReadTime(line, info.start_time) && ReadTime(line, info.end_time); diff --git a/src/Device/Driver/LX/Register.cpp b/src/Device/Driver/LX/Register.cpp index 567cfa1fdc6..6e2dd2674a6 100644 --- a/src/Device/Driver/LX/Register.cpp +++ b/src/Device/Driver/LX/Register.cpp @@ -18,8 +18,8 @@ LXCreateOnPort(const DeviceConfig &config, Port &com_port) } const struct DeviceRegister lx_driver = { - _T("LX"), - _T("LXNAV"), + "LX", + "LXNAV", DeviceRegister::DECLARE | DeviceRegister::LOGGER | DeviceRegister::PASS_THROUGH | DeviceRegister::BULK_BAUD_RATE | diff --git a/src/Device/Driver/Larus.cpp b/src/Device/Driver/Larus.cpp new file mode 100644 index 00000000000..bb551271060 --- /dev/null +++ b/src/Device/Driver/Larus.cpp @@ -0,0 +1,415 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright The XCSoar Project + +/** +* see Documentation https://github.com/larus-breeze/doc_larus, +* for the driver you need https://github.com/larus-breeze/doc_larus/blob/master/documentation/Larus_NMEA_Protocol.md +* and an emulator is here https://github.com/larus-breeze/sw_tools +*/ + + +#include "Device/Driver/Larus.hpp" +#include "Device/Driver.hpp" +#include "Device/Port/Port.hpp" +#include "Device/Util/NMEAWriter.hpp" +#include "NMEA/Checksum.hpp" +#include "NMEA/Info.hpp" +#include "NMEA/Derived.hpp" +#include "NMEA/InputLine.hpp" +#include "Units/System.hpp" +#include "Operation/Operation.hpp" +#include "LogFile.hpp" +#include "util/StaticString.hxx" + +#include + +using std::string_view_literals::operator""sv; + +class LarusDevice : public AbstractDevice { + Port &port; + +public: + LarusDevice(Port &_port) : port(_port) {} + + bool ParseNMEA(const char *line, NMEAInfo &info) override; + bool PutMacCready(double mc, OperationEnvironment &env) override; + bool PutBugs(double bugs, OperationEnvironment &env) override; + bool PutBallast(double fraction, double overload, + OperationEnvironment &env) override; + bool PutQNH(const AtmosphericPressure &pres, + OperationEnvironment &env) override; + +private: + static bool PLARA(NMEAInputLine &line, NMEAInfo &info); + static bool PLARB(NMEAInputLine &line, NMEAInfo &info); + static bool PLARD(NMEAInputLine &line, NMEAInfo &info); + static bool PLARV(NMEAInputLine &line, NMEAInfo &info); + static bool PLARS(NMEAInputLine &line, NMEAInfo &info); + static bool PLARW(NMEAInputLine &line, NMEAInfo &info); + static bool HCHDT(NMEAInputLine &line, NMEAInfo &info); + +}; + +/** + * Parses non-negative floating-point angle value in degrees. + */ +static bool +ReadBearing(NMEAInputLine &line, Angle &value_r) +{ + double value; + if (!line.ReadChecked(value)) + return false; + + if (value < 0 || value > 360) + return false; + + value_r = Angle::Degrees(value).AsBearing(); + return true; +} + +bool +LarusDevice::ParseNMEA(const char *_line, NMEAInfo &info) +{ + if (!VerifyNMEAChecksum(_line)) + return false; + + NMEAInputLine line(_line); + const auto type = line.ReadView(); + if (type.starts_with("$PLAR"sv)) { + switch (type[5]) { + case 'A': + return PLARA(line, info); + case 'B': + return PLARB(line, info); + case 'D': + return PLARD(line, info); + case 'V': + return PLARV(line, info); + case 'W': + return PLARW(line, info); + case 'S': + return PLARS(line, info); + default: + break; + } + } + else if (type == "$HCHDT"sv) + return HCHDT(line, info); + + return false; +} + +bool +LarusDevice::HCHDT(NMEAInputLine &line, NMEAInfo &info) +{ + /* + * Heading sentence + * + * 1 2 3 + * | | | + * $HCHDT,x.x,a*hh + * + * State of Heading + * + * Field Number: + * 1) Heading + * 2) Type: (T)rue or (M)agnetic + * 3) Checksum + */ + double value; + if (line.ReadChecked(value)) { + if (value >= 0 && value <= 360) { + switch (line.ReadOneChar()) { + case 'T': + info.attitude.heading = Angle::Degrees(value); + info.attitude.heading_available.Update(info.clock); + return true; + case 'M': + default: + return false; // false means: an other (general) parser should look + } + } + } + return false; +} + +bool +LarusDevice::PLARA(NMEAInputLine &line, NMEAInfo &info) +{ + /* + * Attitude-Sentence + * + * 1 2 3 4 + * | | | | + * $PLARA,x.x,x.x,x.x*hh + * + * This sentence gives information about the current attitude. The different fields + * have the following meaning: + * + * Field Number: + * 1) Roll angle (positive while turning right) + * 2) Pitch angle (positive when nose up) + * 3) Yaw angle (true heading) + * 4) Checksum + */ + double value; + if (line.ReadChecked(value)) { + if (value >= -180 && value <= 180) { + info.attitude.bank_angle = Angle::Degrees(value); + info.attitude.bank_angle_available.Update(info.clock); + } + } + if (line.ReadChecked(value)) { + if (value >= -90 && value <= 90) { + info.attitude.pitch_angle = Angle::Degrees(value); + info.attitude.pitch_angle_available.Update(info.clock); + } + } + if (line.ReadChecked(value)) { + if (value >= 0 && value <= 360) { + info.attitude.heading = Angle::Degrees(value); + info.attitude.heading_available.Update(info.clock); + } + } + return true; +} + +bool +LarusDevice::PLARB(NMEAInputLine &line, NMEAInfo &info) +{ + /* + * Battery voltage sentence + * + * 1 2 + * | | + * $PLARB,xx.xx*hh + * + * Field Number: + * 1) battery voltage in Volt + * 2) Checksum + */ + double value; + if (line.ReadChecked(value)) { + if (value >= 0 && value <= 25) { + info.voltage = value; + info.voltage_available.Update(info.clock); + } + } + return true; +} + +bool +LarusDevice::PLARD([[maybe_unused]] NMEAInputLine &line, [[maybe_unused]] NMEAInfo &info) +{ + /* + * Instant air density sentence + * + * 1 2 3 + * | | | + * $PLARD,xxxx.x,a*hh + * + * This sentence gives information about the instant air density at the + * current altitude. The different fields have the following meaning: + * + * Field Number: + * 1) Instant air density in g/m^3. + * 2) a = (M)easured or (E)stimated + * 3) Checksum + */ + // XCSoar does not support that the air density is provided from the + // outside. + return true; +} + +bool +LarusDevice::PLARV(NMEAInputLine &line, NMEAInfo &info) +{ + /* + * $PLARV,x.x,x.x,x,x.x*hh + * + * Vario Data: TEK vario, average vario, height (std pressure) + * and speed (tas) + * + * Field Number: + * 1) Total Energy Variometer (TEK vario) + * 2) Average Climb Rate over one circle + * 3) Pressure Height + * 4) True Air Speed (TAS) + * 5) Checksum + */ + + double value; + // Parse total energy variometer + if (line.ReadChecked(value)) { + info.ProvideTotalEnergyVario( + Units::ToSysUnit(value, Unit::METER_PER_SECOND)); + } + + line.Skip(); + + // Parse barometric altitude + double altitude; // used in ProvideTrueAirspeedWithAltitude too + if (line.ReadChecked(altitude)) { + altitude = Units::ToSysUnit(altitude, Unit::METER); + info.ProvidePressureAltitude(altitude); + } + + // Parse true airspeed + if (line.ReadChecked(value)) + info.ProvideTrueAirspeedWithAltitude( + Units::ToSysUnit(value, Unit::KILOMETER_PER_HOUR), altitude + ); + + return true; +} + +bool +LarusDevice::PLARW(NMEAInputLine &line, NMEAInfo &info) +{ + /* + * $PLARW,x.x,x.x,t,v*hh + * + * Field Number: + * 1) wind angle + * 2) wind speed + * 3) t = (A)verage or (I)nstantaneous + * 4) v = Status A=valid + * 5) Checksum + */ + SpeedVector wind; + if (!ReadBearing(line, wind.bearing)) + return false; + + double windspeed; + if (!line.ReadChecked(windspeed)) + return false; + wind.norm = Units::ToSysUnit(windspeed, Unit::KILOMETER_PER_HOUR); + + switch (line.ReadOneChar()) { + case 'A': + info.ProvideExternalWind(wind); + break; + case 'I': + info.ProvideExternalInstantaneousWind(wind); + break; + default: + // xcsoar does not support instantaneous wind + return false; + } + + return true; +} + +/* +$PLARS Settings parameters bidirectional + + 1 2 3 4 + | | | | +$PLARS,a,a,xxx*hh + +Examples: +$PLARS,L,MC,1.3*1E +$PLARS,L,BAL,1.00*6B +$PLARS,L,BUGS,15*3B +$PLARS,L,QNH,1013.2*74 + +$PLARS,H,MC,2.1*1B +$PLARS,H,BAL,1.00*68 +$PLARS,H,BUGS,0*0B +$PLARS,H,QNH,1031.4*76 + +The $PLARS record is intended for exchanging setting values between Larus and a host system such as +XCSoar. The record can be used in both directions: from host to Larus or from Larus to host. + +These records should not be sent cyclically, but only when needed during initialization and when +changes are made. + + Data source (L: Larus, H: Host) + Settings parameter + MC MacCready (0.0 - 9.9) + BAL Ballast (0.00 - 1.00) + BUGS Bugs in % (0 - 50) + QNH QNH in hPa + Value (format depends on settings parameter, see examples) + Checksum +*/ +bool +LarusDevice::PLARS(NMEAInputLine &line, NMEAInfo &info) +{ // the line starts with the host indicator + if (line.ReadOneChar() == 'L') { + double value; + auto field = line.ReadView(); + if (line.ReadChecked(value)) { + if (field == "MC"sv) { + // - value is MacCReady in m/s [0.0 - 9.9] + return info.settings.ProvideMacCready(value, info.clock); + } else if (field == "BUGS"sv) { + // - value is bugs in % [0 - 50] + return info.settings.ProvideBugs(1.0 - value/100.0, info.clock); + } else if (field == "BAL"sv) { + // - value is ballast fraction [0.00 - 1.00] + return info.settings.ProvideBallastFraction(value, info.clock); + } else if (field == "QNH"sv) { + // - value is pressure in hPa + return info.settings.ProvideQNH(AtmosphericPressure::HectoPascal(value), info.clock); + } + } + } + return false; +} + +bool +LarusDevice::PutBugs(double bugs, OperationEnvironment &env) +{ + // $PLARS,H,BUGS,0*0B + char buffer[50]; + sprintf(buffer, "PLARS,H,BUGS,%0.0f", (1.0-bugs) * 100.0); + PortWriteNMEA(port, buffer, env); + return true; +} + +bool +LarusDevice::PutMacCready(double mc, OperationEnvironment &env) +{ + // $PLARS,H,MC,2.1*1B + char buffer[50]; + sprintf(buffer, "PLARS,H,MC,%0.1f", mc); + PortWriteNMEA(port, buffer, env); + return true; +} + +bool +LarusDevice::PutBallast(double fraction, [[maybe_unused]] double overload, + OperationEnvironment &env) +{ + // $PLARS,H,BAL,1.00*68 + char buffer[50]; + sprintf(buffer, "PLARS,H,BAL,%0.3f", fraction); + PortWriteNMEA(port, buffer, env); + return true; +} + +bool +LarusDevice::PutQNH(const AtmosphericPressure &pres, + OperationEnvironment &env) +{ + // $PLARS,H,QNH,1031.4*76 + char buffer[50]; + sprintf(buffer, "PLARS,H,QNH,%0.1f", pres.GetHectoPascal()); + PortWriteNMEA(port, buffer, env); + return true; +} + + +static Device * +LarusCreateOnPort([[maybe_unused]] const DeviceConfig &config, Port &com_port) +{ + return new LarusDevice(com_port); +} + +const struct DeviceRegister larus_driver = { + "Larus", + "Larus", + DeviceRegister::SEND_SETTINGS, + LarusCreateOnPort, +}; diff --git a/src/Device/Driver/Larus.hpp b/src/Device/Driver/Larus.hpp new file mode 100644 index 00000000000..3d362b3bc80 --- /dev/null +++ b/src/Device/Driver/Larus.hpp @@ -0,0 +1,26 @@ +/* +Copyright_License { + + XCSoar Glide Computer - http://www.xcsoar.org/ + Copyright (C) 2000-2022 The XCSoar Project + A detailed list of copyright holders can be found in the file "AUTHORS". + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +} +*/ + +#pragma once + +extern const struct DeviceRegister larus_driver; diff --git a/src/Device/Driver/Leonardo.cpp b/src/Device/Driver/Leonardo.cpp index 74139e9c4a3..e3aab49fdbe 100644 --- a/src/Device/Driver/Leonardo.cpp +++ b/src/Device/Driver/Leonardo.cpp @@ -190,8 +190,8 @@ LeonardoCreateOnPort([[maybe_unused]] const DeviceConfig &config, [[maybe_unused } const struct DeviceRegister leonardo_driver = { - _T("Leonardo"), - _T("Digifly Leonardo"), + "Leonardo", + "Digifly Leonardo", 0, LeonardoCreateOnPort, }; diff --git a/src/Device/Driver/LevilAHRS_G.cpp b/src/Device/Driver/LevilAHRS_G.cpp index 6d5066f1383..ec017f49e66 100644 --- a/src/Device/Driver/LevilAHRS_G.cpp +++ b/src/Device/Driver/LevilAHRS_G.cpp @@ -21,7 +21,7 @@ class LevilDevice : public AbstractDevice { static void ErrorMessage([[maybe_unused]] unsigned code) { - Message::AddMessage(_T("Levil AHRS: hardware error !")); + Message::AddMessage("Levil AHRS: hardware error !"); } static bool @@ -140,8 +140,8 @@ LevilCreateOnPort([[maybe_unused]] const DeviceConfig &config, [[maybe_unused]] } const struct DeviceRegister levil_driver = { - _T("Levil AHRS"), - _T("Levil AHRS"), + "Levil AHRS", + "Levil AHRS", 0, LevilCreateOnPort, }; diff --git a/src/Device/Driver/NmeaOut.cpp b/src/Device/Driver/NmeaOut.cpp index 705231ce6e5..57b384ea56b 100644 --- a/src/Device/Driver/NmeaOut.cpp +++ b/src/Device/Driver/NmeaOut.cpp @@ -5,8 +5,8 @@ #include "Device/Driver.hpp" const struct DeviceRegister nmea_out_driver = { - _T("NmeaOut"), - _T("NMEA output"), + "NmeaOut", + "NMEA output", DeviceRegister::NMEA_OUT|DeviceRegister::NO_TIMEOUT, nullptr, }; diff --git a/src/Device/Driver/OpenVario.cpp b/src/Device/Driver/OpenVario.cpp index ce0036e1dfe..d01485e327f 100644 --- a/src/Device/Driver/OpenVario.cpp +++ b/src/Device/Driver/OpenVario.cpp @@ -354,8 +354,8 @@ OpenVarioCreateOnPort([[maybe_unused]] const DeviceConfig &config, Port &com_por } const struct DeviceRegister open_vario_driver = { - _T("OpenVario"), - _T("OpenVario"), + "OpenVario", + "OpenVario", DeviceRegister::SEND_SETTINGS, OpenVarioCreateOnPort, }; diff --git a/src/Device/Driver/PosiGraph.cpp b/src/Device/Driver/PosiGraph.cpp index edbfe20f38a..7cc99d9bc59 100644 --- a/src/Device/Driver/PosiGraph.cpp +++ b/src/Device/Driver/PosiGraph.cpp @@ -62,8 +62,8 @@ PGCreateOnPort(const DeviceConfig &config, Port &com_port) } const struct DeviceRegister posigraph_driver = { - _T("PosiGraph Logger"), - _T("PosiGraph Logger"), + "PosiGraph Logger", + "PosiGraph Logger", DeviceRegister::DECLARE | DeviceRegister::BULK_BAUD_RATE | DeviceRegister::LOGGER, PGCreateOnPort, diff --git a/src/Device/Driver/ThermalExpress/Driver.cpp b/src/Device/Driver/ThermalExpress/Driver.cpp index a2c41a3ae4f..f77559cc8cc 100644 --- a/src/Device/Driver/ThermalExpress/Driver.cpp +++ b/src/Device/Driver/ThermalExpress/Driver.cpp @@ -43,8 +43,8 @@ ThermalExpressCreateOnPort([[maybe_unused]] const DeviceConfig &config, [[maybe_ } const struct DeviceRegister thermalexpress_driver = { - _T("ThermalExpress"), - _T("Thermal Express"), + "ThermalExpress", + "Thermal Express", 0, ThermalExpressCreateOnPort, }; diff --git a/src/Device/Driver/Vaulter.cpp b/src/Device/Driver/Vaulter.cpp index 4deee183f58..aa84ec5a289 100644 --- a/src/Device/Driver/Vaulter.cpp +++ b/src/Device/Driver/Vaulter.cpp @@ -164,8 +164,8 @@ VaulterCreateOnPort([[maybe_unused]] const DeviceConfig &config, Port &com_port) } const struct DeviceRegister vaulter_driver = { - _T("Vaulter"), - _T("WSI Vaulter"), + "Vaulter", + "WSI Vaulter", DeviceRegister::RECEIVE_SETTINGS | DeviceRegister::SEND_SETTINGS, VaulterCreateOnPort, }; diff --git a/src/Device/Driver/Vega/Parser.cpp b/src/Device/Driver/Vega/Parser.cpp index 662f2a91520..16d30edfb59 100644 --- a/src/Device/Driver/Vega/Parser.cpp +++ b/src/Device/Driver/Vega/Parser.cpp @@ -9,10 +9,6 @@ #include #include -#ifdef _UNICODE -#include -#endif - using std::string_view_literals::operator""sv; static bool @@ -189,7 +185,7 @@ PDTSM(NMEAInputLine &line, [[maybe_unused]] NMEAInfo &info) buffer.SetASCII(message); // todo duration handling - Message::AddMessage(_T("VEGA:"), buffer); + Message::AddMessage("VEGA:", buffer); return true; } diff --git a/src/Device/Driver/Vega/Register.cpp b/src/Device/Driver/Vega/Register.cpp index e1a4169a626..81617f2cd51 100644 --- a/src/Device/Driver/Vega/Register.cpp +++ b/src/Device/Driver/Vega/Register.cpp @@ -11,8 +11,8 @@ VegaCreateOnPort([[maybe_unused]] const DeviceConfig &config, Port &com_port) } const struct DeviceRegister vega_driver = { - _T("Vega"), - _T("Vega"), + "Vega", + "Vega", DeviceRegister::MANAGE | DeviceRegister::RECEIVE_SETTINGS | DeviceRegister::SEND_SETTINGS, VegaCreateOnPort, diff --git a/src/Device/Driver/Volkslogger/Declare.cpp b/src/Device/Driver/Volkslogger/Declare.cpp index 6ac47342e87..df3ad51c30a 100644 --- a/src/Device/Driver/Volkslogger/Declare.cpp +++ b/src/Device/Driver/Volkslogger/Declare.cpp @@ -9,30 +9,13 @@ #include "dbbconv.h" #include "Engine/Waypoint/Waypoint.hpp" -#ifdef _UNICODE -#include -#endif - #include static void -CopyToNarrowBuffer(char *dest, size_t max_size, const TCHAR *src) +CopyToNarrowBuffer(char *dest, size_t max_size, const char *src) { -#ifdef _UNICODE - size_t src_length = _tcslen(src); - if (src_length >= max_size) - src_length = max_size - 1; - - int dest_length = WideCharToMultiByte(CP_ACP, 0, src, src_length, - dest, max_size - 1, - nullptr, nullptr); - if (dest_length < 0) - dest_length = 0; - dest[dest_length] = 0; -#else strncpy(dest, src, max_size - 1); dest[max_size - 1] = 0; -#endif } static void diff --git a/src/Device/Driver/Volkslogger/Logger.cpp b/src/Device/Driver/Volkslogger/Logger.cpp index 2cc6133c1f3..f76834bf907 100644 --- a/src/Device/Driver/Volkslogger/Logger.cpp +++ b/src/Device/Driver/Volkslogger/Logger.cpp @@ -90,7 +90,7 @@ DownloadFlightInner(Port &port, unsigned bulkrate, if (length == 0) return false; - FILE *outfile = _tfopen(path.c_str(), _T("wt")); + FILE *outfile = _tfopen(path.c_str(), "wt"); if (outfile == nullptr) return false; diff --git a/src/Device/Driver/Volkslogger/Register.cpp b/src/Device/Driver/Volkslogger/Register.cpp index a7115630917..d85739b5497 100644 --- a/src/Device/Driver/Volkslogger/Register.cpp +++ b/src/Device/Driver/Volkslogger/Register.cpp @@ -23,8 +23,8 @@ VolksloggerCreateOnPort(const DeviceConfig &config, Port &com_port) } const struct DeviceRegister volkslogger_driver = { - _T("Volkslogger"), - _T("Volkslogger"), + "Volkslogger", + "Volkslogger", DeviceRegister::DECLARE | DeviceRegister::LOGGER | DeviceRegister::BULK_BAUD_RATE, VolksloggerCreateOnPort, diff --git a/src/Device/Driver/Westerboer.cpp b/src/Device/Driver/Westerboer.cpp index d1139bb6f76..323f1792620 100644 --- a/src/Device/Driver/Westerboer.cpp +++ b/src/Device/Driver/Westerboer.cpp @@ -172,8 +172,8 @@ WesterboerCreateOnPort([[maybe_unused]] const DeviceConfig &config, Port &com_po } const struct DeviceRegister westerboer_driver = { - _T("Westerboer VW1150"), - _T("Westerboer VW1150"), + "Westerboer VW1150", + "Westerboer VW1150", DeviceRegister::RECEIVE_SETTINGS | DeviceRegister::SEND_SETTINGS, WesterboerCreateOnPort, }; diff --git a/src/Device/Driver/XCOM760.cpp b/src/Device/Driver/XCOM760.cpp index 62415b6edf3..ead0304e7fd 100644 --- a/src/Device/Driver/XCOM760.cpp +++ b/src/Device/Driver/XCOM760.cpp @@ -18,10 +18,10 @@ class XCOM760Device : public AbstractDevice { /* virtual methods from class Device */ bool PutVolume(unsigned volume, OperationEnvironment &env) override; bool PutActiveFrequency(RadioFrequency frequency, - const TCHAR *name, + const char *name, OperationEnvironment &env) override; bool PutStandbyFrequency(RadioFrequency frequency, - const TCHAR *name, + const char *name, OperationEnvironment &env) override; }; @@ -36,7 +36,7 @@ XCOM760Device::PutVolume(unsigned volume, OperationEnvironment &env) bool XCOM760Device::PutActiveFrequency(RadioFrequency frequency, - [[maybe_unused]] const TCHAR *name, + [[maybe_unused]] const char *name, OperationEnvironment &env) { char szTmp[32]; @@ -49,7 +49,7 @@ XCOM760Device::PutActiveFrequency(RadioFrequency frequency, bool XCOM760Device::PutStandbyFrequency(RadioFrequency frequency, - [[maybe_unused]] const TCHAR *name, + [[maybe_unused]] const char *name, OperationEnvironment &env) { char szTmp[32]; @@ -67,8 +67,8 @@ XCOM760CreateOnPort([[maybe_unused]] const DeviceConfig &config, Port &com_port) } const struct DeviceRegister xcom760_driver = { - _T("XCOM760"), - _T("XCOM760"), + "XCOM760", + "XCOM760", DeviceRegister::NO_TIMEOUT | DeviceRegister::SEND_SETTINGS, XCOM760CreateOnPort, }; diff --git a/src/Device/Driver/XCTracer/Register.cpp b/src/Device/Driver/XCTracer/Register.cpp index adf0094e0f4..cbeaa490773 100644 --- a/src/Device/Driver/XCTracer/Register.cpp +++ b/src/Device/Driver/XCTracer/Register.cpp @@ -11,8 +11,8 @@ XCTracerCreateOnPort([[maybe_unused]] const DeviceConfig &config, [[maybe_unused } const struct DeviceRegister xctracer_driver = { - _T("XCTracer"), - _T("XC-Tracer Vario"), + "XCTracer", + "XC-Tracer Vario", 0, XCTracerCreateOnPort, }; diff --git a/src/Device/Driver/XCVario.cpp b/src/Device/Driver/XCVario.cpp index b3af31ce5e0..f70f5ae9be7 100644 --- a/src/Device/Driver/XCVario.cpp +++ b/src/Device/Driver/XCVario.cpp @@ -299,8 +299,8 @@ XVCCreateOnPort([[maybe_unused]] const DeviceConfig &config, Port &com_port) } const struct DeviceRegister xcv_driver = { - _T("XCVario"), - _T("XCVario"), + "XCVario", + "XCVario", DeviceRegister::RECEIVE_SETTINGS | DeviceRegister::SEND_SETTINGS, XVCCreateOnPort, }; diff --git a/src/Device/Driver/Zander.cpp b/src/Device/Driver/Zander.cpp index 951edae745e..8dd9a761d69 100644 --- a/src/Device/Driver/Zander.cpp +++ b/src/Device/Driver/Zander.cpp @@ -142,8 +142,8 @@ ZanderCreateOnPort([[maybe_unused]] const DeviceConfig &config, [[maybe_unused]] } const struct DeviceRegister zander_driver = { - _T("Zander"), - _T("Zander / SDI"), + "Zander", + "Zander / SDI", DeviceRegister::RECEIVE_SETTINGS, ZanderCreateOnPort, }; diff --git a/src/Device/MultipleDevices.cpp b/src/Device/MultipleDevices.cpp index 8eab36e48bd..d2b4fd91cb8 100644 --- a/src/Device/MultipleDevices.cpp +++ b/src/Device/MultipleDevices.cpp @@ -67,7 +67,7 @@ MultipleDevices::HasVega() const noexcept } void -MultipleDevices::VegaWriteNMEA(const TCHAR *text, +MultipleDevices::VegaWriteNMEA(const char *text, OperationEnvironment &env) noexcept { for (DeviceDescriptor *i : devices) @@ -114,7 +114,7 @@ MultipleDevices::PutPilotEvent(OperationEnvironment &env) noexcept void MultipleDevices::PutActiveFrequency(RadioFrequency frequency, - const TCHAR *name, + const char *name, OperationEnvironment &env) noexcept { for (DeviceDescriptor *i : devices) @@ -123,7 +123,7 @@ MultipleDevices::PutActiveFrequency(RadioFrequency frequency, void MultipleDevices::PutStandbyFrequency(RadioFrequency frequency, - const TCHAR *name, + const char *name, OperationEnvironment &env) noexcept { for (DeviceDescriptor *i : devices) diff --git a/src/Device/MultipleDevices.hpp b/src/Device/MultipleDevices.hpp index fd627f4a464..f7a4c73a453 100644 --- a/src/Device/MultipleDevices.hpp +++ b/src/Device/MultipleDevices.hpp @@ -70,7 +70,7 @@ class MultipleDevices final : PortListener { [[gnu::pure]] bool HasVega() const noexcept; - void VegaWriteNMEA(const TCHAR *text, OperationEnvironment &env) noexcept; + void VegaWriteNMEA(const char *text, OperationEnvironment &env) noexcept; void PutMacCready(double mac_cready, OperationEnvironment &env) noexcept; void PutBugs(double bugs, OperationEnvironment &env) noexcept; @@ -78,9 +78,9 @@ class MultipleDevices final : PortListener { OperationEnvironment &env) noexcept; void PutVolume(unsigned volume, OperationEnvironment &env) noexcept; void PutPilotEvent(OperationEnvironment &env) noexcept; - void PutActiveFrequency(RadioFrequency frequency, const TCHAR *name, + void PutActiveFrequency(RadioFrequency frequency, const char *name, OperationEnvironment &env) noexcept; - void PutStandbyFrequency(RadioFrequency frequency, const TCHAR *name, + void PutStandbyFrequency(RadioFrequency frequency, const char *name, OperationEnvironment &env) noexcept; void PutTransponderCode(TransponderCode code, OperationEnvironment &env) noexcept; void PutQNH(AtmosphericPressure pres, OperationEnvironment &env) noexcept; diff --git a/src/Device/Port/AndroidBluetoothPort.cpp b/src/Device/Port/AndroidBluetoothPort.cpp index 57c179a8392..87ff5ebb357 100644 --- a/src/Device/Port/AndroidBluetoothPort.cpp +++ b/src/Device/Port/AndroidBluetoothPort.cpp @@ -10,7 +10,7 @@ std::unique_ptr OpenAndroidBluetoothPort(BluetoothHelper &bluetooth_helper, - const TCHAR *address, PortListener *listener, + const char *address, PortListener *listener, DataHandler &handler) { assert(address != nullptr); @@ -31,7 +31,7 @@ OpenAndroidBluetoothServerPort(BluetoothHelper &bluetooth_helper, std::unique_ptr OpenAndroidBleHm10Port(BluetoothHelper &bluetooth_helper, - const TCHAR *address, PortListener *listener, + const char *address, PortListener *listener, DataHandler &handler) { assert(address != nullptr); diff --git a/src/Device/Port/AndroidBluetoothPort.hpp b/src/Device/Port/AndroidBluetoothPort.hpp index 43092828722..59ff9124773 100644 --- a/src/Device/Port/AndroidBluetoothPort.hpp +++ b/src/Device/Port/AndroidBluetoothPort.hpp @@ -15,7 +15,7 @@ class DataHandler; std::unique_ptr OpenAndroidBluetoothPort(BluetoothHelper &bluetooth_helper, - const TCHAR *address, PortListener *_listener, + const char *address, PortListener *_listener, DataHandler &_handler); std::unique_ptr @@ -24,5 +24,5 @@ OpenAndroidBluetoothServerPort(BluetoothHelper &bluetooth_helper, std::unique_ptr OpenAndroidBleHm10Port(BluetoothHelper &bluetooth_helper, - const TCHAR *address, PortListener *_listener, + const char *address, PortListener *_listener, DataHandler &_handler); diff --git a/src/Device/Port/AndroidIOIOUartPort.hpp b/src/Device/Port/AndroidIOIOUartPort.hpp index c3d9ac6626a..90297ace2f6 100644 --- a/src/Device/Port/AndroidIOIOUartPort.hpp +++ b/src/Device/Port/AndroidIOIOUartPort.hpp @@ -17,18 +17,18 @@ namespace AndroidIOIOUartPort { static inline unsigned getNumberUarts() { return 4; } - static inline const TCHAR *getPortHelp(unsigned UartID) { + static inline const char *getPortHelp(unsigned UartID) { switch (UartID) { case 0: - return _T("IOIO external board Uart: pin3=out, pin4=in"); + return "IOIO external board Uart: pin3=out, pin4=in"; case 1: - return _T("IOIO external board Uart: pin5=out, pin6=in"); + return "IOIO external board Uart: pin5=out, pin6=in"; case 2: - return _T("IOIO external board Uart: pin10=out, pin11=in"); + return "IOIO external board Uart: pin10=out, pin11=in"; case 3: - return _T("IOIO external board Uart: pin12=out, pin13=in"); + return "IOIO external board Uart: pin12=out, pin13=in"; default: - return _T("Illegal IOIO Uart ID"); + return "Illegal IOIO Uart ID"; } } } diff --git a/src/Device/Port/ConfiguredPort.cpp b/src/Device/Port/ConfiguredPort.cpp index 245d60f6c51..2cfe12dc181 100644 --- a/src/Device/Port/ConfiguredPort.cpp +++ b/src/Device/Port/ConfiguredPort.cpp @@ -7,7 +7,6 @@ #include "K6BtPort.hpp" #include "Device/Config.hpp" #include "LogFile.hpp" -#include "util/ConvertString.hpp" #include "TCPClientPort.hpp" #ifdef ANDROID @@ -42,7 +41,7 @@ * See http://msdn.microsoft.com/en-us/library/bb202042.aspx */ static bool -DetectGPS([[maybe_unused]] TCHAR *path, [[maybe_unused]] std::size_t path_max_size) +DetectGPS([[maybe_unused]] char *path, [[maybe_unused]] std::size_t path_max_size) { return false; } @@ -63,6 +62,18 @@ WrapPort(const DeviceConfig &config, PortListener *listener, return port; } +#if defined(_WIN32) +static const char * +WindowsPort(char buffer[], const DeviceConfig &config) { + if (config.path.empty()) + throw std::runtime_error("No port path configured"); + + // the usual windows style of device names: + strcpy(buffer, "\\\\.\\"); + strcat(buffer, config.path.c_str());return buffer; +} +#endif + static std::unique_ptr OpenPortInternal(EventLoop &event_loop, Cares::Channel &cares, #ifdef ANDROID @@ -73,8 +84,8 @@ OpenPortInternal(EventLoop &event_loop, Cares::Channel &cares, const DeviceConfig &config, PortListener *listener, DataHandler &handler) { - const TCHAR *path = nullptr; - TCHAR buffer[MAX_PATH]; + const char *path = nullptr; + char buffer[MAX_PATH]; switch (config.port_type) { case DeviceConfig::PortType::DISABLED: @@ -84,7 +95,11 @@ OpenPortInternal(EventLoop &event_loop, Cares::Channel &cares, if (config.path.empty()) throw std::runtime_error("No port path configured"); +#ifdef _WIN32 + path = WindowsPort(buffer, config); +#else path = config.path.c_str(); +#endif break; case DeviceConfig::PortType::BLE_HM10: @@ -98,10 +113,14 @@ OpenPortInternal(EventLoop &event_loop, Cares::Channel &cares, return OpenAndroidBleHm10Port(*bluetooth_helper, config.bluetooth_mac, listener, handler); +#elif defined (_WIN32) + path = WindowsPort(buffer, config); + break; #else throw std::runtime_error("Bluetooth not available"); #endif + case DeviceConfig::PortType::BLE_SENSOR: case DeviceConfig::PortType::RFCOMM: #ifdef ANDROID if (config.bluetooth_mac.empty()) @@ -112,6 +131,9 @@ OpenPortInternal(EventLoop &event_loop, Cares::Channel &cares, return OpenAndroidBluetoothPort(*bluetooth_helper, config.bluetooth_mac, listener, handler); +#elif defined(_WIN32) + path = WindowsPort(buffer, config); + break; #else throw std::runtime_error("Bluetooth not available"); #endif @@ -145,13 +167,13 @@ OpenPortInternal(EventLoop &event_loop, Cares::Channel &cares, if (!DetectGPS(buffer, sizeof(buffer))) throw std::runtime_error("No GPS detected"); - LogFormat(_T("GPS detected: %s"), buffer); + LogFormat("GPS detected: %s", buffer); path = buffer; break; case DeviceConfig::PortType::INTERNAL: - case DeviceConfig::PortType::BLE_SENSOR: +// case DeviceConfig::PortType::BLE_SENSOR: case DeviceConfig::PortType::DROIDSOAR_V2: case DeviceConfig::PortType::NUNCHUCK: case DeviceConfig::PortType::I2CPRESSURESENSOR: @@ -160,12 +182,11 @@ OpenPortInternal(EventLoop &event_loop, Cares::Channel &cares, break; case DeviceConfig::PortType::TCP_CLIENT: { - const WideToUTF8Converter ip_address(config.ip_address); - if (!ip_address.IsValid()) + if (config.ip_address.empty()) throw std::runtime_error("No IP address configured"); - return std::make_unique(event_loop, cares, - ip_address, config.tcp_port, + return std::make_unique(event_loop, cares, config.ip_address, + config.tcp_port, listener, handler); } @@ -201,7 +222,7 @@ OpenPortInternal(EventLoop &event_loop, Cares::Channel &cares, #endif } - case DeviceConfig::PortType::ANDROID_USB_SERIAL: + case DeviceConfig::PortType::USB_SERIAL: #ifdef ANDROID if (config.path.empty()) throw std::runtime_error("No name configured"); @@ -212,6 +233,14 @@ OpenPortInternal(EventLoop &event_loop, Cares::Channel &cares, return OpenAndroidUsbSerialPort(*usb_serial_helper, config.path.c_str(), config.baud_rate, listener, handler); +#elif defined(_WIN32) + if (config.path.empty()) + throw std::runtime_error("No port path configured"); + + // the usual windows style of device names: + strcpy(buffer, "\\\\.\\"); + strcat(buffer, config.path.c_str()); + path = buffer; #else throw std::runtime_error("Android USB serial not available"); #endif diff --git a/src/Device/Port/DumpPort.cpp b/src/Device/Port/DumpPort.cpp index 971f1a74926..df25b21f308 100644 --- a/src/Device/Port/DumpPort.cpp +++ b/src/Device/Port/DumpPort.cpp @@ -8,6 +8,8 @@ #include #include +using std::string_view_literals::operator""sv; + #ifdef __clang__ /* true, the nullptr cast below is a bad kludge */ #pragma GCC diagnostic ignored "-Wnull-dereference" @@ -58,10 +60,15 @@ DumpPort::Write(std::span src) std::size_t nbytes; try { nbytes = port->Write(src); - } catch (...) { - if (enabled) - LogFmt("Write({})=error", src.size()); - throw; +// } catch (...) { + } catch (std::exception &e) { + if (e.what() == "Port is closed"sv) { + return 0; + } else { + if (enabled) + LogFmt("Write({})=error", src.size()); + throw; + } } if (enabled) { diff --git a/src/Device/Port/Port.cpp b/src/Device/Port/Port.cpp index 0db8ea97638..9b73bb64442 100644 --- a/src/Device/Port/Port.cpp +++ b/src/Device/Port/Port.cpp @@ -13,6 +13,13 @@ #include #include +#include + +#if defined(__MSVC__) && defined(_DEBUG) +# include +# include +#endif + Port::Port(PortListener *_listener, DataHandler &_handler) noexcept :listener(_listener), handler(_handler) {} @@ -43,6 +50,29 @@ Port::FullWrite(std::span src, std::chrono::steady_clock::duration _timeout) { const TimeoutClock timeout(_timeout); +#ifdef TEST_AUG // 06.08.2023 +#ifdef _DEBUG // TODO(August2111) + int iLoop = 0; +#endif + const char *p = (const char *)buffer, *end = p + length; + while (p < end) { +#ifdef _DEBUG + iLoop++; // TODO(August2111) +#endif + if (timeout.HasExpired()) + throw DeviceTimeout{"Port write timeout"}; + + std::size_t nbytes = Write(p, end - p); +#if defined(__MSVC__) && defined(_DEBUG) + if (nbytes == 0) { + // August2111: Wie kann p < end sein und bei Write(p, end - p) nur 0 + // herauskommen + auto error = GetLastError(); + std::cout << "Error: " << error << std ::endl; + break; // TODO(August2111) + } +#endif +#endif while (!src.empty()) { if (timeout.HasExpired()) diff --git a/src/Device/Port/SerialPort.cpp b/src/Device/Port/SerialPort.cpp index 46f22a11c81..0874833b9a5 100644 --- a/src/Device/Port/SerialPort.cpp +++ b/src/Device/Port/SerialPort.cpp @@ -34,7 +34,7 @@ SerialPort::~SerialPort() noexcept } void -SerialPort::Open(const TCHAR *path, unsigned _baud_rate) +SerialPort::Open(const char *path, unsigned _baud_rate) { assert(!Thread::IsInside()); @@ -50,8 +50,12 @@ SerialPort::Open(const TCHAR *path, unsigned _baud_rate) nullptr); // Handle to port with attribute to copy // If it fails to open the port, return false. - if (hPort == INVALID_HANDLE_VALUE) + if (hPort == INVALID_HANDLE_VALUE) { +#ifdef _DEBUG + auto error = GetLastError(); +#endif throw MakeLastError("Failed to open serial port"); + } baud_rate = _baud_rate; diff --git a/src/Device/Port/SerialPort.hpp b/src/Device/Port/SerialPort.hpp index c4ba3a54ab9..64f6391e8b8 100644 --- a/src/Device/Port/SerialPort.hpp +++ b/src/Device/Port/SerialPort.hpp @@ -38,7 +38,7 @@ class SerialPort : public BufferedPort, protected StoppableThread * * Throws on error. */ - void Open(const TCHAR *path, unsigned baud_rate); + void Open(const char *path, unsigned baud_rate); protected: bool SetRxTimeout(unsigned Timeout); diff --git a/src/Device/Port/TTYPort.cpp b/src/Device/Port/TTYPort.cpp index 1e34690ba79..13c1f740945 100644 --- a/src/Device/Port/TTYPort.cpp +++ b/src/Device/Port/TTYPort.cpp @@ -164,7 +164,7 @@ TTYPort::Drain() } void -TTYPort::Open(const TCHAR *path, unsigned baud_rate) +TTYPort::Open(const char *path, unsigned baud_rate) { auto fd = OpenTTY(path, baud_rate); ::SetBaudrate(TTYDescriptor(fd), baud_rate); diff --git a/src/Device/Port/TTYPort.hpp b/src/Device/Port/TTYPort.hpp index 18267304d52..6b6488bd041 100644 --- a/src/Device/Port/TTYPort.hpp +++ b/src/Device/Port/TTYPort.hpp @@ -38,7 +38,7 @@ class TTYPort : public BufferedPort * * Throws on error. */ - void Open(const TCHAR *path, unsigned baud_rate); + void Open(const char *path, unsigned baud_rate); /** * Opens this object with a new pseudo-terminal. This is only used diff --git a/src/Device/Register.cpp b/src/Device/Register.cpp index 5e896e54113..bdbefdfe340 100644 --- a/src/Device/Register.cpp +++ b/src/Device/Register.cpp @@ -4,6 +4,7 @@ #include "Device/Register.hpp" #include "Device/Driver.hpp" #include "Device/Driver/AirControlDisplay.hpp" +#include "Device/Driver/Anemoi.hpp" #include "Device/Driver/CAI302.hpp" #include "Device/Driver/CaiGpsNav.hpp" #include "Device/Driver/CaiLNav.hpp" @@ -35,10 +36,13 @@ #include "Device/Driver/LevilAHRS_G.hpp" #include "Device/Driver/BlueFlyVario.hpp" #include "Device/Driver/OpenVario.hpp" +#include "Device/Driver/FreeVario.hpp" +#include "Device/Driver/Larus.hpp" #include "Device/Driver/Vaulter.hpp" #include "Device/Driver/ATR833/Register.hpp" #include "Device/Driver/XCTracer.hpp" #include "Device/Driver/KRT2.hpp" +#include "Device/Driver/AR62xx.hpp" #include "util/Macros.hpp" #include "util/StringAPI.hxx" @@ -68,6 +72,7 @@ static const struct DeviceRegister *const driver_list[] = { &flytec_driver, &ilec_driver, &westerboer_driver, + &larus_driver, &imi_driver, &flarm_driver, &flynet_driver, @@ -77,12 +82,15 @@ static const struct DeviceRegister *const driver_list[] = { &bluefly_driver, &cai_lnav_driver, &open_vario_driver, + &free_vario_driver, &vaulter_driver, &krt2_driver, &atr833_driver, &xctracer_driver, &thermalexpress_driver, &acd_driver, + &anemoi_driver, + &ar62xx_driver, nullptr }; @@ -95,7 +103,7 @@ GetDriverByIndex(unsigned i) } const struct DeviceRegister * -FindDriverByName(const TCHAR *name) +FindDriverByName(const char *name) { for (auto i = driver_list; *i != nullptr; ++i) { const DeviceRegister &driver = **i; @@ -106,8 +114,8 @@ FindDriverByName(const TCHAR *name) return driver_list[0]; } -const TCHAR * -FindDriverDisplayName(const TCHAR *name) +const char * +FindDriverDisplayName(const char *name) { assert(name != nullptr); diff --git a/src/Device/Register.hpp b/src/Device/Register.hpp index 904d04b7bfd..4482b1c992a 100644 --- a/src/Device/Register.hpp +++ b/src/Device/Register.hpp @@ -18,12 +18,12 @@ GetDriverByIndex(unsigned i); [[gnu::pure]] const DeviceRegister * -FindDriverByName(const TCHAR *name); +FindDriverByName(const char *name); /** * Find the driver with the specified name, and return its display * name. If no such driver was found, the specified name is returned. */ [[gnu::pure]] -const TCHAR * -FindDriverDisplayName(const TCHAR *name); +const char * +FindDriverDisplayName(const char *name); diff --git a/src/Device/Util/NMEAReader.cpp b/src/Device/Util/NMEAReader.cpp index 8b4344a043e..a3a18af6e0d 100644 --- a/src/Device/Util/NMEAReader.cpp +++ b/src/Device/Util/NMEAReader.cpp @@ -50,7 +50,12 @@ PortNMEAReader::GetLine() /* verify the checksum following the asterisk (two hex digits) */ +#if defined(__APPLE__) && (!defined(TARGET_OS_IPHONE) || !TARGET_OS_IPHONE) + // MacOS workaround + const uint8_t calculated_checksum = NMEAChecksum(start); +#else // MacOS const uint8_t calculated_checksum = NMEAChecksum({start, asterisk}); +#endif // MacOS const char checksum_buffer[3] = { asterisk[1], asterisk[2], 0 }; char *endptr; diff --git a/src/Device/device.cpp b/src/Device/device.cpp index 48b4490bc77..a3533573732 100644 --- a/src/Device/device.cpp +++ b/src/Device/device.cpp @@ -33,13 +33,17 @@ DeviceConfigOverlaps(const DeviceConfig &a, const DeviceConfig &b) switch (a.port_type) { case DeviceConfig::PortType::SERIAL: case DeviceConfig::PortType::PTY: - case DeviceConfig::PortType::ANDROID_USB_SERIAL: return a.path.equals(b.path); + case DeviceConfig::PortType::USB_SERIAL: case DeviceConfig::PortType::RFCOMM: case DeviceConfig::PortType::BLE_HM10: case DeviceConfig::PortType::BLE_SENSOR: +#ifdef _WIN32 + return a.port_name.equals(b.port_name); +#else return a.bluetooth_mac.equals(b.bluetooth_mac); +#endif case DeviceConfig::PortType::IOIOUART: return a.ioio_uart_id == b.ioio_uart_id; diff --git a/src/Dialogs/Airspace/AirspaceCRendererSettingsPanel.cpp b/src/Dialogs/Airspace/AirspaceCRendererSettingsPanel.cpp index 241284335b2..8dd6954a17b 100644 --- a/src/Dialogs/Airspace/AirspaceCRendererSettingsPanel.cpp +++ b/src/Dialogs/Airspace/AirspaceCRendererSettingsPanel.cpp @@ -65,7 +65,7 @@ AirspaceClassRendererSettingsPanel::Prepare(ContainerWindow &parent, AddInteger(_("Border Width"), _("The width of the border drawn around each airspace. " "Set this value to zero to hide the border."), - _T("%d"), _T("%d"), 0, 5, 1, settings.border_width); + "%d", "%d", 0, 5, 1, settings.border_width); static constexpr StaticEnumChoice fill_mode_list[] = { { AirspaceClassRendererSettings::FillMode::ALL, N_("Filled"), }, diff --git a/src/Dialogs/Airspace/AirspaceList.cpp b/src/Dialogs/Airspace/AirspaceList.cpp index a57f35d32cc..7fb79980787 100644 --- a/src/Dialogs/Airspace/AirspaceList.cpp +++ b/src/Dialogs/Airspace/AirspaceList.cpp @@ -148,22 +148,22 @@ static GeoPoint location; static Angle last_heading; static constexpr StaticEnumChoice type_filter_list[] = { - { WILDCARD, _T("*") }, - { OTHER, _T("Other") }, - { RESTRICT, _T("Restricted areas") }, - { PROHIBITED, _T("Prohibited areas") }, - { DANGER, _T("Danger areas") }, - { CLASSA, _T("Class A") }, - { CLASSB, _T("Class B") }, - { CLASSC, _T("Class C") }, - { CLASSD, _T("Class D") }, - { NOGLIDER, _T("No gliders") }, - { CTR, _T("CTR") }, - { WAVE, _T("Wave") }, - { CLASSE, _T("Class E") }, - { CLASSF, _T("Class F") }, - { TMZ, _T("TMZ") }, - { MATZ, _T("MATZ") }, + { WILDCARD, "*" }, + { OTHER, "Other" }, + { RESTRICT, "Restricted areas" }, + { PROHIBITED, "Prohibited areas" }, + { DANGER, "Danger areas" }, + { CLASSA, "Class A" }, + { CLASSB, "Class B" }, + { CLASSC, "Class C" }, + { CLASSD, "Class D" }, + { NOGLIDER, "No gliders" }, + { CTR, "CTR" }, + { WAVE, "Wave" }, + { CLASSE, "Class E" }, + { CLASSF, "Class F" }, + { TMZ, "TMZ" }, + { MATZ, "MATZ" }, nullptr }; @@ -206,7 +206,7 @@ AirspaceListWidget::UpdateList() if (dialog_state.type != WILDCARD) data.cls = (AirspaceClass)dialog_state.type; - const TCHAR *name_filter = filter_widget.GetValueString(NAME); + const char *name_filter = filter_widget.GetValueString(NAME); if (!StringIsEmpty(name_filter)) data.name_prefix = name_filter; @@ -248,7 +248,7 @@ AirspaceListWidget::FilterMode(bool direction) filter_widget.LoadValueEnum(DISTANCE, WILDCARD); filter_widget.LoadValueEnum(DIRECTION, WILDCARD); } else { - filter_widget.LoadValue(NAME, _T("")); + filter_widget.LoadValue(NAME, ""); } } @@ -297,14 +297,14 @@ AirspaceListWidget::OnPaintItem(Canvas &canvas, const PixelRect rc, } [[gnu::pure]] -static const TCHAR * -GetHeadingString(TCHAR *buffer) +static const char * +GetHeadingString(char *buffer) { - TCHAR heading[32]; + char heading[32]; FormatBearing(heading, ARRAY_SIZE(heading), CommonInterface::Basic().attitude.heading); - StringFormatUnsafe(buffer, _T("%s (%s)"), _("Heading"), heading); + StringFormatUnsafe(buffer, "%s (%s)", _("Heading"), heading); return buffer; } @@ -330,7 +330,7 @@ AirspaceFilterWidget::Update() DataFieldEnum &direction_df = *(DataFieldEnum *) direction_control.GetDataField(); - TCHAR buffer[64]; + char buffer[64]; direction_df.replaceEnumText(0, GetHeadingString(buffer)); direction_control.RefreshDisplay(); } @@ -338,16 +338,16 @@ AirspaceFilterWidget::Update() static void FillDistanceEnum(DataFieldEnum &df) { - df.AddChoice(0, _T("*")); + df.AddChoice(0, "*"); static constexpr unsigned distances[] = { 25, 50, 75, 100, 150, 250, 500, 1000 }; - TCHAR buffer[64]; - const TCHAR *unit = Units::GetDistanceName(); + char buffer[64]; + const char *unit = Units::GetDistanceName(); for (unsigned i = 0; i < ARRAY_SIZE(distances); ++i) { - StringFormatUnsafe(buffer, _T("%u %s"), distances[i], unit); + StringFormatUnsafe(buffer, "%u %s", distances[i], unit); df.AddChoice(distances[i], buffer); } @@ -357,9 +357,9 @@ FillDistanceEnum(DataFieldEnum &df) static void FillDirectionEnum(DataFieldEnum &df) { - TCHAR buffer[64]; + char buffer[64]; - df.AddChoice(WILDCARD, _T("*")); + df.AddChoice(WILDCARD, "*"); df.AddChoice(0, GetHeadingString(buffer)); static constexpr unsigned directions[] = { @@ -375,7 +375,7 @@ FillDirectionEnum(DataFieldEnum &df) static DataField * CreateNameDataField(DataFieldListener *listener) { - return new PrefixDataField(_T(""), listener); + return new PrefixDataField("", listener); } static DataField * diff --git a/src/Dialogs/Airspace/dlgAirspace.cpp b/src/Dialogs/Airspace/dlgAirspace.cpp index cc6ea4be7df..14d52da0be8 100644 --- a/src/Dialogs/Airspace/dlgAirspace.cpp +++ b/src/Dialogs/Airspace/dlgAirspace.cpp @@ -70,7 +70,7 @@ AirspaceSettingsListWidget::OnPaintItem(Canvas &canvas, PixelRect rc, CommonInterface::GetMapSettings().airspace; const AirspaceLook &look = CommonInterface::main_window->GetLook().map.airspace; - const TCHAR *const name = AirspaceFormatter::GetClass((AirspaceClass)i); + const char *const name = AirspaceFormatter::GetClass((AirspaceClass)i); if (color_mode) { int second_x = row_renderer.NextColumn(canvas, rc, name); diff --git a/src/Dialogs/Airspace/dlgAirspaceDetails.cpp b/src/Dialogs/Airspace/dlgAirspaceDetails.cpp index e32bc8bb15a..b31b8534d98 100644 --- a/src/Dialogs/Airspace/dlgAirspaceDetails.cpp +++ b/src/Dialogs/Airspace/dlgAirspaceDetails.cpp @@ -50,7 +50,7 @@ AirspaceDetailsWidget::Prepare([[maybe_unused]] ContainerWindow &parent, if (airspace->GetRadioFrequency().Format(buffer.data(), buffer.capacity()) != nullptr) { - buffer += _T(" MHz"); + buffer += " MHz"; AddReadOnly(_("Radio"), nullptr, buffer); AddButton(_("Set Active Frequency"), [this](){ diff --git a/src/Dialogs/Airspace/dlgAirspaceWarnings.cpp b/src/Dialogs/Airspace/dlgAirspaceWarnings.cpp index 8b42dc7b6d5..f102fa2353f 100644 --- a/src/Dialogs/Airspace/dlgAirspaceWarnings.cpp +++ b/src/Dialogs/Airspace/dlgAirspaceWarnings.cpp @@ -269,7 +269,7 @@ AirspaceWarningListWidget::OnPaintItem(Canvas &canvas, const PixelRect paint_rc, unsigned i) noexcept { - TCHAR buffer[128]; + char buffer[128]; // This constant defines the margin that should be respected // for renderring within the paint_rc area. @@ -290,9 +290,9 @@ AirspaceWarningListWidget::OnPaintItem(Canvas &canvas, // word "inside" is used as the etalon, because it is longer than "near" and // currently (9.4.2011) there is no other possibility for the status text. - const int status_width = canvas.CalcTextWidth(_T("inside")); + const int status_width = canvas.CalcTextWidth("inside"); // "1888" is used in order to have enough space for 4-digit heights with "AGL" - const int altitude_width = canvas.CalcTextWidth(_T("1888 m AGL")); + const int altitude_width = canvas.CalcTextWidth("1888 m AGL"); // Dynamic columns scaling - "name" column is flexible, altitude and state // columns are fixed-width. @@ -306,7 +306,7 @@ AirspaceWarningListWidget::OnPaintItem(Canvas &canvas, canvas.SetTextColor(COLOR_GRAY); { // name, altitude info - StringFormat(buffer, ARRAY_SIZE(buffer), _T("%s %s"), + StringFormat(buffer, ARRAY_SIZE(buffer), "%s %s", airspace.GetName(), AirspaceFormatter::GetClass(airspace)); @@ -322,19 +322,19 @@ AirspaceWarningListWidget::OnPaintItem(Canvas &canvas, if (const auto &solution = warning.GetSolution(); warning.IsWarning() && !warning.IsInside() && solution.IsValid()) { - _stprintf(buffer, _T("%d secs"), + _stprintf(buffer, "%d secs", (int)solution.elapsed_time.count()); if (solution.distance > 0) - _stprintf(buffer + _tcslen(buffer), _T(" dist %d m"), + _stprintf(buffer + strlen(buffer), " dist %d m", (int)solution.distance); else { /* the airspace is right above or below us - show the vertical distance */ - _tcscat(buffer, _T(" vertical ")); + strcat(buffer, " vertical "); auto delta = solution.altitude - CommonInterface::Basic().nav_altitude; - FormatRelativeUserAltitude(delta, buffer + _tcslen(buffer), true); + FormatRelativeUserAltitude(delta, buffer + strlen(buffer), true); } row_renderer.DrawSecondRow(canvas, text_rc, buffer); @@ -343,21 +343,21 @@ AirspaceWarningListWidget::OnPaintItem(Canvas &canvas, /* draw the warning state indicator */ Color state_color; - const TCHAR *state_text; + const char *state_text; if (warning.IsInside()) { state_color = warning.IsActive() ? inside_color : inside_ack_color; - state_text = _T("inside"); + state_text = "inside"; } else if (warning.IsWarning()) { state_color = warning.IsActive() ? near_color : near_ack_color; - state_text = _T("near"); + state_text = "near"; } else { state_color = COLOR_WHITE; state_text = NULL; } const PixelSize state_text_size = - canvas.CalcTextSize(state_text != NULL ? state_text : _T("W")); + canvas.CalcTextSize(state_text != NULL ? state_text : "W"); if (state_color != COLOR_WHITE) { /* colored background */ @@ -430,7 +430,7 @@ AirspaceWarningListWidget::UpdateList() const unsigned sound_interval = ((tt_closest_airspace * 3 / warning_config.warning_time) + 1) * 2; if (sound_interval_counter >= sound_interval) { - PlayResource(_T("IDR_WAV_BEEPBWEEP")); + PlayResource("IDR_WAV_BEEPBWEEP"); sound_interval_counter = 1; } else ++sound_interval_counter; diff --git a/src/Dialogs/CMakeLists.txt b/src/Dialogs/CMakeLists.txt new file mode 100644 index 00000000000..557cbf85804 --- /dev/null +++ b/src/Dialogs/CMakeLists.txt @@ -0,0 +1,71 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source Files\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +file(GLOB_RECURSE ${TARGET_NAME}_HEADERS *.h *.hpp *.hxx) +set(HEADER_FILES ) +foreach(source_file ${${TARGET_NAME}_HEADERS}) + # string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header Files\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +target_link_libraries(${TARGET_NAME} PUBLIC + util Airspace event Form InfoBoxes Widget + Screen ui Device Weather Repository Gauge + Formatter Task Data Polar +) +# message(FATAL_ERROR "Stop!") + +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER FrontEnd) + +add_dependencies(${TARGET_NAME} util Form) + +# message(FATAL_ERROR Stop!) diff --git a/src/Dialogs/CMakeSource.cmake b/src/Dialogs/CMakeSource.cmake new file mode 100644 index 00000000000..deb6e0255d1 --- /dev/null +++ b/src/Dialogs/CMakeSource.cmake @@ -0,0 +1,195 @@ +set(_SOURCES + Dialogs/Airspace/AirspaceCRendererSettingsDialog.cpp + Dialogs/Airspace/AirspaceCRendererSettingsPanel.cpp + Dialogs/Airspace/AirspaceList.cpp + Dialogs/Airspace/dlgAirspace.cpp + Dialogs/Airspace/dlgAirspaceDetails.cpp + Dialogs/Airspace/dlgAirspacePatterns.cpp + Dialogs/Airspace/dlgAirspaceWarnings.cpp + Dialogs/ColorListDialog.cpp + Dialogs/ComboPicker.cpp + Dialogs/DataField.cpp + Dialogs/Device/BlueFly/BlueFlyConfigurationDialog.cpp + Dialogs/Device/CAI302/UnitsEditor.cpp + Dialogs/Device/CAI302/WaypointUploader.cpp + Dialogs/Device/DeviceEditWidget.cpp + Dialogs/Device/DeviceListDialog.cpp + Dialogs/Device/FLARM/ConfigWidget.cpp + Dialogs/Device/LX/ManageLX16xxDialog.cpp + Dialogs/Device/LX/ManageNanoDialog.cpp + Dialogs/Device/LX/ManageLXNAVVarioDialog.cpp + Dialogs/Device/LX/NanoConfigWidget.cpp + Dialogs/Device/LX/LXNAVVarioConfigWidget.cpp + Dialogs/Device/ManageCAI302Dialog.cpp + Dialogs/Device/ManageFlarmDialog.cpp + Dialogs/Device/PortMonitor.cpp + Dialogs/Device/PortPicker.cpp + Dialogs/Device/PortDataField.cpp + Dialogs/Device/Vega/SwitchesDialog.cpp + Dialogs/Device/Vega/VegaConfigurationDialog.cpp + Dialogs/Device/Vega/VegaDemoDialog.cpp + Dialogs/Device/Vega/VegaParametersWidget.cpp + Dialogs/DialogSettings.cpp + Dialogs/dlgAnalysis.cpp + Dialogs/dlgChecklist.cpp + Dialogs/dlgCredits.cpp + Dialogs/dlgInfoBoxAccess.cpp + Dialogs/dlgQuickMenu.cpp + Dialogs/dlgSimulatorPrompt.cpp + Dialogs/dlgStatus.cpp + Dialogs/DownloadFilePicker.cpp + Dialogs/Error.cpp + Dialogs/FileManager.cpp + Dialogs/FilePicker.cpp + Dialogs/GeoPointEntry.cpp + Dialogs/HelpDialog.cpp + Dialogs/Inflate.cpp + Dialogs/JobDialog.cpp + Dialogs/KnobTextEntry.cpp + Dialogs/ListPicker.cpp + Dialogs/LockScreen.cpp + Dialogs/MapItemListDialog.cpp + Dialogs/MapItemListSettingsDialog.cpp + Dialogs/MapItemListSettingsPanel.cpp + Dialogs/Message.cpp + Dialogs/NumberEntry.cpp + + Dialogs/Plane/PlaneDetailsDialog.cpp + Dialogs/Plane/PlaneListDialog.cpp + Dialogs/Plane/PlanePolarDialog.cpp + Dialogs/Plane/PolarShapeEditWidget.cpp + + Dialogs/ProfileListDialog.cpp + Dialogs/ProfilePasswordDialog.cpp + + Dialogs/ProgressDialog.cpp + Dialogs/ReplayDialog.cpp + + Dialogs/Settings/dlgBasicSettings.cpp + Dialogs/Settings/dlgConfigInfoboxes.cpp + Dialogs/Settings/dlgConfiguration.cpp + Dialogs/Settings/Panels/AirspaceConfigPanel.cpp + Dialogs/Settings/Panels/CloudConfigPanel.cpp + Dialogs/Settings/Panels/WeGlideConfigPanel.cpp + Dialogs/Settings/Panels/GaugesConfigPanel.cpp + Dialogs/Settings/Panels/GlideComputerConfigPanel.cpp + Dialogs/Settings/Panels/InfoBoxesConfigPanel.cpp + Dialogs/Settings/Panels/InterfaceConfigPanel.cpp + Dialogs/Settings/Panels/LayoutConfigPanel.cpp + Dialogs/Settings/Panels/LoggerConfigPanel.cpp + Dialogs/Settings/Panels/MapDisplayConfigPanel.cpp + Dialogs/Settings/Panels/PagesConfigPanel.cpp + Dialogs/Settings/Panels/RouteConfigPanel.cpp + Dialogs/Settings/Panels/SafetyFactorsConfigPanel.cpp + Dialogs/Settings/Panels/ScoringConfigPanel.cpp + Dialogs/Settings/Panels/SiteConfigPanel.cpp + Dialogs/Settings/Panels/SymbolsConfigPanel.cpp + Dialogs/Settings/Panels/TaskDefaultsConfigPanel.cpp + Dialogs/Settings/Panels/TaskRulesConfigPanel.cpp + Dialogs/Settings/Panels/TerrainDisplayConfigPanel.cpp + Dialogs/Settings/Panels/TimeConfigPanel.cpp + Dialogs/Settings/Panels/TrackingConfigPanel.cpp + Dialogs/Settings/Panels/UnitsConfigPanel.cpp + Dialogs/Settings/Panels/VarioConfigPanel.cpp + Dialogs/Settings/Panels/WaypointDisplayConfigPanel.cpp + Dialogs/Settings/Panels/WeatherConfigPanel.cpp + Dialogs/Settings/Panels/WindConfigPanel.cpp + Dialogs/Settings/WindSettingsDialog.cpp + Dialogs/Settings/WindSettingsPanel.cpp + + Dialogs/SimulatorPromptWindow.cpp + Dialogs/StartupDialog.cpp + + Dialogs/StatusPanels/FlightStatusPanel.cpp + Dialogs/StatusPanels/RulesStatusPanel.cpp + Dialogs/StatusPanels/StatusPanel.cpp + Dialogs/StatusPanels/SystemStatusPanel.cpp + Dialogs/StatusPanels/TaskStatusPanel.cpp + Dialogs/StatusPanels/TimesStatusPanel.cpp + + Dialogs/Task/AlternatesListDialog.cpp + Dialogs/Task/dlgTaskHelpers.cpp + Dialogs/Task/Manager/TaskActionsPanel.cpp + Dialogs/Task/Manager/TaskClosePanel.cpp + Dialogs/Task/Manager/TaskEditPanel.cpp + Dialogs/Task/Manager/TaskListPanel.cpp + Dialogs/Task/Manager/TaskManagerDialog.cpp + Dialogs/Task/Manager/TaskMapButtonRenderer.cpp + Dialogs/Task/Manager/TaskMiscPanel.cpp + Dialogs/Task/Manager/TaskPropertiesPanel.cpp + Dialogs/Task/Manager/WeGlideTasksPanel.cpp # 7.36 + Dialogs/Task/MutateTaskPointDialog.cpp + Dialogs/Task/OptionalStartsDialog.cpp + Dialogs/Task/TargetDialog.cpp + Dialogs/Task/TaskPointDialog.cpp + Dialogs/Task/Widgets/CylinderZoneEditWidget.cpp + Dialogs/Task/Widgets/KeyholeZoneEditWidget.cpp + Dialogs/Task/Widgets/LineSectorZoneEditWidget.cpp + Dialogs/Task/Widgets/ObservationZoneEditWidget.cpp + Dialogs/Task/Widgets/SectorZoneEditWidget.cpp + + Dialogs/TextEntry.cpp + Dialogs/TimeEntry.cpp + Dialogs/DateEntry.cpp + Dialogs/TouchTextEntry.cpp + + Dialogs/Tracking/CloudEnableDialog.cpp + Dialogs/Traffic/FlarmTrafficDetails.cpp + Dialogs/Traffic/TeamCodeDialog.cpp + Dialogs/Traffic/TrafficList.cpp + + Dialogs/Waypoint/dlgWaypointDetails.cpp + Dialogs/Waypoint/dlgWaypointEdit.cpp + Dialogs/Waypoint/Manager.cpp + Dialogs/Waypoint/NearestWaypoint.cpp + Dialogs/Waypoint/WaypointCommandsWidget.cpp + Dialogs/Waypoint/WaypointInfoWidget.cpp + Dialogs/Waypoint/WaypointList.cpp + Dialogs/Weather/NOAADetails.cpp + Dialogs/Weather/NOAAList.cpp + Dialogs/Weather/PCMetDialog.cpp + Dialogs/Weather/RASPDialog.cpp + Dialogs/Weather/WeatherDialog.cpp + + Dialogs/WidgetDialog.cpp + + Dialogs/CoDialog.cpp +) + + + +if(ON) # IS_OPENVARIO + list(APPEND _SOURCES + ../OpenVario/FileMenuWidget.cpp + ../OpenVario/DisplaySettingsWidget.cpp + ../OpenVario/SystemSettingsWidget.cpp + ../OpenVario/ExtraWidget.cpp + + ../OpenVario/System/OpenVarioDevice.cpp + ../OpenVario/System/OpenVarioTools.cpp + + ../OpenVario/System/SystemMenuWidget.cpp + + ../OpenVario/System/Setting/RotationWidget.cpp + ../OpenVario/System/WifiDialogOV.cpp + ../OpenVario/System/WifiSupplicantOV.cpp + + Dialogs/ProcessDialog.cpp + ) +endif() + +if(UNIX) + list(APPEND _SOURCES + Dialogs/Settings/Panels/AudioVarioConfigPanel.cpp + Dialogs/Settings/Panels/AudioConfigPanel.cpp + + Dialogs/Weather/MapOverlayWidget.cpp + ) +endif() + +set(SCRIPT_FILES + CMakeSource.cmake + + ../../build/main.mk +) + diff --git a/src/Dialogs/CoDialog.cpp b/src/Dialogs/CoDialog.cpp index aa3f9a5a687..8966a0373a6 100644 --- a/src/Dialogs/CoDialog.cpp +++ b/src/Dialogs/CoDialog.cpp @@ -28,7 +28,7 @@ class CoDialog { public: CoDialog(UI::SingleWindow &parent, const DialogLook &dialog_look, - const TCHAR *caption, + const char *caption, PluggableOperationEnvironment *_env) noexcept :dialog(parent, dialog_look, caption), inject_task(asio_thread->GetEventLoop()) @@ -69,7 +69,7 @@ class CoDialog { bool ShowCoDialog(UI::SingleWindow &parent, const DialogLook &dialog_look, - const TCHAR *caption, Co::InvokeTask task, + const char *caption, Co::InvokeTask task, PluggableOperationEnvironment *env) { CoDialog dialog{parent, dialog_look, caption, env}; diff --git a/src/Dialogs/CoDialog.hpp b/src/Dialogs/CoDialog.hpp index 1616083ffae..6bc8a8d8320 100644 --- a/src/Dialogs/CoDialog.hpp +++ b/src/Dialogs/CoDialog.hpp @@ -21,5 +21,5 @@ namespace Co { class InvokeTask; } */ bool ShowCoDialog(UI::SingleWindow &parent, const DialogLook &dialog_look, - const TCHAR *caption, Co::InvokeTask task, + const char *caption, Co::InvokeTask task, PluggableOperationEnvironment *env); diff --git a/src/Dialogs/CoFunctionDialog.hpp b/src/Dialogs/CoFunctionDialog.hpp index e9a34be3eb5..276804f4cbe 100644 --- a/src/Dialogs/CoFunctionDialog.hpp +++ b/src/Dialogs/CoFunctionDialog.hpp @@ -17,7 +17,7 @@ template [[nodiscard]] std::optional ShowCoFunctionDialog(UI::SingleWindow &parent, const DialogLook &dialog_look, - const TCHAR *caption, Co::Task &&task, + const char *caption, Co::Task &&task, PluggableOperationEnvironment *env) { ReturnValue value; diff --git a/src/Dialogs/ComboPicker.cpp b/src/Dialogs/ComboPicker.cpp index 4d10d101f2c..98164e0fecd 100644 --- a/src/Dialogs/ComboPicker.cpp +++ b/src/Dialogs/ComboPicker.cpp @@ -31,18 +31,18 @@ class ComboPickerSupport : public ListItemRenderer { } }; -static const TCHAR* +static const char* OnItemHelp(unsigned i) { return (*ComboListPopup)[i].help_text.c_str(); } int -ComboPicker(const TCHAR *caption, +ComboPicker(const char *caption, const ComboList &combo_list, - const TCHAR *help_text, + const char *help_text, bool enable_item_help, - const TCHAR *extra_caption) + const char *extra_caption) { ComboListPopup = &combo_list; @@ -58,11 +58,11 @@ ComboPicker(const TCHAR *caption, } bool -ComboPicker(const TCHAR *caption, DataField &df, - const TCHAR *help_text) +ComboPicker(const char *caption, DataField &df, + const char *help_text) { StaticString<256> buffer; - const TCHAR *reference = nullptr; + const char *reference = nullptr; while (true) { const ComboList combo_list = df.CreateComboList(reference); diff --git a/src/Dialogs/ComboPicker.hpp b/src/Dialogs/ComboPicker.hpp index fc6476f03a9..2f4ae895a2c 100644 --- a/src/Dialogs/ComboPicker.hpp +++ b/src/Dialogs/ComboPicker.hpp @@ -9,16 +9,16 @@ class ComboList; class DataField; int -ComboPicker(const TCHAR *caption, +ComboPicker(const char *caption, const ComboList &combo_list, - const TCHAR *help_text = nullptr, + const char *help_text = nullptr, bool enable_item_help = false, - const TCHAR *extra_caption=nullptr); + const char *extra_caption=nullptr); /** * @return true if the user has selected a new value (though it may be * equal to the old one) */ bool -ComboPicker(const TCHAR *caption, DataField &df, - const TCHAR *help_text = nullptr); +ComboPicker(const char *caption, DataField &df, + const char *help_text = nullptr); diff --git a/src/Dialogs/DataField.cpp b/src/Dialogs/DataField.cpp index 7e475c573b6..f5b40646193 100644 --- a/src/Dialogs/DataField.cpp +++ b/src/Dialogs/DataField.cpp @@ -24,8 +24,8 @@ #include bool -EditDataFieldDialog(const TCHAR *caption, DataField &df, - const TCHAR *help_text) +EditDataFieldDialog(const char *caption, DataField &df, + const char *help_text) { const auto type = df.GetType(); if (type == DataField::Type::FILE) { @@ -85,7 +85,7 @@ EditDataFieldDialog(const TCHAR *caption, DataField &df, type == DataField::Type::PREFIX) { auto &sdf = static_cast(df); - const TCHAR *value = sdf.GetValue(); + const char *value = sdf.GetValue(); assert(value != nullptr); StaticString buffer(value); diff --git a/src/Dialogs/DataField.hpp b/src/Dialogs/DataField.hpp index e9c9ecc42f8..da666c45029 100644 --- a/src/Dialogs/DataField.hpp +++ b/src/Dialogs/DataField.hpp @@ -13,5 +13,5 @@ class DataField; * @return true if the value has been modified */ bool -EditDataFieldDialog(const TCHAR *caption, DataField &df, - const TCHAR *help_text); +EditDataFieldDialog(const char *caption, DataField &df, + const char *help_text); diff --git a/src/Dialogs/DateEntry.cpp b/src/Dialogs/DateEntry.cpp index de572334917..dd1742a6cb5 100644 --- a/src/Dialogs/DateEntry.cpp +++ b/src/Dialogs/DateEntry.cpp @@ -10,11 +10,10 @@ #include "UIGlobals.hpp" bool -DateEntryDialog(const TCHAR *caption, BrokenDate &value, +DateEntryDialog(const char *caption, BrokenDate &value, bool nullable) { - /* create the dialog */ - + // create the dialog const DialogLook &look = UIGlobals::GetDialogLook(); TWidgetDialog dialog(WidgetDialog::Auto{}, @@ -23,8 +22,7 @@ DateEntryDialog(const TCHAR *caption, BrokenDate &value, ContainerWindow &client_area = dialog.GetClientAreaWindow(); - /* create the input control */ - + // create the input control WindowStyle control_style; control_style.Hide(); control_style.TabStop(); @@ -37,21 +35,26 @@ DateEntryDialog(const TCHAR *caption, BrokenDate &value, entry->SetValue(value); entry->SetCallback(dialog.MakeModalResultCallback(mrOK)); - /* create buttons */ - dialog.AddButton(_("OK"), mrOK); + // create buttons + dialog.first_button = dialog.AddButton(_("OK"), mrOK); dialog.AddButton(_("Cancel"), mrCancel); - dialog.AddButton(_("Reset"), [&entry = *entry, start_value = value](){ + dialog.last_button = + dialog.AddButton(_("Reset"), [&entry = *entry, start_value = value]() { entry.SetValue(start_value); // the start value }); if (nullable) - dialog.AddButton(_("Clear"), [&entry=*entry](){ + dialog.last_button = dialog.AddButton( + _("Clear"), [&entry = *entry]() { entry.SetInvalid(); }); - /* run it */ + // set handler for cursor overflow + entry->SetLeftOverflow(dialog.SetFocusButtonCallback(dialog.last_button)); + entry->SetRightOverflow(dialog.SetFocusButtonCallback(dialog.first_button)); + // ... and run it dialog.SetWidget(std::move(entry)); if (dialog.ShowModal() != mrOK) diff --git a/src/Dialogs/DateEntry.hpp b/src/Dialogs/DateEntry.hpp index 34678140de9..def9730b97b 100644 --- a/src/Dialogs/DateEntry.hpp +++ b/src/Dialogs/DateEntry.hpp @@ -8,5 +8,5 @@ struct BrokenDate; bool -DateEntryDialog(const TCHAR *caption, BrokenDate &value, +DateEntryDialog(const char *caption, BrokenDate &value, bool nullable=false); diff --git a/src/Dialogs/Device/BlueFly/BlueFlyConfigurationDialog.cpp b/src/Dialogs/Device/BlueFly/BlueFlyConfigurationDialog.cpp index 6e1dcff4655..f885db524f4 100644 --- a/src/Dialogs/Device/BlueFly/BlueFlyConfigurationDialog.cpp +++ b/src/Dialogs/Device/BlueFly/BlueFlyConfigurationDialog.cpp @@ -33,15 +33,15 @@ class BlueFlyConfigurationWidget final void Prepare([[maybe_unused]] ContainerWindow &parent, [[maybe_unused]] const PixelRect &rc) noexcept override { AddFloat(N_("Volume"), nullptr, - _T("%.2f"), - _T("%.2f"), + "%.2f", + "%.2f", 0, 1.0, 0.1, true, 0); static constexpr StaticEnumChoice modes[] = { - { 0, _T("BlueFlyVario") }, - { 1, _T("LK8EX1") }, - { 2, _T("LX") }, - { 3, _T("FlyNet") }, + { 0, "BlueFlyVario" }, + { 1, "LK8EX1" }, + { 2, "LX" }, + { 3, "FlyNet" }, { 0 } }; @@ -73,7 +73,7 @@ class BlueFlyConfigurationWidget final } catch (OperationCancelled) { return false; } catch (...) { - ShowError(std::current_exception(), _T("BlueFly Vario")); + ShowError(std::current_exception(), "BlueFly Vario"); return false; } @@ -108,8 +108,12 @@ dlgConfigurationBlueFlyVarioShowModal(Device &_device) WidgetDialog dialog(WidgetDialog::Auto{}, UIGlobals::GetMainWindow(), look, - _T("BlueFly Vario"), - new BlueFlyConfigurationWidget(look, dialog, device)); + "BlueFly Vario"); + // unfortunately this internal declaration isn't possible with MSVC! + // so I have to set this widget later... + // (BlueFlyConfigurationWidget(.., dialog,..) with dialog from paren funktion + dialog.FinishPreliminary( + new BlueFlyConfigurationWidget(look, dialog, device)); dialog.AddButton(_("Cancel"), mrCancel); dialog.ShowModal(); diff --git a/src/Dialogs/Device/CAI302/UnitsEditor.cpp b/src/Dialogs/Device/CAI302/UnitsEditor.cpp index e06268b6341..94397012c33 100644 --- a/src/Dialogs/Device/CAI302/UnitsEditor.cpp +++ b/src/Dialogs/Device/CAI302/UnitsEditor.cpp @@ -11,58 +11,58 @@ CAI302UnitsEditor::Prepare([[maybe_unused]] ContainerWindow &parent, [[maybe_unused]] const PixelRect &rc) noexcept { static constexpr StaticEnumChoice vario_list[] = { - { 0, _T("m/s"), }, - { 1, _T("kt"), }, + { 0, "m/s", }, + { 1, "kt", }, nullptr }; AddEnum(_("Vario"), NULL, vario_list, data.GetVarioUnit()); static constexpr StaticEnumChoice altitude_list[] = { - { 0, _T("m"), }, - { 1, _T("ft"), }, + { 0, "m", }, + { 1, "ft", }, nullptr }; AddEnum(_("Altitude"), NULL, altitude_list, data.GetAltitudeUnit()); static constexpr StaticEnumChoice temperature_list[] = { - { 0, _T(DEG "C"), }, - { 1, _T(DEG "F"), }, + { 0, DEG "C", }, + { 1, DEG "F", }, nullptr }; AddEnum(_("Temperature"), NULL, temperature_list, data.GetTemperatureUnit()); static constexpr StaticEnumChoice pressure_list[] = { - { 0, _T("hPa"), }, - { 1, _T("inHg"), }, + { 0, "hPa", }, + { 1, "inHg", }, nullptr }; AddEnum(_("Pressure"), NULL, pressure_list, data.GetPressureUnit()); static constexpr StaticEnumChoice distance_list[] = { - { 0, _T("km"), }, - { 1, _T("NM"), }, - { 2, _T("mi"), }, + { 0, "km", }, + { 1, "NM", }, + { 2, "mi", }, nullptr }; AddEnum(_("Distance"), NULL, distance_list, data.GetDistanceUnit()); static constexpr StaticEnumChoice speed_list[] = { - { 0, _T("m/s"), }, - { 1, _T("kt"), }, - { 2, _T("mph"), }, + { 0, "m/s", }, + { 1, "kt", }, + { 2, "mph", }, nullptr }; AddEnum(_("Speed"), NULL, speed_list, data.GetSpeedUnit()); static constexpr StaticEnumChoice sink_tone_list[] = { - { 0, _T("off"), }, - { 1, _T("on"), }, + { 0, "off", }, + { 1, "on", }, nullptr }; AddEnum(_("Sink tone"), NULL, sink_tone_list, diff --git a/src/Dialogs/Device/DeviceEditWidget.cpp b/src/Dialogs/Device/DeviceEditWidget.cpp index 7697f767ca1..f2a441bf084 100644 --- a/src/Dialogs/Device/DeviceEditWidget.cpp +++ b/src/Dialogs/Device/DeviceEditWidget.cpp @@ -27,55 +27,55 @@ enum ControlIndex { static void FillBaudRates(DataFieldEnum &dfe) noexcept { - dfe.addEnumText(_T("1200"), 1200); - dfe.addEnumText(_T("2400"), 2400); - dfe.addEnumText(_T("4800"), 4800); - dfe.addEnumText(_T("9600"), 9600); - dfe.addEnumText(_T("19200"), 19200); - dfe.addEnumText(_T("38400"), 38400); - dfe.addEnumText(_T("57600"), 57600); - dfe.addEnumText(_T("115200"), 115200); + dfe.addEnumText("1200", 1200); + dfe.addEnumText("2400", 2400); + dfe.addEnumText("4800", 4800); + dfe.addEnumText("9600", 9600); + dfe.addEnumText("19200", 19200); + dfe.addEnumText("38400", 38400); + dfe.addEnumText("57600", 57600); + dfe.addEnumText("115200", 115200); } static void FillTCPPorts(DataFieldEnum &dfe) noexcept { - dfe.addEnumText(_T("4353"), 4353); - dfe.addEnumText(_T("10110"), 10110); - dfe.addEnumText(_T("4352"), 4352); - dfe.addEnumText(_T("2000"), 2000); - dfe.addEnumText(_T("23"), 23); - dfe.addEnumText(_T("8880"), 8880); - dfe.addEnumText(_T("8881"), 8881); - dfe.addEnumText(_T("8882"), 8882); + dfe.addEnumText("4353", 4353); + dfe.addEnumText("10110", 10110); + dfe.addEnumText("4352", 4352); + dfe.addEnumText("2000", 2000); + dfe.addEnumText("23", 23); + dfe.addEnumText("8880", 8880); + dfe.addEnumText("8881", 8881); + dfe.addEnumText("8882", 8882); } static void FillI2CBus(DataFieldEnum &dfe) noexcept { - dfe.addEnumText(_T("0"), 0U); - dfe.addEnumText(_T("1"), 1U); - dfe.addEnumText(_T("2"), 2U); + dfe.addEnumText("0", 0U); + dfe.addEnumText("1", 1U); + dfe.addEnumText("2", 2U); } /* Only lists possible addresses of supported devices */ static void FillI2CAddr(DataFieldEnum &dfe) noexcept { - dfe.addEnumText(_T("0x76 (MS5611)"), 0x76); - dfe.addEnumText(_T("0x77 (BMP085 and MS5611)"), 0x77); -// dfe.addEnumText(_T("0x52 (Nunchuck)"), 0x52); Is implied by device, no choice -// dfe.addEnumText(_T("0x69 (MPU6050)"), 0x69); Is implied by device, no choice -// dfe.addEnumText(_T("0x1e (HMC5883)"), 0x1e); Is implied by device, no choice + dfe.addEnumText("0x76 (MS5611)", 0x76); + dfe.addEnumText("0x77 (BMP085 and MS5611)", 0x77); +// dfe.addEnumText("0x52 (Nunchuck)", 0x52); Is implied by device, no choice +// dfe.addEnumText("0x69 (MPU6050)", 0x69); Is implied by device, no choice +// dfe.addEnumText("0x1e (HMC5883)", 0x1e); Is implied by device, no choice } static void FillPress(DataFieldEnum &dfe) noexcept { - dfe.addEnumText(_T("Static & Vario"), (unsigned)DeviceConfig::PressureUse::STATIC_WITH_VARIO); - dfe.addEnumText(_T("Static"), (unsigned)DeviceConfig::PressureUse::STATIC_ONLY); - dfe.addEnumText(_T("TE probe (compensated vario)"), (unsigned)DeviceConfig::PressureUse::TEK_PRESSURE); - dfe.addEnumText(_T("Pitot (airspeed)"), (unsigned)DeviceConfig::PressureUse::PITOT); + dfe.addEnumText("Static & Vario", (unsigned)DeviceConfig::PressureUse::STATIC_WITH_VARIO); + dfe.addEnumText("Static", (unsigned)DeviceConfig::PressureUse::STATIC_ONLY); + dfe.addEnumText("TE probe (compensated vario)", (unsigned)DeviceConfig::PressureUse::TEK_PRESSURE); + dfe.addEnumText("Pitot (airspeed)", (unsigned)DeviceConfig::PressureUse::PITOT); } /** @@ -88,15 +88,15 @@ FillPress(DataFieldEnum &dfe) noexcept static void FillEngineType(DataFieldEnum &dfe) noexcept { - dfe.addEnumText(_T("None"), static_cast(DeviceConfig::EngineType::NONE)); - dfe.addEnumText(_T("2S1I"), static_cast(DeviceConfig::EngineType::TWO_STROKE_1_IGN)); - dfe.addEnumText(_T("2S2I"), static_cast(DeviceConfig::EngineType::TWO_STROKE_2_IGN)); - dfe.addEnumText(_T("4S1I"), static_cast(DeviceConfig::EngineType::FOUR_STROKE_1_IGN)); + dfe.addEnumText("None", static_cast(DeviceConfig::EngineType::NONE)); + dfe.addEnumText("2S1I", static_cast(DeviceConfig::EngineType::TWO_STROKE_1_IGN)); + dfe.addEnumText("2S2I", static_cast(DeviceConfig::EngineType::TWO_STROKE_2_IGN)); + dfe.addEnumText("4S1I", static_cast(DeviceConfig::EngineType::FOUR_STROKE_1_IGN)); } static bool -EditPortCallback(const TCHAR *caption, DataField &df, - [[maybe_unused]] const TCHAR *help_text) noexcept +EditPortCallback(const char *caption, DataField &df, + [[maybe_unused]] const char *help_text) noexcept { return PortPicker((DataFieldEnum &)df, caption); } @@ -117,7 +117,7 @@ DeviceEditWidget::SetConfig(const DeviceConfig &_config) noexcept WndProperty &port_control = GetControl(Port); DataFieldEnum &port_df = *(DataFieldEnum *)port_control.GetDataField(); - SetPort(port_df, config); + SetDevicePort(port_df, config); port_control.RefreshDisplay(); LoadValueEnum(BaudRate, config.baud_rate); @@ -140,7 +140,7 @@ DeviceEditWidget::SetConfig(const DeviceConfig &_config) noexcept static bool SupportsBulkBaudRate(const DataField &df) noexcept { - const TCHAR *driver_name = df.GetAsString(); + const char *driver_name = df.GetAsString(); if (driver_name == nullptr) return false; @@ -155,7 +155,7 @@ SupportsBulkBaudRate(const DataField &df) noexcept static bool CanReceiveSettings(const DataField &df) noexcept { - const TCHAR *driver_name = df.GetAsString(); + const char *driver_name = df.GetAsString(); if (driver_name == nullptr) return false; @@ -170,7 +170,7 @@ CanReceiveSettings(const DataField &df) noexcept static bool CanSendSettings(const DataField &df) noexcept { - const TCHAR *driver_name = df.GetAsString(); + const char *driver_name = df.GetAsString(); if (driver_name == nullptr) return false; @@ -185,7 +185,7 @@ CanSendSettings(const DataField &df) noexcept static bool CanPassThrough(const DataField &df) noexcept { - const TCHAR *driver_name = df.GetAsString(); + const char *driver_name = df.GetAsString(); if (driver_name == nullptr) return false; @@ -257,14 +257,14 @@ DeviceEditWidget::Prepare(ContainerWindow &parent, Add(_("Baud rate"), nullptr, baud_rate_df); DataFieldEnum *bulk_baud_rate_df = new DataFieldEnum(this); - bulk_baud_rate_df->addEnumText(_T("Default"), 0u); + bulk_baud_rate_df->addEnumText("Default", 0u); FillBaudRates(*bulk_baud_rate_df); bulk_baud_rate_df->SetValue(config.bulk_baud_rate); Add(_("Bulk baud rate"), _("The baud rate used for bulk transfers, such as task declaration or flight download."), bulk_baud_rate_df); - DataFieldString *ip_address_df = new DataFieldString(_T(""), this); + DataFieldString *ip_address_df = new DataFieldString("", this); ip_address_df->SetValue(config.ip_address); Add(_("IP address"), nullptr, ip_address_df); @@ -333,7 +333,7 @@ DeviceEditWidget::Prepare(ContainerWindow &parent, config.sync_to_device, this); SetExpertRow(SyncToDevice); - AddBoolean(_T("K6Bt"), + AddBoolean("K6Bt", _("Whether you use a K6Bt to connect the device."), config.k6bt, this); SetExpertRow(K6Bt); @@ -375,7 +375,7 @@ FinishPortField(DeviceConfig &config, const DataFieldEnum &df) noexcept case DeviceConfig::PortType::SERIAL: case DeviceConfig::PortType::PTY: - case DeviceConfig::PortType::ANDROID_USB_SERIAL: + case DeviceConfig::PortType::USB_SERIAL: /* Serial Port */ if (new_type == config.port_type && StringIsEqual(config.path, df.GetAsString())) @@ -383,12 +383,25 @@ FinishPortField(DeviceConfig &config, const DataFieldEnum &df) noexcept config.port_type = new_type; config.path = df.GetAsString(); + config.port_name = df.GetAsDisplayString(); return true; case DeviceConfig::PortType::RFCOMM: case DeviceConfig::PortType::BLE_HM10: case DeviceConfig::PortType::BLE_SENSOR: /* Bluetooth */ +#ifdef _WIN32 + // identical with Serial Port + if (new_type == config.port_type && + StringIsEqual(config.path, df.GetAsString())) + return false; + + config.port_type = new_type; + config.path = df.GetAsString(); + config.port_name = df.GetAsDisplayString(); + return true; +#else + /* Bluetooth */ if (new_type == config.port_type && StringIsEqual(config.bluetooth_mac, df.GetAsString())) return false; @@ -396,7 +409,7 @@ FinishPortField(DeviceConfig &config, const DataFieldEnum &df) noexcept config.port_type = new_type; config.bluetooth_mac = df.GetAsString(); return true; - +#endif case DeviceConfig::PortType::IOIOUART: /* IOIO UART */ if (new_type == config.port_type && diff --git a/src/Dialogs/Device/DeviceListDialog.cpp b/src/Dialogs/Device/DeviceListDialog.cpp index f494e136e67..fe8f862a5d1 100644 --- a/src/Dialogs/Device/DeviceListDialog.cpp +++ b/src/Dialogs/Device/DeviceListDialog.cpp @@ -167,7 +167,7 @@ class DeviceListWidget final static_assert(sizeof(Item) == 4, "wrong size"); Item items[NUMDEV]; - tstring error_messages[NUMDEV]; + std::string error_messages[NUMDEV]; Button *disable_button; Button *reconnect_button, *flight_button; @@ -369,15 +369,15 @@ DeviceListWidget::OnPaintItem(Canvas &canvas, const PixelRect rc, const unsigned margin = Layout::GetTextPadding(); - TCHAR port_name_buffer[128]; - const TCHAR *port_name = + char port_name_buffer[128]; + const char *port_name = config.GetPortName(port_name_buffer, ARRAY_SIZE(port_name_buffer)); - StaticString<256> text(_T("A: ")); + StaticString<256> text("A: "); text[0u] += idx; if (config.UsesDriver()) { - const TCHAR *driver_name = FindDriverDisplayName(config.driver_name); + const char *driver_name = FindDriverDisplayName(config.driver_name); text.AppendFormat(_("%s on %s"), driver_name, port_name); } else { @@ -390,7 +390,7 @@ DeviceListWidget::OnPaintItem(Canvas &canvas, const PixelRect rc, /* show a list of features that are available in the second row */ StaticString<256> buffer; - const TCHAR *status; + const char *status; if (flags.alive) { if (flags.location) { buffer = _("GPS fix"); @@ -402,54 +402,54 @@ DeviceListWidget::OnPaintItem(Canvas &canvas, const PixelRect rc, } if (flags.baro) { - buffer.append(_T("; ")); + buffer.append("; "); buffer.append(_("Baro")); } if (flags.pitot) { - buffer.append(_T("; ")); + buffer.append("; "); buffer.append(_("Pitot")); } if (flags.airspeed) { - buffer.append(_T("; ")); + buffer.append("; "); buffer.append(_("Airspeed")); } if (flags.vario) { - buffer.append(_T("; ")); + buffer.append("; "); buffer.append(_("Vario")); } if (flags.traffic) - buffer.append(_T("; FLARM")); + buffer.append("; FLARM"); if (flags.temperature || flags.humidity) { - buffer.append(_T("; ")); - buffer.append(_T("Environment")); + buffer.append("; "); + buffer.append("Environment"); } if (flags.radio) { - buffer.append(_T("; ")); - buffer.append(_T("Radio")); + buffer.append("; "); + buffer.append("Radio"); } if (flags.transponder) { - buffer.append(_T("; XPDR")); + buffer.append("; XPDR"); } if (flags.engine) - buffer.append(_T("; Engine")); + buffer.append("; Engine"); if (flags.debug) { - buffer.append(_T("; ")); + buffer.append("; "); buffer.append(_("Debug")); } if (flags.battery_percent >= 0) { - buffer.append(_T("; ")); + buffer.append("; "); buffer.append(_("Battery")); - buffer.AppendFormat(_T("=%d%%"), flags.battery_percent); + buffer.AppendFormat("=%d%%", flags.battery_percent); } status = buffer; @@ -461,7 +461,7 @@ DeviceListWidget::OnPaintItem(Canvas &canvas, const PixelRect rc, buffer = _("No data"); if (flags.debug) { - buffer.append(_T("; ")); + buffer.append("; "); buffer.append(_("Debug")); } @@ -676,9 +676,9 @@ DeviceListWidget::ManageCurrent() return; } - if (descriptor.IsDriver(_T("CAI 302"))) + if (descriptor.IsDriver("CAI 302")) ManageCAI302Dialog(UIGlobals::GetMainWindow(), look, *device); - else if (descriptor.IsDriver(_T("FLARM"))) { + else if (descriptor.IsDriver("FLARM")) { FlarmVersion version; { @@ -688,7 +688,7 @@ DeviceListWidget::ManageCurrent() } ManageFlarmDialog(*device, version); - } else if (descriptor.IsDriver(_T("LX"))) { + } else if (descriptor.IsDriver("LX")) { DeviceInfo info, secondary_info; { @@ -705,9 +705,9 @@ DeviceListWidget::ManageCurrent() ManageNanoDialog(lx_device, info); else if (lx_device.IsLX16xx()) ManageLX16xxDialog(lx_device, info); - } else if (descriptor.IsDriver(_T("Vega"))) + } else if (descriptor.IsDriver("Vega")) dlgConfigurationVarioShowModal(*device); - else if (descriptor.IsDriver(_T("BlueFly"))) + else if (descriptor.IsDriver("BlueFly")) dlgConfigurationBlueFlyVarioShowModal(*device); } diff --git a/src/Dialogs/Device/FLARM/ConfigWidget.cpp b/src/Dialogs/Device/FLARM/ConfigWidget.cpp index f0a9e509cd4..f868846a1cb 100644 --- a/src/Dialogs/Device/FLARM/ConfigWidget.cpp +++ b/src/Dialogs/Device/FLARM/ConfigWidget.cpp @@ -94,18 +94,18 @@ FLARMConfigWidget::Prepare([[maybe_unused]] ContainerWindow &parent, notrack = GetUnsignedValue(device, "NOTRACK", 0) == 1; static constexpr StaticEnumChoice baud_list[] = { - { 0, _T("4800") }, - { 1, _T("9600") }, - { 2, _T("19200") }, - { 4, _T("38400") }, - { 5, _T("57600") }, + { 0, "4800" }, + { 1, "9600" }, + { 2, "19200" }, + { 4, "38400" }, + { 5, "57600" }, nullptr }; AddEnum(_("Baud rate"), NULL, baud_list, baud); AddBoolean(_("Stealth mode"), NULL, priv); - AddInteger(_("Threshold"), NULL, _T("%d m/s"), _T("%d"), 1, 10, 1, thre); - AddInteger(_("Range"), NULL, _T("%d m"), _T("%d"), 2000, 25500, 250, range); + AddInteger(_("Threshold"), NULL, "%d m/s", "%d", 1, 10, 1, thre); + AddInteger(_("Range"), NULL, "%d m", "%d", 2000, 25500, 250, range); static constexpr StaticEnumChoice acft_list[] = { { FlarmTraffic::AircraftType::UNKNOWN, N_("Unknown") }, @@ -127,7 +127,7 @@ FLARMConfigWidget::Prepare([[maybe_unused]] ContainerWindow &parent, }; AddEnum(_("Type"), NULL, acft_list, acft); - AddInteger(_("Logger interval"), NULL, _T("%d s"), _T("%d"), + AddInteger(_("Logger interval"), NULL, "%d s", "%d", 1, 8, 1, log_int); AddBoolean(_("No tracking mode"), NULL, notrack); @@ -138,7 +138,7 @@ FLARMConfigWidget::Save(bool &_changed) noexcept try { PopupOperationEnvironment env; bool changed = false; - NarrowString<32> buffer; + StaticString<32> buffer; if (SaveValueEnum(Baud, baud)) { buffer.UnsafeFormat("%u", baud); @@ -187,6 +187,6 @@ try { } catch (OperationCancelled) { return false; } catch (...) { - ShowError(std::current_exception(), _T("FLARM")); + ShowError(std::current_exception(), "FLARM"); return false; } diff --git a/src/Dialogs/Device/LX/LXNAVVarioConfigWidget.cpp b/src/Dialogs/Device/LX/LXNAVVarioConfigWidget.cpp index eb520f38935..4fab6299e53 100644 --- a/src/Dialogs/Device/LX/LXNAVVarioConfigWidget.cpp +++ b/src/Dialogs/Device/LX/LXNAVVarioConfigWidget.cpp @@ -52,17 +52,17 @@ LXNAVVarioConfigWidget::Prepare([[maybe_unused]] ContainerWindow &parent, [[mayb brpda = WaitUnsignedValue(device, "BRPDA", 5); static constexpr StaticEnumChoice baud_list[] = { - { 0, _T("4800") }, - { 1, _T("9600") }, - { 2, _T("19200") }, - { 3, _T("38400") }, - { 4, _T("57600") }, - { 5, _T("115200") }, - { 6, _T("230400") }, - { 7, _T("256000") }, - { 8, _T("460800") }, - { 9, _T("500k") }, - { 10, _T("1M") }, + { 0, "4800" }, + { 1, "9600" }, + { 2, "19200" }, + { 3, "38400" }, + { 4, "57600" }, + { 5, "115200" }, + { 6, "230400" }, + { 7, "256000" }, + { 8, "460800" }, + { 9, "500k" }, + { 10, "1M" }, { 0 } }; @@ -75,7 +75,7 @@ LXNAVVarioConfigWidget::Save(bool &_changed) noexcept try { PopupOperationEnvironment env; bool changed = false; - NarrowString<32> buffer; + StaticString<32> buffer; if (SaveValueEnum(BRGPS, brgps)) { buffer.UnsafeFormat("%u", brgps); @@ -94,6 +94,6 @@ try { } catch (OperationCancelled) { return false; } catch (...) { - ShowError(std::current_exception(), _T("Vega")); + ShowError(std::current_exception(), "Vega"); return false; } diff --git a/src/Dialogs/Device/LX/ManageLX16xxDialog.cpp b/src/Dialogs/Device/LX/ManageLX16xxDialog.cpp index 67f5275e9ff..fb870cd1dc8 100644 --- a/src/Dialogs/Device/LX/ManageLX16xxDialog.cpp +++ b/src/Dialogs/Device/LX/ManageLX16xxDialog.cpp @@ -54,7 +54,7 @@ void ManageLX16xxDialog(Device &device, const DeviceInfo &info) { StaticString<64> title; - title.Format(_T("LX %s"), info.product.c_str()); + title.Format("LX %s", info.product.c_str()); WidgetDialog dialog(WidgetDialog::Auto{}, UIGlobals::GetMainWindow(), UIGlobals::GetDialogLook(), diff --git a/src/Dialogs/Device/LX/ManageLXNAVVarioDialog.cpp b/src/Dialogs/Device/LX/ManageLXNAVVarioDialog.cpp index cdc6bbabb0c..567322e2da6 100644 --- a/src/Dialogs/Device/LX/ManageLXNAVVarioDialog.cpp +++ b/src/Dialogs/Device/LX/ManageLXNAVVarioDialog.cpp @@ -61,11 +61,11 @@ ManageLXNAVVarioWidget::Prepare([[maybe_unused]] ContainerWindow &parent, [[mayb AddButton(_("Setup"), [this](){ LXNAVVarioConfigWidget widget(GetLook(), device); DefaultWidgetDialog(UIGlobals::GetMainWindow(), GetLook(), - _T("LXNAV Vario"), widget); + "LXNAV Vario", widget); }); if (device.IsNano()) - AddButton(_T("LXNAV Nano"), [this](){ + AddButton("LXNAV Nano", [this](){ MessageOperationEnvironment env; if (device.EnablePassThrough(env)) { ManageNanoDialog(device, secondary_info); @@ -80,7 +80,7 @@ ManageLXNAVVarioDialog(Device &device, const DeviceInfo &info, { WidgetDialog dialog(WidgetDialog::Auto{}, UIGlobals::GetMainWindow(), UIGlobals::GetDialogLook(), - _T("LXNAV Vario"), + "LXNAV Vario", new ManageLXNAVVarioWidget(UIGlobals::GetDialogLook(), (LXDevice &)device, info, secondary_info)); diff --git a/src/Dialogs/Device/LX/ManageNanoDialog.cpp b/src/Dialogs/Device/LX/ManageNanoDialog.cpp index 62358395c51..ab6e7710a82 100644 --- a/src/Dialogs/Device/LX/ManageNanoDialog.cpp +++ b/src/Dialogs/Device/LX/ManageNanoDialog.cpp @@ -60,7 +60,7 @@ ManageNanoWidget::Prepare([[maybe_unused]] ContainerWindow &parent, [[maybe_unus AddButton(_("Setup"), [this](){ NanoConfigWidget widget(GetLook(), device); DefaultWidgetDialog(UIGlobals::GetMainWindow(), GetLook(), - _T("LXNAV Nano"), widget); + "LXNAV Nano", widget); }); } @@ -69,7 +69,7 @@ ManageNanoDialog(Device &device, const DeviceInfo &info) { WidgetDialog dialog(WidgetDialog::Auto{}, UIGlobals::GetMainWindow(), UIGlobals::GetDialogLook(), - _T("LXNAV Nano"), + "LXNAV Nano", new ManageNanoWidget(UIGlobals::GetDialogLook(), (LXDevice &)device, info)); dialog.AddButton(_("Close"), mrCancel); diff --git a/src/Dialogs/Device/LX/NanoConfigWidget.cpp b/src/Dialogs/Device/LX/NanoConfigWidget.cpp index 2decb003da6..7abb3e49a49 100644 --- a/src/Dialogs/Device/LX/NanoConfigWidget.cpp +++ b/src/Dialogs/Device/LX/NanoConfigWidget.cpp @@ -64,13 +64,13 @@ NanoConfigWidget::Prepare([[maybe_unused]] ContainerWindow &parent, RequestAllSettings(device); static constexpr StaticEnumChoice baud_list[] = { - { 2400, _T("2400") }, - { 4800, _T("4800") }, - { 9600, _T("9600") }, - { 19200, _T("19200") }, - { 38400, _T("38400") }, - { 57600, _T("57600") }, - { 115200, _T("115200") }, + { 2400, "2400" }, + { 4800, "4800" }, + { 9600, "9600" }, + { 19200, "19200" }, + { 38400, "38400" }, + { 57600, "57600" }, + { 115200, "115200" }, { 0 } }; @@ -90,7 +90,7 @@ NanoConfigWidget::Prepare([[maybe_unused]] ContainerWindow &parent, WaitBoolValue(device, "NMEA", true)); AddInteger(_("Recording interval"), NULL, - _T("%d s"), _T("%d"), 1, 60, 1, + "%d s", "%d", 1, 60, 1, WaitUnsignedValue(device, "RECINT", 1)); } @@ -139,6 +139,6 @@ try { } catch (OperationCancelled) { return false; } catch (...) { - ShowError(std::current_exception(), _T("LXNAV Nano")); + ShowError(std::current_exception(), "LXNAV Nano"); return false; } diff --git a/src/Dialogs/Device/ManageCAI302Dialog.cpp b/src/Dialogs/Device/ManageCAI302Dialog.cpp index 16b4a09d165..4f9c8ab7e44 100644 --- a/src/Dialogs/Device/ManageCAI302Dialog.cpp +++ b/src/Dialogs/Device/ManageCAI302Dialog.cpp @@ -105,7 +105,7 @@ ManageCAI302Widget::Prepare([[maybe_unused]] ContainerWindow &parent, AddButton(_("Delete all flights"), [this](){ if (ShowMessageBox(_("Do you really want to delete all flights from the device?"), - _T("CAI 302"), MB_YESNO) != IDYES) + "CAI 302", MB_YESNO) != IDYES) return; MessageOperationEnvironment env; @@ -134,7 +134,7 @@ ManageCAI302Dialog([[maybe_unused]] SingleWindow &parent, const DialogLook &look { WidgetDialog dialog(WidgetDialog::Auto{}, UIGlobals::GetMainWindow(), UIGlobals::GetDialogLook(), - _T("CAI 302"), + "CAI 302", new ManageCAI302Widget(look, (CAI302Device &)device)); dialog.AddButton(_("Close"), mrCancel); dialog.ShowModal(); diff --git a/src/Dialogs/Device/ManageFlarmDialog.cpp b/src/Dialogs/Device/ManageFlarmDialog.cpp index a7ca856eff5..15e6e722d86 100644 --- a/src/Dialogs/Device/ManageFlarmDialog.cpp +++ b/src/Dialogs/Device/ManageFlarmDialog.cpp @@ -60,7 +60,7 @@ ManageFLARMWidget::Prepare([[maybe_unused]] ContainerWindow &parent, AddButton(_("Setup"), [this](){ FLARMConfigWidget widget(GetLook(), device); DefaultWidgetDialog(UIGlobals::GetMainWindow(), GetLook(), - _T("FLARM"), widget); + "FLARM", widget); }); AddButton(_("Reboot"), [this](){ @@ -79,7 +79,7 @@ ManageFlarmDialog(Device &device, const FlarmVersion &version) { WidgetDialog dialog(WidgetDialog::Auto{}, UIGlobals::GetMainWindow(), UIGlobals::GetDialogLook(), - _T("FLARM"), + "FLARM", new ManageFLARMWidget(UIGlobals::GetDialogLook(), (FlarmDevice &)device, version)); dialog.AddButton(_("Close"), mrCancel); diff --git a/src/Dialogs/Device/ManageI2CPitotDialog.cpp b/src/Dialogs/Device/ManageI2CPitotDialog.cpp index 9630dac1f97..272321833ca 100644 --- a/src/Dialogs/Device/ManageI2CPitotDialog.cpp +++ b/src/Dialogs/Device/ManageI2CPitotDialog.cpp @@ -105,9 +105,9 @@ void ManageI2CPitotWidget::Prepare([[maybe_unused]] ContainerWindow &parent, [[maybe_unused]] const PixelRect &rc) noexcept { - AddReadOnly(_("Pitot"), nullptr, _T("%.2f"), UnitGroup::PRESSURE, 0); - AddReadOnly(_("Pressure"), nullptr, _T("%.2f"), UnitGroup::PRESSURE, 0); - AddReadOnly(_("Offset"), nullptr, _T("%.2f"), + AddReadOnly(_("Pitot"), nullptr, "%.2f", UnitGroup::PRESSURE, 0); + AddReadOnly(_("Pressure"), nullptr, "%.2f", UnitGroup::PRESSURE, 0); + AddReadOnly(_("Offset"), nullptr, "%.2f", UnitGroup::PRESSURE, device.GetConfig().sensor_offset); } diff --git a/src/Dialogs/Device/PortDataField.cpp b/src/Dialogs/Device/PortDataField.cpp index dbd54701a3d..5e5a4335fb0 100644 --- a/src/Dialogs/Device/PortDataField.cpp +++ b/src/Dialogs/Device/PortDataField.cpp @@ -14,6 +14,8 @@ #ifdef _WIN32 # include "system/WindowsRegistry.hpp" # include "util/StringFormat.hpp" +# include +# include #endif #ifdef ANDROID @@ -27,7 +29,7 @@ static constexpr struct { DeviceConfig::PortType type; - const TCHAR *label; + const char *label; } port_types[] = { { DeviceConfig::PortType::DISABLED, N_("Disabled") }, #ifdef HAVE_INTERNAL_GPS @@ -35,8 +37,8 @@ static constexpr struct { #endif #ifdef ANDROID { DeviceConfig::PortType::RFCOMM_SERVER, N_("Bluetooth server") }, - { DeviceConfig::PortType::DROIDSOAR_V2, _T("DroidSoar V2") }, - { DeviceConfig::PortType::GLIDER_LINK, _T("GliderLink traffic receiver") }, + { DeviceConfig::PortType::DROIDSOAR_V2, "DroidSoar V2" }, + { DeviceConfig::PortType::GLIDER_LINK, "GliderLink traffic receiver" }, #ifndef NDEBUG { DeviceConfig::PortType::NUNCHUCK, N_("IOIO switches and Nunchuk") }, #endif @@ -59,8 +61,8 @@ static constexpr unsigned num_port_types = std::size(port_types) - 1; static unsigned AddPort(DataFieldEnum &df, DeviceConfig::PortType type, - const TCHAR *text, const TCHAR *display_string=nullptr, - const TCHAR *help=nullptr) noexcept + const char *text, const char *display_string=nullptr, + const char *help=nullptr) noexcept { /* the upper 16 bit is the port type, and the lower 16 bit is a serial number to make the enum id unique */ @@ -100,39 +102,70 @@ DetectSerialPorts(DataFieldEnum &df) noexcept #elif defined(_WIN32) -/** - * If this is a "COMx" name, parse "x" and return it; otherwise, - * return -1. - */ -[[gnu::pure]] -static int -ComIndex(TCHAR *name) noexcept -{ - const TCHAR *suffix = StringAfterPrefix(name, _T("COM")); - if (suffix == nullptr) - return -1; - - TCHAR *endptr; - const auto i = _tcstoul(suffix, &endptr, 10); - if (endptr == suffix || *endptr != _T('\0')) - return -1; - - return static_cast(i); -} - static void DetectSerialPorts(DataFieldEnum &df) noexcept try { +//------------------------------- + RegistryKey bthenums{HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\" + "Enum\\BthEnum"}; + std::map bthmap; + for (unsigned k = 0;; ++k) { + char dev_name[128]; + char name[128]; + char friendly_name[128]; + + if (!bthenums.EnumKey(k, std::span{dev_name})) + break; + std::string map_name(dev_name); + if (!map_name.starts_with("Dev_")) + continue; + RegistryKey bthenum_dev{bthenums, dev_name}; + // only one is possible... + if (!bthenum_dev.EnumKey(0, std::span{name})) + break; + RegistryKey bthenum_key{bthenum_dev, name}; + if (!bthenum_key.GetValue("FriendlyName", friendly_name)) + break; + map_name = map_name.substr(4); + for (std::string::iterator it = map_name.begin(); it != map_name.end(); + ++it) + *it = towlower(*it); + bthmap[map_name] = friendly_name; // Left "Dev_" + } + RegistryKey bthle{HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\" + "Enum\\BthLE"}; + std::map blemap; + for (unsigned k = 0;; ++k) { + char dev_name[128]; + char name[128]; + char friendly_name[128]; + + if (!bthle.EnumKey(k, std::span{dev_name})) + break; + std::string map_name(dev_name); + if (!map_name.starts_with("Dev_")) + continue; + RegistryKey bthle_dev{bthle, dev_name}; + // only one is possible... + if (!bthle_dev.EnumKey(0, std::span{name})) + break; + RegistryKey bthle_key{bthle_dev, name}; + if (!bthle_key.GetValue("FriendlyName", friendly_name)) + break; + map_name = map_name.substr(4); + for (std::string::iterator it = map_name.begin(); it != map_name.end(); + ++it) + *it = towlower(*it); + blemap[map_name] = friendly_name; // Left "Dev_" + } + /* the registry key HKEY_LOCAL_MACHINE/Hardware/DEVICEMAP/SERIALCOMM is the best way to discover serial ports on Windows */ - - RegistryKey hardware{HKEY_LOCAL_MACHINE, _T("Hardware")}; - RegistryKey devicemap{hardware, _T("DEVICEMAP")}; - RegistryKey serialcomm{devicemap, _T("SERIALCOMM")}; + RegistryKey serialcomm{HKEY_LOCAL_MACHINE, "Hardware\\DeviceMap\\SerialComm"}; for (unsigned i = 0;; ++i) { - TCHAR name[128]; - TCHAR value[64]; + char name[128]; + char value[64]; DWORD type; if (!serialcomm.EnumValue(i, std::span{name}, &type, @@ -143,21 +176,57 @@ try { // weird continue; - const TCHAR *path = value; - - TCHAR buffer[128]; - if (const auto com_idx = ComIndex(value); com_idx >= 0) { - if (com_idx < 10) - /* old-style raw names (with trailing colon for backwards - compatibility with older XCSoar versions) */ - StringFormatUnsafe(buffer, _T("%s:"), value); - else - /* COM10 and above must use UNC paths */ - StringFormatUnsafe(buffer, _T("\\\\.\\%s"), value); - path = buffer; - } + RegistryKey devices {HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\" + "Control\\COM Name Arbiter\\Devices"}; + char name1[0x200]; + + if (!devices.GetValue(value, name1)) + break; - AddPort(df, DeviceConfig::PortType::SERIAL, path, name); + // Registry "COM Name Arbiter\Devices" starts with + // BlueTooth: "\\?\bthenum#" + // USB: "\\?\usb#" + // Normal: "\\?\acpi#" - an Kupschis Rechner! + std::string dev = name1; + if (dev.starts_with("\\\\?\\usb#")) { + std::vector strs; + std::string port_name; + boost::split(strs, name, boost::is_any_of("\\")); + port_name = value; + port_name += " ("; + port_name += strs[2]; + port_name += ")"; + + AddPort(df, DeviceConfig::PortType::USB_SERIAL, value, port_name.c_str()); + } else if (dev.starts_with("\\\\?\\bthenum#")) { + std::vector strs; + std::string port_name; + boost::split(strs, name1, boost::is_any_of("#")); + boost::split(strs, strs[2], boost::is_any_of("_")); + if (strs[1] == "c00000000") { + boost::split(strs, strs[0], boost::is_any_of("&")); + if (strs[3] != "000000000000") { + DeviceConfig::PortType port_type = DeviceConfig::PortType::DISABLED; + port_name = value; + port_name += " ("; + if (blemap.find(strs[3]) != blemap.end()) { + port_type = DeviceConfig::PortType::RFCOMM; + port_type = DeviceConfig::PortType::BLE_HM10; + // port_type = DeviceConfig::PortType::BLE_SENSOR; + port_name += blemap[strs[3]]; + } else if (bthmap.find(strs[3]) != bthmap.end()) { + port_type = DeviceConfig::PortType::RFCOMM; + port_name += bthmap[strs[3]]; + } + + port_name += ")"; + if (port_type != DeviceConfig::PortType::DISABLED) + AddPort(df, port_type, value, + port_name.c_str()); + } + } + } else // if (dev.starts_with("\\\\?\\acpi#")) + AddPort(df, DeviceConfig::PortType::SERIAL, value, name); } } catch (const std::system_error &) { // silently ignore registry errors @@ -177,9 +246,11 @@ FillPortTypes(DataFieldEnum &df, const DeviceConfig &config) noexcept } } -void +// this function is only used inside this source file. +// maybe this is to check with the tests! +static void SetPort(DataFieldEnum &df, DeviceConfig::PortType type, - const TCHAR *value) noexcept + const char *value) noexcept { assert(value != nullptr); @@ -187,25 +258,32 @@ SetPort(DataFieldEnum &df, DeviceConfig::PortType type, df.SetValue(AddPort(df, type, value)); } -static void -FillSerialPorts(DataFieldEnum &df, const DeviceConfig &config) noexcept -{ +static void FillSerialPorts(DataFieldEnum &df, + const DeviceConfig &config) noexcept { #if defined(HAVE_POSIX) || defined(_WIN32) DetectSerialPorts(df); #endif - if (config.port_type == DeviceConfig::PortType::SERIAL) + switch (config.port_type) { + case DeviceConfig::PortType::SERIAL: + case DeviceConfig::PortType::RFCOMM: + case DeviceConfig::PortType::BLE_HM10: + case DeviceConfig::PortType::BLE_SENSOR: + case DeviceConfig::PortType::USB_SERIAL: SetPort(df, config.port_type, config.path); + default: + break; + } } void SetBluetoothPort(DataFieldEnum &df, DeviceConfig::PortType type, - const TCHAR *bluetooth_mac) noexcept + const char *bluetooth_mac) noexcept { assert(bluetooth_mac != nullptr); if (!df.SetValue(bluetooth_mac)) { - const TCHAR *name = nullptr; + const char *name = nullptr; #ifdef ANDROID if (bluetooth_helper != nullptr) name = bluetooth_helper->GetNameFromAddress(Java::GetEnv(), @@ -229,9 +307,9 @@ FillAndroidUsbSerialPorts([[maybe_unused]] DataFieldEnum &df, [[maybe_unused]] const DeviceConfig &config) noexcept { #ifdef ANDROID - if (config.port_type == DeviceConfig::PortType::ANDROID_USB_SERIAL && + if (config.port_type == DeviceConfig::PortType::USB_SERIAL && !config.path.empty()) - SetPort(df, DeviceConfig::PortType::ANDROID_USB_SERIAL, config.path); + SetPort(df, DeviceConfig::PortType::USB_SERIAL, config.path); #endif } @@ -241,11 +319,11 @@ FillAndroidIOIOPorts([[maybe_unused]] DataFieldEnum &df, [[maybe_unused]] const #if defined(ANDROID) df.EnableItemHelp(true); - TCHAR tempID[4]; - TCHAR tempName[15]; + char tempID[4]; + char tempName[15]; for (unsigned i = 0; i < AndroidIOIOUartPort::getNumberUarts(); i++) { - StringFormatUnsafe(tempID, _T("%u"), i); - StringFormat(tempName, sizeof(tempName), _T("IOIO UART %u"), i); + StringFormatUnsafe(tempID, "%u", i); + StringFormat(tempName, sizeof(tempName), "IOIO UART %u", i); unsigned id = AddPort(df, DeviceConfig::PortType::IOIOUART, tempID, tempName, AndroidIOIOUartPort::getPortHelp(i)); @@ -268,7 +346,7 @@ FillPorts(DataFieldEnum &df, const DeviceConfig &config) noexcept void UpdatePortEntry(DataFieldEnum &df, DeviceConfig::PortType type, - const TCHAR *value, const TCHAR *name) noexcept + const char *value, const char *name) noexcept { for (std::size_t i = 0, n = df.Count(); i < n; ++i) { const auto &item = df[i]; @@ -283,8 +361,14 @@ UpdatePortEntry(DataFieldEnum &df, DeviceConfig::PortType type, AddPort(df, type, value, name); } +/* +with some compiler and constellations the function name 'SetPort' makes +problems during the linking: +SetPort(DataFieldEnum&, const DeviceConfig&) not found... +After renaming to SetDevicePort this problem disappears. +*/ void -SetPort(DataFieldEnum &df, const DeviceConfig &config) noexcept +SetDevicePort(DataFieldEnum &df, const DeviceConfig &config) noexcept { switch (config.port_type) { case DeviceConfig::PortType::DISABLED: @@ -303,7 +387,7 @@ SetPort(DataFieldEnum &df, const DeviceConfig &config) noexcept break; case DeviceConfig::PortType::SERIAL: - case DeviceConfig::PortType::ANDROID_USB_SERIAL: + case DeviceConfig::PortType::USB_SERIAL: SetPort(df, config.port_type, config.path); return; @@ -315,7 +399,7 @@ SetPort(DataFieldEnum &df, const DeviceConfig &config) noexcept case DeviceConfig::PortType::IOIOUART: StaticString<16> buffer; - buffer.UnsafeFormat(_T("%d"), config.ioio_uart_id); + buffer.UnsafeFormat("%d", config.ioio_uart_id); df.SetValue(buffer); return; } diff --git a/src/Dialogs/Device/PortDataField.hpp b/src/Dialogs/Device/PortDataField.hpp index a4c375e79c6..ae191900369 100644 --- a/src/Dialogs/Device/PortDataField.hpp +++ b/src/Dialogs/Device/PortDataField.hpp @@ -14,18 +14,14 @@ FillPorts(DataFieldEnum &df, const DeviceConfig &config) noexcept; void UpdatePortEntry(DataFieldEnum &df, DeviceConfig::PortType type, - const TCHAR *value, const TCHAR *name) noexcept; - -void -SetPort(DataFieldEnum &df, DeviceConfig::PortType type, - const TCHAR *value) noexcept; + const char *value, const char *name) noexcept; void SetBluetoothPort(DataFieldEnum &df, DeviceConfig::PortType type, - const TCHAR *bluetooth_mac) noexcept; + const char *bluetooth_mac) noexcept; void -SetPort(DataFieldEnum &df, const DeviceConfig &config) noexcept; +SetDevicePort(DataFieldEnum &df, const DeviceConfig &config) noexcept; [[gnu::pure]] DeviceConfig::PortType diff --git a/src/Dialogs/Device/PortMonitor.cpp b/src/Dialogs/Device/PortMonitor.cpp index 6f8d89a7739..e0fd75bb0ba 100644 --- a/src/Dialogs/Device/PortMonitor.cpp +++ b/src/Dialogs/Device/PortMonitor.cpp @@ -51,7 +51,7 @@ class PortTerminalBridge final : public DataHandler { private: void OnNotification() noexcept { while (true) { - std::array data; + std::array data; size_t length; { @@ -155,9 +155,9 @@ ShowPortMonitor(DeviceDescriptor &device) { const Look &look = UIGlobals::GetLook(); - std::array buffer; + std::array buffer; StaticString<128> caption; - caption.Format(_T("%s: %s"), _("Port monitor"), + caption.Format("%s: %s", _("Port monitor"), device.GetConfig().GetPortName(buffer.data(), buffer.size())); TWidgetDialog diff --git a/src/Dialogs/Device/PortPicker.cpp b/src/Dialogs/Device/PortPicker.cpp index 82aab11e0ff..2d35d6c4a26 100644 --- a/src/Dialogs/Device/PortPicker.cpp +++ b/src/Dialogs/Device/PortPicker.cpp @@ -36,7 +36,7 @@ class PortListItemRenderer final { void PaintItem(Canvas &canvas, PixelRect rc, const ComboList::Item &item) noexcept { - if (const TCHAR *text = ToDisplayString(DeviceConfig::PortType(item.int_value >> 16)); + if (const char *text = ToDisplayString(DeviceConfig::PortType(item.int_value >> 16)); text != nullptr) rc.right = row_renderer.DrawRightColumn(canvas, rc, text); @@ -44,10 +44,10 @@ class PortListItemRenderer final { } private: - static const TCHAR *ToDisplayString(DeviceConfig::PortType type) noexcept { + static const char *ToDisplayString(DeviceConfig::PortType type) noexcept { switch (type) { case DeviceConfig::PortType::RFCOMM: - return _T("Bluetooth"); + return "Bluetooth"; case DeviceConfig::PortType::BLE_HM10: return _("BLE port"); @@ -55,7 +55,7 @@ class PortListItemRenderer final { case DeviceConfig::PortType::BLE_SENSOR: return _("BLE sensor"); - case DeviceConfig::PortType::ANDROID_USB_SERIAL: + case DeviceConfig::PortType::USB_SERIAL: return _("USB serial"); default: @@ -84,7 +84,7 @@ class PortPickerWidget struct DetectedPort { DeviceConfig::PortType type; - tstring address, name; + std::string address, name; }; Mutex detected_mutex; @@ -245,7 +245,7 @@ PortPickerWidget::OnDeviceDetected(Type type, const char *address, break; case Type::USB_SERIAL: - port_type = DeviceConfig::PortType::ANDROID_USB_SERIAL; + port_type = DeviceConfig::PortType::USB_SERIAL; break; } @@ -282,7 +282,7 @@ PortPickerWidget::OnDetectedNotification() noexcept #endif bool -PortPicker(DataFieldEnum &df, const TCHAR *caption) noexcept +PortPicker(DataFieldEnum &df, const char *caption) noexcept { TWidgetDialog dialog(WidgetDialog::Full{}, UIGlobals::GetMainWindow(), diff --git a/src/Dialogs/Device/PortPicker.hpp b/src/Dialogs/Device/PortPicker.hpp index a63d9fa423a..2c18c6bd00d 100644 --- a/src/Dialogs/Device/PortPicker.hpp +++ b/src/Dialogs/Device/PortPicker.hpp @@ -8,4 +8,4 @@ class DataFieldEnum; #include bool -PortPicker(DataFieldEnum &df, const TCHAR *caption) noexcept; +PortPicker(DataFieldEnum &df, const char *caption) noexcept; diff --git a/src/Dialogs/Device/Vega/AlertParameters.hpp b/src/Dialogs/Device/Vega/AlertParameters.hpp index 6d51c547144..96a34407258 100644 --- a/src/Dialogs/Device/Vega/AlertParameters.hpp +++ b/src/Dialogs/Device/Vega/AlertParameters.hpp @@ -10,25 +10,25 @@ static constexpr VegaParametersWidget::StaticParameter alert_parameters[] = { { DataField::Type::INTEGER, "GearOnDelay", N_("Gear on delay"), NULL, - NULL, 1, 2000, 50, _T("%d ms") }, + NULL, 1, 2000, 50, "%d ms" }, { DataField::Type::INTEGER, "GearOffDelay", N_("Gear off delay"), NULL, - NULL, 1, 2000, 50, _T("%d ms") }, + NULL, 1, 2000, 50, "%d ms" }, { DataField::Type::INTEGER, "GearRepeatTime", N_("Interval; gear"), NULL, - NULL, 1, 100, 1, _T("%d s") }, + NULL, 1, 100, 1, "%d s" }, { DataField::Type::INTEGER, "PlyMaxComDelay", N_("Radio com. max. delay"), NULL, - NULL, 0, 100, 1, _T("%d s") }, + NULL, 0, 100, 1, "%d s" }, { DataField::Type::INTEGER, "BatLowDelay", N_("Battery low delay"), NULL, - NULL, 0, 100, 1, _T("%d s") }, + NULL, 0, 100, 1, "%d s" }, { DataField::Type::INTEGER, "BatEmptyDelay", N_("Battery empty delay"), NULL, - NULL, 0, 100, 1, _T("%d s") }, + NULL, 0, 100, 1, "%d s" }, { DataField::Type::INTEGER, "BatRepeatTime", N_("Interval; battery"), NULL, - NULL, 0, 100, 1, _T("%d s") }, + NULL, 0, 100, 1, "%d s" }, /* sentinel */ { DataField::Type::BOOLEAN } diff --git a/src/Dialogs/Device/Vega/AudioDeadbandParameters.hpp b/src/Dialogs/Device/Vega/AudioDeadbandParameters.hpp index 4fccce3ae09..6627bcdde6c 100644 --- a/src/Dialogs/Device/Vega/AudioDeadbandParameters.hpp +++ b/src/Dialogs/Device/Vega/AudioDeadbandParameters.hpp @@ -23,12 +23,12 @@ VegaParametersWidget::StaticParameter audio_deadband_parameters[] = { { DataField::Type::INTEGER, "ToneDeadbandCirclingHigh", N_("Circling hi cutoff"), N_("High limit of circling dead band"), - NULL, 0, 100, 1, _T("%d %%"), + NULL, 0, 100, 1, "%d %%", }, { DataField::Type::INTEGER, "ToneDeadbandCirclingLow", N_("Circling low cutoff"), N_("Low limit of circling dead band"), - NULL, 0, 100, 1, _T("%d %%"), + NULL, 0, 100, 1, "%d %%", }, { DataField::Type::ENUM, "ToneDeadbandCruiseType", @@ -39,12 +39,12 @@ VegaParametersWidget::StaticParameter audio_deadband_parameters[] = { { DataField::Type::INTEGER, "ToneDeadbandCruiseHigh", N_("Cruise hi cutoff"), N_("High limit of cruise dead band"), - NULL, 0, 100, 1, _T("%d %%"), + NULL, 0, 100, 1, "%d %%", }, { DataField::Type::INTEGER, "ToneDeadbandCruiseLow", N_("Cruise low cutoff"), N_("Low limit of cruise dead band"), - NULL, 0, 100, 1, _T("%d %%"), + NULL, 0, 100, 1, "%d %%", }, /* sentinel */ diff --git a/src/Dialogs/Device/Vega/AudioModeParameters.hpp b/src/Dialogs/Device/Vega/AudioModeParameters.hpp index 07657b8afba..14ca644b291 100644 --- a/src/Dialogs/Device/Vega/AudioModeParameters.hpp +++ b/src/Dialogs/Device/Vega/AudioModeParameters.hpp @@ -10,38 +10,38 @@ static constexpr StaticEnumChoice tone_climb_comparisons[] = { { 0, N_("None") }, - { 1, _T("Gross>MacCready") }, - { 2, _T("Gross>Average") }, + { 1, "Gross>MacCready" }, + { 2, "Gross>Average" }, { 0 } }; static constexpr StaticEnumChoice tone_cruise_lift_detection_types[] = { { 0, N_("Disabled") }, - { 1, _T("Relative>0") }, - { 2, _T("Relative>MacCready/2") }, - { 3, _T("Gross>0") }, - { 4, _T("Net>MacCready/2") }, - { 5, _T("Relative>MacCready") }, - { 6, _T("Net>MacCready") }, + { 1, "Relative>0" }, + { 2, "Relative>MacCready/2" }, + { 3, "Gross>0" }, + { 4, "Net>MacCready/2" }, + { 5, "Relative>MacCready" }, + { 6, "Net>MacCready" }, { 0 } }; static constexpr StaticEnumChoice time_scales[] = { - { 0, _T(" 0.0s") }, - { 1, _T(" 0.8s") }, - { 2, _T(" 1.7s") }, - { 3, _T(" 3.5s") }, - { 4, _T(" 7.5s") }, - { 5, _T("15.0s") }, - { 6, _T("30.0s") }, + { 0, " 0.0s" }, + { 1, " 0.8s" }, + { 2, " 1.7s" }, + { 3, " 3.5s" }, + { 4, " 7.5s" }, + { 5, "15.0s" }, + { 6, "30.0s" }, { 0 } }; static constexpr StaticEnumChoice filter_time[] = { - { 0, _T(" 1.0s") }, - { 1, _T(" 1.3s") }, - { 2, _T(" 1.8s") }, - { 3, _T(" 2.7s") }, + { 0, " 1.0s" }, + { 1, " 1.3s" }, + { 2, " 1.8s" }, + { 3, " 2.7s" }, { 0 } }; @@ -69,17 +69,17 @@ VegaParametersWidget::StaticParameter audio_mode_parameters[] = { { DataField::Type::INTEGER, "ToneMeanVolumeCircling", N_("Circling volume"), N_("Mean volume level in circling modes."), - NULL, 0, 8, 1, _T("%d/8"), + NULL, 0, 8, 1, "%d/8", }, { DataField::Type::INTEGER, "ToneMeanVolumeCruise", N_("Cruise volume"), N_("Mean volume level in cruise modes. If set to zero, scales with airspeed."), - NULL, 0, 8, 1, _T("%d/8"), + NULL, 0, 8, 1, "%d/8", }, { DataField::Type::INTEGER, "ToneBaseFrequencyOffset", N_("Base frequency"), N_("Adjustment to base frequency of tones in all modes."), - NULL, -30, 30, 1, _T("%d"), + NULL, -30, 30, 1, "%d", }, { DataField::Type::ENUM, "VarioTimeConstantCircling", N_("Filter circling"), @@ -94,7 +94,7 @@ VegaParametersWidget::StaticParameter audio_mode_parameters[] = { { DataField::Type::INTEGER, "TonePitchScale", N_("Tone pitch scale"), N_("Adjustment to base pitch scale of tones in all modes."), - NULL, 32, 100, 1, _T("%d"), + NULL, 32, 100, 1, "%d", }, /* sentinel */ diff --git a/src/Dialogs/Device/Vega/AudioParameters.hpp b/src/Dialogs/Device/Vega/AudioParameters.hpp index a9ba1b6f487..6f4aeee585b 100644 --- a/src/Dialogs/Device/Vega/AudioParameters.hpp +++ b/src/Dialogs/Device/Vega/AudioParameters.hpp @@ -12,49 +12,49 @@ #include static constexpr StaticEnumChoice beep_types[] = { - { 0, _T("Silence") }, - { 1, _T("Short") }, - { 2, _T("Medium") }, - { 3, _T("Long") }, - { 4, _T("Continuous") }, - { 5, _T("Short double") }, + { 0, "Silence" }, + { 1, "Short" }, + { 2, "Medium" }, + { 3, "Long" }, + { 4, "Continuous" }, + { 5, "Short double" }, { 0 } }; static constexpr StaticEnumChoice pitch_schemes[] = { - { 0, _T("Constant high") }, - { 1, _T("Constant medium") }, - { 2, _T("Constant low") }, - { 3, _T("Speed percent") }, - { 4, _T("Speed error") }, - { 5, _T("Vario gross") }, - { 6, _T("Vario net") }, - { 7, _T("Vario relative") }, - { 8, _T("Vario gross/relative") }, + { 0, "Constant high" }, + { 1, "Constant medium" }, + { 2, "Constant low" }, + { 3, "Speed percent" }, + { 4, "Speed error" }, + { 5, "Vario gross" }, + { 6, "Vario net" }, + { 7, "Vario relative" }, + { 8, "Vario gross/relative" }, { 0 } }; static constexpr StaticEnumChoice period_schemes[] = { - { 0, _T("Constant high") }, - { 1, _T("Constant medium") }, - { 2, _T("Constant low") }, - { 3, _T("Speed percent") }, - { 4, _T("Speed error") }, - { 5, _T("Vario gross") }, - { 6, _T("Vario net") }, - { 7, _T("Vario relative") }, - { 8, _T("Vario gross/relative") }, - { 9, _T("Intermittent") }, + { 0, "Constant high" }, + { 1, "Constant medium" }, + { 2, "Constant low" }, + { 3, "Speed percent" }, + { 4, "Speed error" }, + { 5, "Vario gross" }, + { 6, "Vario net" }, + { 7, "Vario relative" }, + { 8, "Vario gross/relative" }, + { 9, "Intermittent" }, { 0 } }; static constexpr StaticEnumChoice pitch_and_period_scales[] = { - { 0, _T("+Linear") }, - { 1, _T("+Low end") }, - { 2, _T("+High end") }, - { 3, _T("-Linear") }, - { 4, _T("-Low end") }, - { 5, _T("-High end") }, + { 0, "+Linear" }, + { 1, "+Low end" }, + { 2, "+High end" }, + { 3, "-Linear" }, + { 4, "-Low end" }, + { 5, "-High end" }, { 0 } }; diff --git a/src/Dialogs/Device/Vega/CalibrationParameters.hpp b/src/Dialogs/Device/Vega/CalibrationParameters.hpp index cf4a11f2e91..ca9cd7b2100 100644 --- a/src/Dialogs/Device/Vega/CalibrationParameters.hpp +++ b/src/Dialogs/Device/Vega/CalibrationParameters.hpp @@ -11,22 +11,22 @@ VegaParametersWidget::StaticParameter calibration_parameters[] = { { DataField::Type::INTEGER, "TotalEnergyMixingRatio", N_("TE mixing"), N_("Proportion of TE probe value used in total energy mixing with pitot/static total energy."), - NULL, 0, 8, 1, _T("%d/8"), + NULL, 0, 8, 1, "%d/8", }, { DataField::Type::INTEGER, "CalibrationAirSpeed", N_("ASI cal."), N_("Calibration factor applied to measured airspeed to obtain indicated airspeed."), - NULL, 0, 200, 1, _T("%d %%"), + NULL, 0, 200, 1, "%d %%", }, { DataField::Type::INTEGER, "CalibrationTEStatic", N_("TE static cal."), N_("Calibration factor applied to static pressure used in total energy calculation."), - NULL, 0, 200, 1, _T("%d %%"), + NULL, 0, 200, 1, "%d %%", }, { DataField::Type::INTEGER, "CalibrationTEDynamic", N_("TE dynamic cal."), N_("Calibration factor applied to dynamic pressure used in total energy calculation."), - NULL, 0, 200, 1, _T("%d %%"), + NULL, 0, 200, 1, "%d %%", }, /* sentinel */ diff --git a/src/Dialogs/Device/Vega/DisplayParameters.hpp b/src/Dialogs/Device/Vega/DisplayParameters.hpp index 3f26b98d707..a3d45738c92 100644 --- a/src/Dialogs/Device/Vega/DisplayParameters.hpp +++ b/src/Dialogs/Device/Vega/DisplayParameters.hpp @@ -8,9 +8,9 @@ #include "Language/Language.hpp" static constexpr StaticEnumChoice needle_gauge_types[] = { - { 0, _T("None") }, - { 1, _T("LX") }, - { 2, _T("Analog") }, + { 0, "None" }, + { 1, "LX" }, + { 2, "Analog" }, { 0 }, }; @@ -19,7 +19,7 @@ VegaParametersWidget::StaticParameter display_parameters[] = { { DataField::Type::ENUM, "NeedleGaugeType", N_("Needle gauge type"), NULL, needle_gauge_types }, { DataField::Type::INTEGER, "LedBrightness", N_("LED bright"), NULL, - NULL, 1, 15, 1, _T("%d/15") }, + NULL, 1, 15, 1, "%d/15" }, /* sentinel */ { DataField::Type::BOOLEAN } diff --git a/src/Dialogs/Device/Vega/FlarmAlertParameters.hpp b/src/Dialogs/Device/Vega/FlarmAlertParameters.hpp index 942fde29d52..eac0a63e34d 100644 --- a/src/Dialogs/Device/Vega/FlarmAlertParameters.hpp +++ b/src/Dialogs/Device/Vega/FlarmAlertParameters.hpp @@ -8,19 +8,19 @@ #include "Language/Language.hpp" static constexpr StaticEnumChoice flarm_user_interfaces[] = { - { 0, _T("LED+Buzzer") }, - { 1, _T("None") }, - { 2, _T("Buzzer") }, - { 3, _T("LED") }, + { 0, "LED+Buzzer" }, + { 1, "None" }, + { 2, "Buzzer" }, + { 3, "LED" }, { 0 } }; static constexpr VegaParametersWidget::StaticParameter flarm_alert_parameters[] = { { DataField::Type::INTEGER, "FlarmMaxObjectsReported", - N_("Max. objects reported"), NULL, NULL, 0, 15, 1, _T("%d") }, + N_("Max. objects reported"), NULL, NULL, 0, 15, 1, "%d" }, { DataField::Type::INTEGER, "FlarmMaxObjectsReportedOnCircling", - N_("Max. reported"), NULL, NULL, 0, 4, 1, _T("%d") }, + N_("Max. reported"), NULL, NULL, 0, 4, 1, "%d" }, { DataField::Type::ENUM, "FlarmUserInterface", N_("Flarm interface"), NULL, flarm_user_interfaces }, { DataField::Type::BOOLEAN, "KeepOnStraightFlightMode", diff --git a/src/Dialogs/Device/Vega/FlarmIdentificationParameters.hpp b/src/Dialogs/Device/Vega/FlarmIdentificationParameters.hpp index 8ad4ddf8a7d..74185ca6006 100644 --- a/src/Dialogs/Device/Vega/FlarmIdentificationParameters.hpp +++ b/src/Dialogs/Device/Vega/FlarmIdentificationParameters.hpp @@ -8,21 +8,21 @@ #include "Language/Language.hpp" static constexpr StaticEnumChoice flarm_aircraft_types[] = { - { 0, _T("Undefined") }, - { 1, _T("Glider") }, - { 2, _T("Tow plane") }, - { 3, _T("Helicopter") }, - { 4, _T("Parachute") }, - { 5, _T("Drop plane") }, - { 6, _T("Fixed hangglider") }, - { 7, _T("Soft paraglider") }, - { 8, _T("Powered aircraft") }, - { 9, _T("Jet aircraft") }, - { 10, _T("UFO") }, - { 11, _T("Baloon") }, - { 12, _T("Blimp, Zeppelin") }, - { 13, _T("UAV (Drone)") }, - { 14, _T("Static") }, + { 0, "Undefined" }, + { 1, "Glider" }, + { 2, "Tow plane" }, + { 3, "Helicopter" }, + { 4, "Parachute" }, + { 5, "Drop plane" }, + { 6, "Fixed hangglider" }, + { 7, "Soft paraglider" }, + { 8, "Powered aircraft" }, + { 9, "Jet aircraft" }, + { 10, "UFO" }, + { 11, "Baloon" }, + { 12, "Blimp, Zeppelin" }, + { 13, "UAV (Drone)" }, + { 14, "Static" }, { 0 } }; diff --git a/src/Dialogs/Device/Vega/FlarmRepeatParameters.hpp b/src/Dialogs/Device/Vega/FlarmRepeatParameters.hpp index 7b860f5ec38..6e38ea4f144 100644 --- a/src/Dialogs/Device/Vega/FlarmRepeatParameters.hpp +++ b/src/Dialogs/Device/Vega/FlarmRepeatParameters.hpp @@ -10,13 +10,13 @@ static constexpr VegaParametersWidget::StaticParameter flarm_repeat_parameters[] = { { DataField::Type::INTEGER, "FlarmInfoRepeatTime", N_("Interval; info"), NULL, - NULL, 1, 2000, 100, _T("%d ms") }, + NULL, 1, 2000, 100, "%d ms" }, { DataField::Type::INTEGER, "FlarmCautionRepeatTime", N_("Interval; caution"), NULL, - NULL, 1, 2000, 100, _T("%d ms") }, + NULL, 1, 2000, 100, "%d ms" }, { DataField::Type::INTEGER, "FlarmWarningRepeatTime", N_("Interval; warning"), NULL, - NULL, 1, 2000, 100, _T("%d ms") }, + NULL, 1, 2000, 100, "%d ms" }, /* sentinel */ { DataField::Type::BOOLEAN } diff --git a/src/Dialogs/Device/Vega/HardwareParameters.hpp b/src/Dialogs/Device/Vega/HardwareParameters.hpp index 482caad6fb6..269a298a28e 100644 --- a/src/Dialogs/Device/Vega/HardwareParameters.hpp +++ b/src/Dialogs/Device/Vega/HardwareParameters.hpp @@ -15,13 +15,13 @@ static constexpr StaticEnumChoice tri_state[] = { }; static constexpr StaticEnumChoice baud_rates[] = { - { 0, _T("Auto") }, - { 1, _T("4800") }, - { 2, _T("9600") }, - { 3, _T("19200") }, - { 4, _T("38400") }, - { 5, _T("57600") }, - { 6, _T("115200") }, + { 0, "Auto" }, + { 1, "4800" }, + { 2, "9600" }, + { 3, "19200" }, + { 4, "38400" }, + { 5, "57600" }, + { 6, "115200" }, { 0 }, }; diff --git a/src/Dialogs/Device/Vega/LimitParameters.hpp b/src/Dialogs/Device/Vega/LimitParameters.hpp index a3e4946542f..8d3eb8a76a1 100644 --- a/src/Dialogs/Device/Vega/LimitParameters.hpp +++ b/src/Dialogs/Device/Vega/LimitParameters.hpp @@ -9,17 +9,17 @@ static constexpr VegaParametersWidget::StaticParameter limit_parameters[] = { { DataField::Type::INTEGER, "VelocityNeverExceed", N_("VNE"), NULL, - NULL, 0, 2000, 10, _T("%d (0.1 m/s)") }, + NULL, 0, 2000, 10, "%d (0.1 m/s)" }, { DataField::Type::INTEGER, "VelocitySafeTerrain", N_("V terrain"), NULL, - NULL, 0, 2000, 10, _T("%d (0.1 m/s)") }, + NULL, 0, 2000, 10, "%d (0.1 m/s)" }, { DataField::Type::INTEGER, "VelocitySafeTerrain", N_("Height terrain"), - NULL, NULL, 0, 2000, 10, _T("%d m") }, + NULL, NULL, 0, 2000, 10, "%d m" }, { DataField::Type::INTEGER, "VelocityManoeuvering", N_("V manoeuvering"), - NULL, NULL, 0, 2000, 10, _T("%d (0.1 m/s)") }, + NULL, NULL, 0, 2000, 10, "%d (0.1 m/s)" }, { DataField::Type::INTEGER, "VelocityAirBrake", N_("V airbrake"), - NULL, NULL, 0, 2000, 10, _T("%d (0.1 m/s)") }, + NULL, NULL, 0, 2000, 10, "%d (0.1 m/s)" }, { DataField::Type::INTEGER, "VelocityFlap", N_("V flap"), - NULL, NULL, 0, 2000, 10, _T("%d (0.1 m/s)") }, + NULL, NULL, 0, 2000, 10, "%d (0.1 m/s)" }, /* sentinel */ { DataField::Type::BOOLEAN } diff --git a/src/Dialogs/Device/Vega/LoggerParameters.hpp b/src/Dialogs/Device/Vega/LoggerParameters.hpp index 9783ac87789..231e8ec00e0 100644 --- a/src/Dialogs/Device/Vega/LoggerParameters.hpp +++ b/src/Dialogs/Device/Vega/LoggerParameters.hpp @@ -10,14 +10,14 @@ static constexpr VegaParametersWidget::StaticParameter logger_parameters[] = { { DataField::Type::INTEGER, "UTCOffset", N_("UTC offset"), NULL, - NULL, -13, 13, 1, _T("%d"), + NULL, -13, 13, 1, "%d", }, { DataField::Type::BOOLEAN, "IGCLoging", N_("IGC logging"), }, { DataField::Type::INTEGER, "IGCLoggerInterval", N_("Logger interval"), NULL, - NULL, 1, 12, 1, _T("%d"), + NULL, 1, 12, 1, "%d", }, /* sentinel */ diff --git a/src/Dialogs/Device/Vega/MixerParameters.hpp b/src/Dialogs/Device/Vega/MixerParameters.hpp index af93d6bc045..1a54a2c0dc5 100644 --- a/src/Dialogs/Device/Vega/MixerParameters.hpp +++ b/src/Dialogs/Device/Vega/MixerParameters.hpp @@ -11,15 +11,15 @@ VegaParametersWidget::StaticParameter mixer_parameters[] = { { DataField::Type::BOOLEAN, "MuteVarioOnPlay", N_("Mute vario on voice") }, { DataField::Type::BOOLEAN, "MuteVarioOnCom", N_("Mute vario on radio") }, { DataField::Type::INTEGER, "VarioRelativeMuteVol", N_("Vario muting"), - NULL, NULL, 0, 254, 1, _T("%d/255") }, + NULL, NULL, 0, 254, 1, "%d/255" }, { DataField::Type::INTEGER, "VoiceRelativeMuteVol", N_("Voice muting"), - NULL, NULL, 0, 254, 1, _T("%d/255") }, + NULL, NULL, 0, 254, 1, "%d/255" }, { DataField::Type::INTEGER, "MuteComSpkThreshold", N_("Speaker threshold"), - NULL, NULL, 0, 254, 1, _T("%d/255") }, + NULL, NULL, 0, 254, 1, "%d/255" }, { DataField::Type::INTEGER, "MuteComPhnThreshold", N_("Headset threshold"), - NULL, NULL, 0, 254, 1, _T("%d/255") }, + NULL, NULL, 0, 254, 1, "%d/255" }, { DataField::Type::INTEGER, "MinUrgentVolume", N_("Urgent min. volume"), - NULL, NULL, 0, 254, 1, _T("%d/255") }, + NULL, NULL, 0, 254, 1, "%d/255" }, /* sentinel */ { DataField::Type::BOOLEAN } diff --git a/src/Dialogs/Device/Vega/VegaConfigurationDialog.cpp b/src/Dialogs/Device/Vega/VegaConfigurationDialog.cpp index a8734579af5..db0cf785b8d 100644 --- a/src/Dialogs/Device/Vega/VegaConfigurationDialog.cpp +++ b/src/Dialogs/Device/Vega/VegaConfigurationDialog.cpp @@ -25,26 +25,26 @@ #include "Look/DialogLook.hpp" #include "Operation/MessageOperationEnvironment.hpp" -static const TCHAR *const captions[] = { - _T(" 1 Hardware"), - _T(" 2 Calibration"), - _T(" 3 Audio Modes"), - _T(" 4 Deadband"), - _T(" 5 Tones: Cruise Faster"), - _T(" 6 Tones: Cruise Slower"), - _T(" 7 Tones: Cruise in Lift"), - _T(" 8 Tones: Circling, climbing fast"), - _T(" 9 Tones: Circling, climbing slow"), - _T("10 Tones: Circling, descending"), - _T("11 Vario flight logger"), - _T("12 Audio mixer"), - _T("13 FLARM Alerts"), - _T("14 FLARM Identification"), - _T("15 FLARM Repeats"), - _T("16 Alerts"), - _T("17 Airframe Limits"), - _T("18 Audio Schemes"), - _T("19 Display"), +static const char *const captions[] = { + " 1 Hardware", + " 2 Calibration", + " 3 Audio Modes", + " 4 Deadband", + " 5 Tones: Cruise Faster", + " 6 Tones: Cruise Slower", + " 7 Tones: Cruise in Lift", + " 8 Tones: Circling, climbing fast", + " 9 Tones: Circling, climbing slow", + "10 Tones: Circling, descending", + "11 Vario flight logger", + "12 Audio mixer", + "13 FLARM Alerts", + "14 FLARM Identification", + "15 FLARM Repeats", + "16 Alerts", + "17 Airframe Limits", + "18 Audio Schemes", + "19 Display", }; static const char *const audio_pages[] = { @@ -130,7 +130,7 @@ static void SetParametersScheme(PagerWidget &pager, int schemetype) { if(ShowMessageBox(_("Set new audio scheme? Old values will be lost."), - _T("Vega"), + "Vega", MB_YESNO | MB_ICONQUESTION) != IDYES) return; @@ -201,10 +201,10 @@ class VegaSchemeButtonsPage : public RowFormWidget { void Prepare(ContainerWindow &parent, const PixelRect &rc) noexcept override { RowFormWidget::Prepare(parent, rc); - AddButton(_T("Vega"), MakeSetParametersScheme(pager, 0)); - AddButton(_T("Borgelt"), MakeSetParametersScheme(pager, 1)); - AddButton(_T("Cambridge"), MakeSetParametersScheme(pager, 2)); - AddButton(_T("Zander"), MakeSetParametersScheme(pager, 3)); + AddButton("Vega", MakeSetParametersScheme(pager, 0)); + AddButton("Borgelt", MakeSetParametersScheme(pager, 1)); + AddButton("Cambridge", MakeSetParametersScheme(pager, 2)); + AddButton("Zander", MakeSetParametersScheme(pager, 3)); } }; diff --git a/src/Dialogs/Device/Vega/VegaDemoDialog.cpp b/src/Dialogs/Device/Vega/VegaDemoDialog.cpp index 3c6e2ffa2bf..9b129027489 100644 --- a/src/Dialogs/Device/Vega/VegaDemoDialog.cpp +++ b/src/Dialogs/Device/Vega/VegaDemoDialog.cpp @@ -29,8 +29,8 @@ VegaWriteDemo() if (!last_time.CheckUpdate(std::chrono::milliseconds(250))) return; - TCHAR dbuf[100]; - _stprintf(dbuf, _T("PDVDD,%d,%d"), + char dbuf[100]; + _stprintf(dbuf, "PDVDD,%d,%d", iround(VegaDemoW * 10), iround(VegaDemoV * 10)); @@ -80,14 +80,14 @@ VegaDemoWidget::Prepare([[maybe_unused]] ContainerWindow &parent, [[maybe_unused { AddFloat(_("TE vario"), _("This produces a fake TE vario gross vertical velocity. It can be used when in circling mode to demonstrate the lift tones. When not in circling mode, set this to a realistic negative value so speed command tones are produced."), - _T("%.1f %s"), _T("%.1f"), + "%.1f %s", "%.1f", Units::ToUserVSpeed(-20), Units::ToUserVSpeed(20), GetUserVerticalSpeedStep(), false, UnitGroup::VERTICAL_SPEED, VegaDemoW, this); AddFloat(_("Airspeed"), _("This produces a fake airspeed. It can be used when not in circling mode to demonstrate the speed command tones."), - _T("%.0f %s"), _T("%.0f"), 0, 200, 2, + "%.0f %s", "%.0f", 0, 200, 2, false, UnitGroup::HORIZONTAL_SPEED, VegaDemoV, this); AddBoolean(_("Circling"), @@ -99,8 +99,8 @@ void dlgVegaDemoShowModal() { PopupOperationEnvironment env; - backend_components->devices->VegaWriteNMEA(_T("PDVSC,S,DemoMode,0"), env); - backend_components->devices->VegaWriteNMEA(_T("PDVSC,S,DemoMode,3"), env); + backend_components->devices->VegaWriteNMEA("PDVSC,S,DemoMode,0", env); + backend_components->devices->VegaWriteNMEA("PDVSC,S,DemoMode,3", env); const DialogLook &look = UIGlobals::GetDialogLook(); TWidgetDialog @@ -111,5 +111,5 @@ dlgVegaDemoShowModal() dialog.ShowModal(); // deactivate demo. - backend_components->devices->VegaWriteNMEA(_T("PDVSC,S,DemoMode,0"), env); + backend_components->devices->VegaWriteNMEA("PDVSC,S,DemoMode,0", env); } diff --git a/src/Dialogs/Device/Vega/VegaParametersWidget.cpp b/src/Dialogs/Device/Vega/VegaParametersWidget.cpp index 9a44c687a61..422a5c6088e 100644 --- a/src/Dialogs/Device/Vega/VegaParametersWidget.cpp +++ b/src/Dialogs/Device/Vega/VegaParametersWidget.cpp @@ -10,18 +10,18 @@ #include void -VegaParametersWidget::AddBoolean(const char *name, const TCHAR *label, - const TCHAR *help) +VegaParametersWidget::AddBoolean(const char *name, const char *label, + const char *help) { AddParameter(name); RowFormWidget::AddBoolean(label, help); } void -VegaParametersWidget::AddInteger(const char *name, const TCHAR *label, - const TCHAR *help, +VegaParametersWidget::AddInteger(const char *name, const char *label, + const char *help, int min_value, int max_value, - const TCHAR *format) + const char *format) { AddParameter(name); RowFormWidget::AddInteger(label, help, format, format, @@ -29,8 +29,8 @@ VegaParametersWidget::AddInteger(const char *name, const TCHAR *label, } void -VegaParametersWidget::AddEnum(const char *name, const TCHAR *label, - const TCHAR *help, const StaticEnumChoice *list) +VegaParametersWidget::AddEnum(const char *name, const char *label, + const char *help, const StaticEnumChoice *list) { AddParameter(name); RowFormWidget::AddEnum(label, help, list); @@ -41,8 +41,8 @@ VegaParametersWidget::AddParameter(const StaticParameter &p) { assert(p.label != NULL); - const TCHAR *label = gettext(p.label); - const TCHAR *help = p.help != NULL ? gettext(p.help) : NULL; + const char *label = gettext(p.label); + const char *help = p.help != NULL ? gettext(p.help) : NULL; switch (p.type) { case DataField::Type::BOOLEAN: diff --git a/src/Dialogs/Device/Vega/VegaParametersWidget.hpp b/src/Dialogs/Device/Vega/VegaParametersWidget.hpp index f7b515bcd56..6119b2ff9f7 100644 --- a/src/Dialogs/Device/Vega/VegaParametersWidget.hpp +++ b/src/Dialogs/Device/Vega/VegaParametersWidget.hpp @@ -16,13 +16,13 @@ class VegaParametersWidget : public RowFormWidget { const char *name; - const TCHAR *label, *help; + const char *label, *help; const StaticEnumChoice *choices; int min_value, max_value, step; - const TCHAR *format; + const char *format; }; private: @@ -66,11 +66,11 @@ class VegaParametersWidget : public RowFormWidget { public: /* methods to construct the form */ - void AddBoolean(const char *name, const TCHAR *label, - const TCHAR *help=NULL); - void AddInteger(const char *name, const TCHAR *label, const TCHAR *help, - int min_value, int max_value, const TCHAR *format); - void AddEnum(const char *name, const TCHAR *label, const TCHAR *help, + void AddBoolean(const char *name, const char *label, + const char *help=NULL); + void AddInteger(const char *name, const char *label, const char *help, + int min_value, int max_value, const char *format); + void AddEnum(const char *name, const char *label, const char *help, const StaticEnumChoice *list); private: diff --git a/src/Dialogs/DialogSettings.cpp b/src/Dialogs/DialogSettings.cpp index 537d88906b7..1bf4b562efe 100644 --- a/src/Dialogs/DialogSettings.cpp +++ b/src/Dialogs/DialogSettings.cpp @@ -9,4 +9,5 @@ DialogSettings::SetDefaults() noexcept text_input_style = TextInputStyle::Default; tab_style = TabStyle::Text; expert = false; + xcsoar_style = false; } diff --git a/src/Dialogs/DialogSettings.hpp b/src/Dialogs/DialogSettings.hpp index 4f25c345e1d..23fa6ecc8cf 100644 --- a/src/Dialogs/DialogSettings.hpp +++ b/src/Dialogs/DialogSettings.hpp @@ -28,6 +28,7 @@ struct DialogSettings { * Show the "expert" settings? */ bool expert; + bool xcsoar_style; void SetDefaults() noexcept; }; diff --git a/src/Dialogs/Dialogs.h b/src/Dialogs/Dialogs.h index 799a7d63077..8e010918b84 100644 --- a/src/Dialogs/Dialogs.h +++ b/src/Dialogs/Dialogs.h @@ -3,6 +3,8 @@ #pragma once +#include + namespace UI { class SingleWindow; } void dlgBasicSettingsShowModal(); @@ -17,5 +19,5 @@ void dlgStatusShowModal(int page); void dlgCreditsShowModal(UI::SingleWindow &parent); -void -dlgQuickMenuShowModal(UI::SingleWindow &parent) noexcept; +void dlgQuickMenuShowModal(UI::SingleWindow & parent, + const char *mode) noexcept; diff --git a/src/Dialogs/DownloadFilePicker.cpp b/src/Dialogs/DownloadFilePicker.cpp index 6829350757c..530fa6bc668 100644 --- a/src/Dialogs/DownloadFilePicker.cpp +++ b/src/Dialogs/DownloadFilePicker.cpp @@ -24,7 +24,6 @@ #include "ui/event/PeriodicTimer.hpp" #include "thread/Mutex.hxx" #include "Operation/ThreadedOperationEnvironment.hpp" -#include "util/ConvertString.hpp" #include @@ -106,12 +105,11 @@ class DownloadProgress final : Net::DownloadListener { * Throws on error. */ static AllocatedPath -DownloadFile(const char *uri, const char *_base) +DownloadFile(const char *uri, const char *base) { assert(Net::DownloadManager::IsAvailable()); - const UTF8ToWideConverter base(_base); - if (!base.IsValid()) + if (!base) return nullptr; ProgressDialog dialog(UIGlobals::GetMainWindow(), UIGlobals::GetDialogLook(), @@ -253,7 +251,7 @@ try { FileRepository repository; - const auto path = LocalPath(_T("repository")); + const auto path = LocalPath("repository"); FileLineReaderA reader(path); ParseFileRepository(repository, reader); @@ -268,7 +266,7 @@ try { list.Invalidate(); UpdateButtons(); -} catch (const std::runtime_error &e) { +} catch (const std::runtime_error & /* e */) { } void @@ -285,8 +283,7 @@ DownloadFilePickerWidget::OnPaintItem(Canvas &canvas, const PixelRect rc, { const auto &file = items[i]; - const UTF8ToWideConverter name(file.GetName()); - row_renderer.DrawTextRow(canvas, rc, name); + row_renderer.DrawTextRow(canvas, rc, file.GetName()); } void @@ -322,7 +319,7 @@ DownloadFilePickerWidget::OnDownloadComplete(Path path_relative) noexcept if (name == nullptr) return; - if (name == Path(_T("repository"))) { + if (name == Path("repository")) { const std::lock_guard lock{mutex}; repository_failed = false; repository_modified = true; @@ -339,7 +336,7 @@ DownloadFilePickerWidget::OnDownloadError(Path path_relative, if (name == nullptr) return; - if (name == Path(_T("repository"))) { + if (name == Path("repository")) { const std::lock_guard lock{mutex}; repository_failed = true; repository_error = std::move(error); @@ -375,7 +372,7 @@ AllocatedPath DownloadFilePicker(FileType file_type) { if (!Net::DownloadManager::IsAvailable()) { - const TCHAR *message = + const char *message = _("The file manager is not available on this device."); ShowMessageBox(message, _("File Manager"), MB_OK); return nullptr; diff --git a/src/Dialogs/Error.cpp b/src/Dialogs/Error.cpp index 196a4ae298f..269dbb82c02 100644 --- a/src/Dialogs/Error.cpp +++ b/src/Dialogs/Error.cpp @@ -3,24 +3,22 @@ #include "Error.hpp" #include "Message.hpp" -#include "util/ConvertString.hpp" #include "util/Exception.hxx" #include "util/StaticString.hxx" void -ShowError(std::exception_ptr e, const TCHAR *caption) noexcept +ShowError(std::exception_ptr e, const char *caption) noexcept { - ShowMessageBox(UTF8ToWideConverter(GetFullMessage(e).c_str()), caption, + ShowMessageBox(GetFullMessage(e).c_str(), caption, MB_OK|MB_ICONEXCLAMATION); } void -ShowError(const TCHAR *msg, std::exception_ptr e, - const TCHAR *caption) noexcept +ShowError(const char *msg, std::exception_ptr e, + const char *caption) noexcept { StaticString<1024> buffer; - buffer.Format(_T("%s\n%s"), msg, - UTF8ToWideConverter(GetFullMessage(e).c_str()).c_str()); + buffer.Format("%s\n%s", msg, GetFullMessage(e).c_str()); buffer.CropIncompleteUTF8(); ShowMessageBox(msg, caption, diff --git a/src/Dialogs/Error.hpp b/src/Dialogs/Error.hpp index 46dcd6c1856..2ddb7579c25 100644 --- a/src/Dialogs/Error.hpp +++ b/src/Dialogs/Error.hpp @@ -7,8 +7,8 @@ #include void -ShowError(std::exception_ptr e, const TCHAR *caption) noexcept; +ShowError(std::exception_ptr e, const char *caption) noexcept; void -ShowError(const TCHAR *msg, std::exception_ptr e, - const TCHAR *caption) noexcept; +ShowError(const char *msg, std::exception_ptr e, + const char *caption) noexcept; diff --git a/src/Dialogs/FileManager.cpp b/src/Dialogs/FileManager.cpp index af4c5467f1c..0396a17ffa7 100644 --- a/src/Dialogs/FileManager.cpp +++ b/src/Dialogs/FileManager.cpp @@ -18,7 +18,6 @@ #include "Formatter/TimeFormatter.hpp" #include "time/BrokenDateTime.hpp" #include "net/http/Features.hpp" -#include "util/ConvertString.hpp" #include "util/Macros.hpp" #include "Repository/FileRepository.hpp" #include "Repository/Parser.hpp" @@ -42,11 +41,10 @@ static AllocatedPath LocalPath(const AvailableFile &file) { - const UTF8ToWideConverter base(file.GetName()); - if (!base.IsValid()) + if (!file.GetName()) return nullptr; - return LocalPath(base); + return LocalPath(file.GetName()); } #ifdef HAVE_DOWNLOAD_MANAGER @@ -58,28 +56,16 @@ FindRemoteFile(const FileRepository &repository, const char *name) return repository.FindByName(name); } -#ifdef _UNICODE -[[gnu::pure]] -static const AvailableFile * -FindRemoteFile(const FileRepository &repository, const TCHAR *name) -{ - const WideToUTF8Converter name2(name); - if (!name2.IsValid()) - return nullptr; - - return FindRemoteFile(repository, name2); -} -#endif [[gnu::pure]] static bool -CanDownload(const FileRepository &repository, const TCHAR *name) +CanDownload(const FileRepository &repository, const char *name) { return FindRemoteFile(repository, name) != nullptr; } static bool -UpdateAvailable(const FileRepository &repository, const TCHAR *name) +UpdateAvailable(const FileRepository &repository, const char *name) { const AvailableFile *remote_file = FindRemoteFile(repository, name); @@ -114,7 +100,7 @@ class ManagedFileListWidget DownloadStatus download_status; - void Set(const TCHAR *_name, const DownloadStatus *_download_status, + void Set(const char *_name, const DownloadStatus *_download_status, bool _failed, bool _out_of_date) { name = _name; @@ -143,7 +129,7 @@ class ManagedFileListWidget TwoTextRowsRenderer row_renderer; #ifdef HAVE_DOWNLOAD_MANAGER - Button *download_button, *add_button, *cancel_button, *update_button; + Button *download_button, *add_button, *cancel_button, *update_button, *delete_button; /** * Whether at least one file is out of date. @@ -245,13 +231,14 @@ class ManagedFileListWidget } [[gnu::pure]] - int FindItem(const TCHAR *name) const noexcept; + int FindItem(const char *name) const noexcept; void LoadRepositoryFile(); void RefreshList(); void UpdateButtons(); void Download(); + void Delete(); void Add(); void Cancel(); void UpdateFiles(); @@ -314,7 +301,7 @@ ManagedFileListWidget::Unprepare() noexcept } int -ManagedFileListWidget::FindItem(const TCHAR *name) const noexcept +ManagedFileListWidget::FindItem(const char *name) const noexcept { for (auto i = items.begin(), end = items.end(); i != end; ++i) if (StringIsEqual(i->name, name)) @@ -336,10 +323,10 @@ try { repository.Clear(); - const auto path = LocalPath(_T("repository")); + const auto path = LocalPath("repository"); FileLineReaderA reader(path); ParseFileRepository(repository, reader); -} catch (const std::runtime_error &e) { +} catch (const std::runtime_error & /* e */) { } void @@ -396,8 +383,10 @@ ManagedFileListWidget::CreateButtons(WidgetDialog &dialog) noexcept { #ifdef HAVE_DOWNLOAD_MANAGER if (Net::DownloadManager::IsAvailable()) { - download_button = dialog.AddButton(_("Download"), [this](){ Download(); }); + // download_button = dialog.AddButton(_("Download"), [this](){ Download(); }); + download_button = dialog.AddButton(_("Update"), [this](){ Download(); }); add_button = dialog.AddButton(_("Add"), [this](){ Add(); }); + delete_button = dialog.AddButton(_("Delete"), [this](){ Delete(); }); cancel_button = dialog.AddButton(_("Cancel"), [this](){ Cancel(); }); update_button = dialog.AddButton(_("Update all"), [this](){ UpdateFiles(); @@ -434,18 +423,18 @@ ManagedFileListWidget::OnPaintItem(Canvas &canvas, const PixelRect rc, if (file.download_status.position < 0) { text = _("Queued"); } else if (file.download_status.size > 0) { - text.Format(_T("%s (%u%%)"), _("Downloading"), + text.Format("%s (%u%%)", _("Downloading"), unsigned(file.download_status.position * 100 / file.download_status.size)); } else { - TCHAR size[32]; + char size[32]; FormatByteSize(size, ARRAY_SIZE(size), file.download_status.position); - text.Format(_T("%s (%s)"), _("Downloading"), size); + text.Format("%s (%s)", _("Downloading"), size); } row_renderer.DrawRightFirstRow(canvas, rc, text); } else if (file.failed) { - const TCHAR *text = _("Error"); + const char *text = _("Error"); row_renderer.DrawRightFirstRow(canvas, rc, text); } @@ -464,6 +453,28 @@ ManagedFileListWidget::OnCursorMoved([[maybe_unused]] unsigned index) noexcept UpdateButtons(); } +void +ManagedFileListWidget::Delete() +{ +#ifdef HAVE_DOWNLOAD_MANAGER + assert(Net::DownloadManager::IsAvailable()); + + if (items.empty()) + return; + + const unsigned current = GetList().GetCursorIndex(); + assert(current < items.size()); + + auto path = LocalPath(items[current].name); + // TODO(aug): + // Please delete only w/o asking if the file in no profile inserted + auto r = File::Delete(path); + if (r) + RefreshList(); + // else not deleted??? +#endif +} + void ManagedFileListWidget::Download() { @@ -482,11 +493,11 @@ ManagedFileListWidget::Download() return; const AvailableFile &remote_file = *remote_file_p; - const UTF8ToWideConverter base(remote_file.GetName()); - if (!base.IsValid()) + if (!remote_file.GetName()) return; - Net::DownloadManager::Enqueue(remote_file.uri.c_str(), Path(base)); + Net::DownloadManager::Enqueue(remote_file.uri.c_str(), + Path(remote_file.GetName())); #endif } @@ -517,16 +528,14 @@ AddFileListItemRenderer::OnPaintItem(Canvas &canvas, const PixelRect rc, const AvailableFile &file = list[i]; - const UTF8ToWideConverter name(file.GetName()); - if (name.IsValid()) - row_renderer.DrawFirstRow(canvas, rc, name); + if (file.GetName()) + row_renderer.DrawFirstRow(canvas, rc, file.GetName()); - const UTF8ToWideConverter description(file.GetDescription()); - if (description.IsValid()) - row_renderer.DrawSecondRow(canvas, rc, description); + if (file.GetDescription()) + row_renderer.DrawSecondRow(canvas, rc, file.GetDescription()); if (file.update_date.IsPlausible()) { - TCHAR string_buffer[21]; + char string_buffer[21]; FormatISO8601(string_buffer, file.update_date); row_renderer.DrawRightSecondRow(canvas, rc, string_buffer); } @@ -546,11 +555,10 @@ ManagedFileListWidget::Add() /* already downloading this file */ continue; - const UTF8ToWideConverter name(remote_file.GetName()); - if (!name.IsValid()) + if (!remote_file.GetName()) continue; - if (FindItem(name) < 0) + if (FindItem(remote_file.GetName()) < 0) list.push_back(remote_file); } @@ -568,11 +576,11 @@ ManagedFileListWidget::Add() assert((unsigned)i < list.size()); const AvailableFile &remote_file = list[i]; - const UTF8ToWideConverter base(remote_file.GetName()); - if (!base.IsValid()) + if (!remote_file.GetName()) return; - Net::DownloadManager::Enqueue(remote_file.GetURI(), Path(base)); + Net::DownloadManager::Enqueue(remote_file.GetURI(), + Path(remote_file.GetName())); #endif } @@ -586,11 +594,11 @@ ManagedFileListWidget::UpdateFiles() { const AvailableFile *remote_file = FindRemoteFile(repository, file.name); if (remote_file != nullptr) { - const UTF8ToWideConverter base(remote_file->GetName()); - if (!base.IsValid()) + if (!remote_file->GetName()) return; - Net::DownloadManager::Enqueue(remote_file->GetURI(), Path(base)); + Net::DownloadManager::Enqueue(remote_file->GetURI(), + Path(remote_file->GetName())); } } } @@ -642,16 +650,10 @@ ManagedFileListWidget::OnDownloadAdded(Path path_relative, if (name == nullptr) return; - const WideToUTF8Converter name2(name.c_str()); - if (!name2.IsValid()) - return; - - const std::string name3(name2); - { const std::lock_guard lock{mutex}; - downloads[name3] = DownloadStatus{size, position}; - failures.erase(name3); + downloads[name.c_str()] = DownloadStatus{size, position}; + failures.erase(name.c_str()); } download_notify.SendNotification(); @@ -664,18 +666,12 @@ ManagedFileListWidget::OnDownloadComplete(Path path_relative) noexcept if (name == nullptr) return; - const WideToUTF8Converter name2(name.c_str()); - if (!name2.IsValid()) - return; - - const std::string name3(name2); - { const std::lock_guard lock{mutex}; - downloads.erase(name3); + downloads.erase(name.c_str()); - if (StringIsEqual(name2, "repository")) { + if (StringIsEqual(name.c_str(), "repository")) { repository_failed = false; repository_modified = true; } @@ -692,22 +688,17 @@ ManagedFileListWidget::OnDownloadError(Path path_relative, if (name == nullptr) return; - const WideToUTF8Converter name2(name.c_str()); - if (!name2.IsValid()) - return; - - const std::string name3(name2); { const std::lock_guard lock{mutex}; - downloads.erase(name3); + downloads.erase(name.c_str()); // TODO: store the error - if (StringIsEqual(name2, "repository")) { + if (StringIsEqual(name.c_str(), "repository")) { repository_failed = true; } else - failures.insert(name3); + failures.insert(name.c_str()); } download_notify.SendNotification(); @@ -763,7 +754,7 @@ ShowFileManager() } #endif - const TCHAR *message = + const char *message = _("The file manager is not available on this device."); ShowMessageBox(message, _("File Manager"), MB_OK); diff --git a/src/Dialogs/FilePicker.cpp b/src/Dialogs/FilePicker.cpp index 6b64e28cd11..40e0d67757a 100644 --- a/src/Dialogs/FilePicker.cpp +++ b/src/Dialogs/FilePicker.cpp @@ -14,14 +14,14 @@ #endif bool -FilePicker(const TCHAR *caption, FileDataField &df, - const TCHAR *help_text) +FilePicker(const char *caption, FileDataField &df, + const char *help_text) { ComboList combo_list = df.CreateComboList(nullptr); if (combo_list.size() == 0) return false; - const TCHAR *extra_caption = nullptr; + const char *extra_caption = nullptr; #ifdef HAVE_DOWNLOAD_MANAGER // with FileType::IGC don't show the 'Download'-Button! if (df.GetFileType() != FileType::IGC && @@ -52,7 +52,7 @@ FilePicker(const TCHAR *caption, FileDataField &df, } AllocatedPath -FilePicker(const TCHAR *caption, const TCHAR *patterns) +FilePicker(const char *caption, const char *patterns) { assert(patterns != nullptr); diff --git a/src/Dialogs/FilePicker.hpp b/src/Dialogs/FilePicker.hpp index e0a8de4f9df..8302581ad48 100644 --- a/src/Dialogs/FilePicker.hpp +++ b/src/Dialogs/FilePicker.hpp @@ -9,8 +9,8 @@ class AllocatedPath; class FileDataField; bool -FilePicker(const TCHAR *caption, FileDataField &df, - const TCHAR *help_text = nullptr); +FilePicker(const char *caption, FileDataField &df, + const char *help_text = nullptr); /** * Ask the user to pick a file from the data directory. @@ -21,4 +21,4 @@ FilePicker(const TCHAR *caption, FileDataField &df, * cancelled the dialog or if there are no matching files */ AllocatedPath -FilePicker(const TCHAR *caption, const TCHAR *patterns); +FilePicker(const char *caption, const char *patterns); diff --git a/src/Dialogs/GeoPointEntry.cpp b/src/Dialogs/GeoPointEntry.cpp index fc30dec1fd3..5e2505d0e28 100644 --- a/src/Dialogs/GeoPointEntry.cpp +++ b/src/Dialogs/GeoPointEntry.cpp @@ -11,7 +11,7 @@ #include "Geo/GeoPoint.hpp" bool -GeoPointEntryDialog(const TCHAR *caption, GeoPoint &value, +GeoPointEntryDialog(const char *caption, GeoPoint &value, const CoordinateFormat format, bool nullable) { diff --git a/src/Dialogs/GeoPointEntry.hpp b/src/Dialogs/GeoPointEntry.hpp index aab7d787522..1c2a190d8ac 100644 --- a/src/Dialogs/GeoPointEntry.hpp +++ b/src/Dialogs/GeoPointEntry.hpp @@ -10,6 +10,6 @@ enum class CoordinateFormat : uint8_t; struct GeoPoint; bool -GeoPointEntryDialog(const TCHAR *caption, GeoPoint &value, +GeoPointEntryDialog(const char *caption, GeoPoint &value, CoordinateFormat format, bool nullable=false); diff --git a/src/Dialogs/HelpDialog.cpp b/src/Dialogs/HelpDialog.cpp index b0a68fa73a2..875bc85cf79 100644 --- a/src/Dialogs/HelpDialog.cpp +++ b/src/Dialogs/HelpDialog.cpp @@ -11,15 +11,15 @@ #include void -HelpDialog(const TCHAR *Caption, const TCHAR *HelpText) +HelpDialog(const char *Caption, const char *HelpText) { assert(HelpText != nullptr); - const TCHAR *prefix = _("Help"); + const char *prefix = _("Help"); StaticString<100> full_caption; if (Caption != nullptr) { - full_caption.Format(_T("%s: %s"), prefix, Caption); + full_caption.Format("%s: %s", prefix, Caption); Caption = full_caption.c_str(); } else Caption = prefix; diff --git a/src/Dialogs/HelpDialog.hpp b/src/Dialogs/HelpDialog.hpp index f7a79791122..de811cad6e8 100644 --- a/src/Dialogs/HelpDialog.hpp +++ b/src/Dialogs/HelpDialog.hpp @@ -6,4 +6,4 @@ #include void -HelpDialog(const TCHAR *caption, const TCHAR *text); +HelpDialog(const char *caption, const char *text); diff --git a/src/Dialogs/JobDialog.cpp b/src/Dialogs/JobDialog.cpp index 0cd6f474194..b0b04bc8fbf 100644 --- a/src/Dialogs/JobDialog.cpp +++ b/src/Dialogs/JobDialog.cpp @@ -26,7 +26,7 @@ class DialogJobThread : public JobThread { bool JobDialog(SingleWindow &parent, const DialogLook &dialog_look, - const TCHAR *caption, + const char *caption, Job &job, bool cancellable) { ProgressDialog form(parent, dialog_look, caption); diff --git a/src/Dialogs/JobDialog.hpp b/src/Dialogs/JobDialog.hpp index e680657a353..626bbe053a5 100644 --- a/src/Dialogs/JobDialog.hpp +++ b/src/Dialogs/JobDialog.hpp @@ -22,18 +22,18 @@ class Job; */ bool JobDialog(UI::SingleWindow &parent, const DialogLook &dialog_look, - const TCHAR *caption, Job &job, + const char *caption, Job &job, bool cancellable=false); class DialogJobRunner : public JobRunner { UI::SingleWindow &parent; const DialogLook &dialog_look; - const TCHAR *caption; + const char *caption; bool cancellable; public: DialogJobRunner(UI::SingleWindow &_parent, const DialogLook &_dialog_look, - const TCHAR *_caption, bool _cancellable=false) + const char *_caption, bool _cancellable=false) :parent(_parent), dialog_look(_dialog_look), caption(_caption), cancellable(_cancellable) {} diff --git a/src/Dialogs/KnobTextEntry.cpp b/src/Dialogs/KnobTextEntry.cpp index ac2ff6d0f9c..2df0cb7acee 100644 --- a/src/Dialogs/KnobTextEntry.cpp +++ b/src/Dialogs/KnobTextEntry.cpp @@ -27,8 +27,8 @@ enum Buttons { static constexpr size_t MAX_TEXTENTRY = 40; -static constexpr TCHAR EntryLetters[] = - _T(" ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.-"); +static constexpr char EntryLetters[] = + " ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.-"; static constexpr unsigned MAXENTRYLETTERS = ARRAY_SIZE(EntryLetters) - 1; @@ -39,7 +39,7 @@ static constexpr unsigned MAXENTRYLETTERS = ARRAY_SIZE(EntryLetters) - 1; */ [[gnu::const]] static unsigned -FindEntryLetter(TCHAR ch) +FindEntryLetter(char ch) { for (unsigned i = 0; i < (int)MAXENTRYLETTERS; ++i) if (EntryLetters[i] == ch) @@ -54,17 +54,17 @@ class KnobTextEntryWindow final : public PaintWindow { unsigned int cursor; int lettercursor; - TCHAR buffer[MAX_TEXTENTRY]; + char buffer[MAX_TEXTENTRY]; public: - KnobTextEntryWindow(const TCHAR *text, size_t width) + KnobTextEntryWindow(const char *text, size_t width) :max_width(std::min(MAX_TEXTENTRY, width)), cursor(0), lettercursor(0) { CopyTruncateString(buffer, max_width, text); MoveCursor(); } - TCHAR *GetValue() { + char *GetValue() { return buffer; } @@ -83,7 +83,7 @@ class KnobTextEntryWindow final : public PaintWindow { } void MoveCursor() { - if (cursor >= _tcslen(buffer)) + if (cursor >= strlen(buffer)) buffer[cursor + 1] = 0; lettercursor = FindEntryLetter(ToUpperASCII(buffer[cursor])); @@ -165,18 +165,18 @@ KnobTextEntryWindow::OnPaint(Canvas &canvas) noexcept } class KnobTextEntryWidget final : public WindowWidget { - const TCHAR *const text; + const char *const text; const size_t width; public: - KnobTextEntryWidget(const TCHAR *_text, size_t _width) noexcept + KnobTextEntryWidget(const char *_text, size_t _width) noexcept :text(_text), width(_width) {} auto &GetWindow() noexcept { return (KnobTextEntryWindow &)WindowWidget::GetWindow(); } - TCHAR *GetValue() { + char *GetValue() { return GetWindow().GetValue(); } @@ -198,22 +198,22 @@ class KnobTextEntryWidget final : public WindowWidget { inline void KnobTextEntryWidget::CreateButtons(WidgetDialog &dialog) { - dialog.AddButton(_T("A+"), [this](){ GetWindow().IncrementLetter(); }); + dialog.AddButton("A+", [this](){ GetWindow().IncrementLetter(); }); dialog.AddButtonKey(KEY_UP); - dialog.AddButton(_T("A-"), [this](){ GetWindow().DecrementLetter(); }); + dialog.AddButton("A-", [this](){ GetWindow().DecrementLetter(); }); dialog.AddButtonKey(KEY_DOWN); - dialog.AddSymbolButton(_T("<"), [this](){ GetWindow().MoveCursorLeft(); }); + dialog.AddSymbolButton("<", [this](){ GetWindow().MoveCursorLeft(); }); dialog.AddButtonKey(KEY_LEFT); - dialog.AddSymbolButton(_T(">"), [this](){ GetWindow().MoveCursorRight(); }); + dialog.AddSymbolButton(">", [this](){ GetWindow().MoveCursorRight(); }); dialog.AddButtonKey(KEY_RIGHT); } void -KnobTextEntry(TCHAR *text, size_t width, - const TCHAR *caption) +KnobTextEntry(char *text, size_t width, + const char *caption) { if (width == 0) width = MAX_TEXTENTRY; diff --git a/src/Dialogs/ListPicker.cpp b/src/Dialogs/ListPicker.cpp index 9828b905eeb..c6e59515aff 100644 --- a/src/Dialogs/ListPicker.cpp +++ b/src/Dialogs/ListPicker.cpp @@ -34,7 +34,7 @@ class ListPickerWidget : public ListWidget { UpdateHelp(GetList().GetCursorIndex()); }}; - const TCHAR *const caption, *const help_text; + const char *const caption, *const help_text; ItemHelpCallback_t item_help_callback; TextWidget *help_widget; TwoWidgets *two_widgets; @@ -44,7 +44,7 @@ class ListPickerWidget : public ListWidget { unsigned _row_height, ListItemRenderer &_item_renderer, WndForm &_dialog, - const TCHAR *_caption, const TCHAR *_help_text) noexcept + const char *_caption, const char *_help_text) noexcept :num_items(_num_items), initial_value(_initial_value), row_height(_row_height), visible(false), @@ -119,13 +119,13 @@ class ListPickerWidget : public ListWidget { }; int -ListPicker(const TCHAR *caption, +ListPicker(const char *caption, unsigned num_items, unsigned initial_value, unsigned item_height, ListItemRenderer &item_renderer, bool update, - const TCHAR *help_text, + const char *help_text, ItemHelpCallback_t _itemhelp_callback, - const TCHAR *extra_caption) + const char *extra_caption) { assert(num_items <= 0x7fffffff); assert((num_items == 0 && initial_value == 0) || initial_value < num_items); diff --git a/src/Dialogs/ListPicker.hpp b/src/Dialogs/ListPicker.hpp index de9bd4a90fa..8af81ed002e 100644 --- a/src/Dialogs/ListPicker.hpp +++ b/src/Dialogs/ListPicker.hpp @@ -8,7 +8,7 @@ class ListItemRenderer; /** returns string of item's help text **/ -typedef const TCHAR* (*ItemHelpCallback_t)(unsigned item); +typedef const char* (*ItemHelpCallback_t)(unsigned item); /** * Shows a list dialog and lets the user pick an item. @@ -26,10 +26,10 @@ typedef const TCHAR* (*ItemHelpCallback_t)(unsigned item); * the user clicked the "extra" button */ int -ListPicker(const TCHAR *caption, +ListPicker(const char *caption, unsigned num_items, unsigned initial_value, unsigned item_height, ListItemRenderer &item_renderer, bool update = false, - const TCHAR *help_text = nullptr, + const char *help_text = nullptr, ItemHelpCallback_t itemhelp_callback = nullptr, - const TCHAR *extra_caption=nullptr); + const char *extra_caption=nullptr); diff --git a/src/Dialogs/LockScreen.cpp b/src/Dialogs/LockScreen.cpp index 4b2182ab4b6..0db0ec87907 100644 --- a/src/Dialogs/LockScreen.cpp +++ b/src/Dialogs/LockScreen.cpp @@ -44,7 +44,7 @@ ShowLockBox() WindowStyle button_style; - const Button button(client_area, dialog_look.button, _T("U"), button_rc, button_style, + const Button button(client_area, dialog_look.button, "U", button_rc, button_style, [&wf](){ wf.SetModalResult(mrCancel); }); wf.ShowModal(); diff --git a/src/Dialogs/MapItemListDialog.cpp b/src/Dialogs/MapItemListDialog.cpp index 706bcc829c9..9ac0c359728 100644 --- a/src/Dialogs/MapItemListDialog.cpp +++ b/src/Dialogs/MapItemListDialog.cpp @@ -284,11 +284,11 @@ ShowMapItemDialog(const MapItem &item, #endif case MapItem::Type::OVERLAY: - ShowWeatherDialog(_T("overlay")); + ShowWeatherDialog("overlay"); break; case MapItem::Type::RASP: - ShowWeatherDialog(_T("rasp")); + ShowWeatherDialog("rasp"); break; } } diff --git a/src/Dialogs/Message.cpp b/src/Dialogs/Message.cpp index b38bbd8c69e..7f3ed09e553 100644 --- a/src/Dialogs/Message.cpp +++ b/src/Dialogs/Message.cpp @@ -16,7 +16,7 @@ #include int -ShowMessageBox(const TCHAR *text, const TCHAR *caption, +ShowMessageBox(const char *text, const char *caption, unsigned flags) noexcept { assert(text != NULL); diff --git a/src/Dialogs/Message.hpp b/src/Dialogs/Message.hpp index a0e9d2cd466..c08de0debc0 100644 --- a/src/Dialogs/Message.hpp +++ b/src/Dialogs/Message.hpp @@ -44,5 +44,5 @@ enum { * @return */ int -ShowMessageBox(const TCHAR *text, const TCHAR *caption, +ShowMessageBox(const char *text, const char *caption, unsigned flags) noexcept; diff --git a/src/Dialogs/NumberEntry.cpp b/src/Dialogs/NumberEntry.cpp index f06f1159bc0..69759cced86 100644 --- a/src/Dialogs/NumberEntry.cpp +++ b/src/Dialogs/NumberEntry.cpp @@ -9,126 +9,91 @@ #include "Math/Angle.hpp" #include "UIGlobals.hpp" +enum DataType{ + DATA_SIGNED, + DATA_UNSIGNED, + DATA_ANGLE, +}; + +// ---------------------------------------------------------------------------- +template bool -NumberEntryDialog(const TCHAR *caption, - int &value, unsigned length) +NumberEntryDialog(TWidgetDialog &dialog, + const DataType type, + T &value, unsigned length) { - /* create the dialog */ - - const DialogLook &look = UIGlobals::GetDialogLook(); - - TWidgetDialog - dialog(WidgetDialog::Auto{}, UIGlobals::GetMainWindow(), look, caption); - ContainerWindow &client_area = dialog.GetClientAreaWindow(); - /* create the input control */ - + //create the input control WindowStyle control_style; control_style.Hide(); control_style.TabStop(); - auto entry = std::make_unique(look); - entry->CreateSigned(client_area, client_area.GetClientRect(), control_style, - length, 0); + auto entry = std::make_unique(UIGlobals::GetDialogLook()); + switch (type) { + case DATA_SIGNED: + entry->CreateSigned(client_area, client_area.GetClientRect(), control_style, + length, 0); + break; + case DATA_ANGLE: // TODO(August2111): check of correctness + case DATA_UNSIGNED: + entry->CreateUnsigned(client_area, client_area.GetClientRect(), + control_style, length, 0); + break; + } entry->Resize(entry->GetRecommendedSize()); entry->SetValue(value); + entry->SetCallback(dialog.MakeModalResultCallback(mrOK)); - /* create buttons */ - - dialog.AddButton(_("OK"), mrOK); - dialog.AddButton(_("Cancel"), mrCancel); + // create buttons + dialog.first_button = dialog.AddButton(_("OK"), mrOK); + dialog.last_button = dialog.AddButton(_("Cancel"), mrCancel); - /* run it */ + // set handler for cursor overflow + entry->SetLeftOverflow(dialog.SetFocusButtonCallback(dialog.last_button)); + entry->SetRightOverflow(dialog.SetFocusButtonCallback(dialog.first_button)); + // run it dialog.SetWidget(std::move(entry)); - bool result = dialog.ShowModal() == mrOK; - if (!result) - return false; + return (dialog.ShowModal() == mrOK); +} +// ---------------------------------------------------------------------------- +/** NumberEntryDialog for big signed numbers -> SIGNED with +/-! */ +bool +NumberEntryDialog(const char *caption, int &value, unsigned length) { + TWidgetDialog dialog(WidgetDialog::Auto{}, + UIGlobals::GetMainWindow(), + UIGlobals::GetDialogLook(), caption); + if (!NumberEntryDialog(dialog, DATA_SIGNED, value, length)) + return false; value = ((DigitEntry &)dialog.GetWidget().GetWindow()).GetIntegerValue(); return true; } +// ---------------------------------------------------------------------------- +/** NumberEntryDialog for big unsigned numbers -> UNSIGNED! */ bool -NumberEntryDialog(const TCHAR *caption, - unsigned &value, unsigned length) -{ - /* create the dialog */ - - const DialogLook &look = UIGlobals::GetDialogLook(); - - TWidgetDialog - dialog(WidgetDialog::Auto{}, UIGlobals::GetMainWindow(), look, caption); - - ContainerWindow &client_area = dialog.GetClientAreaWindow(); - - /* create the input control */ - - WindowStyle control_style; - control_style.Hide(); - control_style.TabStop(); - - auto entry = std::make_unique(look); - entry->CreateUnsigned(client_area, client_area.GetClientRect(), control_style, - length, 0); - entry->Resize(entry->GetRecommendedSize()); - entry->SetValue(value); - - /* create buttons */ - - dialog.AddButton(_("OK"), mrOK); - dialog.AddButton(_("Cancel"), mrCancel); - - /* run it */ - - dialog.SetWidget(std::move(entry)); - - bool result = dialog.ShowModal() == mrOK; - if (!result) - return false; - +NumberEntryDialog(const char *caption, unsigned &value, unsigned length) { + TWidgetDialog dialog(WidgetDialog::Auto{}, + UIGlobals::GetMainWindow(), + UIGlobals::GetDialogLook(), caption); + if (!NumberEntryDialog(dialog, DATA_UNSIGNED, value, length)) + return false; value = ((DigitEntry &)dialog.GetWidget().GetWindow()).GetUnsignedValue(); return true; } +// ---------------------------------------------------------------------------- +/** NumberEntryDialog for big angle values */ bool -AngleEntryDialog(const TCHAR *caption, Angle &value) -{ - /* create the dialog */ - - const DialogLook &look = UIGlobals::GetDialogLook(); - - TWidgetDialog - dialog(WidgetDialog::Auto{}, UIGlobals::GetMainWindow(), look, caption); - - ContainerWindow &client_area = dialog.GetClientAreaWindow(); - - /* create the input control */ - - WindowStyle control_style; - control_style.Hide(); - control_style.TabStop(); - - auto entry = std::make_unique(look); - entry->CreateAngle(client_area, client_area.GetClientRect(), control_style); - entry->Resize(entry->GetRecommendedSize()); - entry->SetValue(value); - - /* create buttons */ - - dialog.AddButton(_("OK"), mrOK); - dialog.AddButton(_("Cancel"), mrCancel); - - /* run it */ - - dialog.SetWidget(std::move(entry)); - - bool result = dialog.ShowModal() == mrOK; - if (!result) - return false; - +AngleEntryDialog(const char *caption, Angle &value) { + TWidgetDialog dialog(WidgetDialog::Auto{}, + UIGlobals::GetMainWindow(), + UIGlobals::GetDialogLook(), caption); + if (!NumberEntryDialog(dialog, DATA_ANGLE, value, 0)) + return false; value = ((DigitEntry &)dialog.GetWidget().GetWindow()).GetAngleValue(); return true; } diff --git a/src/Dialogs/NumberEntry.hpp b/src/Dialogs/NumberEntry.hpp index 1bf8096827a..a4057cb452f 100644 --- a/src/Dialogs/NumberEntry.hpp +++ b/src/Dialogs/NumberEntry.hpp @@ -7,12 +7,14 @@ class Angle; +/** NumberEntryDialog for big unsigned numbers -> SIGNED with +/-! */ bool -NumberEntryDialog(const TCHAR *caption, +NumberEntryDialog(const char *caption, int &value, unsigned length); +/** NumberEntryDialog for big unsigned numbers -> UNSIGNED! */ bool -NumberEntryDialog(const TCHAR *caption, +NumberEntryDialog(const char *caption, unsigned &value, unsigned length); -bool AngleEntryDialog(const TCHAR *caption, Angle &value); +bool AngleEntryDialog(const char *caption, Angle &value); diff --git a/src/Dialogs/Plane/PlaneDetailsDialog.cpp b/src/Dialogs/Plane/PlaneDetailsDialog.cpp index b969b20647b..75ea64c2258 100644 --- a/src/Dialogs/Plane/PlaneDetailsDialog.cpp +++ b/src/Dialogs/Plane/PlaneDetailsDialog.cpp @@ -61,17 +61,17 @@ PlaneEditWidget::UpdateCaption() noexcept return; StaticString<128> tmp; - tmp.Format(_T("%s: %s"), _("Plane Details"), GetValueString(REGISTRATION)); + tmp.Format("%s: %s", _("Plane Details"), GetValueString(REGISTRATION)); dialog->SetCaption(tmp); } void PlaneEditWidget::UpdatePolarButton() noexcept { - const TCHAR *caption = _("Polar"); + const char *caption = _("Polar"); StaticString<64> buffer; if (!plane.polar_name.empty()) { - buffer.Format(_T("%s: %s"), caption, plane.polar_name.c_str()); + buffer.Format("%s: %s", caption, plane.polar_name.c_str()); caption = buffer; } @@ -94,33 +94,33 @@ PlaneEditWidget::Prepare([[maybe_unused]] ContainerWindow &parent, [[maybe_unuse AddButton(_("Polar"), [this](){ PolarButtonClicked(); }); AddText(_("Type"), nullptr, plane.type); AddInteger(_("Handicap"), nullptr, - _T("%u %%"), _T("%u"), + "%u %%", "%u", 50, 150, 1, plane.handicap); AddFloat(_("Wing Area"), nullptr, - _T("%.1f m²"), _T("%.1f"), + "%.1f m²", "%.1f", 0, 40, 0.1, false, plane.wing_area); AddFloat(_("Empty Mass"), _("Net mass of the rigged plane."), - _T("%.0f %s"), _T("%.0f"), + "%.0f %s", "%.0f", 0, 1000, 5, false, UnitGroup::MASS, plane.empty_mass); AddFloat(_("Max. Ballast"), nullptr, - _T("%.0f l"), _T("%.0f"), + "%.0f l", "%.0f", 0, 500, 5, false, plane.max_ballast); AddInteger(_("Dump Time"), nullptr, - _T("%u s"), _T("%u"), + "%u s", "%u", 10, 300, 5, plane.dump_time); AddFloat(_("Max. Cruise Speed"), nullptr, - _T("%.0f %s"), _T("%.0f"), 0, 300, 5, + "%.0f %s", "%.0f", 0, 300, 5, false, UnitGroup::HORIZONTAL_SPEED, plane.max_speed); /* TODO: this should be a select list from https://api.weglide.org/v1/aircraft */ if (CommonInterface::GetComputerSettings().weglide.enabled) - AddInteger(_("WeGlide Type"), nullptr, _T("%d"), _T("%d"), 1, 999, + AddInteger(_("WeGlide Type"), nullptr, "%d", "%d", 1, 999, 1, plane.weglide_glider_type); else AddDummy(); @@ -161,7 +161,7 @@ PlaneEditWidget::PolarButtonClicked() noexcept dlgPlanePolarShowModal(plane); UpdatePolarButton(); - if (plane.polar_name != _T("Custom")) + if (plane.polar_name != "Custom") LoadValue(TYPE, plane.polar_name.c_str()); /* reload attributes that may have been modified */ diff --git a/src/Dialogs/Plane/PlaneListDialog.cpp b/src/Dialogs/Plane/PlaneListDialog.cpp index fbb62d16a92..7720d61311e 100644 --- a/src/Dialogs/Plane/PlaneListDialog.cpp +++ b/src/Dialogs/Plane/PlaneListDialog.cpp @@ -40,7 +40,7 @@ class PlaneListWidget final StaticString<32> name; AllocatedPath path; - ListItem(tstring_view _name, Path _path) noexcept + ListItem(std::string_view _name, Path _path) noexcept :name(_name), path(_path) {} bool operator<(const ListItem &i2) const noexcept { @@ -56,8 +56,8 @@ class PlaneListWidget final PlaneFileVisitor(std::vector &_list) noexcept:list(_list) {} void Visit(Path path, Path filename) override { - tstring_view name{filename.c_str()}; - RemoveSuffix(name, tstring_view{_T(".xcp")}); + std::string_view name{filename.c_str()}; + RemoveSuffix(name, std::string_view{".xcp"}); list.emplace_back(name, path); } @@ -106,7 +106,7 @@ PlaneListWidget::UpdateList() noexcept list.clear(); PlaneFileVisitor pfv(list); - VisitDataFiles(_T("*.xcp"), pfv); + VisitDataFiles("*.xcp", pfv); unsigned len = list.size(); @@ -154,7 +154,7 @@ PlaneListWidget::OnPaintItem(Canvas &canvas, const PixelRect rc, if (Profile::GetPathIsEqual("PlanePath", list[i].path)) { StaticString<256> buffer; - buffer.Format(_T("%s - %s"), list[i].name.c_str(), _("Active")); + buffer.Format("%s - %s", list[i].name.c_str(), _("Active")); row_renderer.DrawFirstRow(canvas, rc, buffer); } else row_renderer.DrawFirstRow(canvas, rc, list[i].name); @@ -195,7 +195,7 @@ PlaneListWidget::LoadWithDialog(unsigned i) noexcept { bool result = Load(i); if (!result) { - const TCHAR *title = _("Error"); + const char *title = _("Error"); StaticString<256> text; text.Format(_("Activating plane \"%s\" failed."), list[i].name.c_str()); @@ -225,7 +225,7 @@ PlaneListWidget::NewClicked() noexcept } StaticString<42> filename(plane.registration); - filename += _T(".xcp"); + filename += ".xcp"; const auto path = LocalPath(filename); @@ -257,7 +257,7 @@ PlaneListWidget::EditClicked(bool copy) noexcept const unsigned index = GetList().GetCursorIndex(); const Path old_path = list[index].path; - const TCHAR *old_filename = list[index].name; + const char *old_filename = list[index].name; Plane plane; PlaneGlue::ReadFile(plane, old_path); @@ -270,7 +270,7 @@ PlaneListWidget::EditClicked(bool copy) noexcept } StaticString<42> filename(plane.registration); - filename += _T(".xcp"); + filename += ".xcp"; if (copy || filename != old_filename) { const auto path = AllocatedPath::Build(old_path.GetParent(), @@ -345,7 +345,7 @@ PlaneListWidget::OnActivateItem(unsigned i) noexcept tmp.Format(_("Activate plane \"%s\"?"), list[i].name.c_str()); - if (ShowMessageBox(tmp, _T(" "), MB_YESNO) == IDYES) + if (ShowMessageBox(tmp, " ", MB_YESNO) == IDYES) LoadWithDialog(i); } diff --git a/src/Dialogs/Plane/PlanePolarDialog.cpp b/src/Dialogs/Plane/PlanePolarDialog.cpp index 5e0a20d2a65..a7e2b77720b 100644 --- a/src/Dialogs/Plane/PlanePolarDialog.cpp +++ b/src/Dialogs/Plane/PlanePolarDialog.cpp @@ -18,7 +18,6 @@ #include "system/Path.hpp" #include "Language/Language.hpp" #include "UIGlobals.hpp" -#include "util/ConvertString.hpp" class PlanePolarWidget final : public RowFormWidget, DataFieldListener { @@ -112,7 +111,7 @@ PlanePolarWidget::Prepare([[maybe_unused]] ContainerWindow &parent, Add(std::make_unique(plane.polar_shape, listener)); AddFloat(_("Reference Mass"), _("Reference mass of the polar."), - _T("%.0f %s"), _T("%.0f"), + "%.0f %s", "%.0f", 0, 1000, 5, false, UnitGroup::MASS, plane.polar_shape.reference_mass); } @@ -180,7 +179,7 @@ inline void PlanePolarWidget::ImportClicked() noexcept { // let the user select - const auto path = FilePicker(_("Load Polar From File"), _T("*.plr\0")); + const auto path = FilePicker(_("Load Polar From File"), "*.plr\0"); if (path == nullptr) return; @@ -210,7 +209,7 @@ PlanePolarWidget::ImportClicked() noexcept void PlanePolarWidget::OnModified([[maybe_unused]] DataField &df) noexcept { - plane.polar_name = _T("Custom"); + plane.polar_name = "Custom"; UpdatePolarLabel(); UpdateInvalidLabel(); } @@ -219,7 +218,7 @@ bool dlgPlanePolarShowModal(Plane &_plane) noexcept { StaticString<128> caption; - caption.Format(_T("%s: %s"), _("Plane Polar"), _plane.registration.c_str()); + caption.Format("%s: %s", _("Plane Polar"), _plane.registration.c_str()); const DialogLook &look = UIGlobals::GetDialogLook(); TWidgetDialog diff --git a/src/Dialogs/Plane/PolarShapeEditWidget.cpp b/src/Dialogs/Plane/PolarShapeEditWidget.cpp index 483f2eba28e..4e59987537b 100644 --- a/src/Dialogs/Plane/PolarShapeEditWidget.cpp +++ b/src/Dialogs/Plane/PolarShapeEditWidget.cpp @@ -107,8 +107,8 @@ PolarShapeEditWidget::Prepare(ContainerWindow &parent, const unsigned width = _rc.GetWidth(), height = _rc.GetHeight(); - const TCHAR *v_text = _("Polar V"); - const TCHAR *w_text = _("Polar W"); + const char *v_text = _("Polar V"); + const char *w_text = _("Polar W"); const unsigned row_height = height / 2; const unsigned label_width = 2 * Layout::GetTextPadding() + @@ -130,9 +130,9 @@ PolarShapeEditWidget::Prepare(ContainerWindow &parent, rc.bottom = row_height; for (unsigned i = 0; i < ARRAY_SIZE(points); ++i, rc.left += edit_width, rc.right += edit_width) { - points[i].v = std::make_unique(panel, look, _T(""), + points[i].v = std::make_unique(panel, look, "", rc, 0, style); - DataFieldFloat *df = new DataFieldFloat(_T("%.0f"), _T("%.0f %s"), + DataFieldFloat *df = new DataFieldFloat("%.0f", "%.0f %s", 0, 300, 0, 1, false, listener); points[i].v->SetDataField(df); @@ -166,9 +166,9 @@ PolarShapeEditWidget::Prepare(ContainerWindow &parent, for (unsigned i = 0; i < ARRAY_SIZE(points); ++i, rc.left += edit_width, rc.right += edit_width) { - points[i].w = std::make_unique(panel, look, _T(""), + points[i].w = std::make_unique(panel, look, "", rc, 0, style); - DataFieldFloat *df = new DataFieldFloat(_T("%.2f"), _T("%.2f %s"), + DataFieldFloat *df = new DataFieldFloat("%.2f", "%.2f %s", min, 0, 0, step, false, listener); diff --git a/src/Dialogs/ProcessDialog.cpp b/src/Dialogs/ProcessDialog.cpp index 6484c1e4f28..fd4eaf35adc 100644 --- a/src/Dialogs/ProcessDialog.cpp +++ b/src/Dialogs/ProcessDialog.cpp @@ -6,8 +6,8 @@ #include "Widget/LargeTextWidget.hpp" #include "ui/event/poll/Queue.hpp" #include "ui/event/Globals.hpp" -#include "Language/Language.hpp" #include "event/PipeEvent.hxx" +#include "Language/Language.hpp" #include "io/Open.hxx" #include "io/UniqueFileDescriptor.hxx" #include "system/Error.hxx" @@ -17,7 +17,13 @@ #include #include #include +#ifdef _WIN32 + // TODO(August2111): needs work! +typedef size_t pid_t; +#include +#else #include +#endif class ProcessWidget final : public LargeTextWidget { const char *const*const argv; @@ -63,14 +69,32 @@ class ProcessWidget final : public LargeTextWidget { static bool UnblockAllSignals() noexcept { +#ifdef _WIN32 + // TODO(August2111): needs work! + return false; +#else sigset_t ss; sigemptyset(&ss); return sigprocmask(SIG_SETMASK, &ss, nullptr) == 0; +#endif } void ProcessWidget::Start() { +#ifdef _WIN32 + // TODO(August2111): needs work! + std::stringstream ss; + ss << "Call Linux Command:" << std::endl; + ss << "=================" << std::endl << std::endl; + + unsigned int i = 0; + for (auto arg = argv[0]; arg != nullptr; arg = argv[++i]) { + printf("%s\n", arg); + ss << arg << ' '; + } + system(ss.str().c_str()); +#else auto dev_null = OpenReadOnly("/dev/null"); UniqueFileDescriptor r, w; @@ -95,6 +119,7 @@ ProcessWidget::Start() fd.Open(r.Release()); fd.ScheduleRead(); +#endif } void @@ -102,12 +127,16 @@ ProcessWidget::Cancel() noexcept { fd.Close(); +#ifdef _WIN32 + // TODO(August2111): needs work! +#else if (pid > 0) { kill(pid, SIGTERM); int status; waitpid(pid, &status, 0); } +#endif } bool @@ -121,7 +150,9 @@ ProcessWidget::OnExit(int code) noexcept return false; dialog->SetModalResult(result); +#ifndef _WIN32 UI::event_queue->Interrupt(); +#endif return true; } @@ -143,7 +174,9 @@ ProcessWidget::OnPipeReady(unsigned) noexcept cancel_button->SetCaption(_("Close")); // make sure the EventLoop gets interrupted so the UI gets redrawn +#ifndef _WIN32 UI::event_queue->Interrupt(); +#endif return; } @@ -151,6 +184,10 @@ ProcessWidget::OnPipeReady(unsigned) noexcept fd.Close(); int status; +#ifdef _WIN32 + // TODO(August2111): needs work! + status = 0; +#else if (waitpid(pid, &status, 0) == pid) { pid = 0; @@ -160,14 +197,16 @@ ProcessWidget::OnPipeReady(unsigned) noexcept status = EXIT_FAILURE; } else status = EXIT_FAILURE; - +#endif if (OnExit(status)) return; cancel_button->SetCaption(_("Close")); // make sure the EventLoop gets interrupted so the UI gets redrawn +#ifndef _WIN32 UI::event_queue->Interrupt(); +#endif return; } @@ -177,7 +216,9 @@ ProcessWidget::OnPipeReady(unsigned) noexcept SetText(text.c_str()); // make sure the EventLoop gets interrupted so the UI gets redrawn +#ifndef _WIN32 UI::event_queue->Interrupt(); +#endif } void @@ -204,7 +245,7 @@ ProcessWidget::Unprepare() noexcept int RunProcessDialog(UI::SingleWindow &parent, const DialogLook &dialog_look, - const TCHAR *caption, + const char *caption, const char *const*argv, std::function on_exit) noexcept { diff --git a/src/Dialogs/ProcessDialog.hpp b/src/Dialogs/ProcessDialog.hpp index 20ce0231901..50d47f08bfd 100644 --- a/src/Dialogs/ProcessDialog.hpp +++ b/src/Dialogs/ProcessDialog.hpp @@ -13,6 +13,6 @@ namespace UI { class SingleWindow; } int RunProcessDialog(UI::SingleWindow &parent, const DialogLook &dialog_look, - const TCHAR *caption, + const char *caption, const char *const*argv, std::function on_exit={}) noexcept; diff --git a/src/Dialogs/ProfileListDialog.cpp b/src/Dialogs/ProfileListDialog.cpp index 8f6328349f3..d2443041875 100644 --- a/src/Dialogs/ProfileListDialog.cpp +++ b/src/Dialogs/ProfileListDialog.cpp @@ -28,7 +28,7 @@ class ProfileListWidget final StaticString<32> name; AllocatedPath path; - ListItem(const TCHAR *_name, Path _path) + ListItem(const char *_name, Path _path) :name(_name), path(_path) {} bool operator<(const ListItem &i2) const { @@ -89,7 +89,7 @@ class ProfileListWidget final protected: /* virtual methods from TextListWidget */ - const TCHAR *GetRowText(unsigned i) const noexcept override { + const char *GetRowText(unsigned i) const noexcept override { return list[i].name; } @@ -109,7 +109,7 @@ ProfileListWidget::UpdateList() list.clear(); ProfileFileVisitor pfv(list); - VisitDataFiles(_T("*.prf"), pfv); + VisitDataFiles("*.prf", pfv); unsigned len = list.size(); @@ -173,7 +173,7 @@ ProfileListWidget::NewClicked() StaticString<80> filename; filename = name; - filename += _T(".prf"); + filename += ".prf"; const auto path = LocalPath(filename); if (!File::CreateExclusive(path)) { @@ -240,7 +240,7 @@ ProfileListWidget::CopyClicked() StaticString<80> new_filename; new_filename = new_name; - new_filename += _T(".prf"); + new_filename += ".prf"; const auto new_path = LocalPath(new_filename); @@ -262,7 +262,7 @@ ProfileListWidget::CopyClicked() } static bool -ConfirmDeleteProfile(const TCHAR *name) +ConfirmDeleteProfile(const char *name) { StaticString<256> tmp; StaticString<256> tmp_name(name); diff --git a/src/Dialogs/ProfilePasswordDialog.cpp b/src/Dialogs/ProfilePasswordDialog.cpp index 8ce8243126f..396238d9861 100644 --- a/src/Dialogs/ProfilePasswordDialog.cpp +++ b/src/Dialogs/ProfilePasswordDialog.cpp @@ -33,12 +33,12 @@ CheckProfilePassword(const ProfileMap &map) { /* oh no, profile passwords are not truly secure! */ - BasicStringBuffer profile_password; + BasicStringBuffer profile_password; if (!map.Get(ProfileKeys::Password, profile_password)) /* not password protected */ return ProfilePasswordResult::UNPROTECTED; - BasicStringBuffer user_password; + BasicStringBuffer user_password; user_password.clear(); if (!TextEntryDialog(user_password, _("Enter your password"))) return ProfilePasswordResult::CANCEL; @@ -78,7 +78,7 @@ CheckProfilePasswordResult(ProfilePasswordResult result) bool SetProfilePasswordDialog(ProfileMap &map) { - BasicStringBuffer new_password; + BasicStringBuffer new_password; new_password.clear(); if (!TextEntryDialog(new_password, _("Enter a new password"))) return false; diff --git a/src/Dialogs/ProgressDialog.cpp b/src/Dialogs/ProgressDialog.cpp index d34fee5ba9d..ef473d841db 100644 --- a/src/Dialogs/ProgressDialog.cpp +++ b/src/Dialogs/ProgressDialog.cpp @@ -13,7 +13,7 @@ using namespace UI; ProgressDialog::ProgressDialog(SingleWindow &parent, const DialogLook &dialog_look, - const TCHAR *caption) + const char *caption) :WndForm(parent, dialog_look, parent.GetClientRect(), caption), progress(GetClientAreaWindow()) { diff --git a/src/Dialogs/ProgressDialog.hpp b/src/Dialogs/ProgressDialog.hpp index fec6e1c3608..510c7639fae 100644 --- a/src/Dialogs/ProgressDialog.hpp +++ b/src/Dialogs/ProgressDialog.hpp @@ -20,13 +20,13 @@ class ProgressDialog public: ProgressDialog(UI::SingleWindow &parent, const DialogLook &dialog_look, - const TCHAR *caption); + const char *caption); void AddCancelButton(std::function &&callback={}); /* virtual methods from class OperationEnvironment */ - void SetText(const TCHAR *text) noexcept override { + void SetText(const char *text) noexcept override { progress.SetMessage(text); } diff --git a/src/Dialogs/ReplayDialog.cpp b/src/Dialogs/ReplayDialog.cpp index 5f0d4c0184d..f9cd8f98aae 100644 --- a/src/Dialogs/ReplayDialog.cpp +++ b/src/Dialogs/ReplayDialog.cpp @@ -28,7 +28,7 @@ class ReplayControlWidget final void CreateButtons(WidgetDialog &dialog) noexcept { dialog.AddButton(_("Start"), [this](){ OnStartClicked(); }); dialog.AddButton(_("Stop"), [this](){ OnStopClicked(); }); - dialog.AddButton(_T("+10'"), [this](){ OnFastForwardClicked(); }); + dialog.AddButton("+10'", [this](){ OnFastForwardClicked(); }); } private: @@ -49,13 +49,13 @@ ReplayControlWidget::Prepare([[maybe_unused]] ContainerWindow &parent, AddFile(_("File"), _("Name of file to replay. Can be an IGC file (.igc), a raw NMEA log file (.nmea), or if blank, runs the demo."), {}, - _T("*.nmea\0*.igc\0"), + "*.nmea\0*.igc\0", true); LoadValue(FILE, replay.GetFilename()); AddFloat(_("Rate"), _("Time acceleration of replay. Set to 0 for pause, 1 for normal real-time replay."), - _T("%.0f x"), _T("%.0f"), + "%.0f x", "%.0f", 0, 10, 1, false, replay.GetTimeScale()); GetDataField(RATE).SetOnModified([this]{ replay.SetTimeScale(GetValueFloat(RATE)); diff --git a/src/Dialogs/Settings/Panels/AirspaceConfigPanel.cpp b/src/Dialogs/Settings/Panels/AirspaceConfigPanel.cpp index 1bf60462435..a3c7b6efa3f 100644 --- a/src/Dialogs/Settings/Panels/AirspaceConfigPanel.cpp +++ b/src/Dialogs/Settings/Panels/AirspaceConfigPanel.cpp @@ -166,12 +166,12 @@ AirspaceConfigPanel::Prepare(ContainerWindow &parent, AddFloat(_("Clip altitude"), _("For clip airspace mode, this is the altitude below which airspace is displayed."), - _T("%.0f %s"), _T("%.0f"), 0, 20000, 100, false, + "%.0f %s", "%.0f", 0, 20000, 100, false, UnitGroup::ALTITUDE, renderer.clip_altitude); AddFloat(_("Margin"), _("For auto and all below airspace mode, this is the altitude above/below which airspace is included."), - _T("%.0f %s"), _T("%.0f"), 0, 10000, 100, false, + "%.0f %s", "%.0f", 0, 10000, 100, false, UnitGroup::ALTITUDE, computer.warnings.altitude_warning_margin); AddBoolean(_("Warnings"), _("Enable/disable all airspace warnings."), diff --git a/src/Dialogs/Settings/Panels/AudioConfigPanel.cpp b/src/Dialogs/Settings/Panels/AudioConfigPanel.cpp index 9e87ab33893..39b26a32a81 100644 --- a/src/Dialogs/Settings/Panels/AudioConfigPanel.cpp +++ b/src/Dialogs/Settings/Panels/AudioConfigPanel.cpp @@ -37,7 +37,7 @@ AudioConfigPanel::Prepare(ContainerWindow &parent, const auto &settings = CommonInterface::GetUISettings().sound; - AddInteger(_("Master Volume"), nullptr, _T("%d %%"), _T("%d"), + AddInteger(_("Master Volume"), nullptr, "%d %%", "%d", 0, VolumeController::GetMaxValue(), 1, settings.master_volume); } diff --git a/src/Dialogs/Settings/Panels/AudioVarioConfigPanel.cpp b/src/Dialogs/Settings/Panels/AudioVarioConfigPanel.cpp index 0f56753d9b4..5fb5ae5d0a4 100644 --- a/src/Dialogs/Settings/Panels/AudioVarioConfigPanel.cpp +++ b/src/Dialogs/Settings/Panels/AudioVarioConfigPanel.cpp @@ -2,11 +2,14 @@ // Copyright The XCSoar Project #include "AudioVarioConfigPanel.hpp" +#include "Dialogs/Message.hpp" #include "Profile/Keys.hpp" #include "Language/Language.hpp" #include "Interface.hpp" #include "Widget/RowFormWidget.hpp" +#include "Form/DataField/Boolean.hpp" #include "Form/DataField/Float.hpp" +#include "Form/DataField/Listener.hpp" #include "UIGlobals.hpp" #include "Audio/Features.hpp" #include "Audio/VarioGlue.hpp" @@ -14,8 +17,8 @@ #include "Formatter/UserUnits.hpp" enum ControlIndex { - Enabled, - Volume, + ENABLED, + VOLUME, DEAD_BAND_ENABLED, SPACER, MIN_FREQUENCY, @@ -27,7 +30,7 @@ enum ControlIndex { }; -class AudioVarioConfigPanel final : public RowFormWidget { +class AudioVarioConfigPanel final : public RowFormWidget, DataFieldListener { public: AudioVarioConfigPanel() :RowFormWidget(UIGlobals::GetDialogLook()) {} @@ -35,8 +38,23 @@ class AudioVarioConfigPanel final : public RowFormWidget { public: void Prepare(ContainerWindow &parent, const PixelRect &rc) noexcept override; bool Save(bool &changed) noexcept override; + +private: + /* methods from DataFieldListener */ + void OnModified(DataField &df) noexcept override; }; +void +AudioVarioConfigPanel::OnModified([[maybe_unused]] DataField &df) noexcept +{ + if (IsDataField(ENABLED, df)) { + bool enabled = ((const DataFieldBoolean &)df).GetValue(); + // SetEnabled(((const DataFieldBoolean &)df).GetValue()); + ShowMessageBox(enabled ? "Audio enabled" : "disabled", + "Audio-Enable", 0); //MB_OK); + } +} + void AudioVarioConfigPanel::Prepare(ContainerWindow &parent, const PixelRect &rc) noexcept @@ -50,9 +68,9 @@ AudioVarioConfigPanel::Prepare(ContainerWindow &parent, AddBoolean(_("Audio vario"), _("Emulate the sound of an electronic vario."), - settings.enabled); + settings.enabled, this); - AddInteger(_("Volume"), nullptr, _T("%u %%"), _T("%u"), + AddInteger(_("Volume"), nullptr, "%u %%", "%u", 0, 100, 1, settings.volume); AddBoolean(_("Enable Deadband"), @@ -64,19 +82,19 @@ AudioVarioConfigPanel::Prepare(ContainerWindow &parent, AddInteger(_("Min. Frequency"), _("The tone frequency that is played at maximum sink rate."), - _T("%u Hz"), _T("%u"), + "%u Hz", "%u", 50, 3000, 50, settings.min_frequency); SetExpertRow(MIN_FREQUENCY); AddInteger(_("Zero Frequency"), _("The tone frequency that is played at zero climb rate."), - _T("%u Hz"), _T("%u"), + "%u Hz", "%u", 50, 3000, 50, settings.zero_frequency); SetExpertRow(ZERO_FREQUENCY); AddInteger(_("Max. Frequency"), _("The tone frequency that is played at maximum climb rate."), - _T("%u Hz"), _T("%u"), + "%u Hz", "%u", 50, 3000, 50, settings.max_frequency); SetExpertRow(MAX_FREQUENCY); @@ -85,7 +103,7 @@ AudioVarioConfigPanel::Prepare(ContainerWindow &parent, AddFloat(_("Deadband min. lift"), _("Below this lift threshold the vario will start to play sounds if the 'Deadband' feature is enabled."), - _T("%.1f %s"), _T("%.1f"), + "%.1f %s", "%.1f", Units::ToUserVSpeed(-5), 0, GetUserVerticalSpeedStep(), false, UnitGroup::VERTICAL_SPEED, settings.min_dead); @@ -95,7 +113,7 @@ AudioVarioConfigPanel::Prepare(ContainerWindow &parent, AddFloat(_("Deadband max. lift"), _("Above this lift threshold the vario will start to play sounds if the 'Deadband' feature is enabled."), - _T("%.1f %s"), _T("%.1f"), + "%.1f %s", "%.1f", 0, Units::ToUserVSpeed(2), GetUserVerticalSpeedStep(), false, UnitGroup::VERTICAL_SPEED, settings.max_dead); @@ -112,10 +130,10 @@ AudioVarioConfigPanel::Save(bool &changed) noexcept auto &settings = CommonInterface::SetUISettings().sound.vario; - changed |= SaveValue(Enabled, ProfileKeys::SoundAudioVario, + changed |= SaveValue(ENABLED, ProfileKeys::SoundAudioVario, settings.enabled); - changed |= SaveValueInteger(Volume, ProfileKeys::SoundVolume, + changed |= SaveValueInteger(VOLUME, ProfileKeys::SoundVolume, settings.volume); changed |= SaveValue(DEAD_BAND_ENABLED, ProfileKeys::VarioDeadBandEnabled, diff --git a/src/Dialogs/Settings/Panels/CloudConfigPanel.cpp b/src/Dialogs/Settings/Panels/CloudConfigPanel.cpp index 3e7d086b861..7039f6a3abd 100644 --- a/src/Dialogs/Settings/Panels/CloudConfigPanel.cpp +++ b/src/Dialogs/Settings/Panels/CloudConfigPanel.cpp @@ -60,12 +60,12 @@ CloudConfigPanel::Prepare(ContainerWindow &parent, const auto &settings = CommonInterface::GetComputerSettings().tracking.skylines.cloud; - AddBoolean(_T("XCSoar Cloud"), + AddBoolean("XCSoar Cloud", _("Participate in the XCSoar Cloud field test? This transmits your location, thermal/wave locations and other weather data to our test server."), settings.enabled == TriState::TRUE, this); - AddBoolean(_T("Show thermals"), + AddBoolean("Show thermals", _("Obtain and show thermal locations reported by others."), settings.show_thermals); diff --git a/src/Dialogs/Settings/Panels/ConfigPanel.hpp b/src/Dialogs/Settings/Panels/ConfigPanel.hpp index fc34ed2802a..8f8ada20099 100644 --- a/src/Dialogs/Settings/Panels/ConfigPanel.hpp +++ b/src/Dialogs/Settings/Panels/ConfigPanel.hpp @@ -7,7 +7,7 @@ #include namespace ConfigPanel { -void BorrowExtraButton(unsigned i, const TCHAR *caption, +void BorrowExtraButton(unsigned i, const char *caption, std::function callback) noexcept; void ReturnExtraButton(unsigned i); }; diff --git a/src/Dialogs/Settings/Panels/GlideComputerConfigPanel.cpp b/src/Dialogs/Settings/Panels/GlideComputerConfigPanel.cpp index 8a598e924bd..267f0083ca4 100644 --- a/src/Dialogs/Settings/Panels/GlideComputerConfigPanel.cpp +++ b/src/Dialogs/Settings/Panels/GlideComputerConfigPanel.cpp @@ -79,19 +79,19 @@ GlideComputerConfigPanel::Prepare(ContainerWindow &parent, SetExpertRow(EnableExternalTriggerCruise); static constexpr StaticEnumChoice aver_eff_list[] = { - { ae15seconds, _T("15 s"), N_("Preferred period for paragliders.") }, - { ae30seconds, _T("30 s") }, - { ae60seconds, _T("60 s") }, - { ae90seconds, _T("90 s"), N_("Preferred period for gliders.") }, - { ae2minutes, _T("2 min") }, - { ae3minutes, _T("3 min") }, + { AverageEffTime::ae15seconds, "15 s", N_("Preferred period for paragliders.") }, + { AverageEffTime::ae30seconds, "30 s" }, + { AverageEffTime::ae60seconds, "60 s" }, + { AverageEffTime::ae90seconds, "90 s", N_("Preferred period for gliders.") }, + { AverageEffTime::ae2minutes, "2 min" }, + { AverageEffTime::ae3minutes, "3 min" }, nullptr }; AddEnum(_("GR average period"), _("Here you can decide on how many seconds of flight this calculation must be done. " "Normally for gliders a good value is 90-120 seconds, and for paragliders 15 seconds."), - aver_eff_list, settings_computer.average_eff_time); + aver_eff_list, (unsigned)settings_computer.average_eff_time); SetExpertRow(AverEffTime); AddBoolean(_("Predict wind drift"), diff --git a/src/Dialogs/Settings/Panels/InterfaceConfigPanel.cpp b/src/Dialogs/Settings/Panels/InterfaceConfigPanel.cpp index 6ba76ae5a9c..e0ff4316ae4 100644 --- a/src/Dialogs/Settings/Panels/InterfaceConfigPanel.cpp +++ b/src/Dialogs/Settings/Panels/InterfaceConfigPanel.cpp @@ -70,7 +70,7 @@ InterfaceConfigPanel::Prepare(ContainerWindow &parent, AddInteger(_("Text size"), nullptr, - _T("%d %%"), _T("%d"), 75, 200, 5, + "%d %%", "%d", 75, 200, 5, settings.scale); WndProperty *wp_dpi = AddEnum(_("Display Resolution"), @@ -86,7 +86,7 @@ InterfaceConfigPanel::Prepare(ContainerWindow &parent, DataFieldEnum &df = *(DataFieldEnum *)wp_dpi->GetDataField(); df.AddChoice(0, _("Automatic")); for (const unsigned *dpi = dpi_choices; dpi != dpi_choices_end; ++dpi) { - TCHAR buffer[20]; + char buffer[20]; _stprintf(buffer, _("%d dpi"), *dpi); df.AddChoice(*dpi, buffer); } @@ -98,7 +98,7 @@ InterfaceConfigPanel::Prepare(ContainerWindow &parent, AddFile(_("Events"), _("The Input Events file defines the menu system and how XCSoar responds to " "button presses and events from external devices."), - ProfileKeys::InputFile, _T("*.xci\0"), FileType::XCI); + ProfileKeys::InputFile, "*.xci\0", FileType::XCI); SetExpertRow(InputFile); #ifdef HAVE_NLS @@ -110,18 +110,18 @@ InterfaceConfigPanel::Prepare(ContainerWindow &parent, if (wp != nullptr) { DataFieldEnum &df = *(DataFieldEnum *)wp->GetDataField(); df.addEnumText(_("Automatic")); - df.addEnumText(_T("English")); + df.addEnumText("English"); for (const BuiltinLanguage *l = language_table; l->resource != nullptr; ++l) { StaticString<100> display_string; - display_string.Format(_T("%s (%s)"), l->name, l->resource); + display_string.Format("%s (%s)", l->name, l->resource); df.addEnumText(l->resource, display_string); } #ifdef HAVE_BUILTIN_LANGUAGES LanguageFileVisitor lfv(df); - VisitDataFiles(_T("*.mo"), lfv); + VisitDataFiles("*.mo", lfv); #endif df.Sort(2); @@ -129,11 +129,11 @@ InterfaceConfigPanel::Prepare(ContainerWindow &parent, auto value_buffer = Profile::GetPath(ProfileKeys::LanguageFile); Path value = value_buffer; if (value == nullptr) - value = Path(_T("")); + value = Path(""); - if (value == Path(_T("none"))) + if (value == Path("none")) df.SetValue(1); - else if (!value.empty() && value != Path(_T("auto"))) { + else if (!value.empty() && value != Path("auto")) { const Path base = value.GetBase(); if (base != nullptr) df.SetValue(base.c_str()); @@ -206,22 +206,22 @@ InterfaceConfigPanel::Save(bool &_changed) noexcept const auto old_value_buffer = Profile::GetPath(ProfileKeys::LanguageFile); Path old_value = old_value_buffer; if (old_value == nullptr) - old_value = Path(_T("")); + old_value = Path(""); auto old_base = old_value.GetBase(); if (old_base == nullptr) old_base = old_value; AllocatedPath buffer = nullptr; - const TCHAR *new_value, *new_base; + const char *new_value, *new_base; switch (df.GetValue()) { case 0: - new_value = new_base = _T("auto"); + new_value = new_base = "auto"; break; case 1: - new_value = new_base = _T("none"); + new_value = new_base = "none"; break; default: diff --git a/src/Dialogs/Settings/Panels/LayoutConfigPanel.cpp b/src/Dialogs/Settings/Panels/LayoutConfigPanel.cpp index e71d19ad1af..10eb67f9961 100644 --- a/src/Dialogs/Settings/Panels/LayoutConfigPanel.cpp +++ b/src/Dialogs/Settings/Panels/LayoutConfigPanel.cpp @@ -106,6 +106,14 @@ static constexpr StaticEnumChoice info_box_geometry_list[] = { N_("4 Top or Left") }, { InfoBoxSettings::Geometry::BOTTOM_RIGHT_4, N_("4 Bottom or Right") }, + { InfoBoxSettings::Geometry::TOP_8_VARIO_BOTTOM_5, + N_("8 Top + Vario + 5 Bottom (Portrait)") }, + { InfoBoxSettings::Geometry::TOP_8_VARIO_BOTTOM_10, + N_("8 Top + Vario + 10 Bottom (Portrait)") }, + { InfoBoxSettings::Geometry::TOP_12_VARIO, + N_("12 Top + Vario (Portrait)") }, + { InfoBoxSettings::Geometry::TOP_16_VARIO, + N_("16 Top + Vario (Portrait)") }, nullptr }; @@ -188,11 +196,19 @@ LayoutConfigPanel::Prepare(ContainerWindow &parent, ui_settings.display.full_screen); #endif +#if defined(IS_OPENVARIO) + /* moved to OpenVario->DisplaySettingsWidget! + * at OpenVario the System orientation AND the OpenSoar orientation should + * be equal always! + */ + AddDummy(); +#else if (Display::RotateSupported()) AddEnum(_("Display orientation"), _("Rotate the display on devices that support it."), display_orientation_list, (unsigned)ui_settings.display.orientation); else AddDummy(); +#endif AddEnum(_("Dark mode"), nullptr, dark_mode_list, (unsigned)ui_settings.dark_mode); @@ -235,7 +251,7 @@ LayoutConfigPanel::Prepare(ContainerWindow &parent, #endif #ifdef DRAW_MOUSE_CURSOR - AddInteger(_("Cursor zoom"), _("Cursor zoom factor"), _T("%d x"), _T("%d x"), 1, 10, 1, + AddInteger(_("Cursor zoom"), _("Cursor zoom factor"), "%d x", "%d x", 1, 10, 1, (unsigned)ui_settings.display.cursor_size); AddBoolean(_("Invert cursor color"), _("Enable black cursor"), ui_settings.display.invert_cursor_colors); @@ -257,12 +273,14 @@ LayoutConfigPanel::Save(bool &_changed) noexcept bool orientation_changed = false; +#if !defined(IS_OPENVARIO) if (Display::RotateSupported()) { orientation_changed = SaveValueEnum(MapOrientation, ProfileKeys::MapOrientation, ui_settings.display.orientation); changed |= orientation_changed; } +#endif changed |= SaveValueEnum(DarkMode, ProfileKeys::DarkMode, ui_settings.dark_mode); diff --git a/src/Dialogs/Settings/Panels/LoggerConfigPanel.cpp b/src/Dialogs/Settings/Panels/LoggerConfigPanel.cpp index 1c965ec5e97..c7a004c5ec8 100644 --- a/src/Dialogs/Settings/Panels/LoggerConfigPanel.cpp +++ b/src/Dialogs/Settings/Panels/LoggerConfigPanel.cpp @@ -60,7 +60,7 @@ LoggerConfigPanel::Prepare(ContainerWindow &parent, AddFloat(_("Crew weight default"), _("Default for all weight loaded to the glider beyond the empty weight and besides " "the water ballast."), - _T("%.0f %s"), _T("%.0f"), + "%.0f %s", "%.0f", 0, 300, 5, false, UnitGroup::MASS, logger.crew_mass_template); diff --git a/src/Dialogs/Settings/Panels/MapDisplayConfigPanel.cpp b/src/Dialogs/Settings/Panels/MapDisplayConfigPanel.cpp index e33994d0c50..b881cdfe3db 100644 --- a/src/Dialogs/Settings/Panels/MapDisplayConfigPanel.cpp +++ b/src/Dialogs/Settings/Panels/MapDisplayConfigPanel.cpp @@ -114,13 +114,13 @@ MapDisplayConfigPanel::Prepare(ContainerWindow &parent, AddInteger(_("Glider position offset"), _("Defines the location of the glider drawn on the screen in percent from the screen edge."), - _T("%d %%"), _T("%d"), 10, 50, 5, + "%d %%", "%d", 10, 50, 5, settings_map.glider_screen_position); SetExpertRow(GliderScreenPosition); AddFloat(_("Max. auto zoom distance"), _("The upper limit for auto zoom distance."), - _T("%.0f %s"), _T("%.0f"), 20, 250, 10, false, + "%.0f %s", "%.0f", 20, 250, 10, false, UnitGroup::DISTANCE, settings_map.max_auto_zoom_distance); SetExpertRow(MaxAutoZoomDistance); diff --git a/src/Dialogs/Settings/Panels/PagesConfigPanel.cpp b/src/Dialogs/Settings/Panels/PagesConfigPanel.cpp index d3072cae298..dc89f0a9573 100644 --- a/src/Dialogs/Settings/Panels/PagesConfigPanel.cpp +++ b/src/Dialogs/Settings/Panels/PagesConfigPanel.cpp @@ -115,7 +115,7 @@ class PageListWidget } }); - move_up_button = buttons.AddSymbol(_T("^"), [this](){ + move_up_button = buttons.AddSymbol("^", [this](){ const unsigned cursor = GetList().GetCursorIndex(); if (cursor > 0) { std::swap(settings.pages[cursor], settings.pages[cursor - 1]); @@ -123,7 +123,7 @@ class PageListWidget } }); - move_down_button = buttons.AddSymbol(_T("v"), [this](){ + move_down_button = buttons.AddSymbol("v", [this](){ const unsigned n = GetList().GetLength(); const unsigned cursor = GetList().GetCursorIndex(); if (cursor + 1 < n) { @@ -193,11 +193,11 @@ PageLayoutEditWidget::Prepare([[maybe_unused]] ContainerWindow &parent, [[maybe_ ib_list, IBP_AUTO, this); DataFieldEnum &ib = *(DataFieldEnum *)wp->GetDataField(); for (unsigned i = 0; i < InfoBoxSettings::MAX_PANELS; ++i) { - const TCHAR cruise_help[] = N_("For cruise mode. Displayed when 'Auto' is selected and ship is below final glide altitude"); - const TCHAR circling_help[] = N_("For circling mode. Displayed when 'Auto' is selected and ship is circling"); - const TCHAR final_glide_help[] = N_("For final glide mode. Displayed when 'Auto' is selected and ship is above final glide altitude"); - const TCHAR *display_text = gettext(info_box_settings.panels[i].name); - const TCHAR *help_text = N_("A custom InfoBox set"); + const char cruise_help[] = N_("For cruise mode. Displayed when 'Auto' is selected and ship is below final glide altitude"); + const char circling_help[] = N_("For circling mode. Displayed when 'Auto' is selected and ship is circling"); + const char final_glide_help[] = N_("For final glide mode. Displayed when 'Auto' is selected and ship is above final glide altitude"); + const char *display_text = gettext(info_box_settings.panels[i].name); + const char *help_text = N_("A custom InfoBox set"); switch (i) { case 0: help_text = circling_help; @@ -364,14 +364,14 @@ PageListWidget::OnPaintItem(Canvas &canvas, const PixelRect rc, } if (value.infobox_config.enabled) { - buffer.AppendFormat(_T(", %s"), _("InfoBoxes")); + buffer.AppendFormat(", %s", _("InfoBoxes")); if (!value.infobox_config.auto_switch && value.infobox_config.panel < InfoBoxSettings::MAX_PANELS) - buffer.AppendFormat(_T(" (%s)"), + buffer.AppendFormat(" (%s)", gettext(info_box_settings.panels[value.infobox_config.panel].name)); else - buffer.AppendFormat(_T(" (%s)"), _("Auto")); + buffer.AppendFormat(" (%s)", _("Auto")); } switch (value.bottom) { @@ -380,7 +380,7 @@ PageListWidget::OnPaintItem(Canvas &canvas, const PixelRect rc, break; case PageLayout::Bottom::CROSS_SECTION: - buffer.AppendFormat(_T(", %s"), _("Cross section")); + buffer.AppendFormat(", %s", _("Cross section")); break; case PageLayout::Bottom::MAX: diff --git a/src/Dialogs/Settings/Panels/SafetyFactorsConfigPanel.cpp b/src/Dialogs/Settings/Panels/SafetyFactorsConfigPanel.cpp index 25eb85aabf6..53eb5c20c7b 100644 --- a/src/Dialogs/Settings/Panels/SafetyFactorsConfigPanel.cpp +++ b/src/Dialogs/Settings/Panels/SafetyFactorsConfigPanel.cpp @@ -46,13 +46,13 @@ SafetyFactorsConfigPanel::Prepare(ContainerWindow &parent, AddFloat(_("Arrival height"), _("The height above terrain that the glider should arrive at for a safe landing."), - _T("%.0f %s"), _T("%.0f"), + "%.0f %s", "%.0f", 0, 2000, 10, false, UnitGroup::ALTITUDE, task_behaviour.safety_height_arrival); AddFloat(_("Terrain height"), _("The height above terrain that the glider must clear during final glide."), - _T("%.0f %s"), _T("%.0f"), + "%.0f %s", "%.0f", 0, 1000, 10, false, UnitGroup::ALTITUDE, task_behaviour.route_planner.safety_height_terrain); @@ -74,7 +74,7 @@ SafetyFactorsConfigPanel::Prepare(ContainerWindow &parent, _("A permanent polar degradation. " "0% means no degradation, " "50% indicates the glider's sink rate is doubled."), - _T("%.0f %%"), _T("%.0f"), + "%.0f %%", "%.0f", 0, 50, 1, false, (1 - settings_computer.polar.degradation_factor) * 100); SetExpertRow(PolarDegradation); @@ -86,7 +86,7 @@ SafetyFactorsConfigPanel::Prepare(ContainerWindow &parent, AddFloat(_("Safety MC"), _("The MacCready setting used, when safety MC is enabled for reach calculations, in task abort mode and for determining arrival altitude at airfields."), - _T("%.1f %s"), _T("%.1f"), + "%.1f %s", "%.1f", 0, Units::ToUserVSpeed(10), GetUserVerticalSpeedStep(), false, UnitGroup::VERTICAL_SPEED, task_behaviour.safety_mc); SetExpertRow(SafetyMC); @@ -95,7 +95,7 @@ SafetyFactorsConfigPanel::Prepare(ContainerWindow &parent, AddFloat(_("STF risk factor"), _("The STF risk factor reduces the MacCready setting used to calculate speed to fly as the glider gets low, in order to compensate for risk. Set to 0.0 for no compensation, 1.0 scales MC linearly with current height (with reference to height of the maximum climb). If considered, 0.3 is recommended."), - _T("%.1f %s"), _T("%.1f"), + "%.1f %s", "%.1f", 0, 1, 0.1, false, task_behaviour.risk_gamma); SetExpertRow(RiskFactor); diff --git a/src/Dialogs/Settings/Panels/ScoringConfigPanel.cpp b/src/Dialogs/Settings/Panels/ScoringConfigPanel.cpp index 8b9b0b7c207..cf8e6117b6d 100644 --- a/src/Dialogs/Settings/Panels/ScoringConfigPanel.cpp +++ b/src/Dialogs/Settings/Panels/ScoringConfigPanel.cpp @@ -55,8 +55,8 @@ ScoringConfigPanel::ShowFAITriangleControls(bool show) } static constexpr StaticEnumChoice fai_triangle_threshold_list[] = { - { FAITriangleSettings::Threshold::FAI, _T("750km (FAI)") }, - { FAITriangleSettings::Threshold::KM500, _T("500km (OLC, DMSt)") }, + { FAITriangleSettings::Threshold::FAI, "750km (FAI)" }, + { FAITriangleSettings::Threshold::KM500, "500km (OLC, DMSt)" }, nullptr }; @@ -83,7 +83,7 @@ ScoringConfigPanel::Prepare([[maybe_unused]] ContainerWindow &parent, N_("A combination of Classic and FAI rules. 30% of the FAI score are added to the Classic score.") }, { Contest::DMST, ContestToString(Contest::DMST), /* German competition, no translation */ - _T("Deutsche Meisterschaft im Streckensegelflug.") }, + "Deutsche Meisterschaft im Streckensegelflug." }, { Contest::XCONTEST, ContestToString(Contest::XCONTEST), N_("PG online contest with different track values: Free flight - 1 km = 1.0 point; " "flat trianlge - 1 km = 1.2 p; FAI triangle - 1 km = 1.4 p.") }, diff --git a/src/Dialogs/Settings/Panels/SiteConfigPanel.cpp b/src/Dialogs/Settings/Panels/SiteConfigPanel.cpp index 602dd17ae11..212c9405f09 100644 --- a/src/Dialogs/Settings/Panels/SiteConfigPanel.cpp +++ b/src/Dialogs/Settings/Panels/SiteConfigPanel.cpp @@ -42,14 +42,14 @@ class SiteConfigPanel final : public RowFormWidget { void SiteConfigPanel::Prepare([[maybe_unused]] ContainerWindow &parent, [[maybe_unused]] const PixelRect &rc) noexcept { - WndProperty *wp = Add(_T(""), 0, true); + WndProperty *wp = Add("", 0, true); wp->SetText(GetPrimaryDataPath().c_str()); wp->SetEnabled(false); AddFile(_("Map database"), _("The name of the file (.xcm) containing terrain, topography, and optionally " "waypoints, their details and airspaces."), - ProfileKeys::MapFile, _T("*.xcm\0*.lkm\0"), FileType::MAP); + ProfileKeys::MapFile, "*.xcm\0*.lkm\0", FileType::MAP); AddFile(_("Waypoints"), _("Primary waypoints file. Supported file types are Cambridge/WinPilot files (.dat), " @@ -72,28 +72,28 @@ SiteConfigPanel::Prepare([[maybe_unused]] ContainerWindow &parent, [[maybe_unuse SetExpertRow(WatchedWaypointFile); AddFile(_("Airspaces"), _("The file name of the primary airspace file."), - ProfileKeys::AirspaceFile, _T("*.txt\0*.air\0*.sua\0"), + ProfileKeys::AirspaceFile, "*.txt\0*.air\0*.sua\0", FileType::AIRSPACE); AddFile(_("More airspaces"), _("The file name of the secondary airspace file."), - ProfileKeys::AdditionalAirspaceFile, _T("*.txt\0*.air\0*.sua\0"), + ProfileKeys::AdditionalAirspaceFile, "*.txt\0*.air\0*.sua\0", FileType::AIRSPACE); SetExpertRow(AdditionalAirspaceFile); AddFile(_("Waypoint details"), _("The file may contain extracts from enroute supplements or other contributed " "information about individual waypoints and airfields."), - ProfileKeys::AirfieldFile, _T("*.txt\0"), + ProfileKeys::AirfieldFile, "*.txt\0", FileType::WAYPOINTDETAILS); SetExpertRow(AirfieldFile); AddFile(_("FLARM Device Database"), _("The name of the file containing information about registered FLARM devices."), - ProfileKeys::FlarmFile, _T("*.fln\0"), + ProfileKeys::FlarmFile, "*.fln\0", FileType::FLARMNET); - AddFile(_T("RASP"), nullptr, - ProfileKeys::RaspFile, _T("*-rasp*.dat\0"), + AddFile("RASP", nullptr, + ProfileKeys::RaspFile, "*-rasp*.dat\0", FileType::RASP); } diff --git a/src/Dialogs/Settings/Panels/TaskDefaultsConfigPanel.cpp b/src/Dialogs/Settings/Panels/TaskDefaultsConfigPanel.cpp index 4654962ff1f..0d3c77b1005 100644 --- a/src/Dialogs/Settings/Panels/TaskDefaultsConfigPanel.cpp +++ b/src/Dialogs/Settings/Panels/TaskDefaultsConfigPanel.cpp @@ -58,8 +58,8 @@ TaskDefaultsConfigPanel::OnModified(DataField &df) noexcept SetFinishLabel(); } -static const TCHAR *const Caption_GateWidth = N_("Gate width"); -static const TCHAR *const Caption_Radius = N_("Radius"); +static const char *const Caption_GateWidth = N_("Gate width"); +static const char *const Caption_Radius = N_("Radius"); void TaskDefaultsConfigPanel::SetStartLabel() @@ -130,7 +130,7 @@ TaskDefaultsConfigPanel::Prepare(ContainerWindow &parent, task_behaviour.sector_defaults.start_type); AddFloat(Caption_GateWidth, _("Default radius or gate width of the start zone for new tasks."), - _T("%.1f %s"), _T("%.1f"), 0.1, 100, 1.0, true, UnitGroup::DISTANCE, + "%.1f %s", "%.1f", 0.1, 100, 1.0, true, UnitGroup::DISTANCE, task_behaviour.sector_defaults.start_radius); AddSpacer(); @@ -142,7 +142,7 @@ TaskDefaultsConfigPanel::Prepare(ContainerWindow &parent, task_behaviour.sector_defaults.finish_type); AddFloat(Caption_GateWidth, _("Default radius or gate width of the finish zone in new tasks."), - _T("%.1f %s"), _T("%.1f"), 0.1, 100, 1.0, true, UnitGroup::DISTANCE, + "%.1f %s", "%.1f", 0.1, 100, 1.0, true, UnitGroup::DISTANCE, task_behaviour.sector_defaults.finish_radius); AddSpacer(); @@ -152,7 +152,7 @@ TaskDefaultsConfigPanel::Prepare(ContainerWindow &parent, task_behaviour.sector_defaults.turnpoint_type); AddFloat(Caption_Radius, _("Default radius of turnpoint cylinders and sectors in new tasks."), - _T("%.1f %s"), _T("%.1f"), 0.1, 100, 1.0, true, UnitGroup::DISTANCE, + "%.1f %s", "%.1f", 0.1, 100, 1.0, true, UnitGroup::DISTANCE, task_behaviour.sector_defaults.turnpoint_radius); AddSpacer(); diff --git a/src/Dialogs/Settings/Panels/TaskRulesConfigPanel.cpp b/src/Dialogs/Settings/Panels/TaskRulesConfigPanel.cpp index c1617d26246..f99f8f87340 100644 --- a/src/Dialogs/Settings/Panels/TaskRulesConfigPanel.cpp +++ b/src/Dialogs/Settings/Panels/TaskRulesConfigPanel.cpp @@ -46,13 +46,13 @@ TaskRulesConfigPanel::Prepare(ContainerWindow &parent, RowFormWidget::Prepare(parent, rc); AddFloat(_("Start max. speed"), _("Maximum speed allowed in start observation zone. Set to 0 for no limit."), - _T("%.0f %s"), _T("%.0f"), 0, 300, 5, false, UnitGroup::HORIZONTAL_SPEED, + "%.0f %s", "%.0f", 0, 300, 5, false, UnitGroup::HORIZONTAL_SPEED, task_behaviour.ordered_defaults.start_constraints.max_speed); SetExpertRow(StartMaxSpeed); AddFloat(_("Start max. speed margin"), _("Maximum speed above maximum start speed to tolerate. Set to 0 for no tolerance."), - _T("%.0f %s"), _T("%.0f"), 0, 300, 5, false, UnitGroup::HORIZONTAL_SPEED, + "%.0f %s", "%.0f", 0, 300, 5, false, UnitGroup::HORIZONTAL_SPEED, task_behaviour.start_margins.max_speed_margin); SetExpertRow(StartMaxSpeedMargin); @@ -62,13 +62,13 @@ TaskRulesConfigPanel::Prepare(ContainerWindow &parent, AddFloat(_("Start max. height"), _("Maximum height based on start height reference (AGL or MSL) while starting the task. " "Set to 0 for no limit."), - _T("%.0f %s"), _T("%.0f"), 0, 10000, 50, false, UnitGroup::ALTITUDE, + "%.0f %s", "%.0f", 0, 10000, 50, false, UnitGroup::ALTITUDE, task_behaviour.ordered_defaults.start_constraints.max_height); SetExpertRow(StartMaxHeight); AddFloat(_("Start max. height margin"), _("Maximum height above maximum start height to tolerate. Set to 0 for no tolerance."), - _T("%.0f %s"), _T("%.0f"), 0, 10000, 50, false, UnitGroup::ALTITUDE, + "%.0f %s", "%.0f", 0, 10000, 50, false, UnitGroup::ALTITUDE, task_behaviour.start_margins.max_height_margin); SetExpertRow(StartMaxHeightMargin); @@ -92,7 +92,7 @@ TaskRulesConfigPanel::Prepare(ContainerWindow &parent, AddFloat(_("Finish min. height"), _("Minimum height based on finish height reference (AGL or MSL) while finishing the task. " "Set to 0 for no limit."), - _T("%.0f %s"), _T("%.0f"), 0, 10000, 50, false, UnitGroup::ALTITUDE, + "%.0f %s", "%.0f", 0, 10000, 50, false, UnitGroup::ALTITUDE, task_behaviour.ordered_defaults.finish_constraints.min_height); SetExpertRow(FinishMinHeight); diff --git a/src/Dialogs/Settings/Panels/TerrainDisplayConfigPanel.cpp b/src/Dialogs/Settings/Panels/TerrainDisplayConfigPanel.cpp index 79c45df67b0..a31139fcbc5 100644 --- a/src/Dialogs/Settings/Panels/TerrainDisplayConfigPanel.cpp +++ b/src/Dialogs/Settings/Panels/TerrainDisplayConfigPanel.cpp @@ -227,14 +227,14 @@ TerrainDisplayConfigPanel::Prepare(ContainerWindow &parent, AddInteger(_("Terrain contrast"), _("Defines the amount of Phong shading in the terrain rendering. Use large values to emphasise terrain slope, smaller values if flying in steep mountains."), - _T("%d %%"), _T("%d %%"), 0, 100, 5, + "%d %%", "%d %%", 0, 100, 5, ByteToPercent(terrain.contrast)); GetDataField(TerrainContrast).SetListener(this); SetExpertRow(TerrainContrast); AddInteger(_("Terrain brightness"), _("Defines the brightness (whiteness) of the terrain rendering. This controls the average illumination of the terrain."), - _T("%d %%"), _T("%d %%"), 0, 100, 5, + "%d %%", "%d %%", 0, 100, 5, ByteToPercent(terrain.brightness)); GetDataField(TerrainBrightness).SetListener(this); SetExpertRow(TerrainBrightness); diff --git a/src/Dialogs/Settings/Panels/TrackingConfigPanel.cpp b/src/Dialogs/Settings/Panels/TrackingConfigPanel.cpp index e810b7d0e92..81e322e22a6 100644 --- a/src/Dialogs/Settings/Panels/TrackingConfigPanel.cpp +++ b/src/Dialogs/Settings/Panels/TrackingConfigPanel.cpp @@ -130,26 +130,26 @@ TrackingConfigPanel::OnModified(DataField &df) noexcept #if (defined HAVE_SKYLINES_TRACKING || defined HAVE_LIVETRACK24) static constexpr StaticEnumChoice tracking_intervals[] = { - { 1, _T("1 sec") }, - { 2, _T("2 sec") }, - { 3, _T("3 sec") }, - { 5, _T("5 sec") }, - { 10, _T("10 sec") }, - { 15, _T("15 sec") }, - { 20, _T("20 sec") }, - { 30, _T("30 sec") }, - { 45, _T("45 sec") }, - { 60, _T("1 min") }, - { 120, _T("2 min") }, - { 180, _T("3 min") }, - { 300, _T("5 min") }, - { 600, _T("10 min") }, - { 900, _T("15 min") }, - { 1200, _T("20 min") }, - { 1800, _T("30 min") }, - { 2400, _T("40 min") }, - { 3000, _T("50 min") }, - { 3600, _T("60 min") }, + { 1, "1 sec" }, + { 2, "2 sec" }, + { 3, "3 sec" }, + { 5, "5 sec" }, + { 10, "10 sec" }, + { 15, "15 sec" }, + { 20, "20 sec" }, + { 30, "30 sec" }, + { 45, "45 sec" }, + { 60, "1 min" }, + { 120, "2 min" }, + { 180, "3 min" }, + { 300, "5 min" }, + { 600, "10 min" }, + { 900, "15 min" }, + { 1200, "20 min" }, + { 1800, "30 min" }, + { 2400, "40 min" }, + { 3000, "50 min" }, + { 3600, "60 min" }, nullptr, }; @@ -158,9 +158,9 @@ static constexpr StaticEnumChoice tracking_intervals[] = { #ifdef HAVE_LIVETRACK24 static constexpr StaticEnumChoice server_list[] = { - { 0, _T("www.livetrack24.com") }, - { 1, _T("test.livetrack24.com") }, - { 2, _T("livexc.dhv.de") }, + { 0, "www.livetrack24.com" }, + { 1, "test.livetrack24.com" }, + { 2, "livexc.dhv.de" }, nullptr, }; @@ -185,9 +185,9 @@ TrackingConfigPanel::Prepare(ContainerWindow &parent, const PixelRect &rc) noexc RowFormWidget::Prepare(parent, rc); #ifdef HAVE_SKYLINES_TRACKING - AddBoolean(_T("SkyLines"), nullptr, settings.skylines.enabled, this); + AddBoolean("SkyLines", nullptr, settings.skylines.enabled, this); #ifdef HAVE_NET_STATE_ROAMING - AddBoolean(_T("Roaming"), nullptr, settings.skylines.roaming, this); + AddBoolean("Roaming", nullptr, settings.skylines.roaming, this); #endif AddEnum(_("Tracking Interval"), nullptr, tracking_intervals, FindClosestTrackingInterval(settings.skylines.interval)); @@ -202,10 +202,10 @@ TrackingConfigPanel::Prepare(ContainerWindow &parent, const PixelRect &rc) noexc StaticString<64> buffer; if (settings.skylines.key != 0) - buffer.UnsafeFormat(_T("%llX"), (unsigned long long)settings.skylines.key); + buffer.UnsafeFormat("%llX", (unsigned long long)settings.skylines.key); else buffer.clear(); - AddText(_T("Key"), nullptr, buffer); + AddText("Key", nullptr, buffer); #endif #if defined(HAVE_SKYLINES_TRACKING) && defined(HAVE_LIVETRACK24) @@ -213,22 +213,22 @@ TrackingConfigPanel::Prepare(ContainerWindow &parent, const PixelRect &rc) noexc #endif #ifdef HAVE_LIVETRACK24 - AddBoolean(_T("LiveTrack24"), _T(""), settings.livetrack24.enabled, this); + AddBoolean("LiveTrack24", "", settings.livetrack24.enabled, this); AddEnum(_("Tracking Interval"), nullptr, tracking_intervals, FindClosestTrackingInterval(settings.livetrack24.interval)); AddEnum(_("Vehicle Type"), _("Type of vehicle used."), vehicle_type_list, (unsigned) settings.livetrack24.vehicleType); - AddText(_("Vehicle Name"), _T("Name of vehicle used."), + AddText(_("Vehicle Name"), "Name of vehicle used.", settings.livetrack24.vehicle_name); - WndProperty *edit = AddEnum(_("Server"), _T(""), server_list, 0); + WndProperty *edit = AddEnum(_("Server"), "", server_list, 0); ((DataFieldEnum *)edit->GetDataField())->SetValue(settings.livetrack24.server); edit->RefreshDisplay(); - AddText(_("Username"), _T(""), settings.livetrack24.username); - AddPassword(_("Password"), _T(""), settings.livetrack24.password); + AddText(_("Username"), "", settings.livetrack24.username); + AddPassword(_("Password"), "", settings.livetrack24.password); #endif #ifdef HAVE_SKYLINES_TRACKING @@ -245,7 +245,7 @@ static bool SaveKey(const RowFormWidget &form, unsigned idx, std::string_view profile_key, uint64_t &value_r) { - const TCHAR *const s = form.GetValueString(idx); + const char *const s = form.GetValueString(idx); uint64_t value = ParseUint64(s, nullptr, 16); if (value == value_r) return false; diff --git a/src/Dialogs/Settings/Panels/UnitsConfigPanel.cpp b/src/Dialogs/Settings/Panels/UnitsConfigPanel.cpp index 722f562edeb..f2aae72d978 100644 --- a/src/Dialogs/Settings/Panels/UnitsConfigPanel.cpp +++ b/src/Dialogs/Settings/Panels/UnitsConfigPanel.cpp @@ -121,10 +121,10 @@ UnitsConfigPanel::Prepare(ContainerWindow &parent, SetExpertRow(spacer_1); static constexpr StaticEnumChoice units_speed_list[] = { - { Unit::STATUTE_MILES_PER_HOUR, _T("mph") }, + { Unit::STATUTE_MILES_PER_HOUR, "mph" }, { Unit::KNOTS, N_("knots") }, - { Unit::KILOMETER_PER_HOUR, _T("km/h") }, - { Unit::METER_PER_SECOND, _T("m/s") }, + { Unit::KILOMETER_PER_HOUR, "km/h" }, + { Unit::METER_PER_SECOND, "m/s" }, nullptr }; AddEnum(_("Aircraft/Wind speed"), @@ -135,9 +135,9 @@ UnitsConfigPanel::Prepare(ContainerWindow &parent, SetExpertRow(UnitsSpeed); static constexpr StaticEnumChoice units_distance_list[] = { - { Unit::STATUTE_MILES, _T("sm") }, - { Unit::NAUTICAL_MILES, _T("nm") }, - { Unit::KILOMETER, _T("km") }, + { Unit::STATUTE_MILES, "sm" }, + { Unit::NAUTICAL_MILES, "nm" }, + { Unit::KILOMETER, "km" }, nullptr }; AddEnum(_("Distance"), @@ -149,8 +149,8 @@ UnitsConfigPanel::Prepare(ContainerWindow &parent, static constexpr StaticEnumChoice units_lift_list[] = { { Unit::KNOTS, N_("knots") }, - { Unit::METER_PER_SECOND, _T("m/s") }, - { Unit::FEET_PER_MINUTE, _T("ft/min") }, + { Unit::METER_PER_SECOND, "m/s" }, + { Unit::FEET_PER_MINUTE, "ft/min" }, nullptr }; AddEnum(_("Lift"), _("Units used for vertical speeds (variometer)."), @@ -169,8 +169,8 @@ UnitsConfigPanel::Prepare(ContainerWindow &parent, SetExpertRow(UnitsAltitude); static constexpr StaticEnumChoice units_temperature_list[] = { - { Unit::DEGREES_CELCIUS, _T(DEG "C") }, - { Unit::DEGREES_FAHRENHEIT, _T(DEG "F") }, + { Unit::DEGREES_CELCIUS, DEG "C" }, + { Unit::DEGREES_FAHRENHEIT, DEG "F" }, nullptr }; AddEnum(_("Temperature"), _("Units used for temperature."), @@ -179,10 +179,10 @@ UnitsConfigPanel::Prepare(ContainerWindow &parent, SetExpertRow(UnitsTemperature); static constexpr StaticEnumChoice units_taskspeed_list[] = { - { Unit::STATUTE_MILES_PER_HOUR, _T("mph") }, + { Unit::STATUTE_MILES_PER_HOUR, "mph" }, { Unit::KNOTS, N_("knots") }, - { Unit::KILOMETER_PER_HOUR, _T("km/h") }, - { Unit::METER_PER_SECOND, _T("m/s") }, + { Unit::KILOMETER_PER_HOUR, "km/h" }, + { Unit::METER_PER_SECOND, "m/s" }, nullptr }; AddEnum(_("Task speed"), _("Units used for task speeds."), @@ -191,9 +191,9 @@ UnitsConfigPanel::Prepare(ContainerWindow &parent, SetExpertRow(UnitsTaskSpeed); static constexpr StaticEnumChoice pressure_labels_list[] = { - { Unit::HECTOPASCAL, _T("hPa") }, - { Unit::MILLIBAR, _T("mb") }, - { Unit::INCH_MERCURY, _T("inHg") }, + { Unit::HECTOPASCAL, "hPa" }, + { Unit::MILLIBAR, "mb" }, + { Unit::INCH_MERCURY, "inHg" }, nullptr }; AddEnum(_("Pressure"), _("Units used for pressures."), @@ -202,8 +202,8 @@ UnitsConfigPanel::Prepare(ContainerWindow &parent, SetExpertRow(UnitsPressure); static constexpr StaticEnumChoice mass_labels_list[] = { - { Unit::KG, _T("kg") }, - { Unit::LB, _T("lb") }, + { Unit::KG, "kg" }, + { Unit::LB, "lb" }, nullptr }; AddEnum(_("Mass"), _("Units used for mass."), @@ -212,8 +212,8 @@ UnitsConfigPanel::Prepare(ContainerWindow &parent, SetExpertRow(UnitsMass); static constexpr StaticEnumChoice wing_loading_labels_list[] = { - { Unit::KG_PER_M2, _T("kg/m²") }, - { Unit::LB_PER_FT2, _T("lb/ft²") }, + { Unit::KG_PER_M2, "kg/m²" }, + { Unit::LB_PER_FT2, "lb/ft²" }, nullptr }; AddEnum(_("Wing loading"), _("Units used for wing loading."), @@ -225,11 +225,11 @@ UnitsConfigPanel::Prepare(ContainerWindow &parent, SetExpertRow(spacer_2); static constexpr StaticEnumChoice units_lat_lon_list[] = { - { CoordinateFormat::DDMMSS, _T("DDMMSS") }, - { CoordinateFormat::DDMMSS_S, _T("DDMMSS.s") }, - { CoordinateFormat::DDMM_MMM, _T("DDMM.mmm") }, - { CoordinateFormat::DD_DDDDD, _T("DD.ddddd") }, - { CoordinateFormat::UTM, _T("UTM") }, + { CoordinateFormat::DDMMSS, "DDMMSS" }, + { CoordinateFormat::DDMMSS_S, "DDMMSS.s" }, + { CoordinateFormat::DDMM_MMM, "DDMM.mmm" }, + { CoordinateFormat::DD_DDDDD, "DD.ddddd" }, + { CoordinateFormat::UTM, "UTM" }, nullptr }; AddEnum(_("Lat./Lon."), _("Units used for latitude and longitude."), @@ -238,8 +238,8 @@ UnitsConfigPanel::Prepare(ContainerWindow &parent, SetExpertRow(UnitsLatLon); static constexpr StaticEnumChoice rotation_labels_list[] = { - { Unit::HZ, _T("Hz") }, - { Unit::RPM, _T("rpm") }, + { Unit::HZ, "Hz" }, + { Unit::RPM, "rpm" }, nullptr }; AddEnum(_("Rotation"), _("Unit used for rotation."), diff --git a/src/Dialogs/Settings/Panels/WaypointDisplayConfigPanel.cpp b/src/Dialogs/Settings/Panels/WaypointDisplayConfigPanel.cpp index 8c39f1aefa8..622db6a8faf 100644 --- a/src/Dialogs/Settings/Panels/WaypointDisplayConfigPanel.cpp +++ b/src/Dialogs/Settings/Panels/WaypointDisplayConfigPanel.cpp @@ -176,7 +176,7 @@ WaypointDisplayConfigPanel::Prepare(ContainerWindow &parent, AddInteger(_("Landable size"), _("A percentage to select the size landables are displayed on the map."), - _T("%u %%"), _T("%u"), 50, 200, 10, settings.landable_rendering_scale); + "%u %%", "%u", 50, 200, 10, settings.landable_rendering_scale); SetExpertRow(AppLandableRenderingScale); AddBoolean(_("Scale runway length"), diff --git a/src/Dialogs/Settings/Panels/WeGlideConfigPanel.cpp b/src/Dialogs/Settings/Panels/WeGlideConfigPanel.cpp index 32ab738b37c..05c5bcb69eb 100644 --- a/src/Dialogs/Settings/Panels/WeGlideConfigPanel.cpp +++ b/src/Dialogs/Settings/Panels/WeGlideConfigPanel.cpp @@ -77,7 +77,7 @@ WeGlideConfigPanel::Prepare(ContainerWindow &parent, AddInteger(_("Pilot"), _("Take this from your WeGlide Profile. Or set to 0 if not used."), - _T("%d"), _T("%d"), 1, 99999, 1, weglide.pilot_id); + "%d", "%d", 1, 99999, 1, weglide.pilot_id); AddDate(_("Pilot date of birth"), nullptr, weglide.pilot_birthdate); diff --git a/src/Dialogs/Settings/Panels/WeatherConfigPanel.cpp b/src/Dialogs/Settings/Panels/WeatherConfigPanel.cpp index f3431914ff2..3bc22f63dac 100644 --- a/src/Dialogs/Settings/Panels/WeatherConfigPanel.cpp +++ b/src/Dialogs/Settings/Panels/WeatherConfigPanel.cpp @@ -48,22 +48,22 @@ WeatherConfigPanel::Prepare(ContainerWindow &parent, RowFormWidget::Prepare(parent, rc); #ifdef HAVE_PCMET - AddText(_T("pc_met Username"), _T(""), + AddText("pc_met Username", "", settings.pcmet.www_credentials.username); - AddPassword(_T("pc_met Password"), _T(""), + AddPassword("pc_met Password", "", settings.pcmet.www_credentials.password); #if 0 // code disabled because DWD has terminated our access */ - AddText(_T("pc_met FTP Username"), _T(""), + AddText("pc_met FTP Username", "", settings.pcmet.ftp_credentials.username); - AddPassword(_T("pc_met FTP Password"), _T(""), + AddPassword("pc_met FTP Password", "", settings.pcmet.ftp_credentials.password); #endif #endif #ifdef HAVE_HTTP - AddBoolean(_T("Thermal Information Map"), + AddBoolean("Thermal Information Map", _("Show thermal locations downloaded from Thermal Information Map (thermalmap.info)."), settings.enable_tim); #endif diff --git a/src/Dialogs/Settings/WindSettingsPanel.cpp b/src/Dialogs/Settings/WindSettingsPanel.cpp index 7c85349695c..a40de94f1aa 100644 --- a/src/Dialogs/Settings/WindSettingsPanel.cpp +++ b/src/Dialogs/Settings/WindSettingsPanel.cpp @@ -65,7 +65,7 @@ WindSettingsPanel::Prepare(ContainerWindow &parent, WndProperty *wp = AddFloat(_("Speed"), _("Manual adjustment of wind speed."), - _T("%.0f %s"), _T("%.0f"), + "%.0f %s", "%.0f", 0, Units::ToUserWindSpeed(Units::ToSysUnit(200, Unit::KILOMETER_PER_HOUR)), @@ -164,7 +164,7 @@ WindSettingsPanel::UpdateVector() noexcept const DerivedInfo &calculated = CommonInterface::Calculated(); const WindSettings &settings = CommonInterface::SetComputerSettings().wind; - const TCHAR *source = nullptr; + const char *source = nullptr; switch (manual_modified ? DerivedInfo::WindSource::MANUAL : calculated.wind_source) { diff --git a/src/Dialogs/Settings/dlgBasicSettings.cpp b/src/Dialogs/Settings/dlgBasicSettings.cpp index 05311877060..5e3a5f100c9 100644 --- a/src/Dialogs/Settings/dlgBasicSettings.cpp +++ b/src/Dialogs/Settings/dlgBasicSettings.cpp @@ -264,7 +264,7 @@ FlightSetupPanel::Prepare(ContainerWindow &parent, AddFloat(_("Crew"), _("All masses loaded to the glider beyond the empty weight including pilot and copilot, but not water ballast."), - _T("%.0f %s"), _T("%.0f"), + "%.0f %s", "%.0f", 0, 300, 5, false, UnitGroup::MASS, polar_settings.glide_polar_task.GetCrewMass(), this); @@ -272,12 +272,12 @@ FlightSetupPanel::Prepare(ContainerWindow &parent, const double db = 5; AddFloat(_("Ballast"), _("Ballast of the glider. Press \"Dump/Stop\" to toggle count-down of the ballast volume according to the dump rate specified in the configuration settings."), - _T("%.0f l"), _T("%.0f"), + "%.0f l", "%.0f", 0, db*ceil(plane.max_ballast/db), db, false, 0, this); WndProperty *wing_loading = AddFloat(_("Wing loading"), nullptr, - _T("%.1f %s"), _T("%.0f"), 0, + "%.1f %s", "%.0f", 0, 300, 5, false, UnitGroup::WING_LOADING, 0); @@ -286,7 +286,7 @@ FlightSetupPanel::Prepare(ContainerWindow &parent, AddFloat(_("Bugs"), /* xgettext:no-c-format */ _("How clean the glider is. Set to 0% for clean, larger numbers as the wings " "pick up bugs or gets wet. 50% indicates the glider's sink rate is doubled."), - _T("%.0f %%"), _T("%.0f"), + "%.0f %%", "%.0f", 0, 50, 1, false, (1 - polar_settings.bugs) * 100, this); @@ -305,12 +305,12 @@ FlightSetupPanel::Prepare(ContainerWindow &parent, wp->RefreshDisplay(); } - AddReadOnly(_("Altitude"), NULL, _T("%.0f %s"), + AddReadOnly(_("Altitude"), NULL, "%.0f %s", UnitGroup::ALTITUDE, 0); wp = AddFloat(_("Max. temp."), _("Set to forecast ground temperature. Used by convection estimator (temperature trace page of Analysis dialog)"), - _T("%.0f %s"), _T("%.0f"), + "%.0f %s", "%.0f", Temperature::FromCelsius(-50).ToUser(), Temperature::FromCelsius(60).ToUser(), 1, false, @@ -343,7 +343,7 @@ dlgBasicSettingsShowModal() const Plane &plane = CommonInterface::GetComputerSettings().plane; StaticString<128> caption(_("Flight Setup")); - caption.append(_T(" - ")); + caption.append(" - "); caption.append(plane.polar_name); WidgetDialog dialog(WidgetDialog::Auto{}, UIGlobals::GetMainWindow(), diff --git a/src/Dialogs/Settings/dlgConfigInfoboxes.cpp b/src/Dialogs/Settings/dlgConfigInfoboxes.cpp index d9dd337ebb5..1b60028c630 100644 --- a/src/Dialogs/Settings/dlgConfigInfoboxes.cpp +++ b/src/Dialogs/Settings/dlgConfigInfoboxes.cpp @@ -214,13 +214,13 @@ InfoBoxesConfigWidget::Prepare(ContainerWindow &parent, const Layout layout(rc, geometry); AddText(_("Name"), nullptr, - allow_name_change ? (const TCHAR *)data.name : gettext(data.name)); + allow_name_change ? (const char *)data.name : gettext(data.name)); SetReadOnly(NAME, !allow_name_change); DataFieldEnum *dfe = new DataFieldEnum(this); for (unsigned i = 0; i < layout.info_boxes.count; ++i) { - TCHAR label[32]; - _stprintf(label, _T("%u"), i + 1); + char label[32]; + _stprintf(label, "%u", i + 1); dfe->addEnumText(label, i); } @@ -228,12 +228,22 @@ InfoBoxesConfigWidget::Prepare(ContainerWindow &parent, dfe = new DataFieldEnum(this); for (unsigned i = InfoBoxFactory::MIN_TYPE_VAL; i < InfoBoxFactory::NUM_TYPES; i++) { - const TCHAR *name = InfoBoxFactory::GetName((InfoBoxFactory::Type) i); - const TCHAR *desc = InfoBoxFactory::GetDescription((InfoBoxFactory::Type) i); + const char *name = InfoBoxFactory::GetName((InfoBoxFactory::Type) i); + const char *desc = InfoBoxFactory::GetDescription((InfoBoxFactory::Type) i); if (name != NULL) dfe->addEnumText(gettext(name), i, desc != NULL ? gettext(desc) : NULL); } + for (unsigned i = InfoBoxFactory::e_NUM_AREA_2nd; + i < InfoBoxFactory::NUM_TYPES_2nd; i++) { + const InfoBoxFactory::Type type = (InfoBoxFactory::Type) (i); + const char *name = InfoBoxFactory::GetName(type); + const char *desc = InfoBoxFactory::GetDescription(type); + if (name != NULL) + dfe->addEnumText(gettext(name), type, + desc != NULL ? gettext(desc) : NULL); + } + dfe->EnableItemHelp(true); dfe->Sort(0); @@ -290,7 +300,7 @@ InfoBoxesConfigWidget::RefreshEditContentDescription() { DataFieldEnum &df = (DataFieldEnum &)GetDataField(CONTENT); WndFrame &description = (WndFrame &)GetRow(DESCRIPTION); - description.SetText(df.GetHelp() != nullptr ? df.GetHelp() : _T("")); + description.SetText(df.GetHelp() != nullptr ? df.GetHelp() : ""); } void @@ -379,7 +389,7 @@ InfoBoxPreview::OnPaint(Canvas &canvas) noexcept canvas.DrawRectangle(PixelRect{PixelSize{canvas.GetWidth() - 1, canvas.GetHeight() - 1}}); InfoBoxFactory::Type type = parent->GetContents(i); - const TCHAR *caption = type < InfoBoxFactory::NUM_TYPES + const char *caption = type < InfoBoxFactory::NUM_TYPES ? InfoBoxFactory::GetCaption(type) : NULL; if (caption == NULL) diff --git a/src/Dialogs/Settings/dlgConfiguration.cpp b/src/Dialogs/Settings/dlgConfiguration.cpp index 19497b17365..ed0e3a77569 100644 --- a/src/Dialogs/Settings/dlgConfiguration.cpp +++ b/src/Dialogs/Settings/dlgConfiguration.cpp @@ -43,6 +43,11 @@ #include "Audio/Features.hpp" #include "UtilsSettings.hpp" #include "net/http/Features.hpp" +#include "ui/window/SingleWindow.hpp" +#include "UIActions.hpp" +#include "LogFile.hpp" + +#include "Hardware/RotateDisplay.hpp" #ifdef HAVE_PCM_PLAYER #include "Panels/AudioVarioConfigPanel.hpp" @@ -64,15 +69,31 @@ #include "Panels/WeGlideConfigPanel.hpp" +#if defined(IS_OPENVARIO) +#include "OpenVario/FileMenuWidget.hpp" +#include "OpenVario/SystemSettingsWidget.hpp" +#include "OpenVario/System/SystemMenuWidget.hpp" +#include "OpenVario/DisplaySettingsWidget.hpp" +#include "OpenVario/ExtraWidget.hpp" +#include "OpenVario/System/OpenVarioDevice.hpp" +#endif + #include +#if defined(__AUGUST__) // hide this code +// # define SPLIT_XCSOAR_MENU +#endif + static unsigned current_page; // TODO: eliminate global variables static ArrowPagerWidget *pager; -static constexpr TabMenuPage files_pages[] = { +static constexpr TabMenuPage basic_pages[] = { { N_("Site Files"), CreateSiteConfigPanel }, +#if defined(IS_OPENVARIO) && 0 // defined (__AUGUST__) + { N_("TestOpenVario"), CreateSystemMenuWidget}, +#endif { nullptr, nullptr } }; @@ -127,46 +148,83 @@ static constexpr TabMenuPage setup_pages[] = { #ifdef HAVE_TRACKING { N_("Tracking"), CreateTrackingConfigPanel }, #endif - { _T("XCSoar Cloud"), CreateCloudConfigPanel }, + { "XCSoar Cloud", CreateCloudConfigPanel }, #if defined(HAVE_PCMET) || defined(HAVE_HTTP) { N_("Weather"), CreateWeatherConfigPanel }, #endif - { _T("WeGlide"), CreateWeGlideConfigPanel }, + { "WeGlide", CreateWeGlideConfigPanel }, #ifdef HAVE_VOLUME_CONTROLLER { N_("Audio"), CreateAudioConfigPanel }, #endif { nullptr, nullptr } }; + +#ifdef IS_OPENVARIO +static constexpr TabMenuPage openvario_pages[] = { + {N_("System Settings"), CreateSystemSettingsWidget}, + {N_("Display Settings"), CreateDisplaySettingsWidget}, + {N_("File Transfer"), CreateFileMenuWidget}, +#if _DEBUG + // remove with better FW-Upgrade + {N_("Advanced Menu (temp)"), CreateExtraWidget}, +#endif + { nullptr, nullptr } +}; +#endif + static constexpr TabMenuGroup main_menu_captions[] = { - { N_("Site Files"), files_pages }, + { N_("Basic Settings"), basic_pages}, { N_("Map Display"), map_pages }, { N_("Glide Computer"), computer_pages }, { N_("Gauges"), gauge_pages }, { N_("Task Defaults"), task_pages }, { N_("Look"), look_pages }, { N_("Setup"), setup_pages }, +#ifdef IS_OPENVARIO + { N_("OpenVario"), openvario_pages}, +#endif }; static void OnUserLevel(bool expert) noexcept; +#ifdef SPLIT_XCSOAR_MENU +static void OnXCSoarStyle(bool expert) noexcept; +#endif + class ConfigurationExtraButtons final : public NullWidget { struct Layout { +#ifdef SPLIT_XCSOAR_MENU + PixelRect expert, xcsoar_style, button2, button1; + + Layout(const PixelRect &rc) + : expert(rc), xcsoar_style(rc), button2(rc), button1(rc) { +#else PixelRect expert, button2, button1; - Layout(const PixelRect &rc):expert(rc), button2(rc), button1(rc) { + Layout(const PixelRect &rc) + : expert(rc), button2(rc), button1(rc) { +#endif const unsigned height = rc.GetHeight(); const unsigned max_control_height = ::Layout::GetMaximumControlHeight(); if (height >= 3 * max_control_height) { expert.bottom = expert.top + max_control_height; +#ifdef SPLIT_XCSOAR_MENU + xcsoar_style.top = expert.bottom; + xcsoar_style.bottom = xcsoar_style.top + max_control_height; +#endif + button1.top = button2.bottom = rc.bottom - max_control_height; button2.top = button2.bottom - max_control_height; } else { expert.right = button2.left = unsigned(rc.left * 2 + rc.right) / 3; +#ifdef SPLIT_XCSOAR_MENU + xcsoar_style.right = expert.right; +#endif button2.right = button1.left = unsigned(rc.left + rc.right * 2) / 3; } } @@ -175,6 +233,9 @@ class ConfigurationExtraButtons final const DialogLook &look; CheckBoxControl expert; +#ifdef SPLIT_XCSOAR_MENU + CheckBoxControl xcsoar_style; +#endif Button button2, button1; bool borrowed2, borrowed1; @@ -219,9 +280,13 @@ class ConfigurationExtraButtons final expert.Create(parent, look, _("Expert"), layout.expert, style, [](bool value){ OnUserLevel(value); }); - - button2.Create(parent, look.button, _T(""), layout.button2, style); - button1.Create(parent, look.button, _T(""), layout.button1, style); +#ifdef SPLIT_XCSOAR_MENU + xcsoar_style.Create(parent, look, _("XCSoar"), + layout.xcsoar_style, style, + [](bool value){ OnXCSoarStyle(value); }); +#endif + button2.Create(parent, look.button, "", layout.button2, style); + button1.Create(parent, look.button, "", layout.button1, style); } void Show(const PixelRect &rc) noexcept override { @@ -229,6 +294,10 @@ class ConfigurationExtraButtons final expert.SetState(CommonInterface::GetUISettings().dialog.expert); expert.MoveAndShow(layout.expert); +#ifdef SPLIT_XCSOAR_MENU + xcsoar_style.SetState(CommonInterface::GetUISettings().dialog.xcsoar_style); + xcsoar_style.MoveAndShow(layout.xcsoar_style); +#endif if (borrowed2) button2.MoveAndShow(layout.button2); @@ -243,20 +312,40 @@ class ConfigurationExtraButtons final void Hide() noexcept override { expert.FastHide(); +#ifdef SPLIT_XCSOAR_MENU + xcsoar_style.FastHide(); +#endif button2.FastHide(); button1.FastHide(); + #ifdef IS_OPENVARIO + // this is a workaround: the 1st SignalShutdown closed the Setup window + // the 2nd one here close the executable + // a directly exit isn't possible + switch (ContainerWindow::GetExitValue()) { + case LAUNCH_SHELL: // 100, + case START_UPGRADE: // 111 + case LAUNCH_TOUCH_CALIBRATE: // 112, + UIActions::SignalShutdown(true); + break; + default: + break; + } + #endif } void Move(const PixelRect &rc) noexcept override { Layout layout(rc); expert.Move(layout.expert); +#ifdef SPLIT_XCSOAR_MENU + xcsoar_style.Move(layout.xcsoar_style); +#endif button2.Move(layout.button2); button1.Move(layout.button1); } }; void -ConfigPanel::BorrowExtraButton(unsigned i, const TCHAR *caption, +ConfigPanel::BorrowExtraButton(unsigned i, const char *caption, std::function callback) noexcept { ConfigurationExtraButtons &extra = @@ -286,16 +375,51 @@ OnUserLevel(bool expert) noexcept pager->PagerWidget::Move(pager->GetPosition()); } -/** - * close dialog from menu page. from content, goes to menu page +#if defined(SPLIT_XCSOAR_MENU) +static void +OnXCSoarStyle(bool xcsoar_style) noexcept +{ + CommonInterface::SetUISettings().dialog.xcsoar_style = xcsoar_style; + Profile::Set(ProfileKeys::ExtendMenu, xcsoar_style); + + /* force layout update */ + pager->PagerWidget::Move(pager->GetPosition()); +} + + /** + * save the settings in the dialog from menu page. */ static void -OnCloseClicked(WidgetDialog &dialog) +OnSaveClicked(WidgetDialog &dialog) { - if (pager->GetCurrentIndex() == 0) + bool changed = false; + + // PagerWidget +// PagerWidget current = (PagerWidget)dialog.GetWidget(); + if (pager->SaveCurrent(changed)) + // if ((PagerWidget) dialog.GetWidget()).SaveCurrent(changed)) + ; +} +#endif + +/** + * close dialog from menu page. from content, goes to menu page + */ +static void OnCloseClicked(WidgetDialog &dialog) { + if (pager->GetCurrentIndex() == 0) { dialog.SetModalResult(mrOK); - else - pager->ClickPage(0); + } else { + CreateWindowWidget *w = &(CreateWindowWidget &)pager->GetCurrentWidget(); + bool changed = false; + if (w->Save(changed)) { + // if (w.prepared && !w.widget->Save(changed)) + // return ; + + // return true; + } + + pager->ClickPage(0); + } } static void @@ -303,8 +427,8 @@ OnPageFlipped(WidgetDialog &dialog, TabMenuDisplay &menu) { menu.OnPageFlipped(); - TCHAR buffer[128]; - const TCHAR *caption = menu.GetCaption(buffer, ARRAY_SIZE(buffer)); + char buffer[128]; + const char *caption = menu.GetCaption(buffer, ARRAY_SIZE(buffer)); if (caption == nullptr) caption = _("Configuration"); dialog.SetCaption(caption); @@ -318,6 +442,9 @@ void dlgConfigurationShowModal() look, _("Configuration")); pager = new ArrowPagerWidget(look.button, +#ifdef SPLIT_XCSOAR_MENU + [&dialog](){ OnSaveClicked(dialog); }, +#endif [&dialog](){ OnCloseClicked(dialog); }, std::make_unique(look)); @@ -342,15 +469,24 @@ void dlgConfigurationShowModal() dialog.FinishPreliminary(pager); - dialog.ShowModal(); + auto modal_value = dialog.ShowModal(); /* save page number for next time this dialog is opened */ current_page = menu.GetCursor(); + if (modal_value != mrOK) { + // check of restoring ? + } if (dialog.GetChanged()) { Profile::Save(); if (require_restart) - ShowMessageBox(_("Changes to configuration saved. Restart XCSoar to apply changes."), - _T(""), MB_OK); + if (ShowMessageBox( + _("Changes to configuration saved. Restart OpenSoar " + "is needed to apply changes. Do you want restart immediately?"), + "", MB_YESNO | MB_ICONQUESTION) == IDYES) { + if (UI::TopWindow::GetExitValue() == 0) + UI::TopWindow::SetExitValue(EXIT_RESTART); + UIActions::SignalShutdown(true); + } } } diff --git a/src/Dialogs/StartupDialog.cpp b/src/Dialogs/StartupDialog.cpp index 2388fc558d2..d91168602ee 100644 --- a/src/Dialogs/StartupDialog.cpp +++ b/src/Dialogs/StartupDialog.cpp @@ -118,8 +118,8 @@ class StartupWidget final : public RowFormWidget { }; static bool -SelectProfileCallback([[maybe_unused]] const TCHAR *caption, [[maybe_unused]] DataField &_df, - [[maybe_unused]] const TCHAR *help_text) noexcept +SelectProfileCallback([[maybe_unused]] const char *caption, [[maybe_unused]] DataField &_df, + [[maybe_unused]] const char *help_text) noexcept { FileDataField &df = (FileDataField &)_df; @@ -182,7 +182,7 @@ dlgStartupShowModal() noexcept /* scan all profile files */ auto *dff = new FileDataField(); - dff->ScanDirectoryTop(_T("*.prf")); + dff->ScanDirectoryTop("*.prf"); if (dff->GetNumFiles() == 1) { /* skip this dialog if there is only one */ diff --git a/src/Dialogs/StatusPanels/FlightStatusPanel.cpp b/src/Dialogs/StatusPanels/FlightStatusPanel.cpp index 9eeb0ddad81..24e284ac2de 100644 --- a/src/Dialogs/StatusPanels/FlightStatusPanel.cpp +++ b/src/Dialogs/StatusPanels/FlightStatusPanel.cpp @@ -57,9 +57,9 @@ FlightStatusPanel::Refresh() noexcept SetText(Distance, FormatUserDistanceSmart(vec.distance)); } else { - SetText(Near, _T("-")); - SetText(Bearing, _T("-")); - SetText(Distance, _T("-")); + SetText(Near, "-"); + SetText(Bearing, "-"); + SetText(Distance, "-"); } } diff --git a/src/Dialogs/StatusPanels/RulesStatusPanel.cpp b/src/Dialogs/StatusPanels/RulesStatusPanel.cpp index e601cd9a78c..f651a9a6e96 100644 --- a/src/Dialogs/StatusPanels/RulesStatusPanel.cpp +++ b/src/Dialogs/StatusPanels/RulesStatusPanel.cpp @@ -28,7 +28,7 @@ enum Controls { void RulesStatusPanel::Refresh() noexcept { - TCHAR Temp[80]; + char Temp[80]; const DerivedInfo &calculated = CommonInterface::Calculated(); const TaskStats &task_stats = calculated.ordered_task_stats; @@ -37,10 +37,10 @@ RulesStatusPanel::Refresh() noexcept /// @todo proper task validity check SetText(ValidStart, start_stats.HasStarted() - ? _("Yes") : _T("No")); + ? _("Yes") : "No"); SetText(ValidFinish, task_stats.task_finished - ? _("Yes") : _T("No")); + ? _("Yes") : "No"); if (start_stats.HasStarted()) { SetText(StartTime, @@ -56,7 +56,7 @@ RulesStatusPanel::Refresh() noexcept ClearValue(StartHeight); } - Temp[0] = _T('\0'); + Temp[0] = '\0'; double finish_height(0); if (backend_components->protected_task_manager) { diff --git a/src/Dialogs/StatusPanels/SystemStatusPanel.cpp b/src/Dialogs/StatusPanels/SystemStatusPanel.cpp index 163f3395862..01d69d951f7 100644 --- a/src/Dialogs/StatusPanels/SystemStatusPanel.cpp +++ b/src/Dialogs/StatusPanels/SystemStatusPanel.cpp @@ -25,7 +25,7 @@ enum Controls { }; [[gnu::pure]] -static const TCHAR * +static const char * GetGPSStatus(const NMEAInfo &basic) noexcept { if (!basic.alive) @@ -38,7 +38,7 @@ GetGPSStatus(const NMEAInfo &basic) noexcept return N_("3D fix"); } -static const TCHAR *const net_state_strings[] = { +static const char *const net_state_strings[] = { N_("Unknown"), N_("Disconnected"), N_("Connected"), @@ -46,7 +46,7 @@ static const TCHAR *const net_state_strings[] = { }; [[gnu::pure]] -static const TCHAR * +static const char * ToString(NetState state) noexcept { return gettext(net_state_strings[unsigned(state)]); @@ -66,7 +66,7 @@ SystemStatusPanel::Refresh() noexcept ClearText(NumSat); else if (gps.satellites_used_available) { // known number of sats - Temp.Format(_T("%u"), gps.satellites_used); + Temp.Format("%u", gps.satellites_used); SetText(NumSat, Temp); } else // valid but unknown number of sats @@ -82,9 +82,9 @@ SystemStatusPanel::Refresh() noexcept if (basic.flarm.version.available && !basic.flarm.version.software_version.empty()) { /* append FLARM firmware version */ - Temp.append(_T(" (fw ")); + Temp.append(" (fw "); Temp.UnsafeAppendASCII(basic.flarm.version.software_version.c_str()); - Temp.push_back(_T(')')); + Temp.push_back(')'); } SetText(FLARM, Temp); @@ -98,13 +98,13 @@ SystemStatusPanel::Refresh() noexcept #ifdef HAVE_BATTERY const auto &battery = Power::global_info.battery; if (battery.remaining_percent) { - Temp.Format(_T("%u %% "), *battery.remaining_percent); + Temp.Format("%u %% ", *battery.remaining_percent); } #endif if (basic.voltage_available) - Temp.AppendFormat(_T("%.1f V"), (double)basic.voltage); + Temp.AppendFormat("%.1f V", (double)basic.voltage); else if (basic.battery_level_available) - Temp.AppendFormat(_T("%.0f%%"), (double)basic.battery_level); + Temp.AppendFormat("%.0f%%", (double)basic.battery_level); SetText(Battery, Temp); @@ -118,7 +118,7 @@ SystemStatusPanel::Prepare([[maybe_unused]] ContainerWindow &parent, AddReadOnly(_("GPS lock")); AddReadOnly(_("Satellites in view")); AddReadOnly(_("Variometer")); - AddReadOnly(_T("FLARM")); + AddReadOnly("FLARM"); AddReadOnly(_("Logger")); AddReadOnly(_("Supply voltage")); AddReadOnly(_("Network")); diff --git a/src/Dialogs/StatusPanels/TaskStatusPanel.cpp b/src/Dialogs/StatusPanels/TaskStatusPanel.cpp index b159bfd208c..c43918f5501 100644 --- a/src/Dialogs/StatusPanels/TaskStatusPanel.cpp +++ b/src/Dialogs/StatusPanels/TaskStatusPanel.cpp @@ -130,7 +130,7 @@ TaskStatusPanel::Prepare([[maybe_unused]] ContainerWindow &parent, [[maybe_unuse _("Adjusts MC value used in the calculator. " "Use this to determine the effect on estimated task time due to changes in conditions. " "This value will not affect the main computer's setting if the dialog is exited with the Cancel button."), - _T("%.1f %s"), _T("%.1f"), + "%.1f %s", "%.1f", 0, Units::ToUserVSpeed(5), GetUserVerticalSpeedStep(), false, 0, this); @@ -140,21 +140,21 @@ TaskStatusPanel::Prepare([[maybe_unused]] ContainerWindow &parent, [[maybe_unuse AddReadOnly(_("AAT range"), /* xgettext:no-c-format */ _("For AAT tasks, this value tells you how far based on the targets of your task you will fly relative to the minimum and maximum possible tasks. -100% indicates the minimum AAT distance. 0% is the nominal AAT distance. +100% is maximum AAT distance."), - _T("%.0f %%"), 0); + "%.0f %%", 0); - AddReadOnly(_("Speed remaining"), nullptr, _T("%.0f %s"), + AddReadOnly(_("Speed remaining"), nullptr, "%.0f %s", UnitGroup::TASK_SPEED, 0); - AddReadOnly(_("Achieved MacCready"), nullptr, _T("%.1f %s"), + AddReadOnly(_("Achieved MacCready"), nullptr, "%.1f %s", UnitGroup::VERTICAL_SPEED, 0); DataFieldFloat &emc_df = (DataFieldFloat &)GetDataField(EFFECTIVE_MC); emc_df.SetFormat(GetUserVerticalSpeedFormat(false, false)); - AddReadOnly(_("Achieved speed"), nullptr, _T("%.0f %s"), + AddReadOnly(_("Achieved speed"), nullptr, "%.0f %s", UnitGroup::TASK_SPEED, 0); AddReadOnly(_("Cruise efficiency"), _("Efficiency of cruise. 100 indicates perfect MacCready performance, greater than 100 indicates better than MacCready performance is achieved through flying in streets. Less than 100 is appropriate if you fly considerably off-track. This value estimates your cruise efficiency according to the current flight history with the set MC value. Calculation begins after task is started."), - _T("%.0f %%"), + "%.0f %%", 0); } diff --git a/src/Dialogs/StatusPanels/TimesStatusPanel.cpp b/src/Dialogs/StatusPanels/TimesStatusPanel.cpp index deca43d0915..14925d202b5 100644 --- a/src/Dialogs/StatusPanels/TimesStatusPanel.cpp +++ b/src/Dialogs/StatusPanels/TimesStatusPanel.cpp @@ -37,7 +37,7 @@ TimesStatusPanel::Refresh() noexcept const unsigned sunsethours = (int)sun.time_of_sunset; const unsigned sunsetmins = (int)((sun.time_of_sunset - double(sunsethours)) * 60); - temp.Format(_T("%02u:%02u - %02u:%02u"), sunrisehours, sunrisemins, sunsethours, sunsetmins); + temp.Format("%02u:%02u - %02u:%02u", sunrisehours, sunrisemins, sunsethours, sunsetmins); SetText(Daylight, temp); } else { ClearText(Daylight); @@ -53,7 +53,7 @@ TimesStatusPanel::Refresh() noexcept } if (basic.date_time_utc.IsDatePlausible()) { - temp.Format(_T("%04d-%02d-%02d"), basic.date_time_utc.year, + temp.Format("%04d-%02d-%02d", basic.date_time_utc.year, basic.date_time_utc.month, basic.date_time_utc.day); SetText(UTCDate, temp); } else { diff --git a/src/Dialogs/Task/Manager/TaskEditPanel.cpp b/src/Dialogs/Task/Manager/TaskEditPanel.cpp index 1d051c75187..dc6f6f32153 100644 --- a/src/Dialogs/Task/Manager/TaskEditPanel.cpp +++ b/src/Dialogs/Task/Manager/TaskEditPanel.cpp @@ -112,9 +112,9 @@ TaskEditPanel::CreateButtons(ButtonPanel &buttons) noexcept [this](){ OnEditTurnpointClicked(); }); mutate_button = buttons.Add(_("Make Finish"), [this](){ OnMakeFinish(); }); - down_button = buttons.Add(std::make_unique(buttons.GetLook(), _T("v")), + down_button = buttons.Add(std::make_unique(buttons.GetLook(), "v"), [this](){ MoveDown(); }); - up_button = buttons.Add(std::make_unique(buttons.GetLook(), _T("^")), + up_button = buttons.Add(std::make_unique(buttons.GetLook(), "^"), [this](){ MoveUp(); }); reverse_button = buttons.Add(_("Reverse"), [this](){ ReverseTask(); }); @@ -151,7 +151,7 @@ TaskEditPanel::RefreshView() UpdateButtons(); { - TCHAR text[300]; + char text[300]; OrderedTaskSummary(ordered_task, text, false); summary.SetText(text); } @@ -221,7 +221,7 @@ TaskEditPanel::OnPaintItem(Canvas &canvas, const PixelRect rc, const unsigned padding = Layout::GetTextPadding(); const unsigned line_height = rc.GetHeight(); - TCHAR buffer[120]; + char buffer[120]; // Draw "Add turnpoint" label if (DrawListIndex == ordered_task->TaskSize()) { diff --git a/src/Dialogs/Task/Manager/TaskListPanel.cpp b/src/Dialogs/Task/Manager/TaskListPanel.cpp index 23c5ba7dc11..511a5616074 100644 --- a/src/Dialogs/Task/Manager/TaskListPanel.cpp +++ b/src/Dialogs/Task/Manager/TaskListPanel.cpp @@ -98,7 +98,7 @@ class TaskListPanel final const OrderedTask *get_cursor_task(); [[gnu::pure]] - const TCHAR *get_cursor_name(); + const char *get_cursor_name(); private: /* virtual methods from class ListControl::Handler */ @@ -141,12 +141,12 @@ TaskListPanel::get_cursor_task() return ordered_task; } -const TCHAR * +const char * TaskListPanel::get_cursor_name() { const unsigned cursor_index = GetList().GetCursorIndex(); if (cursor_index >= task_store.Size()) - return _T(""); + return ""; return task_store.GetName(cursor_index); } @@ -171,9 +171,9 @@ TaskListPanel::RefreshView() dialog.ShowTaskView(ordered_task); if (ordered_task == nullptr) { - summary.SetText(_T("")); + summary.SetText(""); } else { - TCHAR text[300]; + char text[300]; OrderedTaskSummary(ordered_task, text, false); summary.SetText(text); } @@ -190,11 +190,11 @@ TaskListPanel::LoadTask() return; StaticString<1024> text; - text.Format(_T("%s\n(%s)"), _("Load the selected task?"), + text.Format("%s\n(%s)", _("Load the selected task?"), get_cursor_name()); if (const auto errors = orig->CheckTask(); !errors.IsEmpty()) { - text.append(_T("\n")); + text.append("\n"); text.append(getTaskValidationErrors(errors)); } @@ -222,16 +222,16 @@ TaskListPanel::DeleteTask() return; const auto path = task_store.GetPath(cursor_index); - if (StringEndsWithIgnoreCase(path.c_str(), _T(".cup"))) { + if (StringEndsWithIgnoreCase(path.c_str(), ".cup")) { ShowMessageBox(_("Can't delete .CUP files"), _("Error"), MB_OK | MB_ICONEXCLAMATION); return; } - const TCHAR *fname = task_store.GetName(cursor_index); + const char *fname = task_store.GetName(cursor_index); StaticString<1024> text; - text.Format(_T("%s\n(%s)"), _("Delete the selected task?"), fname); + text.Format("%s\n(%s)", _("Delete the selected task?"), fname); if (ShowMessageBox(text.c_str(), _("Task Browser"), MB_YESNO | MB_ICONQUESTION) != IDYES) return; @@ -243,18 +243,18 @@ TaskListPanel::DeleteTask() } static bool -ClearSuffix(TCHAR *p, const TCHAR *suffix) +ClearSuffix(char *p, const char *suffix) { - size_t length = _tcslen(p); - size_t suffix_length = _tcslen(suffix); + size_t length = strlen(p); + size_t suffix_length = strlen(suffix); if (length <= suffix_length) return false; - TCHAR *q = p + length - suffix_length; + char *q = p + length - suffix_length; if (!StringIsEqualIgnoreCase(q, suffix)) return false; - *q = _T('\0'); + *q = '\0'; return true; } @@ -265,23 +265,23 @@ TaskListPanel::RenameTask() if (cursor_index >= task_store.Size()) return; - const TCHAR *oldname = task_store.GetName(cursor_index); + const char *oldname = task_store.GetName(cursor_index); StaticString<40> newname(oldname); - if (ClearSuffix(newname.buffer(), _T(".cup"))) { + if (ClearSuffix(newname.buffer(), ".cup")) { ShowMessageBox(_("Can't rename .CUP files"), _("Rename Error"), MB_ICONEXCLAMATION); return; } - ClearSuffix(newname.buffer(), _T(".tsk")); + ClearSuffix(newname.buffer(), ".tsk"); if (!TextEntryDialog(newname)) return; - newname.append(_T(".tsk")); + newname.append(".tsk"); - const auto tasks_path = MakeLocalPath(_T("tasks")); + const auto tasks_path = MakeLocalPath("tasks"); File::Rename(task_store.GetPath(cursor_index), AllocatedPath::Build(tasks_path, newname)); diff --git a/src/Dialogs/Task/Manager/TaskManagerDialog.cpp b/src/Dialogs/Task/Manager/TaskManagerDialog.cpp index 0c58997be2f..19c76620d68 100644 --- a/src/Dialogs/Task/Manager/TaskManagerDialog.cpp +++ b/src/Dialogs/Task/Manager/TaskManagerDialog.cpp @@ -131,10 +131,10 @@ TaskManagerDialog::UpdateCaption() { StaticString<128> title; if (task->GetName().empty()) - title.Format(_T("%s: %s"), _("Task Manager"), + title.Format("%s: %s", _("Task Manager"), GetButtonCaption(GetCurrentIndex())); else - title.Format(_T("%s: %s - %s"), _("Task Manager"), + title.Format("%s: %s - %s", _("Task Manager"), task->GetName().c_str(), GetButtonCaption(GetCurrentIndex())); dialog.SetCaption(title); diff --git a/src/Dialogs/Task/Manager/TaskPropertiesPanel.cpp b/src/Dialogs/Task/Manager/TaskPropertiesPanel.cpp index cd4180459e2..4bb8035c236 100644 --- a/src/Dialogs/Task/Manager/TaskPropertiesPanel.cpp +++ b/src/Dialogs/Task/Manager/TaskPropertiesPanel.cpp @@ -228,12 +228,12 @@ TaskPropertiesPanel::Prepare([[maybe_unused]] ContainerWindow &parent, AddFloat(_("Start max. speed"), _("Maximum speed allowed in start observation zone. Set to 0 for no limit."), - _T("%.0f %s"), _T("%.0f"), + "%.0f %s", "%.0f", 0, 300, 5, false, 0); AddFloat(_("Start max. height"), _("Maximum height based on start height reference (AGL or MSL) while starting the task. Set to 0 for no limit."), - _T("%.0f %s"), _T("%.0f"), + "%.0f %s", "%.0f", 0, 10000, 25, false, 0); static constexpr StaticEnumChoice altitude_reference_list[] = { @@ -250,7 +250,7 @@ TaskPropertiesPanel::Prepare([[maybe_unused]] ContainerWindow &parent, AddFloat(_("Finish min. height"), _("Minimum height based on finish height reference (AGL or MSL) while finishing the task. Set to 0 for no limit."), - _T("%.0f %s"), _T("%.0f"), + "%.0f %s", "%.0f", 0, 10000, 25, false, 0); AddEnum(_("Finish height ref."), diff --git a/src/Dialogs/Task/Manager/WeGlideTasksPanel.cpp b/src/Dialogs/Task/Manager/WeGlideTasksPanel.cpp index 4dd576a00a2..7664627765d 100644 --- a/src/Dialogs/Task/Manager/WeGlideTasksPanel.cpp +++ b/src/Dialogs/Task/Manager/WeGlideTasksPanel.cpp @@ -25,7 +25,6 @@ #include "net/http/Init.hpp" #include "lib/curl/Global.hxx" #include "util/Compiler.h" -#include "util/ConvertString.hpp" #include "UIGlobals.hpp" #include "Components.hpp" #include "DataComponents.hpp" @@ -123,12 +122,12 @@ WeGlideTasksPanel::OnPaintItem(Canvas &canvas, const PixelRect rc, assert(idx <= list.size()); const auto &info = list[idx]; - if (UTF8ToWideConverter w{info.name.c_str()}; w.IsValid()) - row_renderer.DrawFirstRow(canvas, rc, w); + if (info.name.c_str()) + row_renderer.DrawFirstRow(canvas, rc, info.name.c_str()); if (selection != WeGlideTaskSelection::USER) - if (UTF8ToWideConverter w{info.user_name.c_str()}; w.IsValid()) - row_renderer.DrawSecondRow(canvas, rc, w); + if (info.user_name.c_str()) + row_renderer.DrawSecondRow(canvas, rc, info.user_name.c_str()); row_renderer.DrawRightSecondRow(canvas, rc, FormatUserDistanceSmart(info.distance)); @@ -167,7 +166,7 @@ WeGlideTasksPanel::ReloadList() noexcept UpdateButtons(); }, [](std::exception_ptr error){ - ShowError(error, _T("Error")); + ShowError(error, "Error"); }); } diff --git a/src/Dialogs/Task/MutateTaskPointDialog.cpp b/src/Dialogs/Task/MutateTaskPointDialog.cpp index b4d2fb8e849..5bebcb0abbc 100644 --- a/src/Dialogs/Task/MutateTaskPointDialog.cpp +++ b/src/Dialogs/Task/MutateTaskPointDialog.cpp @@ -18,7 +18,7 @@ static TrivialArray point_types; -static const TCHAR * +static const char * TPTypeItemHelp(unsigned i) { return OrderedTaskPointDescription(point_types[i]); @@ -48,7 +48,7 @@ MutateTaskPointRenderer::OnPaintItem(Canvas &canvas, PixelRect rc, assert(DrawListIndex < point_types.size()); if (point_types[DrawListIndex] == current_type) - rc.left = row_renderer.DrawColumn(canvas, rc, _T("*")); + rc.left = row_renderer.DrawColumn(canvas, rc, "*"); row_renderer.DrawTextRow(canvas, rc, OrderedTaskPointName(point_types[DrawListIndex])); diff --git a/src/Dialogs/Task/OptionalStartsDialog.cpp b/src/Dialogs/Task/OptionalStartsDialog.cpp index 29b43ba2861..4ec018e3a30 100644 --- a/src/Dialogs/Task/OptionalStartsDialog.cpp +++ b/src/Dialogs/Task/OptionalStartsDialog.cpp @@ -119,7 +119,7 @@ OptionStartsWidget::OnPaintItem(Canvas &canvas, PixelRect rc, const OrderedTaskPoint *tp; if (DrawListIndex == 0) { tp = &task.GetPoint(0); - rc.left = row_renderer.DrawColumn(canvas, rc, _T("*")); + rc.left = row_renderer.DrawColumn(canvas, rc, "*"); } else tp = &task.GetOptionalStartPoint(index_optional_starts); diff --git a/src/Dialogs/Task/TargetDialog.cpp b/src/Dialogs/Task/TargetDialog.cpp index 6233a2111aa..0acc2ff8a4b 100644 --- a/src/Dialogs/Task/TargetDialog.cpp +++ b/src/Dialogs/Task/TargetDialog.cpp @@ -343,14 +343,14 @@ TargetWidget::Prepare(ContainerWindow &parent, const PixelRect &rc) noexcept const auto &button_look = UIGlobals::GetDialogLook().button; - name_button.Create(parent, button_look, _T(""), layout.name_button, + name_button.Create(parent, button_look, "", layout.name_button, control_style, [this](){ OnNameClicked(); }); previous_button.Create(parent, layout.previous_button, control_style, - std::make_unique(button_look, _T("<")), + std::make_unique(button_look, "<"), [this](){ OnPrevClicked(); }); next_button.Create(parent, layout.next_button, control_style, - std::make_unique(button_look, _T(">")), + std::make_unique(button_look, ">"), [this](){ OnNextClicked(); }); const unsigned caption_width = ::Layout::Scale(50); @@ -358,14 +358,14 @@ TargetWidget::Prepare(ContainerWindow &parent, const PixelRect &rc) noexcept range.Create(parent, layout.range, _("Distance"), caption_width, control_style); range.SetHelpText(_("For AAT tasks, this setting can be used to adjust the target points within the AAT sectors. Larger values move the target points to produce larger task distances, smaller values move the target points to produce smaller task distances.")); - range.SetDataField(new DataFieldFloat(_T("%.0f"), _T("%.0f %%"), + range.SetDataField(new DataFieldFloat("%.0f", "%.0f %%", -100, 100, 0, 5, false, this)); radial.Create(parent, layout.radial, _("Radial"), caption_width, control_style); radial.SetHelpText(_("For AAT tasks, this setting can be used to adjust the target points within the AAT sectors. Positive values rotate the range line clockwise, negative values rotate the range line counterclockwise.")); - radial.SetDataField(new DataFieldFloat(_T("%.0f"), _T("%.0f" DEG), + radial.SetDataField(new DataFieldFloat("%.0f", "%.0f" DEG, -90, 90, 0, 5, false, this)); @@ -490,7 +490,7 @@ TargetWidget::UpdateNameButton() const OrderedTask &task = lease->GetOrderedTask(); if (target_point < task.TaskSize()) { const OrderedTaskPoint &tp = task.GetTaskPoint(target_point); - buffer.Format(_T("%u: %s"), target_point, + buffer.Format("%u: %s", target_point, tp.GetWaypoint().name.c_str()); } else buffer.clear(); diff --git a/src/Dialogs/Task/TaskPointDialog.cpp b/src/Dialogs/Task/TaskPointDialog.cpp index c637c9db29a..2db19596d23 100644 --- a/src/Dialogs/Task/TaskPointDialog.cpp +++ b/src/Dialogs/Task/TaskPointDialog.cpp @@ -92,11 +92,11 @@ class TaskPointWidget final } void CreateButtons() { - previous_button = dialog.AddSymbolButton(_T("<"), [this](){ + previous_button = dialog.AddSymbolButton("<", [this](){ OnPreviousClicked(); }); - next_button = dialog.AddSymbolButton(_T(">"), [this](){ + next_button = dialog.AddSymbolButton(">", [this](){ OnNextClicked(); }); } @@ -315,7 +315,7 @@ TaskPointWidget::RefreshView() optional_starts.SetCaption(_("Enable Alternate Starts")); else { StaticString<50> tmp; - tmp.Format(_T("%s (%d)"), _("Edit Alternates"), + tmp.Format("%s (%d)", _("Edit Alternates"), ordered_task.GetOptionalStartPointCount()); optional_starts.SetCaption(tmp); } @@ -332,22 +332,22 @@ TaskPointWidget::RefreshView() switch (tp.GetType()) { case TaskPointType::START: type_buffer = _("Start point"); - name_prefix_buffer = _T("Start: "); + name_prefix_buffer = "Start: "; break; case TaskPointType::AST: type_buffer = _("Task point"); - name_prefix_buffer.Format(_T("%d: "), active_index); + name_prefix_buffer.Format("%d: ", active_index); break; case TaskPointType::AAT: type_buffer = _("Assigned area point"); - name_prefix_buffer.Format(_T("%d: "), active_index); + name_prefix_buffer.Format("%d: ", active_index); break; case TaskPointType::FINISH: type_buffer = _("Finish point"); - name_prefix_buffer = _T("Finish: "); + name_prefix_buffer = "Finish: "; break; default: @@ -358,7 +358,7 @@ TaskPointWidget::RefreshView() { StaticString<100> buffer; - buffer.Format(_T("%s %s"), name_prefix_buffer.c_str(), + buffer.Format("%s %s", name_prefix_buffer.c_str(), tp.GetWaypoint().name.c_str()); waypoint_name.SetText(buffer); } diff --git a/src/Dialogs/Task/Widgets/CylinderZoneEditWidget.cpp b/src/Dialogs/Task/Widgets/CylinderZoneEditWidget.cpp index cdc2b56557a..52f76777594 100644 --- a/src/Dialogs/Task/Widgets/CylinderZoneEditWidget.cpp +++ b/src/Dialogs/Task/Widgets/CylinderZoneEditWidget.cpp @@ -21,7 +21,7 @@ CylinderZoneEditWidget::Prepare(ContainerWindow &parent, ObservationZoneEditWidget::Prepare(parent, rc); AddFloat(_("Radius"), _("Radius of the OZ cylinder."), - _T("%.1f %s"), _T("%.1f"), + "%.1f %s", "%.1f", 0.1, 200, 1, true, UnitGroup::DISTANCE, GetObject().GetRadius(), this); diff --git a/src/Dialogs/Task/Widgets/KeyholeZoneEditWidget.cpp b/src/Dialogs/Task/Widgets/KeyholeZoneEditWidget.cpp index 1f20ece946e..f163506d483 100644 --- a/src/Dialogs/Task/Widgets/KeyholeZoneEditWidget.cpp +++ b/src/Dialogs/Task/Widgets/KeyholeZoneEditWidget.cpp @@ -21,13 +21,13 @@ KeyholeZoneEditWidget::Prepare(ContainerWindow &parent, ObservationZoneEditWidget::Prepare(parent, rc); AddFloat(_("Radius"), _("Radius of the OZ sector."), - _T("%.1f %s"), _T("%.1f"), + "%.1f %s", "%.1f", 0.1, 200, 1, true, UnitGroup::DISTANCE, GetObject().GetRadius(), this); AddFloat(_("Inner radius"), _("Inner radius of the OZ sector."), - _T("%.1f %s"), _T("%.1f"), + "%.1f %s", "%.1f", 0.1, 100, 1, true, UnitGroup::DISTANCE, GetObject().GetInnerRadius(), this); diff --git a/src/Dialogs/Task/Widgets/LineSectorZoneEditWidget.cpp b/src/Dialogs/Task/Widgets/LineSectorZoneEditWidget.cpp index 0ad4beef04b..38e0f158ce1 100644 --- a/src/Dialogs/Task/Widgets/LineSectorZoneEditWidget.cpp +++ b/src/Dialogs/Task/Widgets/LineSectorZoneEditWidget.cpp @@ -20,7 +20,7 @@ LineSectorZoneEditWidget::Prepare(ContainerWindow &parent, const PixelRect &rc) ObservationZoneEditWidget::Prepare(parent, rc); AddFloat(_("Gate width"), _("Width of the start/finish gate."), - _T("%.1f %s"), _T("%.1f"), + "%.1f %s", "%.1f", 0.1, 200, 1, true, UnitGroup::DISTANCE, GetObject().GetLength(), this); diff --git a/src/Dialogs/Task/Widgets/SectorZoneEditWidget.cpp b/src/Dialogs/Task/Widgets/SectorZoneEditWidget.cpp index a68094b000d..039d25c3ee7 100644 --- a/src/Dialogs/Task/Widgets/SectorZoneEditWidget.cpp +++ b/src/Dialogs/Task/Widgets/SectorZoneEditWidget.cpp @@ -25,7 +25,7 @@ SectorZoneEditWidget::Prepare(ContainerWindow &parent, const auto shape = GetObject().GetShape(); AddFloat(_("Radius"), _("Radius of the OZ sector."), - _T("%.1f %s"), _T("%.1f"), + "%.1f %s", "%.1f", 0.1, 200, 1, true, UnitGroup::DISTANCE, GetObject().GetRadius(), this); @@ -47,7 +47,7 @@ SectorZoneEditWidget::Prepare(ContainerWindow &parent, const AnnularSectorZone &annulus = (const AnnularSectorZone &)GetObject(); AddFloat(_("Inner radius"), _("Inner radius of the OZ sector."), - _T("%.1f %s"), _T("%.1f"), + "%.1f %s", "%.1f", 0.1, 100, 1, true, UnitGroup::DISTANCE, annulus.GetInnerRadius(), this); diff --git a/src/Dialogs/Task/dlgTaskHelpers.cpp b/src/Dialogs/Task/dlgTaskHelpers.cpp index 5a8080a0161..a7e9235c4ed 100644 --- a/src/Dialogs/Task/dlgTaskHelpers.cpp +++ b/src/Dialogs/Task/dlgTaskHelpers.cpp @@ -28,7 +28,7 @@ * @return True if FAI shape */ static bool -TaskSummaryShape(const OrderedTask *task, TCHAR *text) +TaskSummaryShape(const OrderedTask *task, char *text) { bool FAIShape = false; switch (task->TaskSize()) { @@ -37,33 +37,33 @@ TaskSummaryShape(const OrderedTask *task, TCHAR *text) break; case 1: - _tcscpy(text, _("Unknown")); + strcpy(text, _("Unknown")); break; case 2: - _tcscpy(text, _("Goal")); + strcpy(text, _("Goal")); FAIShape = true; break; case 3: if (task->GetFactory().IsClosed()) { - _tcscpy(text, _("Out and return")); + strcpy(text, _("Out and return")); FAIShape = true; } else - _tcscpy(text, _("Two legs")); + strcpy(text, _("Two legs")); break; case 4: if (!task->GetFactory().IsUnique() ||!task->GetFactory().IsClosed()) - _tcscpy(text, _("Three legs")); + strcpy(text, _("Three legs")); else if (FAITriangleValidator::Validate(*task)) { - _tcscpy(text, _("FAI triangle")); + strcpy(text, _("FAI triangle")); FAIShape = true; } else - _tcscpy(text, _("non-FAI triangle")); + strcpy(text, _("non-FAI triangle")); break; default: @@ -73,16 +73,16 @@ TaskSummaryShape(const OrderedTask *task, TCHAR *text) return FAIShape; } void -OrderedTaskSummary(const OrderedTask *task, TCHAR *text, bool linebreaks) +OrderedTaskSummary(const OrderedTask *task, char *text, bool linebreaks) { const TaskStats &stats = task->GetStats(); - TCHAR summary_shape[100]; + char summary_shape[100]; bool FAIShape = TaskSummaryShape(task, summary_shape); TaskValidationErrorSet validation_errors; if (FAIShape || task->GetFactoryType() == TaskFactoryType::FAI_GENERAL) validation_errors = task->GetFactory().ValidateFAIOZs(); - TCHAR linebreak[3]; + char linebreak[3]; if (linebreaks) { linebreak[0] = '\n'; linebreak[1] = 0; @@ -97,10 +97,10 @@ OrderedTaskSummary(const OrderedTask *task, TCHAR *text, bool linebreaks) OrderedTaskFactoryName(task->GetFactoryType())); } else { if (task->HasTargets()) - StringFormatUnsafe(text, _T("%s%s%s%s%.0f %s%s%s %.0f %s%s%s %.0f %s (%s)"), + StringFormatUnsafe(text, "%s%s%s%s%.0f %s%s%s %.0f %s%s%s %.0f %s (%s)", summary_shape, - validation_errors.IsEmpty() ? _T("") : _T(" / "), - validation_errors.IsEmpty() ? _T("") : getTaskValidationErrors(validation_errors), + validation_errors.IsEmpty() ? "" : " / ", + validation_errors.IsEmpty() ? "" : getTaskValidationErrors(validation_errors), linebreak, (double)Units::ToUserDistance(stats.distance_nominal), Units::GetDistanceName(), @@ -114,10 +114,10 @@ OrderedTaskSummary(const OrderedTask *task, TCHAR *text, bool linebreaks) Units::GetDistanceName(), OrderedTaskFactoryName(task->GetFactoryType())); else - StringFormatUnsafe(text, _T("%s%s%s%s%s %.0f %s (%s)"), + StringFormatUnsafe(text, "%s%s%s%s%s %.0f %s (%s)", summary_shape, - validation_errors.IsEmpty() ? _T("") : _T(" / "), - validation_errors.IsEmpty() ? _T("") : getTaskValidationErrors(validation_errors), + validation_errors.IsEmpty() ? "" : " / ", + validation_errors.IsEmpty() ? "" : getTaskValidationErrors(validation_errors), linebreak, _("dist."), (double)Units::ToUserDistance(stats.distance_nominal), @@ -127,24 +127,24 @@ OrderedTaskSummary(const OrderedTask *task, TCHAR *text, bool linebreaks) } void -OrderedTaskPointLabel(TaskPointType type, const TCHAR *name, - unsigned index, TCHAR* buffer) +OrderedTaskPointLabel(TaskPointType type, const char *name, + unsigned index, char* buffer) { switch (type) { case TaskPointType::START: - StringFormatUnsafe(buffer, _T("S: %s"), name); + StringFormatUnsafe(buffer, "S: %s", name); break; case TaskPointType::AST: - StringFormatUnsafe(buffer, _T("T%d: %s"), index, name); + StringFormatUnsafe(buffer, "T%d: %s", index, name); break; case TaskPointType::AAT: - StringFormatUnsafe(buffer, _T("A%d: %s"), index, name); + StringFormatUnsafe(buffer, "A%d: %s", index, name); break; case TaskPointType::FINISH: - StringFormatUnsafe(buffer, _T("F: %s"), name); + StringFormatUnsafe(buffer, "F: %s", name); break; default: @@ -153,60 +153,60 @@ OrderedTaskPointLabel(TaskPointType type, const TCHAR *name, } void -OrderedTaskPointRadiusLabel(const ObservationZonePoint &ozp, TCHAR* buffer) +OrderedTaskPointRadiusLabel(const ObservationZonePoint &ozp, char* buffer) { switch (ozp.GetShape()) { case ObservationZone::Shape::FAI_SECTOR: - _tcscpy(buffer, _("FAI quadrant")); + strcpy(buffer, _("FAI quadrant")); return; case ObservationZone::Shape::SECTOR: case ObservationZone::Shape::ANNULAR_SECTOR: - StringFormatUnsafe(buffer,_T("%s - %s: %.1f%s"), _("Sector"), _("Radius"), + StringFormatUnsafe(buffer,"%s - %s: %.1f%s", _("Sector"), _("Radius"), (double)Units::ToUserDistance(((const SectorZone &)ozp).GetRadius()), Units::GetDistanceName()); return; case ObservationZone::Shape::LINE: - StringFormatUnsafe(buffer,_T("%s - %s: %.1f%s"), _("Line"), _("Gate width"), + StringFormatUnsafe(buffer,"%s - %s: %.1f%s", _("Line"), _("Gate width"), (double)Units::ToUserDistance(((const LineSectorZone &)ozp).GetLength()), Units::GetDistanceName()); return; case ObservationZone::Shape::CYLINDER: - StringFormatUnsafe(buffer,_T("%s - %s: %.1f%s"), _("Cylinder"), _("Radius"), + StringFormatUnsafe(buffer,"%s - %s: %.1f%s", _("Cylinder"), _("Radius"), (double)Units::ToUserDistance(((const CylinderZone &)ozp).GetRadius()), Units::GetDistanceName()); return; case ObservationZone::Shape::MAT_CYLINDER: - _tcscpy(buffer, _("MAT cylinder")); + strcpy(buffer, _("MAT cylinder")); return; case ObservationZone::Shape::CUSTOM_KEYHOLE: - StringFormatUnsafe(buffer,_T("%s - %s: %.1f%s"), _("Keyhole"), _("Radius"), + StringFormatUnsafe(buffer,"%s - %s: %.1f%s", _("Keyhole"), _("Radius"), (double)Units::ToUserDistance(((const KeyholeZone &)ozp).GetRadius()), Units::GetDistanceName()); return; case ObservationZone::Shape::DAEC_KEYHOLE: - _tcscpy(buffer, _("DAeC Keyhole")); + strcpy(buffer, _("DAeC Keyhole")); return; case ObservationZone::Shape::BGAFIXEDCOURSE: - _tcscpy(buffer, _("BGA Fixed Course")); + strcpy(buffer, _("BGA Fixed Course")); return; case ObservationZone::Shape::BGAENHANCEDOPTION: - _tcscpy(buffer, _("BGA Enhanced Option")); + strcpy(buffer, _("BGA Enhanced Option")); return; case ObservationZone::Shape::BGA_START: - _tcscpy(buffer, _("BGA Start Sector")); + strcpy(buffer, _("BGA Start Sector")); return; case ObservationZone::Shape::SYMMETRIC_QUADRANT: - _tcscpy(buffer, _("Symmetric quadrant")); + strcpy(buffer, _("Symmetric quadrant")); return; } @@ -217,13 +217,13 @@ OrderedTaskPointRadiusLabel(const ObservationZonePoint &ozp, TCHAR* buffer) bool OrderedTaskSave(OrderedTask &task) { - TCHAR fname[69] = _T(""); + char fname[69] = ""; if (!TextEntryDialog(fname, 64, _("Enter a task name"))) return false; - const auto tasks_path = MakeLocalPath(_T("tasks")); + const auto tasks_path = MakeLocalPath("tasks"); - _tcscat(fname, _T(".tsk")); + strcat(fname, ".tsk"); task.SetName(fname); SaveTask(AllocatedPath::Build(tasks_path, fname), task); return true; diff --git a/src/Dialogs/Task/dlgTaskHelpers.hpp b/src/Dialogs/Task/dlgTaskHelpers.hpp index 21f19ddc0df..b2e8559fdbd 100644 --- a/src/Dialogs/Task/dlgTaskHelpers.hpp +++ b/src/Dialogs/Task/dlgTaskHelpers.hpp @@ -17,13 +17,13 @@ class ObservationZonePoint; * @param linebreaks True if each summary item should be separated with a line break */ void -OrderedTaskSummary(const OrderedTask *task, TCHAR *text, bool linebreaks); +OrderedTaskSummary(const OrderedTask *task, char *text, bool linebreaks); void -OrderedTaskPointLabel(TaskPointType type, const TCHAR *name, - unsigned index, TCHAR *buffer); +OrderedTaskPointLabel(TaskPointType type, const char *name, + unsigned index, char *buffer); -void OrderedTaskPointRadiusLabel(const ObservationZonePoint &ozp, TCHAR* radius); +void OrderedTaskPointRadiusLabel(const ObservationZonePoint &ozp, char* radius); bool OrderedTaskSave(OrderedTask &task); diff --git a/src/Dialogs/TextEntry.cpp b/src/Dialogs/TextEntry.cpp index 1928121e909..9e02b140f05 100644 --- a/src/Dialogs/TextEntry.cpp +++ b/src/Dialogs/TextEntry.cpp @@ -7,20 +7,24 @@ #include "Asset.hpp" bool -TextEntryDialog(TCHAR *text, size_t width, - const TCHAR *caption, AllowedCharacters accb, +TextEntryDialog(char *text, size_t width, + const char *caption, AllowedCharacters accb, bool default_shift_state) { switch (UIGlobals::GetDialogSettings().text_input_style) { case DialogSettings::TextInputStyle::Default: + return TouchTextEntry(text, width, caption, accb, default_shift_state); case DialogSettings::TextInputStyle::Keyboard: +#if 1 + return TouchTextEntry(text, width, caption, accb, default_shift_state); +#else if (HasPointer()) return TouchTextEntry(text, width, caption, accb, default_shift_state); else { KnobTextEntry(text, width, caption); return true; } - +#endif case DialogSettings::TextInputStyle::HighScore: KnobTextEntry(text, width, caption); return true; diff --git a/src/Dialogs/TextEntry.hpp b/src/Dialogs/TextEntry.hpp index 0175b5f7805..7398070c88a 100644 --- a/src/Dialogs/TextEntry.hpp +++ b/src/Dialogs/TextEntry.hpp @@ -8,18 +8,18 @@ #include #include -typedef std::function AllowedCharacters; +typedef std::function AllowedCharacters; bool -TextEntryDialog(TCHAR *text, size_t size, - const TCHAR *caption=nullptr, +TextEntryDialog(char *text, size_t size, + const char *caption=nullptr, AllowedCharacters ac=AllowedCharacters(), bool default_shift_state = true); template static inline bool -TextEntryDialog(BasicStringBuffer &text, - const TCHAR *caption=NULL, +TextEntryDialog(BasicStringBuffer &text, + const char *caption=NULL, AllowedCharacters accb=AllowedCharacters(), bool default_shift_state = true) { @@ -29,8 +29,8 @@ TextEntryDialog(BasicStringBuffer &text, template static inline bool -TextEntryDialog(BasicStringBuffer &text, - const TCHAR *caption, +TextEntryDialog(BasicStringBuffer &text, + const char *caption, bool default_shift_state) { AllowedCharacters accb=AllowedCharacters(); @@ -39,11 +39,11 @@ TextEntryDialog(BasicStringBuffer &text, } void -KnobTextEntry(TCHAR *text, size_t width, - const TCHAR *caption); +KnobTextEntry(char *text, size_t width, + const char *caption); bool -TouchTextEntry(TCHAR *text, size_t size, - const TCHAR *caption=nullptr, +TouchTextEntry(char *text, size_t size, + const char *caption=nullptr, AllowedCharacters ac=AllowedCharacters(), bool default_shift_state = true); diff --git a/src/Dialogs/TimeEntry.cpp b/src/Dialogs/TimeEntry.cpp index 5b2d3fa12b3..8a563509ab5 100644 --- a/src/Dialogs/TimeEntry.cpp +++ b/src/Dialogs/TimeEntry.cpp @@ -15,7 +15,7 @@ enum { }; bool -TimeEntryDialog(const TCHAR *caption, RoughTime &value, +TimeEntryDialog(const char *caption, RoughTime &value, RoughTimeDelta time_zone, bool nullable) { /* create the dialog */ diff --git a/src/Dialogs/TimeEntry.hpp b/src/Dialogs/TimeEntry.hpp index e08ab5e7344..e454b0cc4dc 100644 --- a/src/Dialogs/TimeEntry.hpp +++ b/src/Dialogs/TimeEntry.hpp @@ -9,5 +9,5 @@ class RoughTime; class RoughTimeDelta; bool -TimeEntryDialog(const TCHAR *caption, RoughTime &value, +TimeEntryDialog(const char *caption, RoughTime &value, RoughTimeDelta time_zone, bool nullable=false); diff --git a/src/Dialogs/TouchTextEntry.cpp b/src/Dialogs/TouchTextEntry.cpp index 3e855ff6fed..ecf081aa5cd 100644 --- a/src/Dialogs/TouchTextEntry.cpp +++ b/src/Dialogs/TouchTextEntry.cpp @@ -24,7 +24,7 @@ static AllowedCharacters AllowedCharactersCallback; static constexpr size_t MAX_TEXTENTRY = 40; static unsigned int cursor = 0; static size_t max_width; -static TCHAR edittext[MAX_TEXTENTRY]; +static char edittext[MAX_TEXTENTRY]; static void UpdateAllowedCharacters() @@ -60,7 +60,7 @@ OnBackspace() } static bool -DoCharacter(TCHAR character) +DoCharacter(char character) { if (cursor >= max_width - 1) return false; @@ -92,14 +92,12 @@ FormCharacter(unsigned ch) if (ch < 0x20) return false; -#ifndef _UNICODE if (ch >= 0x80) /* TODO: ASCII only for now, because we don't have proper UTF-8 support yet */ return false; -#endif - DoCharacter((TCHAR)ch); + DoCharacter((char)ch); return true; } @@ -112,8 +110,8 @@ ClearText() } bool -TouchTextEntry(TCHAR *text, size_t width, - const TCHAR *caption, +TouchTextEntry(char *text, size_t width, + const char *caption, AllowedCharacters accb, bool default_shift_state) { @@ -171,7 +169,7 @@ TouchTextEntry(TCHAR *text, size_t width, ? rc.right : clear_left + Layout::Scale(50); - WndProperty _editor(client_area, look, _T(""), + WndProperty _editor(client_area, look, "", { 0, padding, backspace_left - padding, editor_bottom }, 0, WindowStyle()); _editor.SetReadOnly(); @@ -209,7 +207,7 @@ TouchTextEntry(TCHAR *text, size_t width, kb = &keyboard; - Button backspace_button(client_area, look.button, _T("<-"), + Button backspace_button(client_area, look.button, "<-", { backspace_left, padding, rc.right - padding, editor_bottom }, button_style, [](){ OnBackspace(); }); @@ -221,7 +219,7 @@ TouchTextEntry(TCHAR *text, size_t width, if (!StringIsEmpty(text)) { CopyTruncateString(edittext, width, text); - cursor = _tcslen(text); + cursor = strlen(text); } UpdateTextboxProp(); diff --git a/src/Dialogs/Tracking/CloudEnableDialog.cpp b/src/Dialogs/Tracking/CloudEnableDialog.cpp index 345a33c9688..6ce9f075508 100644 --- a/src/Dialogs/Tracking/CloudEnableDialog.cpp +++ b/src/Dialogs/Tracking/CloudEnableDialog.cpp @@ -48,11 +48,11 @@ CloudEnableDialog() noexcept return; #endif - const TCHAR *msg = _("The XCSoar project is currently developing a revolutionary service which allows sharing thermal/wave locations and more with other pilots.\n" + const char *msg = _("The XCSoar project is currently developing a revolutionary service which allows sharing thermal/wave locations and more with other pilots.\n" "Do you wish to participate in the field test? This means that your position, thermal/wave locations and other weather data will be transmitted to our test server. You can disable it at any time in the \"Tracking\" settings.\n" "Please help us improve XCSoar!"); - int result = ShowMessageBox(msg, _T("XCSoar Cloud"), + int result = ShowMessageBox(msg, "XCSoar Cloud", MB_YESNOCANCEL|MB_ICONQUESTION); switch (result) { diff --git a/src/Dialogs/Traffic/FlarmTrafficDetails.cpp b/src/Dialogs/Traffic/FlarmTrafficDetails.cpp index 138bddc8464..2c0938f879e 100644 --- a/src/Dialogs/Traffic/FlarmTrafficDetails.cpp +++ b/src/Dialogs/Traffic/FlarmTrafficDetails.cpp @@ -146,8 +146,8 @@ FlarmTrafficDetailsWidget::Hide() noexcept void FlarmTrafficDetailsWidget::UpdateChanging(const MoreData &basic) { - TCHAR tmp[40]; - const TCHAR *value; + char tmp[40]; + const char *value; const FlarmTraffic* target = basic.flarm.traffic.FindTraffic(target_id); @@ -157,22 +157,22 @@ FlarmTrafficDetailsWidget::UpdateChanging(const MoreData &basic) // Fill distance/direction field if (target_ok) { FormatUserDistanceSmart(target->distance, tmp, true, 20, 1000); - TCHAR *p = tmp + _tcslen(tmp); - *p++ = _T(' '); + char *p = tmp + strlen(tmp); + *p++ = ' '; FormatAngleDelta(p, 20, target->Bearing() - basic.track); value = tmp; } else - value = _T("--"); + value = "--"; SetText(DISTANCE, value); // Fill altitude field if (target_ok) { - TCHAR *p = tmp; + char *p = tmp; if (target->altitude_available) { FormatUserAltitude(target->altitude, p); - p += _tcslen(p); - *p++ = _T(' '); + p += strlen(p); + *p++ = ' '; } Angle dir = Angle::FromXY(target->distance, target->relative_altitude); @@ -180,7 +180,7 @@ FlarmTrafficDetailsWidget::UpdateChanging(const MoreData &basic) value = tmp; } else - value = _T("--"); + value = "--"; SetText(ALTITUDE, value); @@ -189,7 +189,7 @@ FlarmTrafficDetailsWidget::UpdateChanging(const MoreData &basic) FormatUserVerticalSpeed(target->climb_rate_avg30s, tmp); value = tmp; } else - value = _T("--"); + value = "--"; SetText(VARIO, value); } @@ -202,11 +202,11 @@ FlarmTrafficDetailsWidget::UpdateChanging(const MoreData &basic) void FlarmTrafficDetailsWidget::Update() { - TCHAR tmp[200], tmp_id[7]; - const TCHAR *value; + char tmp[200], tmp_id[7]; + const char *value; // Set the dialog caption - StringFormatUnsafe(tmp, _T("%s (%s)"), + StringFormatUnsafe(tmp, "%s (%s)", _("FLARM Traffic Details"), target_id.Format(tmp_id)); dialog.SetCaption(tmp); @@ -219,9 +219,9 @@ FlarmTrafficDetailsWidget::Update() // Fill the frequency field if (!StringIsEmpty(record->frequency)) - value = UnsafeBuildString(tmp, record->frequency.c_str(), _T(" MHz")); + value = UnsafeBuildString(tmp, record->frequency.c_str(), " MHz"); else - value = _T("--"); + value = "--"; SetText(RADIO, value); // Fill the home airfield field @@ -231,22 +231,22 @@ FlarmTrafficDetailsWidget::Update() SetText(PLANE, record->plane_type); } else { // Fill the pilot name field - SetText(PILOT, _T("--")); + SetText(PILOT, "--"); // Fill the frequency field - SetText(RADIO, _T("--")); + SetText(RADIO, "--"); // Fill the home airfield field - SetText(AIRPORT, _T("--")); + SetText(AIRPORT, "--"); // Fill the plane type field const FlarmTraffic* target = CommonInterface::Basic().flarm.traffic.FindTraffic(target_id); - const TCHAR* actype; + const char* actype; if (target == nullptr || (actype = FlarmTraffic::GetTypeString(target->type)) == nullptr) - actype = _T("--"); + actype = "--"; SetText(PLANE, actype); } @@ -254,19 +254,19 @@ FlarmTrafficDetailsWidget::Update() // Fill the callsign field (+ registration) // note: don't use target->Name here since it is not updated // yet if it was changed - const TCHAR* cs = FlarmDetails::LookupCallsign(target_id); + const char* cs = FlarmDetails::LookupCallsign(target_id); if (cs != nullptr && cs[0] != 0) { try { - BasicStringBuilder builder(tmp, ARRAY_SIZE(tmp)); + BasicStringBuilder builder(tmp, ARRAY_SIZE(tmp)); builder.Append(cs); if (record) - builder.Append(_T(" ("), record->registration.c_str(), _T(")")); + builder.Append(" (", record->registration.c_str(), ")"); value = tmp; - } catch (BasicStringBuilder::Overflow) { + } catch (BasicStringBuilder::Overflow) { value = cs; } } else - value = _T("--"); + value = "--"; SetText(CALLSIGN, value); // Update the frequently changing fields too diff --git a/src/Dialogs/Traffic/TeamCodeDialog.cpp b/src/Dialogs/Traffic/TeamCodeDialog.cpp index 1ab9ec885c8..65226e6a0cf 100644 --- a/src/Dialogs/Traffic/TeamCodeDialog.cpp +++ b/src/Dialogs/Traffic/TeamCodeDialog.cpp @@ -105,7 +105,7 @@ TeamCodeWidget::Update(const MoreData &basic, const DerivedInfo &calculated) SetText(RELATIVE_BEARING, teamcode_info.teammate_available && basic.track_available ? FormatAngleDelta(teamcode_info.teammate_vector.bearing - basic.track).c_str() - : _T("---")); + : "---"); if (teamcode_info.teammate_available) { SetText(BEARING, @@ -120,7 +120,7 @@ TeamCodeWidget::Update(const MoreData &basic, const DerivedInfo &calculated) SetText(FLARM_LOCK, settings.team_flarm_id.IsDefined() ? settings.team_flarm_callsign.c_str() - : _T("")); + : ""); } void @@ -144,7 +144,7 @@ TeamCodeWidget::OnSetWaypointClicked() inline void TeamCodeWidget::OnCodeClicked() { - TCHAR newTeammateCode[10]; + char newTeammateCode[10]; CopyTruncateString(newTeammateCode, ARRAY_SIZE(newTeammateCode), CommonInterface::GetComputerSettings().team_code.team_code.GetCode()); @@ -166,8 +166,8 @@ TeamCodeWidget::OnFlarmLockClicked() { TeamCodeSettings &settings = CommonInterface::SetComputerSettings().team_code; - TCHAR newTeamFlarmCNTarget[decltype(settings.team_flarm_callsign)::capacity()]; - _tcscpy(newTeamFlarmCNTarget, settings.team_flarm_callsign.c_str()); + char newTeamFlarmCNTarget[decltype(settings.team_flarm_callsign)::capacity()]; + strcpy(newTeamFlarmCNTarget, settings.team_flarm_callsign.c_str()); if (!TextEntryDialog(newTeamFlarmCNTarget, 4)) return; diff --git a/src/Dialogs/Traffic/TrafficDialogs.hpp b/src/Dialogs/Traffic/TrafficDialogs.hpp index 184c85e3cfa..6bb28f3b2c9 100644 --- a/src/Dialogs/Traffic/TrafficDialogs.hpp +++ b/src/Dialogs/Traffic/TrafficDialogs.hpp @@ -17,4 +17,4 @@ void TrafficListDialog(); FlarmId -PickFlarmTraffic(const TCHAR *title, FlarmId array[], unsigned count); +PickFlarmTraffic(const char *title, FlarmId array[], unsigned count); diff --git a/src/Dialogs/Traffic/TrafficList.cpp b/src/Dialogs/Traffic/TrafficList.cpp index 262613a589c..bb30fd31861 100644 --- a/src/Dialogs/Traffic/TrafficList.cpp +++ b/src/Dialogs/Traffic/TrafficList.cpp @@ -78,7 +78,7 @@ class TrafficListWidget : public ListWidget, public DataFieldListener, bool loaded = false; const FlarmNetRecord *record; - const TCHAR *callsign; + const char *callsign; /** * This object's location. Check GeoPoint::IsValid(). @@ -94,7 +94,7 @@ class TrafficListWidget : public ListWidget, public DataFieldListener, /** * The display name of the SkyLines account. */ - tstring name; + std::string name; #ifdef HAVE_SKYLINES_TRACKING StaticString<20> near_name; @@ -116,7 +116,7 @@ class TrafficListWidget : public ListWidget, public DataFieldListener, #ifdef HAVE_SKYLINES_TRACKING explicit Item(uint32_t _id, SkyLinesTracking::Data::Time _time_of_day, const GeoPoint &_location, int _altitude, - tstring &&_name) + std::string &&_name) :id(FlarmId::Undefined()), skylines_id(_id), time_of_day(_time_of_day), color(FlarmColor::COUNT), @@ -323,7 +323,7 @@ class TrafficFilterWidget : public RowFormWidget { void Prepare([[maybe_unused]] ContainerWindow &parent, [[maybe_unused]] const PixelRect &rc) noexcept override { - PrefixDataField *callsign_df = new PrefixDataField(_T(""), listener); + PrefixDataField *callsign_df = new PrefixDataField("", listener); Add(_("Competition ID"), nullptr, callsign_df); } }; @@ -356,7 +356,7 @@ TrafficListWidget::UpdateList() items.clear(); last_update.Clear(); - const TCHAR *callsign = filter_widget->GetValueString(CALLSIGN); + const char *callsign = filter_widget->GetValueString(CALLSIGN); if (!StringIsEmpty(callsign)) { FlarmId ids[30]; unsigned count = FlarmDetails::FindIdsByCallSign(callsign, ids, 30); @@ -392,9 +392,9 @@ TrafficListWidget::UpdateList() const std::lock_guard lock{data.mutex}; for (const auto &i : data.traffic) { const auto name_i = data.user_names.find(i.first); - tstring name = name_i != data.user_names.end() + std::string name = name_i != data.user_names.end() ? name_i->second - : tstring(); + : std::string(); items.emplace_back(i.first, i.second.time_of_day, i.second.location, i.second.altitude, @@ -561,16 +561,17 @@ TrafficListWidget::OnPaintItem(Canvas &canvas, PixelRect rc, assert(index < items.size()); Item &item = items[index]; - assert(item.IsFlarm() + // MSVC don't like this Macro extension used in else branch #ifdef HAVE_SKYLINES_TRACKING - || item.IsSkyLines() + assert(item.IsFlarm() || item.IsSkyLines()); +#else + assert(item.IsFlarm()); #endif - ); item.AutoLoad(); const FlarmNetRecord *record = item.record; - const TCHAR *callsign = item.callsign; + const char *callsign = item.callsign; const DialogLook &look = UIGlobals::GetDialogLook(); const Font &name_font = *look.list.font_bold; @@ -579,7 +580,7 @@ TrafficListWidget::OnPaintItem(Canvas &canvas, PixelRect rc, const unsigned text_padding = Layout::GetTextPadding(); const unsigned frame_padding = text_padding / 2; - TCHAR tmp_id[10]; + char tmp_id[10]; item.id.Format(tmp_id); canvas.Select(name_font); @@ -588,21 +589,21 @@ TrafficListWidget::OnPaintItem(Canvas &canvas, PixelRect rc, if (item.IsFlarm()) { if (record != nullptr) - tmp.Format(_T("%s - %s - %s"), + tmp.Format("%s - %s - %s", callsign, record->registration.c_str(), tmp_id); else if (callsign != nullptr) - tmp.Format(_T("%s - %s"), callsign, tmp_id); + tmp.Format("%s - %s", callsign, tmp_id); else - tmp.Format(_T("%s"), tmp_id); + tmp.Format("%s", tmp_id); #ifdef HAVE_SKYLINES_TRACKING } else if (item.IsSkyLines()) { if (!item.name.empty()) tmp = item.name.c_str(); else - tmp.UnsafeFormat(_T("SkyLines %u"), item.skylines_id); + tmp.UnsafeFormat("SkyLines %u", item.skylines_id); #endif } else { - tmp = _T("?"); + tmp = "?"; } if (item.color != FlarmColor::NONE) { @@ -655,14 +656,14 @@ TrafficListWidget::OnPaintItem(Canvas &canvas, PixelRect rc, if (!record->plane_type.empty()) { if (!tmp.empty()) - tmp.append(_T(" - ")); + tmp.append(" - "); tmp.append(record->plane_type); } if (!record->airfield.empty()) { if (!tmp.empty()) - tmp.append(_T(" - ")); + tmp.append(" - "); tmp.append(record->airfield); } @@ -679,12 +680,12 @@ TrafficListWidget::OnPaintItem(Canvas &canvas, PixelRect rc, tmp.clear(); if (!item.near_name.empty()) - tmp.AppendFormat(_T(" near %s (%s)"), + tmp.AppendFormat(" near %s (%s)", item.near_name.c_str(), FormatUserDistanceSmart(item.near_distance).c_str()); if (!tmp.empty()) - tmp.append(_T("; ")); + tmp.append("; "); tmp.append(FormatUserAltitude(item.altitude).c_str()); if (!tmp.empty()) @@ -764,7 +765,7 @@ TrafficListDialog() } FlarmId -PickFlarmTraffic(const TCHAR *title, FlarmId array[], unsigned count) +PickFlarmTraffic(const char *title, FlarmId array[], unsigned count) { assert(count > 0); diff --git a/src/Dialogs/Waypoint/WaypointInfoWidget.cpp b/src/Dialogs/Waypoint/WaypointInfoWidget.cpp index dfa032edcf6..00acfd105de 100644 --- a/src/Dialogs/Waypoint/WaypointInfoWidget.cpp +++ b/src/Dialogs/Waypoint/WaypointInfoWidget.cpp @@ -19,8 +19,8 @@ #include "Formatter/AngleFormatter.hpp" #include "Formatter/UserGeoPointFormatter.hpp" -static const TCHAR * -FormatGlideResult(TCHAR *buffer, size_t size, +static const char * +FormatGlideResult(char *buffer, size_t size, const GlideResult &result, const GlideSettings &settings) noexcept { @@ -42,12 +42,12 @@ FormatGlideResult(TCHAR *buffer, size_t size, } void -WaypointInfoWidget::AddGlideResult(const TCHAR *label, +WaypointInfoWidget::AddGlideResult(const char *label, const GlideResult &result) noexcept { const ComputerSettings &settings = CommonInterface::GetComputerSettings(); - TCHAR buffer[64]; + char buffer[64]; AddReadOnly(label, nullptr, FormatGlideResult(buffer, ARRAY_SIZE(buffer), result, settings.task.glide)); @@ -90,20 +90,20 @@ WaypointInfoWidget::Prepare(ContainerWindow &parent, if (waypoint->radio_frequency.Format(buffer.buffer(), buffer.capacity()) != nullptr) { - buffer += _T(" MHz"); + buffer += " MHz"; AddReadOnly(_("Radio frequency"), nullptr, buffer); } if (waypoint->runway.IsDirectionDefined()) - buffer.UnsafeFormat(_T("%02u"), waypoint->runway.GetDirectionName()); + buffer.UnsafeFormat("%02u", waypoint->runway.GetDirectionName()); else buffer.clear(); if (waypoint->runway.IsLengthDefined()) { if (!buffer.empty()) - buffer += _T("; "); + buffer += "; "; - TCHAR length_buffer[16]; + char length_buffer[16]; FormatSmallUserDistance(length_buffer, waypoint->runway.GetLength()); buffer += length_buffer; } @@ -121,7 +121,7 @@ WaypointInfoWidget::Prepare(ContainerWindow &parent, if (waypoint->has_elevation) AddReadOnly(_("Elevation"), nullptr, FormatUserAltitude(waypoint->elevation)); else - AddReadOnly(_("Elevation"), nullptr, _T("?")); + AddReadOnly(_("Elevation"), nullptr, "?"); if (basic.time_available && basic.date_time_utc.IsDatePlausible()) { const SunEphemeris::Result sun = @@ -131,7 +131,7 @@ WaypointInfoWidget::Prepare(ContainerWindow &parent, const BrokenTime sunrise = BreakHourOfDay(sun.time_of_sunrise); const BrokenTime sunset = BreakHourOfDay(sun.time_of_sunset); - buffer.UnsafeFormat(_T("%02u:%02u - %02u:%02u"), + buffer.UnsafeFormat("%02u:%02u - %02u:%02u", sunrise.hour, sunrise.minute, sunset.hour, sunset.minute); AddReadOnly(_("Daylight time"), nullptr, buffer); @@ -183,7 +183,7 @@ WaypointInfoWidget::Prepare(ContainerWindow &parent, const auto distance = basic.location.Distance(waypoint->location); const auto gr = distance / delta_h; if (GradientValid(gr)) { - buffer.UnsafeFormat(_T("%.1f"), (double)gr); + buffer.UnsafeFormat("%.1f", (double)gr); AddReadOnly(_("Required glide ratio"), nullptr, buffer); } } diff --git a/src/Dialogs/Waypoint/WaypointInfoWidget.hpp b/src/Dialogs/Waypoint/WaypointInfoWidget.hpp index d208a2f4ce5..52f34533ecb 100644 --- a/src/Dialogs/Waypoint/WaypointInfoWidget.hpp +++ b/src/Dialogs/Waypoint/WaypointInfoWidget.hpp @@ -16,7 +16,7 @@ struct WaypointInfoWidget : public RowFormWidget { WaypointInfoWidget(const DialogLook &look, WaypointPtr _waypoint) noexcept :RowFormWidget(look), waypoint(std::move(_waypoint)) {} - void AddGlideResult(const TCHAR *label, const GlideResult &result) noexcept; + void AddGlideResult(const char *label, const GlideResult &result) noexcept; /* methods from Widget */ void Prepare(ContainerWindow &parent, const PixelRect &rc) noexcept override; diff --git a/src/Dialogs/Waypoint/WaypointList.cpp b/src/Dialogs/Waypoint/WaypointList.cpp index 86ffaffc7b5..b2606ae1a22 100644 --- a/src/Dialogs/Waypoint/WaypointList.cpp +++ b/src/Dialogs/Waypoint/WaypointList.cpp @@ -57,17 +57,17 @@ static constexpr int direction_filter_items[] = { -1, -1, 0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330 }; -static const TCHAR *const type_filter_items[] = { - _T("*"), _T("Airport"), _T("Landable"), - _T("Turnpoint"), - _T("Start"), - _T("Finish"), - _T("Left FAI Triangle"), - _T("Right FAI Triangle"), - _T("Custom"), - _T("File 1"), _T("File 2"), - _T("Map file"), - _T("Recently Used"), +static const char *const type_filter_items[] = { + "*", "Airport", "Landable", + "Turnpoint", + "Start", + "Finish", + "Left FAI Triangle", + "Right FAI Triangle", + "Custom", + "File 1", "File 2", + "Map file", + "Recently Used", nullptr }; @@ -218,14 +218,14 @@ class WaypointListButtons : public RowFormWidget { static WaypointListDialogState dialog_state; -static const TCHAR * -GetDirectionData(TCHAR *buffer, size_t size, int direction_filter_index, +static const char * +GetDirectionData(char *buffer, size_t size, int direction_filter_index, Angle heading) { if (direction_filter_index == 0) - return _T("*"); + return "*"; else if (direction_filter_index == 1) - StringFormatUnsafe(buffer, _T("HDG(%s)"), + StringFormatUnsafe(buffer, "HDG(%s)", FormatBearing(heading).c_str()); else FormatBearing(buffer, size, direction_filter_items[direction_filter_index]); @@ -242,7 +242,7 @@ WaypointFilterWidget::Update(Angle _last_heading) DataFieldEnum &direction_df = *(DataFieldEnum *) direction_control.GetDataField(); - TCHAR buffer[22]; + char buffer[22]; direction_df.replaceEnumText(1, GetDirectionData(buffer, ARRAY_SIZE(buffer), 1, last_heading)); direction_control.RefreshDisplay(); @@ -319,8 +319,8 @@ WaypointListWidget::Prepare(ContainerWindow &parent, static DataField * CreateNameDataField(Waypoints &waypoints, DataFieldListener *listener) { - return new PrefixDataField(_T(""), [&waypoints](const TCHAR *prefix){ - static TCHAR buffer[256]; + return new PrefixDataField("", [&waypoints](const char *prefix){ + static char buffer[256]; return waypoints.SuggestNamePrefix(prefix, buffer, ARRAY_SIZE(buffer)); }, listener); } @@ -329,7 +329,7 @@ static DataField * CreateDistanceDataField(DataFieldListener *listener) { DataFieldEnum *df = new DataFieldEnum(listener); - df->addEnumText(_T("*")); + df->addEnumText("*"); for (unsigned i = 1; i < ARRAY_SIZE(distance_filter_items); i++) { df->addEnumText(FormatUserDistance(Units::ToSysDistance(distance_filter_items[i]))); @@ -342,7 +342,7 @@ CreateDistanceDataField(DataFieldListener *listener) static DataField * CreateDirectionDataField(DataFieldListener *listener, Angle last_heading) { - TCHAR buffer[22]; + char buffer[22]; DataFieldEnum *df = new DataFieldEnum(listener); for (unsigned i = 0; i < ARRAY_SIZE(direction_filter_items); i++) df->addEnumText(GetDirectionData(buffer, ARRAY_SIZE(buffer), i, diff --git a/src/Dialogs/Waypoint/dlgWaypointDetails.cpp b/src/Dialogs/Waypoint/dlgWaypointDetails.cpp index ca5c4f9b22f..e75202af648 100644 --- a/src/Dialogs/Waypoint/dlgWaypointDetails.cpp +++ b/src/Dialogs/Waypoint/dlgWaypointDetails.cpp @@ -407,19 +407,19 @@ WaypointDetailsWidget::Prepare(ContainerWindow &parent, if (!images.empty()) { magnify_button.Create(parent, layout.magnify_button, button_style, - std::make_unique(look.button, _T("+")), + std::make_unique(look.button, "+"), [this](){ OnMagnifyClicked(); }); shrink_button.Create(parent, layout.shrink_button, button_style, - std::make_unique(look.button, _T("-")), + std::make_unique(look.button, "-"), [this](){ OnShrinkClicked(); }); } previous_button.Create(parent, layout.previous_button, button_style, - std::make_unique(look.button, _T("<")), + std::make_unique(look.button, "<"), [this](){ NextPage(-1); }); next_button.Create(parent, layout.next_button, button_style, - std::make_unique(look.button, _T(">")), + std::make_unique(look.button, ">"), [this](){ NextPage(1); }); close_button.Create(parent, look.button, _("Close"), layout.close_button, @@ -613,17 +613,17 @@ static void UpdateCaption(WndForm *form, const Waypoint &waypoint) { StaticString<256> buffer; - buffer.Format(_T("%s: %s"), _("Waypoint"), waypoint.name.c_str()); + buffer.Format("%s: %s", _("Waypoint"), waypoint.name.c_str()); std::string_view key{}; - const TCHAR *name = nullptr; + const char *name = nullptr; switch (waypoint.origin) { case WaypointOrigin::NONE: break; case WaypointOrigin::USER: - name = _T("user.cup"); + name = "user.cup"; break; case WaypointOrigin::PRIMARY: @@ -646,9 +646,9 @@ UpdateCaption(WndForm *form, const Waypoint &waypoint) if (!key.empty()) { const auto filename = Profile::map.GetPathBase(key); if (filename != nullptr) - buffer.AppendFormat(_T(" (%s)"), filename.c_str()); + buffer.AppendFormat(" (%s)", filename.c_str()); } else if (name != nullptr) - buffer.AppendFormat(_T(" (%s)"), name); + buffer.AppendFormat(" (%s)", name); form->SetCaption(buffer); } diff --git a/src/Dialogs/Waypoint/dlgWaypointEdit.cpp b/src/Dialogs/Waypoint/dlgWaypointEdit.cpp index 2a224ffd1fe..c97ff7752cb 100644 --- a/src/Dialogs/Waypoint/dlgWaypointEdit.cpp +++ b/src/Dialogs/Waypoint/dlgWaypointEdit.cpp @@ -80,7 +80,7 @@ WaypointEditWidget::Prepare(ContainerWindow &, const PixelRect &) noexcept UIGlobals::GetFormatSettings().coordinate_format, this)); AddFloat(_("Altitude"), nullptr, - _T("%.0f %s"), _T("%.0f"), + "%.0f %s", "%.0f", 0, 30000, 5, false, UnitGroup::ALTITUDE, value.GetElevationOrZero()); AddEnum(_("Type"), nullptr, waypoint_types, (unsigned)value.type); diff --git a/src/Dialogs/Weather/MapOverlayWidget.cpp b/src/Dialogs/Weather/MapOverlayWidget.cpp index 44f737ecb00..9a6060656c3 100644 --- a/src/Dialogs/Weather/MapOverlayWidget.cpp +++ b/src/Dialogs/Weather/MapOverlayWidget.cpp @@ -49,7 +49,7 @@ class WeatherMapOverlayListWidget final :name(_pc_met.label.c_str()), path(_pc_met.path.c_str()), pc_met(new PCMet::OverlayInfo(std::move(_pc_met))) {} - Item(const TCHAR *_name, Path _path) + Item(const char *_name, Path _path) :name(_name), path(_path) {} bool operator<(const Item &other) const { @@ -80,7 +80,7 @@ class WeatherMapOverlayListWidget final void CreateButtons(ButtonPanel &buttons); private: - int FindItemByName(const TCHAR *name) const { + int FindItemByName(const char *name) const { unsigned i = 0; for (const auto &item : items) { if (item.name == name) @@ -156,7 +156,7 @@ class WeatherMapOverlayListWidget final } /* virtual methods from TextListWidget */ - const TCHAR *GetRowText(unsigned i) const noexcept override { + const char *GetRowText(unsigned i) const noexcept override { return items[i].name.c_str(); } @@ -164,8 +164,8 @@ class WeatherMapOverlayListWidget final void OnPaintItem(Canvas &canvas, PixelRect rc, unsigned i) noexcept override { if (int(i) == active_index) { - rc.left = row_renderer.DrawColumn(canvas, rc, _T(" > ")); - rc.right = row_renderer.DrawRightColumn(canvas, rc, _T(" < ")); + rc.left = row_renderer.DrawColumn(canvas, rc, " > "); + rc.right = row_renderer.DrawRightColumn(canvas, rc, " < "); } TextListWidget::OnPaintItem(canvas, rc, i); @@ -185,7 +185,7 @@ class WeatherMapOverlayListWidget final } private: - void SetOverlay(Path path, const TCHAR *label=nullptr); + void SetOverlay(Path path, const char *label=nullptr); void UseClicked(unsigned i); @@ -231,10 +231,10 @@ WeatherMapOverlayListWidget::UpdateList() } } visitor(items); - const auto weather_path = LocalPath(_T("weather")); - const auto overlay_path = AllocatedPath::Build(weather_path, _T("overlay")); - Directory::VisitSpecificFiles(overlay_path, _T("*.tif"), visitor); - Directory::VisitSpecificFiles(overlay_path, _T("*.tiff"), visitor); + const auto weather_path = LocalPath("weather"); + const auto overlay_path = AllocatedPath::Build(weather_path, "overlay"); + Directory::VisitSpecificFiles(overlay_path, "*.tif", visitor); + Directory::VisitSpecificFiles(overlay_path, "*.tiff", visitor); const unsigned n = items.size(); @@ -276,7 +276,7 @@ SetupOverlay(MapOverlayBitmap &bmp, Path::const_pointer name) /* configure a default, just in case this overlay type is unknown */ bmp.SetAlpha(0.5); - if (StringStartsWithIgnoreCase(name, _T("nb_"))) { + if (StringStartsWithIgnoreCase(name, "nb_")) { name += 3; /* skip "model", go to "met" */ @@ -284,21 +284,21 @@ SetupOverlay(MapOverlayBitmap &bmp, Path::const_pointer name) if (underscore != nullptr) { name = underscore + 1; - if (StringStartsWithIgnoreCase(name, _T("ome_"))) { + if (StringStartsWithIgnoreCase(name, "ome_")) { /* vertical wind */ bmp.SetAlpha(0.5); - } else if (StringStartsWithIgnoreCase(name, _T("w_"))) { + } else if (StringStartsWithIgnoreCase(name, "w_")) { /* horizontal wind */ bmp.SetAlpha(0.7); } } - } else if (StringStartsWithIgnoreCase(name, _T("sat_"))) { + } else if (StringStartsWithIgnoreCase(name, "sat_")) { bmp.IgnoreBitmapAlpha(); bmp.SetAlpha(0.9); - } else if (StringStartsWithIgnoreCase(name, _T("pg_"))) { + } else if (StringStartsWithIgnoreCase(name, "pg_")) { /* precipitation */ bmp.SetAlpha(0.4); - } else if (StringStartsWithIgnoreCase(name, _T("Vertikalwind"))) { + } else if (StringStartsWithIgnoreCase(name, "Vertikalwind")) { /* name of a draft file I got from DWD */ // TODO: remove obsolete prefix bmp.IgnoreBitmapAlpha(); @@ -307,7 +307,7 @@ SetupOverlay(MapOverlayBitmap &bmp, Path::const_pointer name) } void -WeatherMapOverlayListWidget::SetOverlay(Path path, const TCHAR *label) +WeatherMapOverlayListWidget::SetOverlay(Path path, const char *label) { auto *map = UIGlobals::GetMap(); if (map == nullptr) @@ -339,7 +339,7 @@ WeatherMapOverlayListWidget::UseClicked(unsigned i) return; } - const TCHAR *label = nullptr; + const char *label = nullptr; auto &item = items[i]; if (item.pc_met) { const auto &info = *item.pc_met; @@ -364,7 +364,7 @@ WeatherMapOverlayListWidget::UseClicked(unsigned i) item.path = std::move(overlay->path); UpdatePreview(item.path); } catch (...) { - ShowError(std::current_exception(), _T("pc_met")); + ShowError(std::current_exception(), "pc_met"); } } } @@ -399,7 +399,7 @@ WeatherMapOverlayListWidget::UpdateClicked() SetOverlay(overlay->path, info.label.c_str()); item.path = std::move(overlay->path); } catch (...) { - ShowError(std::current_exception(), _T("pc_met")); + ShowError(std::current_exception(), "pc_met"); break; } } diff --git a/src/Dialogs/Weather/NOAADetails.cpp b/src/Dialogs/Weather/NOAADetails.cpp index 01c9e8b39da..a0cee05d934 100644 --- a/src/Dialogs/Weather/NOAADetails.cpp +++ b/src/Dialogs/Weather/NOAADetails.cpp @@ -54,20 +54,20 @@ NOAADetailsWidget::CreateButtons(WidgetDialog &buttons) void NOAADetailsWidget::Update() { - tstring metar_taf = _T(""); + std::string metar_taf = ""; NOAAFormatter::Format(*station_iterator, metar_taf); SetText(metar_taf.c_str()); StaticString<100> caption; - caption.Format(_T("%s: "), _("METAR and TAF")); + caption.Format("%s: ", _("METAR and TAF")); if (!station_iterator->parsed_metar_available || !station_iterator->parsed_metar.name_available) caption += station_iterator->GetCodeT(); else - caption.AppendFormat(_T("%s (%s)"), + caption.AppendFormat("%s (%s)", station_iterator->parsed_metar.name.c_str(), station_iterator->GetCodeT()); diff --git a/src/Dialogs/Weather/NOAAList.cpp b/src/Dialogs/Weather/NOAAList.cpp index 0b3c825b70d..238597cf82b 100644 --- a/src/Dialogs/Weather/NOAAList.cpp +++ b/src/Dialogs/Weather/NOAAList.cpp @@ -158,11 +158,11 @@ UpdateTask(NOAAStore::Item &item, ProgressListener &progress) noexcept inline void NOAAListWidget::AddClicked() { - TCHAR code[5] = _T(""); + char code[5] = ""; if (!TextEntryDialog(code, 5, _("Airport ICAO code"))) return; - if (_tcslen(code) != 4) { + if (strlen(code) != 4) { ShowMessageBox(_("Please enter the FOUR letter code of the desired station."), _("Error"), MB_OK); return; diff --git a/src/Dialogs/Weather/PCMetDialog.cpp b/src/Dialogs/Weather/PCMetDialog.cpp index 8bed39c58da..9d050ace9ae 100644 --- a/src/Dialogs/Weather/PCMetDialog.cpp +++ b/src/Dialogs/Weather/PCMetDialog.cpp @@ -32,7 +32,7 @@ BitmapDialog(const Bitmap &bitmap) TWidgetDialog dialog(WidgetDialog::Full{}, UIGlobals::GetMainWindow(), UIGlobals::GetDialogLook(), - _T("pc_met"), new ViewImageWidget(bitmap)); + "pc_met", new ViewImageWidget(bitmap)); dialog.AddButton(_("Close"), mrOK); // dialog.SetWidget(); dialog.ShowModal(); @@ -60,7 +60,7 @@ BitmapDialog(const PCMet::ImageType &type, const PCMet::ImageArea &area) bitmap.LoadFile(*path); BitmapDialog(bitmap); } catch (...) { - ShowError(std::current_exception(), _T("pc_met")); + ShowError(std::current_exception(), "pc_met"); } } @@ -88,7 +88,7 @@ class ImageAreaListWidget final : public TextListWidget { protected: /* virtual methods from TextListWidget */ - const TCHAR *GetRowText(unsigned i) const noexcept override { + const char *GetRowText(unsigned i) const noexcept override { return areas[i].display_name; } @@ -126,7 +126,7 @@ class ImageTypeListWidget final : public TextListWidget { protected: /* virtual methods from TextListWidget */ - const TCHAR *GetRowText(unsigned i) const noexcept override { + const char *GetRowText(unsigned i) const noexcept override { return PCMet::image_types[i].display_name; } @@ -150,7 +150,7 @@ CreatePCMetWidget() const auto &settings = CommonInterface::GetComputerSettings().weather.pcmet; if (!settings.www_credentials.IsDefined()) return std::make_unique(UIGlobals::GetDialogLook(), - _T("No account was configured.")); + "No account was configured."); auto area_widget = std::make_unique(); auto type_widget = std::make_unique(*area_widget); diff --git a/src/Dialogs/Weather/RASPDialog.cpp b/src/Dialogs/Weather/RASPDialog.cpp index 4e57b6cfc86..0f4ef796fb1 100644 --- a/src/Dialogs/Weather/RASPDialog.cpp +++ b/src/Dialogs/Weather/RASPDialog.cpp @@ -52,14 +52,14 @@ RASPSettingsPanel::FillItemControl() noexcept auto &df = (DataFieldEnum &)GetDataField(ITEM); df.ClearChoices(); - df.AddChoice(-1, _T("none"), _T("none"), nullptr); + df.AddChoice(-1, "none", "none", nullptr); for (unsigned i = 0; i < rasp->GetItemCount(); i++) { const auto &mi = rasp->GetItemInfo(i); - const TCHAR *label = mi.label; + const char *label = mi.label; if (label != nullptr) label = gettext(label); - const TCHAR *help = mi.help; + const char *help = mi.help; if (help != nullptr) help = gettext(help); @@ -86,8 +86,8 @@ RASPSettingsPanel::UpdateTimeControl() noexcept time_df.addEnumText(_("Now")); rasp->ForEachTime(item_index, [&time_df](BrokenTime t){ - TCHAR timetext[10]; - _stprintf(timetext, _T("%02u:%02u"), t.hour, t.minute); + char timetext[10]; + _stprintf(timetext, "%02u:%02u", t.hour, t.minute); time_df.addEnumText(timetext, t.GetMinuteOfDay()); }); @@ -107,7 +107,7 @@ RASPSettingsPanel::Prepare([[maybe_unused]] ContainerWindow &parent, WndProperty *wp; wp = AddFile(_("File"), nullptr, - ProfileKeys::RaspFile, _T("*-rasp*.dat\0"), + ProfileKeys::RaspFile, "*-rasp*.dat\0", FileType::RASP); wp->GetDataField()->SetOnModified([this]{ if (SaveValueFileReader(FILE, ProfileKeys::RaspFile)) { diff --git a/src/Dialogs/Weather/WeatherDialog.cpp b/src/Dialogs/Weather/WeatherDialog.cpp index ac39f71cfc6..377bbdf1c79 100644 --- a/src/Dialogs/Weather/WeatherDialog.cpp +++ b/src/Dialogs/Weather/WeatherDialog.cpp @@ -23,13 +23,13 @@ static void SetTitle(WndForm &form, const TabWidget &pager) { StaticString<128> title; - title.Format(_T("%s: %s"), _("Weather"), + title.Format("%s: %s", _("Weather"), pager.GetButtonCaption(pager.GetCurrentIndex())); form.SetCaption(title); } void -ShowWeatherDialog(const TCHAR *page) +ShowWeatherDialog(const char *page) { const DialogLook &look = UIGlobals::GetDialogLook(); @@ -53,22 +53,22 @@ ShowWeatherDialog(const TCHAR *page) /* setup tabs */ #ifdef HAVE_NOAA - if (page != nullptr && StringIsEqual(page, _T("list"))) + if (page != nullptr && StringIsEqual(page, "list")) start_page = widget.GetSize(); widget.AddTab(CreateNOAAListWidget(), _("METAR and TAF")); #endif - if (page != nullptr && StringIsEqual(page, _T("rasp"))) + if (page != nullptr && StringIsEqual(page, "rasp")) start_page = widget.GetSize(); - widget.AddTab(CreateRaspWidget(), _T("RASP")); + widget.AddTab(CreateRaspWidget(), "RASP"); #ifdef HAVE_PCMET - if (page != nullptr && StringIsEqual(page, _T("pc_met"))) + if (page != nullptr && StringIsEqual(page, "pc_met")) start_page = widget.GetSize(); - widget.AddTab(CreatePCMetWidget(), _T("pc_met")); + widget.AddTab(CreatePCMetWidget(), "pc_met"); #endif #if 0 @@ -77,11 +77,11 @@ ShowWeatherDialog(const TCHAR *page) eventually, we should refactor the code to be generic, allowing arbitrary georeferenced images */ - if (page != nullptr && StringIsEqual(page, _T("overlay"))) + if (page != nullptr && StringIsEqual(page, "overlay")) start_page = widget.GetSize(); // TODO: better and translatable title? - widget.AddTab(CreateWeatherMapOverlayWidget(), _T("Overlay")); + widget.AddTab(CreateWeatherMapOverlayWidget(), "Overlay"); #endif /* restore previous page */ diff --git a/src/Dialogs/Weather/WeatherDialog.hpp b/src/Dialogs/Weather/WeatherDialog.hpp index b8a14ec53df..71e372ed4e2 100644 --- a/src/Dialogs/Weather/WeatherDialog.hpp +++ b/src/Dialogs/Weather/WeatherDialog.hpp @@ -6,4 +6,4 @@ #include void -ShowWeatherDialog(const TCHAR *page); +ShowWeatherDialog(const char *page); diff --git a/src/Dialogs/WidgetDialog.cpp b/src/Dialogs/WidgetDialog.cpp index 6742bd663a6..da330ab4461 100644 --- a/src/Dialogs/WidgetDialog.cpp +++ b/src/Dialogs/WidgetDialog.cpp @@ -30,7 +30,7 @@ WidgetDialog::WidgetDialog(const DialogLook &look) } WidgetDialog::WidgetDialog(SingleWindow &parent, const DialogLook &look, - const PixelRect &rc, const TCHAR *caption, + const PixelRect &rc, const char *caption, Widget *_widget) noexcept :WndForm(parent, look, rc, caption, GetDialogStyle()), buttons(GetClientAreaWindow(), look.button), @@ -42,7 +42,7 @@ WidgetDialog::WidgetDialog(SingleWindow &parent, const DialogLook &look, } WidgetDialog::WidgetDialog(Auto, SingleWindow &parent, const DialogLook &look, - const TCHAR *caption) noexcept + const char *caption) noexcept :WndForm(parent, look, parent.GetClientRect(), caption, GetDialogStyle()), buttons(GetClientAreaWindow(), look.button), widget(GetClientAreaWindow()), @@ -51,7 +51,7 @@ WidgetDialog::WidgetDialog(Auto, SingleWindow &parent, const DialogLook &look, } WidgetDialog::WidgetDialog(Auto tag, SingleWindow &parent, const DialogLook &look, - const TCHAR *caption, + const char *caption, Widget *_widget) noexcept :WidgetDialog(tag, parent, look, caption) { @@ -60,7 +60,7 @@ WidgetDialog::WidgetDialog(Auto tag, SingleWindow &parent, const DialogLook &loo } WidgetDialog::WidgetDialog(Full, SingleWindow &parent, const DialogLook &look, - const TCHAR *caption) noexcept + const char *caption) noexcept :WndForm(parent, look, parent.GetClientRect(), caption, GetDialogStyle()), buttons(GetClientAreaWindow(), look.button), widget(GetClientAreaWindow()), @@ -69,7 +69,7 @@ WidgetDialog::WidgetDialog(Full, SingleWindow &parent, const DialogLook &look, } WidgetDialog::WidgetDialog(Full tag, SingleWindow &parent, const DialogLook &look, - const TCHAR *caption, + const char *caption, Widget *_widget) noexcept :WidgetDialog(tag, parent, look, caption) { @@ -238,7 +238,7 @@ WidgetDialog::OnAnyKeyDown(unsigned key_code) noexcept bool DefaultWidgetDialog(SingleWindow &parent, const DialogLook &look, - const TCHAR *caption, const PixelRect &rc, Widget &widget) + const char *caption, const PixelRect &rc, Widget &widget) { WidgetDialog dialog(parent, look, rc, caption, &widget); dialog.AddButton(_("OK"), mrOK); @@ -254,7 +254,7 @@ DefaultWidgetDialog(SingleWindow &parent, const DialogLook &look, bool DefaultWidgetDialog(SingleWindow &parent, const DialogLook &look, - const TCHAR *caption, Widget &widget) + const char *caption, Widget &widget) { WidgetDialog dialog(WidgetDialog::Auto{}, parent, look, caption, &widget); dialog.AddButton(_("OK"), mrOK); diff --git a/src/Dialogs/WidgetDialog.hpp b/src/Dialogs/WidgetDialog.hpp index 40f229369e4..647fd57f41f 100644 --- a/src/Dialogs/WidgetDialog.hpp +++ b/src/Dialogs/WidgetDialog.hpp @@ -28,7 +28,7 @@ class WidgetDialog : public WndForm { explicit WidgetDialog(const DialogLook &look); WidgetDialog(UI::SingleWindow &parent, const DialogLook &look, - const PixelRect &rc, const TCHAR *caption, + const PixelRect &rc, const char *caption, Widget *widget) noexcept; struct Auto {}; @@ -38,14 +38,14 @@ class WidgetDialog : public WndForm { * Call FinishPreliminary() to resume building the dialog. */ WidgetDialog(Auto, UI::SingleWindow &parent, const DialogLook &look, - const TCHAR *caption) noexcept; + const char *caption) noexcept; /** * Create a dialog with an automatic size (by * Widget::GetMinimumSize() and Widget::GetMaximumSize()). */ WidgetDialog(Auto, UI::SingleWindow &parent, const DialogLook &look, - const TCHAR *caption, Widget *widget) noexcept; + const char *caption, Widget *widget) noexcept; struct Full {}; @@ -54,13 +54,13 @@ class WidgetDialog : public WndForm { * Call FinishPreliminary() to resume building the dialog. */ WidgetDialog(Full, UI::SingleWindow &parent, const DialogLook &look, - const TCHAR *caption) noexcept; + const char *caption) noexcept; /** * Create a full-screen dialog. */ WidgetDialog(Full, UI::SingleWindow &parent, const DialogLook &look, - const TCHAR *caption, Widget *widget) noexcept; + const char *caption, Widget *widget) noexcept; virtual ~WidgetDialog(); @@ -98,16 +98,16 @@ class WidgetDialog : public WndForm { return buttons.Add(std::move(renderer), std::move(callback)); } - Button *AddButton(const TCHAR *caption, + Button *AddButton(const char *caption, Button::Callback callback) noexcept { return buttons.Add(caption, std::move(callback)); } - Button *AddButton(const TCHAR *caption, int modal_result) { + Button *AddButton(const char *caption, int modal_result) { return AddButton(caption, MakeModalResultCallback(modal_result)); } - Button *AddSymbolButton(const TCHAR *caption, + Button *AddSymbolButton(const char *caption, Button::Callback callback) noexcept { return buttons.AddSymbol(caption, std::move(callback)); } @@ -173,8 +173,8 @@ class TWidgetDialog final : public WidgetDialog { */ bool DefaultWidgetDialog(UI::SingleWindow &parent, const DialogLook &look, - const TCHAR *caption, const PixelRect &rc, Widget &widget); + const char *caption, const PixelRect &rc, Widget &widget); bool DefaultWidgetDialog(UI::SingleWindow &parent, const DialogLook &look, - const TCHAR *caption, Widget &widget); + const char *caption, Widget &widget); diff --git a/src/Dialogs/dlgAnalysis.cpp b/src/Dialogs/dlgAnalysis.cpp index dd4c7ef6ef1..5e863381151 100644 --- a/src/Dialogs/dlgAnalysis.cpp +++ b/src/Dialogs/dlgAnalysis.cpp @@ -145,12 +145,12 @@ class AnalysisWidget final : public NullWidget { } void SetCalcVisibility(bool visible); - void SetCalcCaption(const TCHAR *caption); + void SetCalcCaption(const char *caption); void NextPage(int step); void Update(); - void OnGesture(const TCHAR *gesture); + void OnGesture(const char *gesture); private: void OnCalcClicked(); @@ -281,11 +281,11 @@ AnalysisWidget::Prepare(ContainerWindow &parent, const PixelRect &rc) noexcept info.Create(parent, layout.info); const auto &button_look = dialog.GetLook().button; - details_button.Create(parent, button_look, _T("Calc"), layout.details_button, + details_button.Create(parent, button_look, "Calc", layout.details_button, button_style, [this](){ OnCalcClicked(); }); - previous_button.Create(parent, button_look, _T("<"), layout.previous_button, + previous_button.Create(parent, button_look, "<", layout.previous_button, button_style, [this](){ NextPage(-1); }); - next_button.Create(parent, button_look, _T(">"), layout.next_button, + next_button.Create(parent, button_look, ">", layout.next_button, button_style, [this](){ NextPage(1); }); close_button.Create(parent, button_look, _("Close"), layout.close_button, button_style, dialog.MakeModalResultCallback(mrOK)); @@ -303,7 +303,7 @@ AnalysisWidget::SetCalcVisibility(bool visible) } void -AnalysisWidget::SetCalcCaption(const TCHAR *caption) +AnalysisWidget::SetCalcCaption(const char *caption) { details_button.SetCaption(caption); SetCalcVisibility(!StringIsEmpty(caption)); @@ -443,14 +443,14 @@ ChartControl::UpdateCrossSection(const MoreData &basic, void AnalysisWidget::Update() { - TCHAR sTmp[1000]; + char sTmp[1000]; const ComputerSettings &settings_computer = blackboard.GetComputerSettings(); const DerivedInfo &calculated = blackboard.Calculated(); switch (page) { case AnalysisPage::BAROGRAPH: - StringFormatUnsafe(sTmp, _T("%s: %s"), _("Analysis"), + StringFormatUnsafe(sTmp, "%s: %s", _("Analysis"), _("Barograph")); dialog.SetCaption(sTmp); BarographCaption(sTmp, glide_computer.GetFlightStats()); @@ -459,7 +459,7 @@ AnalysisWidget::Update() break; case AnalysisPage::CLIMB: - StringFormatUnsafe(sTmp, _T("%s: %s"), _("Analysis"), + StringFormatUnsafe(sTmp, "%s: %s", _("Analysis"), _("Climb")); dialog.SetCaption(sTmp); ClimbChartCaption(sTmp, glide_computer.GetFlightStats()); @@ -468,32 +468,32 @@ AnalysisWidget::Update() break; case AnalysisPage::THERMAL_BAND: - StringFormatUnsafe(sTmp, _T("%s: %s"), _("Analysis"), + StringFormatUnsafe(sTmp, "%s: %s", _("Analysis"), _("Thermal Band")); dialog.SetCaption(sTmp); ClimbChartCaption(sTmp, glide_computer.GetFlightStats()); info.SetText(sTmp); - SetCalcCaption(_T("")); + SetCalcCaption(""); break; case AnalysisPage::VARIO_HISTOGRAM: - StringFormatUnsafe(sTmp, _T("%s: %s"), _("Analysis"), + StringFormatUnsafe(sTmp, "%s: %s", _("Analysis"), _("Vario Histogram")); dialog.SetCaption(sTmp); - info.SetText(_T("")); - SetCalcCaption(_T("")); + info.SetText(""); + SetCalcCaption(""); break; case AnalysisPage::WIND: - StringFormatUnsafe(sTmp, _T("%s: %s"), _("Analysis"), + StringFormatUnsafe(sTmp, "%s: %s", _("Analysis"), _("Wind at Altitude")); dialog.SetCaption(sTmp); - info.SetText(_T("")); + info.SetText(""); SetCalcCaption(_("Set Wind")); break; case AnalysisPage::POLAR: - StringFormatUnsafe(sTmp, _T("%s: %s (%s %d kg)"), _("Analysis"), + StringFormatUnsafe(sTmp, "%s: %s (%s %d kg)", _("Analysis"), _("Glide Polar"), _("Mass"), (int)settings_computer.polar.glide_polar_task.GetTotalMass()); dialog.SetCaption(sTmp); @@ -503,7 +503,7 @@ AnalysisWidget::Update() break; case AnalysisPage::MACCREADY: - StringFormatUnsafe(sTmp, _T("%s: %s"), _("Analysis"), + StringFormatUnsafe(sTmp, "%s: %s", _("Analysis"), _("MacCready Speeds")); dialog.SetCaption(sTmp); MacCreadyCaption(sTmp, settings_computer.polar.glide_polar_task); @@ -512,7 +512,7 @@ AnalysisWidget::Update() break; case AnalysisPage::TEMPTRACE: - StringFormatUnsafe(sTmp, _T("%s: %s"), _("Analysis"), + StringFormatUnsafe(sTmp, "%s: %s", _("Analysis"), _("Temperature Trace")); dialog.SetCaption(sTmp); TemperatureChartCaption(sTmp, glide_computer.GetCuSonde()); @@ -521,7 +521,7 @@ AnalysisWidget::Update() break; case AnalysisPage::TASK_SPEED: - StringFormatUnsafe(sTmp, _T("%s: %s"), _("Analysis"), + StringFormatUnsafe(sTmp, "%s: %s", _("Analysis"), _("Task Speed")); dialog.SetCaption(sTmp); TaskSpeedCaption(sTmp, glide_computer.GetFlightStats(), @@ -531,7 +531,7 @@ AnalysisWidget::Update() break; case AnalysisPage::TASK: - StringFormatUnsafe(sTmp, _T("%s: %s"), _("Analysis"), + StringFormatUnsafe(sTmp, "%s: %s", _("Analysis"), _("Task")); dialog.SetCaption(sTmp); FlightStatisticsRenderer::CaptionTask(sTmp, calculated); @@ -540,20 +540,20 @@ AnalysisWidget::Update() break; case AnalysisPage::CONTEST: - StringFormatUnsafe(sTmp, _T("%s: %s"), _("Analysis"), + StringFormatUnsafe(sTmp, "%s: %s", _("Analysis"), ContestToString(settings_computer.contest.contest)); dialog.SetCaption(sTmp); - SetCalcCaption(_T("")); + SetCalcCaption(""); FlightStatisticsRenderer::CaptionContest(sTmp, settings_computer.contest, calculated); info.SetText(sTmp); break; case AnalysisPage::AIRSPACE: - StringFormatUnsafe(sTmp, _T("%s: %s"), _("Analysis"), + StringFormatUnsafe(sTmp, "%s: %s", _("Analysis"), _("Airspace")); dialog.SetCaption(sTmp); - info.SetText(_T("")); + info.SetText(""); SetCalcCaption(_("Warnings")); break; @@ -586,11 +586,11 @@ AnalysisWidget::NextPage(int Step) } void -AnalysisWidget::OnGesture(const TCHAR *gesture) +AnalysisWidget::OnGesture(const char *gesture) { - if (StringIsEqual(gesture, _T("R"))) + if (StringIsEqual(gesture, "R")) NextPage(-1); - else if (StringIsEqual(gesture, _T("L"))) + else if (StringIsEqual(gesture, "L")) NextPage(+1); } @@ -619,7 +619,7 @@ ChartControl::OnMouseUp([[maybe_unused]] PixelPoint p) noexcept dragging = false; ReleaseCapture(); - const TCHAR *gesture = gestures.Finish(); + const char *gesture = gestures.Finish(); if (gesture != NULL) analysis_widget.OnGesture(gesture); } diff --git a/src/Dialogs/dlgChecklist.cpp b/src/Dialogs/dlgChecklist.cpp index d36dafdeb2a..d82589a8eb4 100644 --- a/src/Dialogs/dlgChecklist.cpp +++ b/src/Dialogs/dlgChecklist.cpp @@ -10,7 +10,7 @@ #include "util/StaticString.hxx" #include "util/StringSplit.hxx" #include "util/StringCompare.hxx" -#include "util/tstring.hpp" +#include #include "io/DataFile.hpp" #include "io/Reader.hxx" #include "io/BufferedReader.hxx" @@ -23,7 +23,7 @@ #define XCSCHKLIST "xcsoar-checklist.txt" struct ChecklistPage { - tstring title, text; + std::string title, text; bool empty() const noexcept { return title.empty() && text.empty(); @@ -40,7 +40,7 @@ UpdateCaption(WndForm &form, const Checklist &checklist, std::size_t page) const auto &p = checklist[page]; if (!p.title.empty()) { - buffer.append(_T(": ")); + buffer.append(": "); buffer.append(p.title); } @@ -52,7 +52,7 @@ LoadChecklist() noexcept try { Checklist c; - auto file_reader = OpenDataFile(_T(XCSCHKLIST)); + auto file_reader = OpenDataFile(XCSCHKLIST); BufferedReader reader{*file_reader}; StringConverter string_converter{Charset::UTF8}; diff --git a/src/Dialogs/dlgCredits.cpp b/src/Dialogs/dlgCredits.cpp index eba34bb5eff..544fc31a08a 100644 --- a/src/Dialogs/dlgCredits.cpp +++ b/src/Dialogs/dlgCredits.cpp @@ -15,7 +15,6 @@ #include "ui/canvas/Font.hpp" #include "Version.hpp" #include "Inflate.hpp" -#include "util/ConvertString.hpp" #include "util/AllocatedString.hxx" #include "Resources.hpp" #include "UIGlobals.hpp" @@ -68,31 +67,31 @@ LogoPageWindow::OnPaint(Canvas &canvas) noexcept canvas.SetTextColor(COLOR_BLACK); x = middle; - const TCHAR *version = _T("Version: "); + const char *version = "Version: "; PixelSize ts = canvas.CalcTextSize(version); - PixelSize ts2 = canvas.CalcTextSize(XCSoar_VersionString); + PixelSize ts2 = canvas.CalcTextSize(OpenSoar_VersionString); x = middle - ((ts.width + ts2.width) / 2 ); canvas.DrawText({x, y}, version); x += ts.width; - canvas.DrawText({x, y}, XCSoar_VersionString); + canvas.DrawText({x, y}, OpenSoar_VersionString); #ifdef GIT_COMMIT_ID y += ts.height + Layout::FastScale(2); x = middle; - const TCHAR *git = _T("git: "); + const char *git = "git: "; ts = canvas.CalcTextSize(git); - ts2 = canvas.CalcTextSize(_T(GIT_COMMIT_ID)); + ts2 = canvas.CalcTextSize(GIT_COMMIT_ID); x = middle - ((ts.width + ts2.width) / 2 ); canvas.DrawText({x, y}, git); x += ts.width; - canvas.DrawText({x, y}, _T(GIT_COMMIT_ID)); + canvas.DrawText({x, y}, GIT_COMMIT_ID); y += ts.height + Layout::FastScale(2); #endif y += Layout::FastScale(8); - const TCHAR *visit = _T("Vist us at:"); - const TCHAR *url = _T("https://xcsoar.org"); + const char *visit = "Vist us at:"; + const char *url = "https://xcsoar.org"; ts = canvas.CalcTextSize(visit); ts2 = canvas.CalcTextSize(url); x = middle - (ts.width / 2); @@ -120,8 +119,8 @@ extern "C" extern const uint8_t COPYING_gz[]; extern const size_t COPYING_gz_size; - extern const uint8_t NEWS_txt_gz[]; - extern const size_t NEWS_txt_gz_size; + extern const uint8_t OpenSoar_News_md_gz[]; + extern const size_t OpenSoar_News_md_gz_size; extern const uint8_t AUTHORS_gz[]; extern const size_t AUTHORS_gz_size; @@ -133,23 +132,19 @@ dlgCreditsShowModal([[maybe_unused]] UI::SingleWindow &parent) const DialogLook &look = UIGlobals::GetDialogLook(); const auto authors = InflateToString(AUTHORS_gz, AUTHORS_gz_size); - const UTF8ToWideConverter authors2(authors.c_str()); - - const auto news = InflateToString(NEWS_txt_gz, NEWS_txt_gz_size); - const UTF8ToWideConverter news2(news.c_str()); - + const auto news = + InflateToString(OpenSoar_News_md_gz, OpenSoar_News_md_gz_size); const auto license = InflateToString(COPYING_gz, COPYING_gz_size); - const UTF8ToWideConverter license2(license.c_str()); - + WidgetDialog dialog(WidgetDialog::Full{}, UIGlobals::GetMainWindow(), look, _("Credits")); auto pager = std::make_unique(look.button, dialog.MakeModalResultCallback(mrOK)); pager->Add(std::make_unique(CreateLogoPage)); - pager->Add(std::make_unique(look, authors2)); - pager->Add(std::make_unique(look, news2)); - pager->Add(std::make_unique(look, license2)); + pager->Add(std::make_unique(look, authors.c_str())); + pager->Add(std::make_unique(look, news.c_str())); + pager->Add(std::make_unique(look, license.c_str())); dialog.FinishPreliminary(std::move(pager)); dialog.ShowModal(); diff --git a/src/Dialogs/dlgInfoBoxAccess.cpp b/src/Dialogs/dlgInfoBoxAccess.cpp index 80a50dbf2d9..4419af00e35 100644 --- a/src/Dialogs/dlgInfoBoxAccess.cpp +++ b/src/Dialogs/dlgInfoBoxAccess.cpp @@ -59,7 +59,7 @@ dlgInfoBoxAccessShowModeless(const int id, const InfoBoxPanel *panels) if (widget == NULL) continue; - if (!found_setup && StringIsEqual(panels->name, _T("Setup"))) { + if (!found_setup && StringIsEqual(panels->name, "Setup")) { /* add a "Switch InfoBox" button to the "Setup" tab - kludge! */ found_setup = true; diff --git a/src/Dialogs/dlgQuickMenu.cpp b/src/Dialogs/dlgQuickMenu.cpp index e8ca8b87287..f24e5403bf9 100644 --- a/src/Dialogs/dlgQuickMenu.cpp +++ b/src/Dialogs/dlgQuickMenu.cpp @@ -31,7 +31,7 @@ class QuickMenuButtonRenderer final : public ButtonRenderer { public: explicit QuickMenuButtonRenderer(const DialogLook &_look, - const TCHAR *_caption) noexcept + const char *_caption) noexcept :look(_look), caption(_caption) { text_renderer.SetCenter(); text_renderer.SetVCenter(); @@ -149,7 +149,7 @@ QuickMenu::Prepare(ContainerWindow &parent, const PixelRect &rc) noexcept if (!menuItem.IsDefined()) continue; - TCHAR buffer[100]; + char buffer[100]; const auto expanded = ButtonLabel::Expand(menuItem.label, std::span{buffer}); if (!expanded.visible) @@ -185,7 +185,7 @@ QuickMenu::UpdateCaption() noexcept StaticString<32> buffer; unsigned pageSize = GetWindow().GetNumColumns() * grid_view.GetNumRows(); unsigned lastPage = buttons.size() / pageSize; - buffer.Format(_T("Quick Menu %d/%d"), + buffer.Format("Quick Menu %d/%d", grid_view.GetCurrentPage() + 1, lastPage + 1); dialog.SetCaption(buffer); } @@ -211,6 +211,10 @@ QuickMenu::SetFocus() noexcept if (centerPos >= buttons.size()) return false; + while ((centerPos > 0) && + !(buttons[centerPos].IsDefined() && buttons[centerPos].IsEnabled())) + centerPos--; + buttons[centerPos].SetFocus(); grid_view.RefreshLayout(); return true; @@ -267,10 +271,10 @@ ShowQuickMenu(UI::SingleWindow &parent, const Menu &menu) noexcept return dialog.GetWidget().clicked_event; } -void -dlgQuickMenuShowModal(UI::SingleWindow &parent) noexcept +void dlgQuickMenuShowModal(UI::SingleWindow &parent, + [[maybe_unused]] const char *mode) noexcept { - const auto *menu = InputEvents::GetMenu(_T("RemoteStick")); + const auto *menu = InputEvents::GetMenu("RemoteStick"); if (menu == nullptr) return; diff --git a/src/Dialogs/dlgStatus.cpp b/src/Dialogs/dlgStatus.cpp index 8d2b5f81111..30e5e379dbe 100644 --- a/src/Dialogs/dlgStatus.cpp +++ b/src/Dialogs/dlgStatus.cpp @@ -25,7 +25,7 @@ static void SetTitle(WndForm &form, const TabWidget &pager) { StaticString<128> title; - title.Format(_T("%s: %s"), _("Status"), + title.Format("%s: %s", _("Status"), pager.GetButtonCaption(pager.GetCurrentIndex())); form.SetCaption(title); } diff --git a/src/Engine/Airspace/AbstractAirspace.cpp b/src/Engine/Airspace/AbstractAirspace.cpp index a85c8f0f178..1cba550a2c8 100644 --- a/src/Engine/Airspace/AbstractAirspace.cpp +++ b/src/Engine/Airspace/AbstractAirspace.cpp @@ -170,9 +170,9 @@ AbstractAirspace::Intercept(const AircraftState &state, } bool -AbstractAirspace::MatchNamePrefix(const TCHAR *prefix) const noexcept +AbstractAirspace::MatchNamePrefix(const char *prefix) const noexcept { - size_t prefix_length = _tcslen(prefix); + size_t prefix_length = strlen(prefix); return StringIsEqualIgnoreCase(name.c_str(), prefix, prefix_length); } diff --git a/src/Engine/Airspace/AbstractAirspace.hpp b/src/Engine/Airspace/AbstractAirspace.hpp index 1321164c4c8..44612cb1189 100644 --- a/src/Engine/Airspace/AbstractAirspace.hpp +++ b/src/Engine/Airspace/AbstractAirspace.hpp @@ -4,7 +4,7 @@ #pragma once #include "util/TriState.hpp" -#include "util/tstring.hpp" +#include #include "AirspaceAltitude.hpp" #include "AirspaceClass.hpp" #include "AirspaceActivity.hpp" @@ -52,10 +52,10 @@ class AbstractAirspace { AirspaceAltitude altitude_top; /** Airspace name (identifier) */ - tstring name; + std::string name; /** Airspace type */ - tstring astype; + std::string astype; /** Radio frequency (optional) */ RadioFrequency radio_frequency = RadioFrequency::Null(); @@ -197,8 +197,8 @@ class AbstractAirspace { * @param _base Lower limit * @param _top Upper limit */ - void SetProperties(tstring &&_name, const AirspaceClass _class, - tstring &&_type, + void SetProperties(std::string &&_name, const AirspaceClass _class, + std::string &&_type, const AirspaceAltitude &_base, const AirspaceAltitude &_top) noexcept { name = std::move(_name); @@ -241,7 +241,7 @@ class AbstractAirspace { * @return Type as text of airspace */ [[gnu::pure]] - const TCHAR *GetType() const noexcept { + const char *GetType() const noexcept { return astype.c_str(); } @@ -320,7 +320,7 @@ class AbstractAirspace { #endif [[gnu::pure]] - const TCHAR *GetName() const noexcept { + const char *GetName() const noexcept { return name.c_str(); } @@ -328,7 +328,7 @@ class AbstractAirspace { * Returns true if the name begins with the specified string. */ [[gnu::pure]] - bool MatchNamePrefix(const TCHAR *prefix) const noexcept; + bool MatchNamePrefix(const char *prefix) const noexcept; [[gnu::pure]] RadioFrequency GetRadioFrequency() const noexcept { diff --git a/src/Engine/Airspace/AirspaceSorter.hpp b/src/Engine/Airspace/AirspaceSorter.hpp index dad66f9ffcc..5fb6d197936 100644 --- a/src/Engine/Airspace/AirspaceSorter.hpp +++ b/src/Engine/Airspace/AirspaceSorter.hpp @@ -58,7 +58,7 @@ struct AirspaceFilterData { /** * Show only airspaces with a name beginning with this string. */ - const TCHAR *name_prefix = nullptr; + const char *name_prefix = nullptr; /** * Show only airspaces with a direction deviating less than 18 diff --git a/src/Engine/CMakeLists.txt b/src/Engine/CMakeLists.txt new file mode 100644 index 00000000000..bedfef1ae46 --- /dev/null +++ b/src/Engine/CMakeLists.txt @@ -0,0 +1,54 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +list(APPEND CMakeSource.cmake) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) + +target_link_libraries(${TARGET_NAME} Geo) +add_dependencies(${TARGET_NAME} Geo) diff --git a/src/Engine/CMakeSource.cmake b/src/Engine/CMakeSource.cmake new file mode 100644 index 00000000000..77b1ef36f1a --- /dev/null +++ b/src/Engine/CMakeSource.cmake @@ -0,0 +1,158 @@ +set(_SOURCES + Engine/Airspace/AbstractAirspace.cpp + Engine/Airspace/Airspace.cpp + Engine/Airspace/AirspaceAircraftPerformance.cpp + Engine/Airspace/AirspaceAltitude.cpp + Engine/Airspace/AirspaceCircle.cpp + Engine/Airspace/AirspaceIntersectionVisitor.cpp + Engine/Airspace/AirspaceIntersectSort.cpp + Engine/Airspace/AirspacePolygon.cpp + Engine/Airspace/Airspaces.cpp + Engine/Airspace/AirspaceSorter.cpp + Engine/Airspace/AirspacesTerrain.cpp + Engine/Airspace/AirspaceWarning.cpp + Engine/Airspace/AirspaceWarningConfig.cpp + Engine/Airspace/AirspaceWarningManager.cpp + # Engine/Airspace/Predicate/AirspacePredicate.cpp + Engine/Airspace/Predicate/AirspacePredicateHeightRange.cpp + Engine/Airspace/Predicate/OutsideAirspacePredicate.cpp + Engine/Airspace/SoonestAirspace.cpp + Engine/Contest/ContestManager.cpp + Engine/Contest/Settings.cpp + Engine/Contest/Solvers/AbstractContest.cpp + Engine/Contest/Solvers/ContestDijkstra.cpp + Engine/Contest/Solvers/Contests.cpp + Engine/Contest/Solvers/Charron.cpp + Engine/Contest/Solvers/DMStQuad.cpp + Engine/Contest/Solvers/NetCoupe.cpp + Engine/Contest/Solvers/OLCClassic.cpp + Engine/Contest/Solvers/OLCFAI.cpp + Engine/Contest/Solvers/OLCLeague.cpp + Engine/Contest/Solvers/OLCPlus.cpp + Engine/Contest/Solvers/OLCSISAT.cpp + Engine/Contest/Solvers/OLCSprint.cpp + Engine/Contest/Solvers/OLCTriangleRules.cpp # branch cmake OLCTriangle ->OLCTriangleRules + Engine/Contest/Solvers/WeglideDistance.cpp + Engine/Contest/Solvers/WeglideOR.cpp + Engine/Contest/Solvers/WeglideFree.cpp + Engine/Contest/Solvers/WeglideFAI.cpp + Engine/Contest/Solvers/TriangleContest.cpp + Engine/Contest/Solvers/Retrospective.cpp + Engine/Contest/Solvers/TraceManager.cpp + Engine/Contest/Solvers/XContestFree.cpp + Engine/Contest/Solvers/XContestTriangle.cpp + Engine/GlideSolvers/GlidePolar.cpp + Engine/GlideSolvers/GlideResult.cpp + Engine/GlideSolvers/GlideSettings.cpp + Engine/GlideSolvers/GlideState.cpp + Engine/GlideSolvers/GlueGlideState.cpp + Engine/GlideSolvers/InstantSpeed.cpp + Engine/GlideSolvers/MacCready.cpp + Engine/Navigation/Aircraft.cpp + Engine/Navigation/TraceHistory.cpp + Engine/Route/AirspaceRoute.cpp + Engine/Route/Config.cpp + Engine/Route/FlatTriangleFan.cpp + Engine/Route/FlatTriangleFanTree.cpp + Engine/Route/ReachFan.cpp + Engine/Route/RouteLink.cpp + Engine/Route/RoutePlanner.cpp + Engine/Route/RoutePolar.cpp + Engine/Route/RoutePolars.cpp + Engine/Route/TerrainRoute.cpp + Engine/Task/AbstractTask.cpp + Engine/Task/Computer/DistanceStatComputer.cpp + Engine/Task/Computer/ElementStatComputer.cpp + Engine/Task/Computer/IncrementalSpeedComputer.cpp + Engine/Task/Computer/TaskStatsComputer.cpp + Engine/Task/Computer/TaskVarioComputer.cpp + Engine/Task/Computer/WindowStatsComputer.cpp + Engine/Task/Factory/AATTaskFactory.cpp + Engine/Task/Factory/AbstractTaskFactory.cpp + Engine/Task/Factory/Create.cpp + Engine/Task/Factory/FAIGoalTaskFactory.cpp + Engine/Task/Factory/FAIORTaskFactory.cpp + Engine/Task/Factory/FAITaskFactory.cpp + Engine/Task/Factory/FAITriangleTaskFactory.cpp + Engine/Task/Factory/MatTaskFactory.cpp + Engine/Task/Factory/MixedTaskFactory.cpp + Engine/Task/Factory/RTTaskFactory.cpp + Engine/Task/Factory/TouringTaskFactory.cpp + Engine/Task/ObservationZones/AnnularSectorZone.cpp + Engine/Task/ObservationZones/Boundary.cpp + Engine/Task/ObservationZones/CylinderZone.cpp + Engine/Task/ObservationZones/KeyholeZone.cpp + Engine/Task/ObservationZones/LineSectorZone.cpp + Engine/Task/ObservationZones/ObservationZoneClient.cpp + Engine/Task/ObservationZones/ObservationZonePoint.cpp + Engine/Task/ObservationZones/SectorZone.cpp + Engine/Task/ObservationZones/SymmetricSectorZone.cpp + Engine/Task/Ordered/AATIsoline.cpp + Engine/Task/Ordered/AATIsolineSegment.cpp + Engine/Task/Ordered/FinishConstraints.cpp + Engine/Task/Ordered/OrderedTask.cpp + Engine/Task/Ordered/Points/AATPoint.cpp + Engine/Task/Ordered/Points/ASTPoint.cpp + Engine/Task/Ordered/Points/FinishPoint.cpp + Engine/Task/Ordered/Points/IntermediatePoint.cpp + Engine/Task/Ordered/Points/OrderedTaskPoint.cpp + Engine/Task/Ordered/Points/StartPoint.cpp + Engine/Task/Ordered/Settings.cpp + Engine/Task/Ordered/SmartTaskAdvance.cpp + Engine/Task/Ordered/StartConstraints.cpp + Engine/Task/Ordered/TaskAdvance.cpp + Engine/Task/PathSolvers/IsolineCrossingFinder.cpp + Engine/Task/PathSolvers/TaskDijkstra.cpp + Engine/Task/PathSolvers/TaskDijkstraMax.cpp + Engine/Task/PathSolvers/TaskDijkstraMin.cpp + Engine/Task/Points/SampledTaskPoint.cpp + Engine/Task/Points/ScoredTaskPoint.cpp + Engine/Task/Points/TaskLeg.cpp + Engine/Task/Points/TaskPoint.cpp + Engine/Task/Shapes/FAITriangleArea.cpp + Engine/Task/Shapes/FAITrianglePointValidator.cpp + Engine/Task/Shapes/FAITriangleRules.cpp + Engine/Task/Shapes/FAITriangleSettings.cpp + Engine/Task/Shapes/FAITriangleTask.cpp + Engine/Task/Solvers/TaskBestMc.cpp + Engine/Task/Solvers/TaskCruiseEfficiency.cpp + Engine/Task/Solvers/TaskEffectiveMacCready.cpp + Engine/Task/Solvers/TaskGlideRequired.cpp + Engine/Task/Solvers/TaskMacCready.cpp + Engine/Task/Solvers/TaskMacCreadyRemaining.cpp + Engine/Task/Solvers/TaskMacCreadyTotal.cpp + Engine/Task/Solvers/TaskMacCreadyTravelled.cpp + Engine/Task/Solvers/TaskMinTarget.cpp + Engine/Task/Solvers/TaskOptTarget.cpp + Engine/Task/Solvers/TaskSolution.cpp + Engine/Task/Solvers/TaskSolveTravelled.cpp + Engine/Task/Stats/CommonStats.cpp + Engine/Task/Stats/ElementStat.cpp + Engine/Task/Stats/StartStats.cpp + Engine/Task/Stats/TaskStats.cpp + Engine/Task/TaskBehaviour.cpp + Engine/Task/TaskManager.cpp + Engine/Task/Unordered/AbortTask.cpp + Engine/Task/Unordered/AlternateTask.cpp + Engine/Task/Unordered/GotoTask.cpp + Engine/Task/Unordered/UnorderedTask.cpp + Engine/Task/Unordered/UnorderedTaskPoint.cpp + Engine/ThermalBand/ThermalBand.cpp + Engine/ThermalBand/ThermalEncounterBand.cpp + Engine/ThermalBand/ThermalEncounterCollection.cpp + Engine/ThermalBand/ThermalSlice.cpp + Engine/Trace/Point.cpp + Engine/Trace/Trace.cpp + Engine/Trace/Vector.cpp + Engine/Util/AircraftStateFilter.cpp + Engine/Util/Gradient.cpp + Engine/Waypoint/Waypoint.cpp + Engine/Waypoint/Waypoints.cpp +# Engine/Waypoint/WaypointVisitor.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake +) + + diff --git a/src/Engine/Contest/Solvers/Contests.cpp b/src/Engine/Contest/Solvers/Contests.cpp index 2eb4e4736a0..3403d6029b8 100644 --- a/src/Engine/Contest/Solvers/Contests.cpp +++ b/src/Engine/Contest/Solvers/Contests.cpp @@ -4,26 +4,26 @@ #include "Contests.hpp" #include "util/Macros.hpp" -static const TCHAR *const contest_to_string[] = { - _T("OLC Sprint"), - _T("OLC FAI"), - _T("OLC Classic"), - _T("OLC League"), - _T("OLC Plus"), - _T("XContest"), - _T("DHV-XC"), - _T("SIS-AT"), - _T("FFVV NetCoupe"), - _T("DMSt"), - _T("WeGlide FREE"), - _T("WeGlide Distance"), - _T("WeGlide FAI"), - _T("WeGlide O&R"), - _T("Charron"), - _T("None"), +static const char *const contest_to_string[] = { + "OLC Sprint", + "OLC FAI", + "OLC Classic", + "OLC League", + "OLC Plus", + "XContest", + "DHV-XC", + "SIS-AT", + "FFVV NetCoupe", + "DMSt", + "WeGlide FREE", + "WeGlide Distance", + "WeGlide FAI", + "WeGlide O&R", + "Charron", + "None", }; -const TCHAR* +const char* ContestToString(Contest contest) noexcept { unsigned i = (unsigned)contest; diff --git a/src/Engine/Contest/Solvers/Contests.hpp b/src/Engine/Contest/Solvers/Contests.hpp index d2566b83bc1..9bc162d330a 100644 --- a/src/Engine/Contest/Solvers/Contests.hpp +++ b/src/Engine/Contest/Solvers/Contests.hpp @@ -9,5 +9,5 @@ enum class Contest : uint8_t; [[gnu::const]] -const TCHAR * +const char * ContestToString(Contest contest) noexcept; diff --git a/src/Engine/Waypoint/Waypoint.hpp b/src/Engine/Waypoint/Waypoint.hpp index 63e0c752cfe..a016f31cb23 100644 --- a/src/Engine/Waypoint/Waypoint.hpp +++ b/src/Engine/Waypoint/Waypoint.hpp @@ -4,7 +4,7 @@ #pragma once #include "Origin.hpp" -#include "util/tstring.hpp" +#include #include "Geo/GeoPoint.hpp" #include "Geo/Flat/FlatGeoPoint.hpp" #include "RadioFrequency.hpp" @@ -80,19 +80,19 @@ struct Waypoint { double elevation; /** Short name (code) label of waypoint */ - tstring shortname; + std::string shortname; /** Name of waypoint */ - tstring name; + std::string name; /** Additional comment text for waypoint */ - tstring comment; + std::string comment; /** Airfield or additional (long) details */ - tstring details; + std::string details; /** Additional files to be displayed in the WayointDetails dialog */ - std::forward_list files_embed; + std::forward_list files_embed; #ifdef HAVE_RUN_FILE /** Additional files to be opened by external programs */ - std::forward_list files_external; + std::forward_list files_external; #endif /** Unique id */ diff --git a/src/Engine/Waypoint/Waypoints.cpp b/src/Engine/Waypoint/Waypoints.cpp index cfabbd4b2df..a3e5230d94f 100644 --- a/src/Engine/Waypoint/Waypoints.cpp +++ b/src/Engine/Waypoint/Waypoints.cpp @@ -8,37 +8,37 @@ static constexpr std::size_t NORMALIZE_BUFFER_SIZE = 4096; inline WaypointPtr -Waypoints::WaypointNameTree::Get(tstring_view name) const noexcept +Waypoints::WaypointNameTree::Get(std::string_view name) const noexcept { if (name.size() >= NORMALIZE_BUFFER_SIZE) return {}; - TCHAR normalized_name[NORMALIZE_BUFFER_SIZE]; + char normalized_name[NORMALIZE_BUFFER_SIZE]; NormalizeSearchString(normalized_name, name); return RadixTree::Get(normalized_name, nullptr); } inline void -Waypoints::WaypointNameTree::VisitNormalisedPrefix(tstring_view prefix, +Waypoints::WaypointNameTree::VisitNormalisedPrefix(std::string_view prefix, const WaypointVisitor &visitor) const { if (prefix.size() >= NORMALIZE_BUFFER_SIZE) return; - TCHAR normalized[NORMALIZE_BUFFER_SIZE]; + char normalized[NORMALIZE_BUFFER_SIZE]; NormalizeSearchString(normalized, prefix); VisitPrefix(normalized, visitor); } -TCHAR * -Waypoints::WaypointNameTree::SuggestNormalisedPrefix(tstring_view prefix, - TCHAR *dest, +char * +Waypoints::WaypointNameTree::SuggestNormalisedPrefix(std::string_view prefix, + char *dest, size_t max_length) const noexcept { if (prefix.size() >= NORMALIZE_BUFFER_SIZE) return nullptr; - TCHAR normalized[NORMALIZE_BUFFER_SIZE]; + char normalized[NORMALIZE_BUFFER_SIZE]; NormalizeSearchString(normalized, prefix); return Suggest(normalized, dest, max_length); } @@ -46,7 +46,7 @@ Waypoints::WaypointNameTree::SuggestNormalisedPrefix(tstring_view prefix, inline void Waypoints::WaypointNameTree::Add(WaypointPtr wp) noexcept { - AllocatedArray buffer(wp->name.length() + 1); + AllocatedArray buffer(wp->name.length() + 1); NormalizeSearchString(buffer.data(), wp->name); RadixTree::Add(buffer.data(), wp); @@ -60,7 +60,7 @@ Waypoints::WaypointNameTree::Add(WaypointPtr wp) noexcept inline void Waypoints::WaypointNameTree::Remove(const WaypointPtr &wp) noexcept { - AllocatedArray buffer(wp->name.length() + 1); + AllocatedArray buffer(wp->name.length() + 1); NormalizeSearchString(buffer.data(), wp->name); RadixTree::Remove(buffer.data(), wp); @@ -166,7 +166,7 @@ Waypoints::GetNearestIf(const GeoPoint &loc, double range, } WaypointPtr -Waypoints::LookupName(tstring_view name) const noexcept +Waypoints::LookupName(std::string_view name) const noexcept { return name_tree.Get(name); } @@ -237,7 +237,7 @@ Waypoints::VisitWithinRange(const GeoPoint &loc, const double range, } void -Waypoints::VisitNamePrefix(tstring_view prefix, +Waypoints::VisitNamePrefix(std::string_view prefix, WaypointVisitor visitor) const { name_tree.VisitNormalisedPrefix(prefix, visitor); @@ -349,7 +349,7 @@ Waypoints::GenerateTakeoffPoint(const GeoPoint& location, Waypoint to_point(location); to_point.elevation = terrain_alt; to_point.has_elevation = true; - to_point.name = _T("(takeoff)"); + to_point.name = "(takeoff)"; to_point.type = Waypoint::Type::OUTLANDING; return to_point; } @@ -359,7 +359,7 @@ Waypoints::AddTakeoffPoint(const GeoPoint& location, const double terrain_alt) noexcept { // remove old one first - WaypointPtr old_takeoff_point = LookupName(_T("(takeoff)")); + WaypointPtr old_takeoff_point = LookupName("(takeoff)"); if (old_takeoff_point != nullptr) Erase(std::move(old_takeoff_point)); diff --git a/src/Engine/Waypoint/Waypoints.hpp b/src/Engine/Waypoint/Waypoints.hpp index 0b6f49458cc..fb4eaec2995 100644 --- a/src/Engine/Waypoint/Waypoints.hpp +++ b/src/Engine/Waypoint/Waypoints.hpp @@ -9,7 +9,7 @@ #include "util/RadixTree.hpp" #include "util/QuadTree.hxx" #include "util/Serial.hpp" -#include "util/tstring_view.hxx" +#include #include @@ -44,11 +44,11 @@ class Waypoints { class WaypointNameTree : public RadixTree { public: [[gnu::pure]] - WaypointPtr Get(tstring_view name) const noexcept; + WaypointPtr Get(std::string_view name) const noexcept; - void VisitNormalisedPrefix(tstring_view prefix, const WaypointVisitor &visitor) const; - TCHAR *SuggestNormalisedPrefix(tstring_view prefix, - TCHAR *dest, size_t max_length) const noexcept; + void VisitNormalisedPrefix(std::string_view prefix, const WaypointVisitor &visitor) const; + char *SuggestNormalisedPrefix(std::string_view prefix, + char *dest, size_t max_length) const noexcept; void Add(WaypointPtr wp) noexcept; void Remove(const WaypointPtr &wp) noexcept; }; @@ -254,7 +254,7 @@ class Waypoints { * @return Pointer to waypoint if found (or nullptr if not) */ [[gnu::pure]] - WaypointPtr LookupName(tstring_view name) const noexcept; + WaypointPtr LookupName(std::string_view name) const noexcept; /** * Check if a waypoint with same name and approximate location @@ -282,15 +282,15 @@ class Waypoints { * Call visitor function on waypoints with the specified name * prefix. */ - void VisitNamePrefix(tstring_view prefix, WaypointVisitor visitor) const; + void VisitNamePrefix(std::string_view prefix, WaypointVisitor visitor) const; /** * Returns a set of possible characters following the specified * prefix. */ [[gnu::pure]] - TCHAR *SuggestNamePrefix(tstring_view prefix, - TCHAR *dest, size_t max_length) const noexcept { + char *SuggestNamePrefix(std::string_view prefix, + char *dest, size_t max_length) const noexcept { return name_tree.SuggestNormalisedPrefix(prefix, dest, max_length); } diff --git a/src/FLARM/CMakeLists.txt b/src/FLARM/CMakeLists.txt new file mode 100644 index 00000000000..5189981d861 --- /dev/null +++ b/src/FLARM/CMakeLists.txt @@ -0,0 +1,51 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +target_link_libraries(${TARGET_NAME} PUBLIC Computer Profile) + +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/FLARM/CMakeSource.cmake b/src/FLARM/CMakeSource.cmake new file mode 100644 index 00000000000..8379011c530 --- /dev/null +++ b/src/FLARM/CMakeSource.cmake @@ -0,0 +1,24 @@ +set(_SOURCES + FLARM/Error.cpp + FLARM/Calculations.cpp + FLARM/Computer.cpp + FLARM/Details.cpp + FLARM/Id.cpp + FLARM/FlarmNetDatabase.cpp + FLARM/FlarmNetReader.cpp + FLARM/FlarmNetRecord.cpp + FLARM/Friends.cpp + FLARM/Global.cpp + FLARM/Glue.cpp + FLARM/List.cpp + FLARM/NameDatabase.cpp + FLARM/NameFile.cpp + FLARM/Traffic.cpp + FLARM/TrafficDatabases.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake +) + + diff --git a/src/FLARM/Computer.cpp b/src/FLARM/Computer.cpp index 2b1323a8709..09e577c70fc 100644 --- a/src/FLARM/Computer.cpp +++ b/src/FLARM/Computer.cpp @@ -47,7 +47,7 @@ FlarmComputer::Process(FlarmData &flarm, const FlarmData &last_flarm, // if we don't know the target's name yet if (!traffic.HasName()) { // lookup the name of this target's id - const TCHAR *fname = FlarmDetails::LookupCallsign(traffic.id); + const char *fname = FlarmDetails::LookupCallsign(traffic.id); if (fname != NULL) traffic.name = fname; } diff --git a/src/FLARM/Details.cpp b/src/FLARM/Details.cpp index 907fc32a9ca..1317a36fb30 100644 --- a/src/FLARM/Details.cpp +++ b/src/FLARM/Details.cpp @@ -21,7 +21,7 @@ LookupRecord(FlarmId id) noexcept return traffic_databases->flarm_net.FindRecordById(id); } -const TCHAR * +const char * LookupCallsign(FlarmId id) noexcept { if (traffic_databases == nullptr) @@ -31,7 +31,7 @@ LookupCallsign(FlarmId id) noexcept } FlarmId -LookupId(const TCHAR *cn) noexcept +LookupId(const char *cn) noexcept { assert(traffic_databases != nullptr); @@ -39,7 +39,7 @@ LookupId(const TCHAR *cn) noexcept } bool -AddSecondaryItem(FlarmId id, const TCHAR *name) noexcept +AddSecondaryItem(FlarmId id, const char *name) noexcept { assert(id.IsDefined()); assert(traffic_databases != nullptr); @@ -48,7 +48,7 @@ AddSecondaryItem(FlarmId id, const TCHAR *name) noexcept } unsigned -FindIdsByCallSign(const TCHAR *cn, FlarmId array[], unsigned size) noexcept +FindIdsByCallSign(const char *cn, FlarmId array[], unsigned size) noexcept { assert(cn != NULL); assert(!StringIsEmpty(cn)); diff --git a/src/FLARM/Details.hpp b/src/FLARM/Details.hpp index 20b8e5ca7f6..b508f8e6520 100644 --- a/src/FLARM/Details.hpp +++ b/src/FLARM/Details.hpp @@ -27,7 +27,7 @@ LookupRecord(FlarmId id) noexcept; * @return The corresponding callsign if found, otherwise NULL */ [[gnu::pure]] -const TCHAR * +const char * LookupCallsign(FlarmId id) noexcept; /** @@ -38,7 +38,7 @@ LookupCallsign(FlarmId id) noexcept; */ [[gnu::pure]] FlarmId -LookupId(const TCHAR *cn) noexcept; +LookupId(const char *cn) noexcept; /** * Adds a FLARM details couple (callsign + FLARM id) @@ -48,9 +48,9 @@ LookupId(const TCHAR *cn) noexcept; * @return True if successfully added, False otherwise */ bool -AddSecondaryItem(FlarmId id, const TCHAR *name) noexcept; +AddSecondaryItem(FlarmId id, const char *name) noexcept; unsigned -FindIdsByCallSign(const TCHAR *cn, FlarmId array[], unsigned size) noexcept; +FindIdsByCallSign(const char *cn, FlarmId array[], unsigned size) noexcept; } // namespace FlarmDetails diff --git a/src/FLARM/Error.cpp b/src/FLARM/Error.cpp index 54ebcc3ee92..f87c3f394ad 100644 --- a/src/FLARM/Error.cpp +++ b/src/FLARM/Error.cpp @@ -5,14 +5,14 @@ #include "util/Macros.hpp" #include "Language/Language.hpp" -static const TCHAR *const severity_strings[] = { +static const char *const severity_strings[] = { N_("No error"), N_("Information"), N_("Reduced functionality"), N_("Fatal problem"), }; -const TCHAR * +const char * FlarmError::ToString(Severity severity) noexcept { unsigned i = (unsigned)severity; @@ -23,7 +23,7 @@ FlarmError::ToString(Severity severity) noexcept static constexpr struct { FlarmError::Code code; - const TCHAR *string; + const char *string; } error_strings[] = { { FlarmError::Code::FIRMWARE_TIMEOUT, N_("Firmware timeout") }, { FlarmError::Code::POWER, N_("Power") }, @@ -41,7 +41,7 @@ static constexpr struct { { FlarmError::Code::OTHER, nullptr } }; -const TCHAR * +const char * FlarmError::ToString(Code code) noexcept { for (auto i = error_strings; i->string != nullptr; ++i) diff --git a/src/FLARM/Error.hpp b/src/FLARM/Error.hpp index ef42478290e..8115c2ac664 100644 --- a/src/FLARM/Error.hpp +++ b/src/FLARM/Error.hpp @@ -74,7 +74,7 @@ struct FlarmError { * value. */ [[gnu::const]] - static const TCHAR *ToString(Severity severity) noexcept; + static const char *ToString(Severity severity) noexcept; /** * Returns a human-readable translatable string for the given value. @@ -82,15 +82,15 @@ struct FlarmError { * value. */ [[gnu::const]] - static const TCHAR *ToString(Code code) noexcept; + static const char *ToString(Code code) noexcept; [[gnu::pure]] - const TCHAR *GetSeverityString() const noexcept { + const char *GetSeverityString() const noexcept { return ToString(severity); } [[gnu::pure]] - const TCHAR *GetCodeString() const noexcept { + const char *GetCodeString() const noexcept { return ToString(code); } }; diff --git a/src/FLARM/FlarmNetDatabase.cpp b/src/FLARM/FlarmNetDatabase.cpp index 2790a396259..1a9c44c6363 100644 --- a/src/FLARM/FlarmNetDatabase.cpp +++ b/src/FLARM/FlarmNetDatabase.cpp @@ -18,7 +18,7 @@ FlarmNetDatabase::Insert(const FlarmNetRecord &record) noexcept } const FlarmNetRecord * -FlarmNetDatabase::FindFirstRecordByCallSign(const TCHAR *cn) const noexcept +FlarmNetDatabase::FindFirstRecordByCallSign(const char *cn) const noexcept { for (const auto &[id, record] : map) { assert(id.IsDefined()); @@ -31,7 +31,7 @@ FlarmNetDatabase::FindFirstRecordByCallSign(const TCHAR *cn) const noexcept } unsigned -FlarmNetDatabase::FindRecordsByCallSign(const TCHAR *cn, +FlarmNetDatabase::FindRecordsByCallSign(const char *cn, const FlarmNetRecord *array[], [[maybe_unused]] unsigned size) const noexcept { @@ -48,7 +48,7 @@ FlarmNetDatabase::FindRecordsByCallSign(const TCHAR *cn, } unsigned -FlarmNetDatabase::FindIdsByCallSign(const TCHAR *cn, FlarmId array[], +FlarmNetDatabase::FindIdsByCallSign(const char *cn, FlarmId array[], [[maybe_unused]] unsigned size) const noexcept { unsigned count = 0; diff --git a/src/FLARM/FlarmNetDatabase.hpp b/src/FLARM/FlarmNetDatabase.hpp index 63cf07abd6c..ee0a6d5a21d 100644 --- a/src/FLARM/FlarmNetDatabase.hpp +++ b/src/FLARM/FlarmNetDatabase.hpp @@ -46,12 +46,12 @@ class FlarmNetDatabase { * @return FLARMNetRecord object */ [[gnu::pure]] - const FlarmNetRecord *FindFirstRecordByCallSign(const TCHAR *cn) const noexcept; + const FlarmNetRecord *FindFirstRecordByCallSign(const char *cn) const noexcept; - unsigned FindRecordsByCallSign(const TCHAR *cn, + unsigned FindRecordsByCallSign(const char *cn, const FlarmNetRecord *array[], unsigned size) const noexcept; - unsigned FindIdsByCallSign(const TCHAR *cn, FlarmId array[], + unsigned FindIdsByCallSign(const char *cn, FlarmId array[], unsigned size) const noexcept; [[gnu::pure]] diff --git a/src/FLARM/FlarmNetReader.cpp b/src/FLARM/FlarmNetReader.cpp index 5f0277ec908..351de62753c 100644 --- a/src/FLARM/FlarmNetReader.cpp +++ b/src/FLARM/FlarmNetReader.cpp @@ -9,10 +9,7 @@ #include "io/LineReader.hpp" #include "io/FileLineReader.hpp" -#ifndef _UNICODE #include "util/UTF8.hpp" -#endif - #include #include @@ -24,15 +21,12 @@ * @param res Pointer to be written in */ static void -LoadString(const char *bytes, size_t length, TCHAR *res, [[maybe_unused]] size_t res_size) +LoadString(const char *bytes, size_t length, char *res, [[maybe_unused]] size_t res_size) { const char *const end = bytes + length * 2; - -#ifndef _UNICODE const char *const limit = res + res_size - 2; -#endif - TCHAR *p = res; + char *p = res; char tmp[3]; tmp[2] = 0; @@ -44,24 +38,17 @@ LoadString(const char *bytes, size_t length, TCHAR *res, [[maybe_unused]] size_t /* FLARMNet files are ISO-Latin-1, which is kind of short-sighted */ const unsigned char ch = (unsigned char)strtoul(tmp, NULL, 16); -#ifdef _UNICODE - /* Latin-1 can be converted to WIN32 wchar_t by casting */ - *p++ = ch; -#else /* convert to UTF-8 on all other platforms */ if (p >= limit) break; p = Latin1ToUTF8(ch, p); -#endif } *p = 0; -#ifndef _UNICODE assert(ValidateUTF8(res)); -#endif // Trim the string of any additional spaces StripRight(res); @@ -95,9 +82,9 @@ LoadRecord(FlarmNetRecord &record, const char *line) LoadString(line + 158, 7, record.frequency); // Terminate callsign string on first whitespace - for (TCHAR *i = record.callsign.buffer(); *i != _T('\0'); ++i) + for (char *i = record.callsign.buffer(); *i != '\0'; ++i) if (IsWhitespaceFast(*i)) - *i = _T('\0'); + *i = '\0'; return true; } diff --git a/src/FLARM/FlarmNetRecord.hpp b/src/FLARM/FlarmNetRecord.hpp index 7a894848d98..cf84d6f768f 100644 --- a/src/FLARM/FlarmNetRecord.hpp +++ b/src/FLARM/FlarmNetRecord.hpp @@ -10,15 +10,9 @@ class FlarmId; static constexpr std::size_t LatinBufferSize(std::size_t size) noexcept { -#ifdef _UNICODE -/* with wide characters, the exact size of the FLARMNet database field - (plus one for the terminator) is just right, ... */ - return size; -#else /* ..., but when we convert Latin-1 to UTF-8, we need a little bit more buffer */ return size * 3 / 2 + 1; -#endif } /** diff --git a/src/FLARM/Glue.cpp b/src/FLARM/Glue.cpp index 9f84e212fb3..5e12434cdf8 100644 --- a/src/FLARM/Glue.cpp +++ b/src/FLARM/Glue.cpp @@ -50,7 +50,7 @@ LoadSecondary(FlarmNameDatabase &db) noexcept try { LogString("OpenFLARMDetails"); - auto reader = OpenDataFile(_T("xcsoar-flarm.txt")); + auto reader = OpenDataFile("xcsoar-flarm.txt"); BufferedReader buffered_reader{*reader}; LoadFlarmNameFile(buffered_reader, db); } catch (...) { @@ -96,7 +96,7 @@ SaveFlarmColors() noexcept static void SaveSecondary(FlarmNameDatabase &flarm_names) noexcept try { - FileOutputStream fos(LocalPath(_T("xcsoar-flarm.txt"))); + FileOutputStream fos(LocalPath("xcsoar-flarm.txt")); BufferedOutputStream bos(fos); SaveFlarmNameFile(bos, flarm_names); bos.Flush(); diff --git a/src/FLARM/Id.cpp b/src/FLARM/Id.cpp index 1b28a6b5cdb..962b273ccc1 100644 --- a/src/FLARM/Id.cpp +++ b/src/FLARM/Id.cpp @@ -5,10 +5,6 @@ #include -#ifdef _UNICODE -#include -#endif - #include FlarmId @@ -17,14 +13,6 @@ FlarmId::Parse(const char *input, char **endptr_r) noexcept return FlarmId(strtol(input, endptr_r, 16)); } -#ifdef _UNICODE -FlarmId -FlarmId::Parse(const TCHAR *input, TCHAR **endptr_r) noexcept -{ - return FlarmId(_tcstol(input, endptr_r, 16)); -} -#endif - const char * FlarmId::Format(char *buffer) const noexcept { @@ -32,11 +20,3 @@ FlarmId::Format(char *buffer) const noexcept return buffer; } -#ifdef _UNICODE -const TCHAR * -FlarmId::Format(TCHAR *buffer) const noexcept -{ - *fmt::format_to(buffer, _T("{:X}"), value) = 0; - return buffer; -} -#endif diff --git a/src/FLARM/Id.hpp b/src/FLARM/Id.hpp index 7c4eb6faf72..a6ceff7ed3e 100644 --- a/src/FLARM/Id.hpp +++ b/src/FLARM/Id.hpp @@ -6,10 +6,6 @@ #include #include // for the defaulted spaceship operator -#ifdef _UNICODE -#include -#endif - /** * The identification number of a FLARM traffic. */ @@ -40,12 +36,6 @@ class FlarmId { const FlarmId &) noexcept = default; static FlarmId Parse(const char *input, char **endptr_r) noexcept; -#ifdef _UNICODE - static FlarmId Parse(const TCHAR *input, TCHAR **endptr_r) noexcept; -#endif const char *Format(char *buffer) const noexcept; -#ifdef _UNICODE - const TCHAR *Format(TCHAR *buffer) const noexcept; -#endif }; diff --git a/src/FLARM/List.hpp b/src/FLARM/List.hpp index 2020df72d18..da06a0ed140 100644 --- a/src/FLARM/List.hpp +++ b/src/FLARM/List.hpp @@ -9,6 +9,12 @@ #include +#if defined(__MSVC__) || defined(__clang__) // TODO(Augustr2111): make it ok +# define USE_LIST_ITERATOR 1 +#else +#define USE_LIST_ITERATOR 0 +#endif + /** * This class keeps track of the traffic objects received from a * FLARM. @@ -72,7 +78,7 @@ struct TrafficList { modified.Expire(clock, std::chrono::minutes(5)); new_traffic.Expire(clock, std::chrono::minutes(1)); - for (unsigned i = list.size(); i-- > 0;) + for (size_t i = list.size(); i-- > 0;) if (!list[i].Refresh(clock)) list.quick_remove(i); } @@ -115,7 +121,7 @@ struct TrafficList { * @param name the name or call sign * @return the FLARM_TRAFFIC pointer, NULL if not found */ - constexpr FlarmTraffic *FindTraffic(const TCHAR *name) noexcept { + constexpr FlarmTraffic *FindTraffic(const char *name) noexcept { for (auto &traffic : list) if (traffic.name.equals(name)) return &traffic; @@ -129,7 +135,7 @@ struct TrafficList { * @param name the name or call sign * @return the FLARM_TRAFFIC pointer, NULL if not found */ - constexpr const FlarmTraffic *FindTraffic(const TCHAR *name) const noexcept { + constexpr const FlarmTraffic *FindTraffic(const char *name) const noexcept { for (const auto &traffic : list) if (traffic.name.equals(name)) return &traffic; @@ -151,33 +157,45 @@ struct TrafficList { /** * Search for the previous traffic in the ordered list. */ - constexpr const FlarmTraffic *PreviousTraffic(const FlarmTraffic *t) const noexcept { - return t > list.begin() - ? t - 1 - : NULL; + constexpr const FlarmTraffic * + PreviousTraffic(const FlarmTraffic *t) const noexcept { + const FlarmTraffic *ret = nullptr; + for (auto const &iter : list) { + if (&iter == t) + return ret; // the previous + else + ret = &iter; + } + return nullptr; } /** * Search for the next traffic in the ordered list. */ - constexpr const FlarmTraffic *NextTraffic(const FlarmTraffic *t) const noexcept { - return t + 1 < list.end() - ? t + 1 - : NULL; + constexpr const FlarmTraffic * + NextTraffic(const FlarmTraffic *t) const noexcept { + bool found = false; + for (auto const &iter : list) { + if (&iter == t) + found = true; // and continue... + else if (found) + return &iter; // the next one in the list after t + } + return nullptr; } /** * Search for the first traffic in the ordered list. */ constexpr const FlarmTraffic *FirstTraffic() const noexcept { - return list.empty() ? NULL : list.begin(); + return list.empty() ? nullptr : &list.front(); } /** * Search for the last traffic in the ordered list. */ constexpr const FlarmTraffic *LastTraffic() const noexcept { - return list.empty() ? NULL : list.end() - 1; + return list.empty() ? nullptr : &list.back(); } /** @@ -188,7 +206,22 @@ struct TrafficList { const FlarmTraffic *FindMaximumAlert() const noexcept; constexpr unsigned TrafficIndex(const FlarmTraffic *t) const noexcept { +#if USE_LIST_ITERATOR // TODO(August2111): make it ok + #ifdef __clang__ + unsigned int i = 0; + for (const auto &traffic : list) { + if (traffic.id == t->id) + return i; + i++; + } + return 0; // TODO(August2111): This is wrong!!!! + #else // 0 vs. 1 + auto iter = std::find(list.begin(), list.end(), t); + return iter - list.begin(); + #endif // 0 vs. 1 +#else // __MSVC__ return t - list.begin(); +#endif // __MSVC__ } /** @@ -197,4 +230,28 @@ struct TrafficList { bool InCloseRange() const noexcept; }; + +#ifdef __MSVC__ +constexpr bool +operator==(const FlarmTraffic &t1, + const FlarmTraffic &t2) noexcept +{ + return t1.id == t2.id && t1.name == t2.name; +} + +constexpr bool +operator==(const FlarmTraffic t1, + const FlarmTraffic *t2) noexcept +{ + return t1 == *t2; +} + +constexpr bool +operator==(const FlarmTraffic *t1, + const FlarmTraffic &t2) noexcept +{ + return *t1 == t2; +} +#endif + static_assert(std::is_trivial::value, "type is not trivial"); diff --git a/src/FLARM/NameDatabase.cpp b/src/FLARM/NameDatabase.cpp index bb83dcf98c1..a858aa28e4c 100644 --- a/src/FLARM/NameDatabase.cpp +++ b/src/FLARM/NameDatabase.cpp @@ -16,7 +16,7 @@ FlarmNameDatabase::Find(FlarmId id) const noexcept } int -FlarmNameDatabase::Find(const TCHAR *name) const noexcept +FlarmNameDatabase::Find(const char *name) const noexcept { assert(name != nullptr); @@ -27,7 +27,7 @@ FlarmNameDatabase::Find(const TCHAR *name) const noexcept return -1; } -const TCHAR * +const char * FlarmNameDatabase::Get(FlarmId id) const noexcept { int i = Find(id); @@ -38,7 +38,7 @@ FlarmNameDatabase::Get(FlarmId id) const noexcept } FlarmId -FlarmNameDatabase::Get(const TCHAR *name) const noexcept +FlarmNameDatabase::Get(const char *name) const noexcept { int i = Find(name); if (i < 0) @@ -48,7 +48,7 @@ FlarmNameDatabase::Get(const TCHAR *name) const noexcept } unsigned -FlarmNameDatabase::Get(const TCHAR *name, +FlarmNameDatabase::Get(const char *name, FlarmId *buffer, unsigned max) const noexcept { assert(name != nullptr); @@ -64,7 +64,7 @@ FlarmNameDatabase::Get(const TCHAR *name, } bool -FlarmNameDatabase::Set(FlarmId id, const TCHAR *name) noexcept +FlarmNameDatabase::Set(FlarmId id, const char *name) noexcept { assert(id.IsDefined()); assert(name != nullptr); diff --git a/src/FLARM/NameDatabase.hpp b/src/FLARM/NameDatabase.hpp index 6d081780432..ba416132c53 100644 --- a/src/FLARM/NameDatabase.hpp +++ b/src/FLARM/NameDatabase.hpp @@ -17,7 +17,7 @@ class FlarmNameDatabase { StaticString<21> name; Record() = default; - Record(FlarmId _id, const TCHAR *_name) noexcept + Record(FlarmId _id, const char *_name) noexcept :id(_id), name(_name) {} }; @@ -41,10 +41,10 @@ class FlarmNameDatabase { } [[gnu::pure]] - const TCHAR *Get(FlarmId id) const noexcept; + const char *Get(FlarmId id) const noexcept; [[gnu::pure]] - FlarmId Get(const TCHAR *name) const noexcept; + FlarmId Get(const char *name) const noexcept; /** * Look up all records with the specified name. @@ -52,15 +52,15 @@ class FlarmNameDatabase { * @param max the maximum size of the given buffer * @return the number of items copied to the given buffer */ - unsigned Get(const TCHAR *name, + unsigned Get(const char *name, FlarmId *buffer, unsigned max) const noexcept; - bool Set(FlarmId id, const TCHAR *name) noexcept; + bool Set(FlarmId id, const char *name) noexcept; protected: [[gnu::pure]] int Find(FlarmId id) const noexcept; [[gnu::pure]] - int Find(const TCHAR *name) const noexcept; + int Find(const char *name) const noexcept; }; diff --git a/src/FLARM/NameFile.cpp b/src/FLARM/NameFile.cpp index 56f1b57b348..3a2e7cab1dd 100644 --- a/src/FLARM/NameFile.cpp +++ b/src/FLARM/NameFile.cpp @@ -33,7 +33,7 @@ LoadFlarmNameFile(BufferedReader &reader, FlarmNameDatabase &db) void SaveFlarmNameFile(BufferedOutputStream &writer, FlarmNameDatabase &db) { - TCHAR id[16]; + char id[16]; for (const auto &i : db) { assert(i.id.IsDefined()); diff --git a/src/FLARM/Traffic.cpp b/src/FLARM/Traffic.cpp index 624418f963e..08fc7154784 100644 --- a/src/FLARM/Traffic.cpp +++ b/src/FLARM/Traffic.cpp @@ -3,14 +3,14 @@ #include "FLARM/Traffic.hpp" -static constexpr const TCHAR *acTypes[] = { - _T("Unknown"), _T("Glider"), _T("TowPlane"), - _T("Helicopter"), _T("Parachute"), _T("DropPlane"), _T("HangGlider"), - _T("ParaGlider"), _T("PoweredAircraft"), _T("JetAircraft"), - _T("FlyingSaucer"), _T("Balloon"), _T("Airship"), _T("UAV"), - _T("Unknown"), _T("StaticObject") }; +static constexpr const char *acTypes[] = { + "Unknown", "Glider", "TowPlane", + "Helicopter", "Parachute", "DropPlane", "HangGlider", + "ParaGlider", "PoweredAircraft", "JetAircraft", + "FlyingSaucer", "Balloon", "Airship", "UAV", + "Unknown", "StaticObject" }; -const TCHAR * +const char * FlarmTraffic::GetTypeString(AircraftType type) noexcept { std::size_t index = static_cast(type); diff --git a/src/FLARM/Traffic.hpp b/src/FLARM/Traffic.hpp index 9ba70cca35d..d85d6ac871a 100644 --- a/src/FLARM/Traffic.hpp +++ b/src/FLARM/Traffic.hpp @@ -164,7 +164,7 @@ struct FlarmTraffic { } [[gnu::const]] - static const TCHAR *GetTypeString(AircraftType type) noexcept; + static const char *GetTypeString(AircraftType type) noexcept; void Update(const FlarmTraffic &other) noexcept; }; diff --git a/src/FLARM/TrafficDatabases.cpp b/src/FLARM/TrafficDatabases.cpp index c577833d6fd..b0e20d699ab 100644 --- a/src/FLARM/TrafficDatabases.cpp +++ b/src/FLARM/TrafficDatabases.cpp @@ -4,11 +4,11 @@ #include "TrafficDatabases.hpp" #include "util/StringCompare.hxx" -const TCHAR * +const char * TrafficDatabases::FindNameById(FlarmId id) const noexcept { // try to find flarm from userFile - const TCHAR *name = flarm_names.Get(id); + const char *name = flarm_names.Get(id); if (name != nullptr) return name; @@ -21,7 +21,7 @@ TrafficDatabases::FindNameById(FlarmId id) const noexcept } FlarmId -TrafficDatabases::FindIdByName(const TCHAR *name) const noexcept +TrafficDatabases::FindIdByName(const char *name) const noexcept { assert(!StringIsEmpty(name)); @@ -39,7 +39,7 @@ TrafficDatabases::FindIdByName(const TCHAR *name) const noexcept } unsigned -TrafficDatabases::FindIdsByName(const TCHAR *name, +TrafficDatabases::FindIdsByName(const char *name, FlarmId *buffer, unsigned max) const noexcept { assert(!StringIsEmpty(name)); diff --git a/src/FLARM/TrafficDatabases.hpp b/src/FLARM/TrafficDatabases.hpp index 18c4e2a4e84..010f8e44208 100644 --- a/src/FLARM/TrafficDatabases.hpp +++ b/src/FLARM/TrafficDatabases.hpp @@ -36,10 +36,10 @@ struct TrafficDatabases { } [[gnu::pure]] - const TCHAR *FindNameById(FlarmId id) const noexcept; + const char *FindNameById(FlarmId id) const noexcept; [[gnu::pure]] [[gnu::nonnull]] - FlarmId FindIdByName(const TCHAR *name) const noexcept; + FlarmId FindIdByName(const char *name) const noexcept; /** * Look up all records with the specified name. @@ -48,6 +48,6 @@ struct TrafficDatabases { * @return the number of items copied to the given buffer */ [[gnu::nonnull]] - unsigned FindIdsByName(const TCHAR *name, + unsigned FindIdsByName(const char *name, FlarmId *buffer, unsigned max) const noexcept; }; diff --git a/src/FLARM/Version.hpp b/src/FLARM/Version.hpp index 6a01bf8cd92..5f8ed3a883d 100644 --- a/src/FLARM/Version.hpp +++ b/src/FLARM/Version.hpp @@ -15,8 +15,8 @@ struct FlarmVersion { Validity available; - NarrowString<7> hardware_version, software_version; - NarrowString<19> obstacle_version; + StaticString<7> hardware_version, software_version; + StaticString<19> obstacle_version; constexpr void Clear() noexcept { available.Clear(); diff --git a/src/Form/Button.cpp b/src/Form/Button.cpp index bd187900c2e..8a2c50386c6 100644 --- a/src/Form/Button.cpp +++ b/src/Form/Button.cpp @@ -15,7 +15,7 @@ Button::Button(ContainerWindow &parent, const PixelRect &rc, } Button::Button(ContainerWindow &parent, const ButtonLook &look, - const TCHAR *caption, const PixelRect &rc, + const char *caption, const PixelRect &rc, WindowStyle style, Callback _callback) noexcept { @@ -40,7 +40,7 @@ Button::Create(ContainerWindow &parent, void Button::Create(ContainerWindow &parent, const ButtonLook &look, - const TCHAR *caption, const PixelRect &rc, + const char *caption, const PixelRect &rc, WindowStyle style) { Create(parent, rc, style, std::make_unique(look, caption)); @@ -58,7 +58,7 @@ Button::Create(ContainerWindow &parent, const PixelRect &rc, void Button::Create(ContainerWindow &parent, const ButtonLook &look, - const TCHAR *caption, const PixelRect &rc, + const char *caption, const PixelRect &rc, WindowStyle style, Callback _callback) noexcept { Create(parent, rc, style, @@ -67,7 +67,7 @@ Button::Create(ContainerWindow &parent, const ButtonLook &look, } void -Button::SetCaption(const TCHAR *caption) +Button::SetCaption(const char *caption) { assert(caption != nullptr); diff --git a/src/Form/Button.hpp b/src/Form/Button.hpp index 8ebd33f4f43..43d92e75f88 100644 --- a/src/Form/Button.hpp +++ b/src/Form/Button.hpp @@ -43,7 +43,7 @@ class Button : public PaintWindow { Callback _callback) noexcept; Button(ContainerWindow &parent, const ButtonLook &look, - const TCHAR *caption, const PixelRect &rc, + const char *caption, const PixelRect &rc, WindowStyle style, Callback _callback) noexcept; @@ -55,7 +55,7 @@ class Button : public PaintWindow { WindowStyle style, std::unique_ptr _renderer); void Create(ContainerWindow &parent, const ButtonLook &look, - const TCHAR *caption, const PixelRect &rc, + const char *caption, const PixelRect &rc, WindowStyle style); void Create(ContainerWindow &parent, const PixelRect &rc, @@ -63,7 +63,7 @@ class Button : public PaintWindow { Callback _callback) noexcept; void Create(ContainerWindow &parent, const ButtonLook &look, - const TCHAR *caption, const PixelRect &rc, + const char *caption, const PixelRect &rc, WindowStyle style, Callback _callback) noexcept; @@ -87,7 +87,7 @@ class Button : public PaintWindow { * #TextButtonRenderer and may only be used if created with a * #TextButtonRenderer instance. */ - void SetCaption(const TCHAR *caption); + void SetCaption(const char *caption); void SetSelected(bool _selected); diff --git a/src/Form/ButtonPanel.cpp b/src/Form/ButtonPanel.cpp index a49ef17390f..93f8c4855c9 100644 --- a/src/Form/ButtonPanel.cpp +++ b/src/Form/ButtonPanel.cpp @@ -56,14 +56,14 @@ ButtonPanel::Add(std::unique_ptr &&renderer, } Button * -ButtonPanel::Add(const TCHAR *caption, Button::Callback callback) noexcept +ButtonPanel::Add(const char *caption, Button::Callback callback) noexcept { return Add(std::make_unique(look, caption), std::move(callback)); } Button * -ButtonPanel::AddSymbol(const TCHAR *caption, +ButtonPanel::AddSymbol(const char *caption, Button::Callback callback) noexcept { return Add(std::make_unique(look, caption), diff --git a/src/Form/ButtonPanel.hpp b/src/Form/ButtonPanel.hpp index 6301e6bef0b..95a47e19703 100644 --- a/src/Form/ButtonPanel.hpp +++ b/src/Form/ButtonPanel.hpp @@ -56,13 +56,13 @@ class ButtonPanel { Button *Add(std::unique_ptr &&renderer, Button::Callback callback) noexcept; - Button *Add(const TCHAR *caption, Button::Callback callback) noexcept; + Button *Add(const char *caption, Button::Callback callback) noexcept; /** * Add a symbol button. The caption is one of the "special" * #WndSymbolButton strings. */ - Button *AddSymbol(const TCHAR *caption, Button::Callback callback) noexcept; + Button *AddSymbol(const char *caption, Button::Callback callback) noexcept; /** * Assign a hot key to the most recently added button. diff --git a/src/Form/CMakeLists.txt b/src/Form/CMakeLists.txt new file mode 100644 index 00000000000..9685f28f8c0 --- /dev/null +++ b/src/Form/CMakeLists.txt @@ -0,0 +1,54 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + + project(${TARGET_NAME} CXX) # Your project name + +include(CMakeSource.cmake) +# organize the files in subdirectories +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +target_link_libraries(${TARGET_NAME} PUBLIC Dialogs Renderer UIUtil) + +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER FrontEnd) + +add_dependencies(${TARGET_NAME} util) + diff --git a/src/Form/CMakeSource.cmake b/src/Form/CMakeSource.cmake new file mode 100644 index 00000000000..46c18eee7fe --- /dev/null +++ b/src/Form/CMakeSource.cmake @@ -0,0 +1,44 @@ +set(_SOURCES + Form/Button.cpp + Form/ButtonPanel.cpp + Form/CharacterButton.cpp + Form/CheckBox.cpp + Form/Control.cpp + Form/DataField/Angle.cpp + Form/DataField/Base.cpp + Form/DataField/Boolean.cpp + Form/DataField/ComboList.cpp + Form/DataField/Enum.cpp + Form/DataField/File.cpp + Form/DataField/Float.cpp + Form/DataField/GeoPoint.cpp + Form/DataField/Integer.cpp + Form/DataField/Number.cpp + Form/DataField/Password.cpp + Form/DataField/Prefix.cpp + Form/DataField/RoughTime.cpp + Form/DataField/String.cpp + Form/DataField/Time.cpp + Form/DataField/Date.cpp + Form/DigitEntry.cpp + Form/Draw.cpp + Form/Edit.cpp + Form/Form.cpp + Form/Frame.cpp + Form/GridView.cpp + Form/HLine.cpp + Form/Panel.cpp + Form/TabDisplay.cpp + Form/TabMenuDisplay.cpp + + Form/VScrollPanel.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake + + ../../build/form.mk + ../../build/datafield.mk +) + + diff --git a/src/Form/CharacterButton.cpp b/src/Form/CharacterButton.cpp index a6105209fcc..cbd2b777aa3 100644 --- a/src/Form/CharacterButton.cpp +++ b/src/Form/CharacterButton.cpp @@ -3,16 +3,13 @@ #include "Form/CharacterButton.hpp" #include "util/CharUtil.hxx" - -#ifndef _UNICODE #include "util/UTF8.hpp" -#endif #include void CharacterButton::Create(ContainerWindow &parent, const ButtonLook &look, - const TCHAR *text, PixelRect rc, + const char *text, PixelRect rc, OnCharacterCallback _on_character, unsigned _character, const WindowStyle style) noexcept { @@ -28,7 +25,7 @@ unsigned CharacterButton::GetUpperCharacter() const noexcept { unsigned result = character; - if (result < 0x80 && IsLowerAlphaASCII((TCHAR)result)) + if (result < 0x80 && IsLowerAlphaASCII((char)result)) result -= 'a' - 'A'; return result; } @@ -41,12 +38,8 @@ CharacterButton::SetCharacter(unsigned _character) noexcept character = _character; -#ifdef _UNICODE - const TCHAR buffer[2] = { TCHAR(character), _T('\0') }; -#else char buffer[7]; *UnicodeToUTF8(character, buffer) = '\0'; -#endif SetCaption(buffer); } diff --git a/src/Form/CharacterButton.hpp b/src/Form/CharacterButton.hpp index 15f1308963f..babfae468a7 100644 --- a/src/Form/CharacterButton.hpp +++ b/src/Form/CharacterButton.hpp @@ -18,7 +18,7 @@ class CharacterButton : public Button { public: void Create(ContainerWindow &parent, const ButtonLook &look, - const TCHAR *text, PixelRect rc, + const char *text, PixelRect rc, OnCharacterCallback on_character, unsigned character, const WindowStyle _style=WindowStyle()) noexcept; diff --git a/src/Form/CheckBox.cpp b/src/Form/CheckBox.cpp index 51896aa3558..1f42c158e43 100644 --- a/src/Form/CheckBox.cpp +++ b/src/Form/CheckBox.cpp @@ -11,7 +11,7 @@ void CheckBoxControl::Create(ContainerWindow &parent, const DialogLook &_look, - tstring::const_pointer _caption, + std::string::const_pointer _caption, const PixelRect &rc, const WindowStyle style, Callback _callback) noexcept @@ -27,7 +27,7 @@ CheckBoxControl::Create(ContainerWindow &parent, const DialogLook &_look, unsigned CheckBoxControl::GetMinimumWidth(const DialogLook &look, unsigned height, - tstring::const_pointer caption) noexcept + std::string::const_pointer caption) noexcept { const unsigned padding = Layout::GetTextPadding(); return 3 * padding + height + look.check_box.font->TextSize(caption).width; diff --git a/src/Form/CheckBox.hpp b/src/Form/CheckBox.hpp index b54a0e97568..dc9f217572e 100644 --- a/src/Form/CheckBox.hpp +++ b/src/Form/CheckBox.hpp @@ -4,7 +4,7 @@ #pragma once #include "ui/window/PaintWindow.hpp" -#include "util/tstring.hpp" +#include #include #include @@ -19,21 +19,21 @@ class CheckBoxControl : public PaintWindow { bool checked, dragging, pressed; const DialogLook *look; - tstring caption; + std::string caption; using Callback = std::function; Callback callback; public: void Create(ContainerWindow &parent, const DialogLook &look, - tstring::const_pointer caption, + std::string::const_pointer caption, const PixelRect &rc, const WindowStyle style, Callback _callback) noexcept; [[gnu::pure]] static unsigned GetMinimumWidth(const DialogLook &look, unsigned height, - tstring::const_pointer caption) noexcept; + std::string::const_pointer caption) noexcept; /** * Set the function that will receive click events. diff --git a/src/Form/Control.cpp b/src/Form/Control.cpp index 2e412cc595e..34fe8577e6a 100644 --- a/src/Form/Control.cpp +++ b/src/Form/Control.cpp @@ -11,10 +11,10 @@ WindowControl::WindowControl() noexcept } void -WindowControl::SetCaption(const TCHAR *Value) noexcept +WindowControl::SetCaption(const char *Value) noexcept { if (Value == nullptr) - Value = _T(""); + Value = ""; if (!caption.equals(Value)) { caption = Value; diff --git a/src/Form/Control.hpp b/src/Form/Control.hpp index ae91b8afc6a..1a7ee4ec7ad 100644 --- a/src/Form/Control.hpp +++ b/src/Form/Control.hpp @@ -21,7 +21,7 @@ class WindowControl : public PaintWindow { private: /** Helptext of the Control */ - const TCHAR *help_text = nullptr; + const char *help_text = nullptr; public: WindowControl() noexcept; @@ -46,7 +46,7 @@ class WindowControl : public PaintWindow { * Returns the Caption/Text of the Control * @return The Caption/Text of the Control */ - const TCHAR *GetCaption() const noexcept { + const char *GetCaption() const noexcept { return caption.c_str(); } @@ -54,17 +54,17 @@ class WindowControl : public PaintWindow { * Sets the Caption/Text of the Control * @param Value The new Caption/Text of the Control */ - void SetCaption(const TCHAR *Value) noexcept; + void SetCaption(const char *Value) noexcept; /** * Sets the Helptext of the Control * @param Value The new Helptext of the Control */ - void SetHelpText(const TCHAR *_help_text) noexcept { + void SetHelpText(const char *_help_text) noexcept { help_text = _help_text; } - const TCHAR *GetHelpText() const noexcept { + const char *GetHelpText() const noexcept { return help_text; } }; diff --git a/src/Form/DataField/Angle.cpp b/src/Form/DataField/Angle.cpp index a8b74de9fdf..f6917d884ab 100644 --- a/src/Form/DataField/Angle.cpp +++ b/src/Form/DataField/Angle.cpp @@ -50,17 +50,17 @@ AngleDataField::ModifyValue(Angle _value) noexcept Modified(); } -const TCHAR * +const char * AngleDataField::GetAsString() const noexcept { - _stprintf(string_buffer, _T("%u"), GetIntegerValue()); + _stprintf(string_buffer, "%u", GetIntegerValue()); return string_buffer; } -const TCHAR * +const char * AngleDataField::GetAsDisplayString() const noexcept { - _stprintf(string_buffer, _T("%u°"), GetIntegerValue()); + _stprintf(string_buffer, "%u°", GetIntegerValue()); return string_buffer; } @@ -77,7 +77,7 @@ AngleDataField::Dec() noexcept } void -AngleDataField::SetFromCombo(int i, [[maybe_unused]] const TCHAR *s) noexcept +AngleDataField::SetFromCombo(int i, [[maybe_unused]] const char *s) noexcept { assert(i >= 0); assert(unsigned(i) < MAX); @@ -88,14 +88,14 @@ AngleDataField::SetFromCombo(int i, [[maybe_unused]] const TCHAR *s) noexcept static void AppendComboValue(ComboList &combo_list, unsigned value) noexcept { - TCHAR buffer1[16], buffer2[16]; - _stprintf(buffer1, _T("%u"), value); - _stprintf(buffer2, _T("%u°"), value); + char buffer1[16], buffer2[16]; + _stprintf(buffer1, "%u", value); + _stprintf(buffer2, "%u°", value); combo_list.Append(value, buffer1, buffer2); } ComboList -AngleDataField::CreateComboList([[maybe_unused]] const TCHAR *reference) const noexcept +AngleDataField::CreateComboList([[maybe_unused]] const char *reference) const noexcept { ComboList combo_list; diff --git a/src/Form/DataField/Angle.hpp b/src/Form/DataField/Angle.hpp index 4992c7982d4..19a759268f9 100644 --- a/src/Form/DataField/Angle.hpp +++ b/src/Form/DataField/Angle.hpp @@ -22,7 +22,7 @@ class AngleDataField final : public DataField { /** * For GetAsString(). Must be mutable because the method is const. */ - mutable TCHAR string_buffer[16]; + mutable char string_buffer[16]; public: AngleDataField(unsigned _value, unsigned _step, bool _fine, @@ -78,12 +78,12 @@ class AngleDataField final : public DataField { void ModifyValue(Angle _value) noexcept; /* virtual methods from class DataField */ - const TCHAR *GetAsString() const noexcept override; - const TCHAR *GetAsDisplayString() const noexcept override; + const char *GetAsString() const noexcept override; + const char *GetAsDisplayString() const noexcept override; void Inc() noexcept override; void Dec() noexcept override; - ComboList CreateComboList(const TCHAR *reference) const noexcept override; - void SetFromCombo(int i, const TCHAR *s) noexcept override; + ComboList CreateComboList(const char *reference) const noexcept override; + void SetFromCombo(int i, const char *s) noexcept override; }; diff --git a/src/Form/DataField/Base.cpp b/src/Form/DataField/Base.cpp index 7852ce55eb2..6d4a34bb8bf 100644 --- a/src/Form/DataField/Base.cpp +++ b/src/Form/DataField/Base.cpp @@ -35,20 +35,20 @@ DataField::Dec() noexcept { } -const TCHAR * +const char * DataField::GetAsString() const noexcept { return nullptr; } -const TCHAR * +const char * DataField::GetAsDisplayString() const noexcept { return GetAsString(); } ComboList -DataField::CreateComboList([[maybe_unused]] const TCHAR *reference) const noexcept +DataField::CreateComboList([[maybe_unused]] const char *reference) const noexcept { return ComboList(); } diff --git a/src/Form/DataField/Base.hpp b/src/Form/DataField/Base.hpp index 2baa41ae7e0..a251ccd9f10 100644 --- a/src/Form/DataField/Base.hpp +++ b/src/Form/DataField/Base.hpp @@ -84,10 +84,10 @@ class DataField virtual void Dec() noexcept; [[gnu::pure]] - virtual const TCHAR *GetAsString() const noexcept; + virtual const char *GetAsString() const noexcept; [[gnu::pure]] - virtual const TCHAR *GetAsDisplayString() const noexcept; + virtual const char *GetAsDisplayString() const noexcept; virtual void EnableItemHelp([[maybe_unused]] bool value) noexcept {}; @@ -99,10 +99,10 @@ class DataField * "default" reference */ [[gnu::pure]] - virtual ComboList CreateComboList(const TCHAR *reference) const noexcept; + virtual ComboList CreateComboList(const char *reference) const noexcept; virtual void SetFromCombo([[maybe_unused]] int iDataFieldIndex, - [[maybe_unused]] const TCHAR *sValue) noexcept + [[maybe_unused]] const char *sValue) noexcept { /* this method must be implemented by all classes which also implement CreateComboList() */ diff --git a/src/Form/DataField/Boolean.cpp b/src/Form/DataField/Boolean.cpp index 9e007b7d8ef..a78b5f8f179 100644 --- a/src/Form/DataField/Boolean.cpp +++ b/src/Form/DataField/Boolean.cpp @@ -5,7 +5,7 @@ #include "ComboList.hpp" ComboList -DataFieldBoolean::CreateComboList([[maybe_unused]] const TCHAR *reference) const noexcept +DataFieldBoolean::CreateComboList([[maybe_unused]] const char *reference) const noexcept { ComboList combo_list; combo_list.Append(false, false_text); @@ -16,12 +16,12 @@ DataFieldBoolean::CreateComboList([[maybe_unused]] const TCHAR *reference) const } void -DataFieldBoolean::SetFromCombo(int i, const TCHAR *) noexcept +DataFieldBoolean::SetFromCombo(int i, const char *) noexcept { ModifyValue(i != 0); } -const TCHAR * +const char * DataFieldBoolean::GetAsString() const noexcept { return mValue ? true_text : false_text; diff --git a/src/Form/DataField/Boolean.hpp b/src/Form/DataField/Boolean.hpp index 8c55dba337b..cde56e2e256 100644 --- a/src/Form/DataField/Boolean.hpp +++ b/src/Form/DataField/Boolean.hpp @@ -15,7 +15,7 @@ class DataFieldBoolean final : public DataField { public: DataFieldBoolean(bool _value, - const TCHAR *_true_text, const TCHAR *_false_text, + const char *_true_text, const char *_false_text, DataFieldListener *listener=nullptr) noexcept :DataField(Type::BOOLEAN, true, listener), mValue(_value), @@ -39,7 +39,7 @@ class DataFieldBoolean final : public DataField { /* virtual methods from class DataField */ void Inc() noexcept override; void Dec() noexcept override; - const TCHAR *GetAsString() const noexcept override; - ComboList CreateComboList(const TCHAR *reference) const noexcept override; - void SetFromCombo(int i, const TCHAR *s) noexcept override; + const char *GetAsString() const noexcept override; + ComboList CreateComboList(const char *reference) const noexcept override; + void SetFromCombo(int i, const char *s) noexcept override; }; diff --git a/src/Form/DataField/ComboList.cpp b/src/Form/DataField/ComboList.cpp index a70e48ba4f4..88cbd0f7983 100644 --- a/src/Form/DataField/ComboList.cpp +++ b/src/Form/DataField/ComboList.cpp @@ -7,15 +7,15 @@ #include ComboList::Item::Item(int _int_value, - const TCHAR *_string_value, - const TCHAR *_display_string, - const TCHAR *_help_text) noexcept + const char *_string_value, + const char *_display_string, + const char *_help_text) noexcept :int_value(_int_value), string_value(_string_value), display_string(_display_string), help_text(_help_text != nullptr ? _help_text - : _T("")) + : "") { } diff --git a/src/Form/DataField/ComboList.hpp b/src/Form/DataField/ComboList.hpp index 25b500a97a0..26ee7f12be0 100644 --- a/src/Form/DataField/ComboList.hpp +++ b/src/Form/DataField/ComboList.hpp @@ -3,10 +3,10 @@ #pragma once -#include "util/tstring.hpp" #include #include +#include class ComboList { public: @@ -16,13 +16,13 @@ class ComboList { static constexpr int DOWNLOAD = -800003; int int_value; - tstring string_value; - tstring display_string; - tstring help_text; + std::string string_value; + std::string display_string; + std::string help_text; - Item(int _int_value, const TCHAR *_string_value, - const TCHAR *_display_string, - const TCHAR *_help_text = nullptr) noexcept; + Item(int _int_value, const char *_string_value, + const char *_display_string, + const char *_help_text = nullptr) noexcept; Item(const Item &other) = delete; Item &operator=(const Item &other) = delete; @@ -69,26 +69,26 @@ class ComboList { } unsigned Append(int int_value, - const TCHAR *string_value, - const TCHAR *display_string, - const TCHAR *help_text = nullptr) noexcept { + const char *string_value, + const char *display_string, + const char *help_text = nullptr) noexcept { unsigned i = items.size(); items.emplace_back(int_value, string_value, display_string, help_text); return i; } - unsigned Append(const TCHAR *string_value, - const TCHAR *display_string, - const TCHAR *help_text = nullptr) noexcept { + unsigned Append(const char *string_value, + const char *display_string, + const char *help_text = nullptr) noexcept { return Append(items.size(), string_value, display_string, help_text); } - unsigned Append(int int_value, const TCHAR *string_value) noexcept { + unsigned Append(int int_value, const char *string_value) noexcept { return Append(int_value, string_value, string_value); } - unsigned Append(const TCHAR *string_value) noexcept { + unsigned Append(const char *string_value) noexcept { return Append(string_value, string_value); } diff --git a/src/Form/DataField/Date.cpp b/src/Form/DataField/Date.cpp index ff8c31e646c..b26de8ffc68 100644 --- a/src/Form/DataField/Date.cpp +++ b/src/Form/DataField/Date.cpp @@ -4,7 +4,7 @@ #include "Date.hpp" #include "Formatter/TimeFormatter.hpp" -const TCHAR * +const char * DataFieldDate::GetAsString() const noexcept { FormatISO8601(string_buffer, value); diff --git a/src/Form/DataField/Date.hpp b/src/Form/DataField/Date.hpp index 194445e295d..1d8bf102331 100644 --- a/src/Form/DataField/Date.hpp +++ b/src/Form/DataField/Date.hpp @@ -9,7 +9,7 @@ class DataFieldDate final : public DataField { BrokenDate value; - mutable TCHAR string_buffer[OUTBUFFERSIZE + 1]; + mutable char string_buffer[OUTBUFFERSIZE + 1]; public: DataFieldDate(BrokenDate _value, DataFieldListener *listener) noexcept @@ -31,5 +31,5 @@ class DataFieldDate final : public DataField { Modified(); } - const TCHAR *GetAsString() const noexcept override; + const char *GetAsString() const noexcept override; }; diff --git a/src/Form/DataField/Enum.cpp b/src/Form/DataField/Enum.cpp index 443e4e4271a..17ee3057ab4 100644 --- a/src/Form/DataField/Enum.cpp +++ b/src/Form/DataField/Enum.cpp @@ -21,36 +21,36 @@ DataFieldEnum::Entry::~Entry() noexcept } void -DataFieldEnum::Entry::SetString(const TCHAR *_string) noexcept +DataFieldEnum::Entry::SetString(const char *_string) noexcept { free(string); if (display_string != string) free(display_string); - display_string = string = _tcsdup(_string); + display_string = string = strdup(_string); } void -DataFieldEnum::Entry::SetDisplayString(const TCHAR *_string) noexcept +DataFieldEnum::Entry::SetDisplayString(const char *_string) noexcept { if (display_string != string) free(display_string); - display_string = _tcsdup(_string); + display_string = strdup(_string); } void -DataFieldEnum::Entry::Set(unsigned _id, const TCHAR *_string, - const TCHAR *_display_string, - const TCHAR *_help) noexcept +DataFieldEnum::Entry::Set(unsigned _id, const char *_string, + const char *_display_string, + const char *_help) noexcept { id = _id; SetString(_string); if (_display_string != nullptr) - display_string = _tcsdup(_display_string); + display_string = strdup(_display_string); free(help); - help = _help ? _tcsdup(_help) : nullptr; + help = _help ? strdup(_help) : nullptr; } unsigned @@ -61,16 +61,16 @@ DataFieldEnum::GetValue() const noexcept } void -DataFieldEnum::replaceEnumText(std::size_t i, const TCHAR *Text) noexcept +DataFieldEnum::replaceEnumText(std::size_t i, const char *Text) noexcept { if (i <= entries.size()) entries[i].SetString(Text); } bool -DataFieldEnum::AddChoice(unsigned id, const TCHAR *text, - const TCHAR *display_string, - const TCHAR *help) noexcept +DataFieldEnum::AddChoice(unsigned id, const char *text, + const char *display_string, + const char *help) noexcept { if (entries.full()) return false; @@ -84,7 +84,7 @@ void DataFieldEnum::AddChoices(const StaticEnumChoice *p) noexcept { while (p->display_string != nullptr) { - const TCHAR *help = p->help; + const char *help = p->help; if (help != nullptr) help = gettext(help); @@ -94,8 +94,8 @@ DataFieldEnum::AddChoices(const StaticEnumChoice *p) noexcept } unsigned -DataFieldEnum::addEnumText(const TCHAR *Text, const TCHAR *display_string, - const TCHAR *_help) noexcept +DataFieldEnum::addEnumText(const char *Text, const char *display_string, + const char *_help) noexcept { if (entries.full()) return 0; @@ -107,37 +107,37 @@ DataFieldEnum::addEnumText(const TCHAR *Text, const TCHAR *display_string, } void -DataFieldEnum::addEnumTexts(const TCHAR *const*list) noexcept +DataFieldEnum::addEnumTexts(const char *const*list) noexcept { while (*list != nullptr) addEnumText(*list++); } -const TCHAR * +const char * DataFieldEnum::GetAsString() const noexcept { if (entries.empty()) { assert(value == 0); - return _T(""); + return ""; } else { assert(value < entries.size()); return entries[value].GetString(); } } -const TCHAR * +const char * DataFieldEnum::GetAsDisplayString() const noexcept { if (entries.empty()) { assert(value == 0); - return _T(""); + return ""; } else { assert(value < entries.size()); return entries[value].GetDisplayString(); } } -const TCHAR * +const char * DataFieldEnum::GetHelp() const noexcept { if (entries.empty()) { @@ -157,7 +157,7 @@ DataFieldEnum::SetValue(unsigned Value) noexcept } bool -DataFieldEnum::SetValue(const TCHAR *text) noexcept +DataFieldEnum::SetValue(const char *text) noexcept { int i = Find(text); if (i < 0) @@ -179,7 +179,7 @@ DataFieldEnum::ModifyValue(unsigned new_value) noexcept } bool -DataFieldEnum::ModifyValue(const TCHAR *text) noexcept +DataFieldEnum::ModifyValue(const char *text) noexcept { int i = Find(text); if (i < 0) @@ -190,7 +190,7 @@ DataFieldEnum::ModifyValue(const TCHAR *text) noexcept } int -DataFieldEnum::SetStringAutoAdd(const TCHAR *text) noexcept +DataFieldEnum::SetStringAutoAdd(const char *text) noexcept { int index = Find(text); if (index >= 0) { @@ -247,7 +247,7 @@ DataFieldEnum::Sort(std::size_t startindex) noexcept } ComboList -DataFieldEnum::CreateComboList([[maybe_unused]] const TCHAR *reference_string) const noexcept +DataFieldEnum::CreateComboList([[maybe_unused]] const char *reference_string) const noexcept { ComboList combo_list; @@ -260,13 +260,13 @@ DataFieldEnum::CreateComboList([[maybe_unused]] const TCHAR *reference_string) c } void -DataFieldEnum::SetFromCombo(int i, const TCHAR *) noexcept +DataFieldEnum::SetFromCombo(int i, const char *) noexcept { ModifyValue(i); } int -DataFieldEnum::Find(const TCHAR *text) const noexcept +DataFieldEnum::Find(const char *text) const noexcept { assert(text != nullptr); diff --git a/src/Form/DataField/Enum.hpp b/src/Form/DataField/Enum.hpp index e641ed14542..035ea55c81b 100644 --- a/src/Form/DataField/Enum.hpp +++ b/src/Form/DataField/Enum.hpp @@ -14,8 +14,8 @@ */ struct StaticEnumChoice { unsigned id; - const TCHAR *display_string; - const TCHAR *help; + const char *display_string; + const char *help; constexpr StaticEnumChoice(std::nullptr_t n) noexcept :id(0), display_string(n), help(n) {} @@ -23,8 +23,8 @@ struct StaticEnumChoice { template requires(std::is_same_v || std::is_same_v || std::is_enum_v) - constexpr StaticEnumChoice(T _id, const TCHAR *_display_string, - const TCHAR *_help=nullptr) noexcept + constexpr StaticEnumChoice(T _id, const char *_display_string, + const char *_help=nullptr) noexcept :id(static_cast(_id)), display_string(_display_string), help(_help) {} }; @@ -32,9 +32,9 @@ class DataFieldEnum final : public DataField { public: class Entry { unsigned id; - TCHAR *string; - TCHAR *display_string; - TCHAR *help; + char *string; + char *display_string; + char *help; public: Entry() noexcept:string(nullptr), display_string(nullptr), help(nullptr) {} @@ -67,23 +67,23 @@ class DataFieldEnum final : public DataField { return id; } - const TCHAR *GetString() const noexcept { + const char *GetString() const noexcept { return string; } - const TCHAR *GetDisplayString() const noexcept { + const char *GetDisplayString() const noexcept { return display_string; } - const TCHAR *GetHelp() const noexcept { + const char *GetHelp() const noexcept { return help; } - void SetString(const TCHAR *_string) noexcept; - void SetDisplayString(const TCHAR *_string) noexcept; - void Set(unsigned _id, const TCHAR *_string, - const TCHAR *_display_string=nullptr, - const TCHAR *_help=nullptr) noexcept; + void SetString(const char *_string) noexcept; + void SetDisplayString(const char *_string) noexcept; + void Set(unsigned _id, const char *_string, + const char *_display_string=nullptr, + const char *_help=nullptr) noexcept; }; private: @@ -98,13 +98,13 @@ class DataFieldEnum final : public DataField { unsigned GetValue() const noexcept; [[gnu::pure]] - bool Exists(const TCHAR *text) const noexcept { + bool Exists(const char *text) const noexcept { return Find(text) >= 0; } - void replaceEnumText(std::size_t index, const TCHAR *Text) noexcept; + void replaceEnumText(std::size_t index, const char *Text) noexcept; - void SetDisplayString(std::size_t index, const TCHAR *_string) noexcept { + void SetDisplayString(std::size_t index, const char *_string) noexcept { entries[index].SetDisplayString(_string); } @@ -117,9 +117,9 @@ class DataFieldEnum final : public DataField { value = 0; } - bool AddChoice(unsigned id, const TCHAR *text, - const TCHAR *display_string=nullptr, - const TCHAR *help=nullptr) noexcept; + bool AddChoice(unsigned id, const char *text, + const char *display_string=nullptr, + const char *help=nullptr) noexcept; /** * Add choices from the specified nullptr-terminated list (the last @@ -128,19 +128,19 @@ class DataFieldEnum final : public DataField { */ void AddChoices(const StaticEnumChoice *list) noexcept; - bool addEnumText(const TCHAR *text, unsigned id, - const TCHAR *help=nullptr) noexcept { + bool addEnumText(const char *text, unsigned id, + const char *help=nullptr) noexcept { return AddChoice(id, text, nullptr, help); } - unsigned addEnumText(const TCHAR *Text, const TCHAR *display_string=nullptr, - const TCHAR *ItemHelpText=nullptr) noexcept; - void addEnumTexts(const TCHAR *const*list) noexcept; + unsigned addEnumText(const char *Text, const char *display_string=nullptr, + const char *ItemHelpText=nullptr) noexcept; + void addEnumTexts(const char *const*list) noexcept; /** * @return help of current enum item or nullptr if current item has no help */ - const TCHAR *GetHelp() const noexcept; + const char *GetHelp() const noexcept; /** * @param value True if display item help in text box below picker @@ -165,7 +165,7 @@ class DataFieldEnum final : public DataField { * @return false if an item with the specified text was not found, * and therefore the value was not changed */ - bool SetValue(const TCHAR *text) noexcept; + bool SetValue(const char *text) noexcept; bool ModifyValue(unsigned new_value) noexcept; @@ -175,7 +175,7 @@ class DataFieldEnum final : public DataField { return ModifyValue(unsigned(value)); } - bool ModifyValue(const TCHAR *text) noexcept; + bool ModifyValue(const char *text) noexcept; /** * Set the value to the specified string. If there is no choice @@ -183,7 +183,7 @@ class DataFieldEnum final : public DataField { * * @return the new integer value */ - int SetStringAutoAdd(const TCHAR *text) noexcept; + int SetStringAutoAdd(const char *text) noexcept; void Sort(std::size_t startindex = 0) noexcept; @@ -199,17 +199,17 @@ class DataFieldEnum final : public DataField { /* virtual methods from class DataField */ void Inc() noexcept override; void Dec() noexcept override; - const TCHAR *GetAsString() const noexcept override; - const TCHAR *GetAsDisplayString() const noexcept override; - ComboList CreateComboList(const TCHAR *reference) const noexcept override; - void SetFromCombo(int iDataFieldIndex, const TCHAR *sValue) noexcept override; + const char *GetAsString() const noexcept override; + const char *GetAsDisplayString() const noexcept override; + ComboList CreateComboList(const char *reference) const noexcept override; + void SetFromCombo(int iDataFieldIndex, const char *sValue) noexcept override; protected: /** * Finds an entry with the specified text. Returns -1 if not found. */ [[gnu::pure]] - int Find(const TCHAR *text) const noexcept; + int Find(const char *text) const noexcept; [[gnu::pure]] int Find(unsigned id) const noexcept; diff --git a/src/Form/DataField/File.cpp b/src/Form/DataField/File.cpp index 0f08e90a331..e8c6e51220b 100644 --- a/src/Form/DataField/File.cpp +++ b/src/Form/DataField/File.cpp @@ -20,17 +20,17 @@ */ [[gnu::pure]] static bool -IsInternalFile(const TCHAR *str) noexcept +IsInternalFile(const char *str) noexcept { - static const TCHAR *const ifiles[] = { - _T("xcsoar-checklist.txt"), - _T("xcsoar-flarm.txt"), - _T("xcsoar-marks.txt"), - _T("xcsoar-persist.log"), - _T("xcsoar-startup.log"), - _T("xcsoar.log"), - _T("xcsoar-rasp.dat"), - _T("user.cup"), + static const char *const ifiles[] = { + "xcsoar-checklist.txt", + "xcsoar-flarm.txt", + "xcsoar-marks.txt", + "xcsoar-persist.log", + "xcsoar-startup.log", + "xcsoar.log", + "xcsoar-rasp.dat", + "user.cup", nullptr }; @@ -73,11 +73,11 @@ FileDataField::FileDataField(DataFieldListener *listener) noexcept postponed_value(nullptr) {} void -FileDataField::ScanDirectoryTop(const TCHAR *filter) noexcept +FileDataField::ScanDirectoryTop(const char *filter) noexcept { if (!loaded) { if (!postponed_patterns.full() && - _tcslen(filter) < PatternList::value_type().capacity()) { + strlen(filter) < PatternList::value_type().capacity()) { postponed_patterns.append() = filter; return; } else @@ -91,10 +91,10 @@ FileDataField::ScanDirectoryTop(const TCHAR *filter) noexcept } void -FileDataField::ScanMultiplePatterns(const TCHAR *patterns) noexcept +FileDataField::ScanMultiplePatterns(const char *patterns) noexcept { size_t length; - while ((length = _tcslen(patterns)) > 0) { + while ((length = strlen(patterns)) > 0) { ScanDirectoryTop(patterns); patterns += length + 1; } @@ -177,7 +177,7 @@ FileDataField::GetValue() const noexcept if (current_index >= files.size()) // TODO: return nullptr instead of empty string? - return Path(_T("")); + return Path(""); const Path path = files[current_index].path; assert(path != nullptr); @@ -205,11 +205,11 @@ FileDataField::AddNull() noexcept assert(!files.full()); Item &item = files.append(); - item.filename = Path(_T("")); - item.path = Path(_T("")); + item.filename = Path(""); + item.path = Path(""); } -const TCHAR * +const char * FileDataField::GetAsString() const noexcept { if (!loaded && postponed_value != nullptr) @@ -218,10 +218,10 @@ FileDataField::GetAsString() const noexcept if (current_index < files.size()) return files[current_index].path.c_str(); else - return _T(""); + return ""; } -const TCHAR * +const char * FileDataField::GetAsDisplayString() const noexcept { if (!loaded && postponed_value != nullptr) { @@ -236,7 +236,7 @@ FileDataField::GetAsDisplayString() const noexcept if (current_index < files.size()) return files[current_index].filename.c_str(); else - return _T(""); + return ""; } void @@ -305,7 +305,7 @@ FileDataField::Sort() noexcept } ComboList -FileDataField::CreateComboList([[maybe_unused]] const TCHAR *reference) const noexcept +FileDataField::CreateComboList([[maybe_unused]] const char *reference) const noexcept { /* sorry for the const_cast .. this method keeps the promise of not modifying the object, given that one does not count filling the @@ -314,7 +314,7 @@ FileDataField::CreateComboList([[maybe_unused]] const TCHAR *reference) const no ComboList combo_list; - TCHAR buffer[MAX_PATH]; + char buffer[MAX_PATH]; for (unsigned i = 0; i < files.size(); i++) { const Path path = files[i].filename; @@ -331,14 +331,14 @@ FileDataField::CreateComboList([[maybe_unused]] const TCHAR *reference) const no } } - const TCHAR *display_string = path.c_str(); + const char *display_string = path.c_str(); if (found) { /* yes - append the absolute path to allow the user to see the difference */ - _tcscpy(buffer, path.c_str()); - _tcscat(buffer, _T(" (")); - _tcscat(buffer, files[i].path.c_str()); - _tcscat(buffer, _T(")")); + strcpy(buffer, path.c_str()); + strcat(buffer, " ("); + strcat(buffer, files[i].path.c_str()); + strcat(buffer, ")"); display_string = buffer; } @@ -351,7 +351,7 @@ FileDataField::CreateComboList([[maybe_unused]] const TCHAR *reference) const no } void -FileDataField::SetFromCombo(int i, const TCHAR *) noexcept +FileDataField::SetFromCombo(int i, const char *) noexcept { ModifyIndex(i); } diff --git a/src/Form/DataField/File.hpp b/src/Form/DataField/File.hpp index 666c0ae2ce5..1f2764d53f7 100644 --- a/src/Form/DataField/File.hpp +++ b/src/Form/DataField/File.hpp @@ -147,13 +147,13 @@ class FileDataField final : public DataField { /** Sorts the filelist by filenames */ void Sort() noexcept; - void ScanDirectoryTop(const TCHAR *filter) noexcept; + void ScanDirectoryTop(const char *filter) noexcept; /** * Scan multiple shell patterns. Each pattern is terminated by a * null byte, and the list ends with an empty pattern. */ - void ScanMultiplePatterns(const TCHAR *patterns) noexcept; + void ScanMultiplePatterns(const char *patterns) noexcept; /** For use by other classes */ [[gnu::pure]] @@ -165,10 +165,10 @@ class FileDataField final : public DataField { /* virtual methods from class DataField */ void Inc() noexcept override; void Dec() noexcept override; - const TCHAR *GetAsString() const noexcept override; - const TCHAR *GetAsDisplayString() const noexcept override; - ComboList CreateComboList(const TCHAR *reference) const noexcept override; - void SetFromCombo(int i, const TCHAR *s) noexcept override; + const char *GetAsString() const noexcept override; + const char *GetAsDisplayString() const noexcept override; + ComboList CreateComboList(const char *reference) const noexcept override; + void SetFromCombo(int i, const char *s) noexcept override; protected: void EnsureLoaded() noexcept; diff --git a/src/Form/DataField/Float.cpp b/src/Form/DataField/Float.cpp index 0c5318d0941..60b9091dec4 100644 --- a/src/Form/DataField/Float.cpp +++ b/src/Form/DataField/Float.cpp @@ -10,14 +10,14 @@ static bool DataFieldKeyUp = false; -const TCHAR * +const char * DataFieldFloat::GetAsString() const noexcept { _stprintf(mOutBuf, edit_format, (double)mValue); return mOutBuf; } -const TCHAR * +const char * DataFieldFloat::GetAsDisplayString() const noexcept { _stprintf(mOutBuf, display_format, (double)mValue, unit.c_str()); @@ -84,7 +84,7 @@ DataFieldFloat::SpeedUp(bool keyup) noexcept } void -DataFieldFloat::SetFromCombo([[maybe_unused]] int iDataFieldIndex, const TCHAR *sValue) noexcept +DataFieldFloat::SetFromCombo([[maybe_unused]] int iDataFieldIndex, const char *sValue) noexcept { ModifyValue(ParseDouble(sValue)); } @@ -93,14 +93,14 @@ void DataFieldFloat::AppendComboValue(ComboList &combo_list, double value) const noexcept { - TCHAR a[decltype(edit_format)::capacity()], b[decltype(display_format)::capacity()]; + char a[decltype(edit_format)::capacity()], b[decltype(display_format)::capacity()]; _stprintf(a, edit_format, (double)value); _stprintf(b, display_format, (double)value, unit.c_str()); combo_list.Append(a, b); } ComboList -DataFieldFloat::CreateComboList(const TCHAR *reference_string) const noexcept +DataFieldFloat::CreateComboList(const char *reference_string) const noexcept { const auto reference = reference_string != nullptr ? ParseDouble(reference_string) @@ -121,7 +121,7 @@ DataFieldFloat::CreateComboList(const TCHAR *reference_string) const noexcept auto first = corrected_value - surrounding_items * mStep; if (first > mMin + epsilon) /* there are values before "first" - give the user a choice */ - combo_list.Append(ComboList::Item::PREVIOUS_PAGE, _T("<>")); + combo_list.Append(ComboList::Item::PREVIOUS_PAGE, "<>"); else if (first < mMin - epsilon) first = int(mMin / mStep) * mStep; @@ -181,7 +181,7 @@ DataFieldFloat::CreateComboList(const TCHAR *reference_string) const noexcept if (last < mMax - epsilon) /* there are values after "last" - give the user a choice */ - combo_list.Append(ComboList::Item::NEXT_PAGE, _T("<>")); + combo_list.Append(ComboList::Item::NEXT_PAGE, "<>"); return combo_list; } diff --git a/src/Form/DataField/Float.hpp b/src/Form/DataField/Float.hpp index 366c087f267..5d67dbc9331 100644 --- a/src/Form/DataField/Float.hpp +++ b/src/Form/DataField/Float.hpp @@ -17,22 +17,22 @@ class DataFieldFloat final : public NumberDataField { StaticString<8> unit; - mutable TCHAR mOutBuf[OUTBUFFERSIZE+1]; + mutable char mOutBuf[OUTBUFFERSIZE+1]; protected: double SpeedUp(bool keyup) noexcept; public: - DataFieldFloat(const TCHAR *edit_format, const TCHAR *display_format, + DataFieldFloat(const char *edit_format, const char *display_format, double _min, double _max, double _value, double _step, bool _fine, DataFieldListener *listener=nullptr) noexcept :NumberDataField(Type::REAL, true, edit_format, display_format, listener), mValue(_value), mMin(_min), mMax(_max), mStep(_step), mSpeedup(0), mFine(_fine), - unit(_T("")) {} + unit("") {} - void SetUnits(const TCHAR *text) noexcept { + void SetUnits(const char *text) noexcept { unit = text; } @@ -65,10 +65,10 @@ class DataFieldFloat final : public NumberDataField { /* virtual methods from class DataField */ void Inc() noexcept override; void Dec() noexcept override; - const TCHAR *GetAsString() const noexcept override; - const TCHAR *GetAsDisplayString() const noexcept override; - ComboList CreateComboList(const TCHAR *reference) const noexcept override; - void SetFromCombo(int iDataFieldIndex, const TCHAR *sValue) noexcept override; + const char *GetAsString() const noexcept override; + const char *GetAsDisplayString() const noexcept override; + ComboList CreateComboList(const char *reference) const noexcept override; + void SetFromCombo(int iDataFieldIndex, const char *sValue) noexcept override; protected: void AppendComboValue(ComboList &combo_list, double value) const noexcept; diff --git a/src/Form/DataField/GeoPoint.cpp b/src/Form/DataField/GeoPoint.cpp index 8c30f5ba0d9..a61e9903c86 100644 --- a/src/Form/DataField/GeoPoint.cpp +++ b/src/Form/DataField/GeoPoint.cpp @@ -14,11 +14,11 @@ GeoPointDataField::ModifyValue(GeoPoint _value) noexcept Modified(); } -const TCHAR * +const char * GeoPointDataField::GetAsString() const noexcept { if (!value.IsValid()) - return _T(""); + return ""; return FormatGeoPoint(value, string_buffer, std::size(string_buffer), format); diff --git a/src/Form/DataField/GeoPoint.hpp b/src/Form/DataField/GeoPoint.hpp index e7b16a275ca..4ca541987cf 100644 --- a/src/Form/DataField/GeoPoint.hpp +++ b/src/Form/DataField/GeoPoint.hpp @@ -18,7 +18,7 @@ class GeoPointDataField final : public DataField { /** * For GetAsString(). Must be mutable because the method is const. */ - mutable TCHAR string_buffer[64]; + mutable char string_buffer[64]; public: GeoPointDataField(GeoPoint _value, CoordinateFormat _format, @@ -41,5 +41,5 @@ class GeoPointDataField final : public DataField { void ModifyValue(GeoPoint _value) noexcept; /* virtual methods from class DataField */ - const TCHAR *GetAsString() const noexcept override; + const char *GetAsString() const noexcept override; }; diff --git a/src/Form/DataField/Integer.cpp b/src/Form/DataField/Integer.cpp index fb58a957a5d..525ad38f812 100644 --- a/src/Form/DataField/Integer.cpp +++ b/src/Form/DataField/Integer.cpp @@ -11,19 +11,19 @@ static bool datafield_key_up = false; [[gnu::pure]] static int -ParseString(const TCHAR *s) noexcept +ParseString(const char *s) noexcept { return ParseInt(s); } -const TCHAR * +const char * DataFieldInteger::GetAsString() const noexcept { _stprintf(output_buffer, edit_format, value); return output_buffer; } -const TCHAR * +const char * DataFieldInteger::GetAsDisplayString() const noexcept { _stprintf(output_buffer, display_format, value); @@ -83,14 +83,14 @@ void DataFieldInteger::AppendComboValue(ComboList &combo_list, int value) const noexcept { - TCHAR a[decltype(edit_format)::capacity()], b[decltype(display_format)::capacity()]; + char a[decltype(edit_format)::capacity()], b[decltype(display_format)::capacity()]; _stprintf(a, edit_format, value); _stprintf(b, display_format, value); combo_list.Append(combo_list.size(), a, b); } ComboList -DataFieldInteger::CreateComboList(const TCHAR *reference_string) const noexcept +DataFieldInteger::CreateComboList(const char *reference_string) const noexcept { const int reference = reference_string != nullptr ? ParseString(reference_string) @@ -107,7 +107,7 @@ DataFieldInteger::CreateComboList(const TCHAR *reference_string) const noexcept int first = corrected_value - (int)surrounding_items * step; if (first > min) /* there are values before "first" - give the user a choice */ - combo_list.Append(ComboList::Item::PREVIOUS_PAGE, _T("<>")); + combo_list.Append(ComboList::Item::PREVIOUS_PAGE, "<>"); else if (first < min) first = min; @@ -137,14 +137,14 @@ DataFieldInteger::CreateComboList(const TCHAR *reference_string) const noexcept if (last < max) /* there are values after "last" - give the user a choice */ - combo_list.Append(ComboList::Item::NEXT_PAGE, _T("<>")); + combo_list.Append(ComboList::Item::NEXT_PAGE, "<>"); return combo_list; } void DataFieldInteger::SetFromCombo([[maybe_unused]] int index, - const TCHAR *value) noexcept + const char *value) noexcept { SetAsInteger(ParseString(value)); } diff --git a/src/Form/DataField/Integer.hpp b/src/Form/DataField/Integer.hpp index 97ace528407..35b3cf556db 100644 --- a/src/Form/DataField/Integer.hpp +++ b/src/Form/DataField/Integer.hpp @@ -15,13 +15,13 @@ class DataFieldInteger final : public NumberDataField PeriodClock last_step; int speedup; - mutable TCHAR output_buffer[OUTBUFFERSIZE + 1]; + mutable char output_buffer[OUTBUFFERSIZE + 1]; protected: int SpeedUp(bool keyup) noexcept; public: - DataFieldInteger(const TCHAR *edit_format, const TCHAR *display_format, + DataFieldInteger(const char *edit_format, const char *display_format, int _min, int _max, int _value, int _step, DataFieldListener *listener=nullptr) noexcept :NumberDataField(Type::INTEGER, @@ -66,10 +66,10 @@ class DataFieldInteger final : public NumberDataField /* virtual methods from class DataField */ void Inc() noexcept override; void Dec() noexcept override; - const TCHAR *GetAsString() const noexcept override; - const TCHAR *GetAsDisplayString() const noexcept override; - ComboList CreateComboList(const TCHAR *reference) const noexcept override; - void SetFromCombo(int iDataFieldIndex, const TCHAR *sValue) noexcept override; + const char *GetAsString() const noexcept override; + const char *GetAsDisplayString() const noexcept override; + ComboList CreateComboList(const char *reference) const noexcept override; + void SetFromCombo(int iDataFieldIndex, const char *sValue) noexcept override; protected: void AppendComboValue(ComboList &combo_list, int value) const noexcept; diff --git a/src/Form/DataField/Number.cpp b/src/Form/DataField/Number.cpp index d399f4da8b4..c78a587b4a1 100644 --- a/src/Form/DataField/Number.cpp +++ b/src/Form/DataField/Number.cpp @@ -4,8 +4,8 @@ #include "Number.hpp" NumberDataField::NumberDataField(Type type, bool support_combo, - const TCHAR *_edit_format, - const TCHAR *_display_format, + const char *_edit_format, + const char *_display_format, DataFieldListener *listener) noexcept :DataField(type, support_combo, listener), edit_format(_edit_format), display_format(_display_format) @@ -13,9 +13,9 @@ NumberDataField::NumberDataField(Type type, bool support_combo, } void -NumberDataField::SetFormat(const TCHAR *text) noexcept +NumberDataField::SetFormat(const char *text) noexcept { edit_format = text; display_format = text; - display_format += _T(" %s") ; + display_format += " %s" ; } diff --git a/src/Form/DataField/Number.hpp b/src/Form/DataField/Number.hpp index 45e8375c077..7722c7acc6c 100644 --- a/src/Form/DataField/Number.hpp +++ b/src/Form/DataField/Number.hpp @@ -12,10 +12,10 @@ class NumberDataField : public DataField { StaticString<32> display_format; public: - void SetFormat(const TCHAR *text) noexcept; + void SetFormat(const char *text) noexcept; protected: NumberDataField(Type type, bool support_combo, - const TCHAR *edit_format, const TCHAR *display_format, + const char *edit_format, const char *display_format, DataFieldListener *listener=nullptr) noexcept; }; diff --git a/src/Form/DataField/Password.cpp b/src/Form/DataField/Password.cpp index 650c2ca9bc1..e00f2346aac 100644 --- a/src/Form/DataField/Password.cpp +++ b/src/Form/DataField/Password.cpp @@ -5,11 +5,11 @@ #include -const TCHAR * +const char * PasswordDataField::GetAsDisplayString() const noexcept { - const TCHAR *obfuscated = _T("********************************"); - const size_t obfuscated_length = _tcslen(obfuscated); - size_t length = std::min(_tcsclen(GetAsString()), obfuscated_length); + const char *obfuscated = "********************************"; + const size_t obfuscated_length = strlen(obfuscated); + size_t length = std::min(strlen(GetAsString()), obfuscated_length); return obfuscated + (obfuscated_length - length); } diff --git a/src/Form/DataField/Password.hpp b/src/Form/DataField/Password.hpp index 758e5d193f8..99876496319 100644 --- a/src/Form/DataField/Password.hpp +++ b/src/Form/DataField/Password.hpp @@ -11,10 +11,10 @@ */ class PasswordDataField final : public DataFieldString { public: - PasswordDataField(const TCHAR *initial_value, + PasswordDataField(const char *initial_value, DataFieldListener *listener=nullptr) noexcept :DataFieldString(initial_value, listener) {} /* virtual methods from class DataField */ - const TCHAR *GetAsDisplayString() const noexcept override; + const char *GetAsDisplayString() const noexcept override; }; diff --git a/src/Form/DataField/Prefix.cpp b/src/Form/DataField/Prefix.cpp index d386ac761dc..44839899eb1 100644 --- a/src/Form/DataField/Prefix.cpp +++ b/src/Form/DataField/Prefix.cpp @@ -5,60 +5,60 @@ #include "util/StringAPI.hxx" #include "util/StringCompare.hxx" -const TCHAR * +const char * PrefixDataField::GetAsDisplayString() const noexcept { - const TCHAR *s = DataFieldString::GetAsDisplayString(); + const char *s = DataFieldString::GetAsDisplayString(); if (StringIsEmpty(s)) - s = _T("*"); + s = "*"; return s; } void PrefixDataField::Inc() noexcept { - const TCHAR *chars = GetAllowedCharacters(); + const char *chars = GetAllowedCharacters(); if (StringIsEmpty(chars)) return; - const TCHAR current = GetAsString()[0]; - const TCHAR *p = current != _T('\0') + const char current = GetAsString()[0]; + const char *p = current != '\0' ? StringFind(chars, current) : nullptr; - TCHAR next; + char next; if (p == nullptr) next = chars[0]; else next = p[1]; - const TCHAR new_value[2] = { next, _T('\0') }; + const char new_value[2] = { next, '\0' }; ModifyValue(new_value); } void PrefixDataField::Dec() noexcept { - const TCHAR *chars = GetAllowedCharacters(); + const char *chars = GetAllowedCharacters(); if (StringIsEmpty(chars)) return; - const TCHAR current = GetAsString()[0]; + const char current = GetAsString()[0]; - TCHAR next; - if (current == _T('\0')) - next = chars[_tcslen(chars) - 1]; + char next; + if (current == '\0') + next = chars[strlen(chars) - 1]; else { - const TCHAR *p = current != _T('\0') + const char *p = current != '\0' ? StringFind(chars, current) : nullptr; if (p > chars) next = p[-1]; else - next = _T('\0'); + next = '\0'; } - const TCHAR new_value[2] = { next, _T('\0') }; + const char new_value[2] = { next, '\0' }; ModifyValue(new_value); } diff --git a/src/Form/DataField/Prefix.hpp b/src/Form/DataField/Prefix.hpp index 21ce01a6f64..2da2fa6ae40 100644 --- a/src/Form/DataField/Prefix.hpp +++ b/src/Form/DataField/Prefix.hpp @@ -9,19 +9,19 @@ class PrefixDataField final : public DataFieldString { public: - typedef std::function AllowedCharactersFunction; + typedef std::function AllowedCharactersFunction; private: AllowedCharactersFunction allowed_characters; public: - PrefixDataField(const TCHAR *value, + PrefixDataField(const char *value, AllowedCharactersFunction _allowed_characters, DataFieldListener *listener=nullptr) noexcept :DataFieldString(Type::PREFIX, value, listener), allowed_characters(_allowed_characters) {} - PrefixDataField(const TCHAR *value=_T(""), + PrefixDataField(const char *value="", DataFieldListener *listener=nullptr) noexcept :DataFieldString(Type::PREFIX, value, listener) {} @@ -32,13 +32,13 @@ class PrefixDataField final : public DataFieldString { /* virtual methods from class DataField */ void Inc() noexcept override; void Dec() noexcept override; - const TCHAR *GetAsDisplayString() const noexcept override; + const char *GetAsDisplayString() const noexcept override; protected: [[gnu::pure]] - const TCHAR *GetAllowedCharacters() const noexcept { + const char *GetAllowedCharacters() const noexcept { return allowed_characters - ? allowed_characters(_T("")) - : _T("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + ? allowed_characters("") + : "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; } }; diff --git a/src/Form/DataField/RoughTime.cpp b/src/Form/DataField/RoughTime.cpp index e95dba7b268..68d728352b0 100644 --- a/src/Form/DataField/RoughTime.cpp +++ b/src/Form/DataField/RoughTime.cpp @@ -6,7 +6,7 @@ #include -static TCHAR buffer[8]; +static char buffer[8]; void RoughTimeDataField::ModifyValue(RoughTime _value) noexcept @@ -18,24 +18,24 @@ RoughTimeDataField::ModifyValue(RoughTime _value) noexcept Modified(); } -const TCHAR * +const char * RoughTimeDataField::GetAsString() const noexcept { if (!value.IsValid()) - return _T(""); + return ""; - _stprintf(buffer, _T("%02u:%02u"), value.GetHour(), value.GetMinute()); + _stprintf(buffer, "%02u:%02u", value.GetHour(), value.GetMinute()); return buffer; } -const TCHAR * +const char * RoughTimeDataField::GetAsDisplayString() const noexcept { if (!value.IsValid()) - return _T(""); + return ""; RoughTime local_value = value + time_zone; - _stprintf(buffer, _T("%02u:%02u"), + _stprintf(buffer, "%02u:%02u", local_value.GetHour(), local_value.GetMinute()); return buffer; } diff --git a/src/Form/DataField/RoughTime.hpp b/src/Form/DataField/RoughTime.hpp index f91b9f5585f..463d6f2869c 100644 --- a/src/Form/DataField/RoughTime.hpp +++ b/src/Form/DataField/RoughTime.hpp @@ -51,6 +51,6 @@ class RoughTimeDataField final : public DataField { /* virtual methods from class DataField */ void Inc() noexcept override; void Dec() noexcept override; - const TCHAR *GetAsString() const noexcept override; - const TCHAR *GetAsDisplayString() const noexcept override; + const char *GetAsString() const noexcept override; + const char *GetAsDisplayString() const noexcept override; }; diff --git a/src/Form/DataField/String.cpp b/src/Form/DataField/String.cpp index 8b7f8302218..af5c62881c2 100644 --- a/src/Form/DataField/String.cpp +++ b/src/Form/DataField/String.cpp @@ -4,7 +4,7 @@ #include "String.hpp" void -DataFieldString::ModifyValue(const TCHAR *new_value) noexcept +DataFieldString::ModifyValue(const char *new_value) noexcept { if (new_value == mValue) return; @@ -14,12 +14,12 @@ DataFieldString::ModifyValue(const TCHAR *new_value) noexcept } void -DataFieldString::SetValue(const TCHAR *Value) noexcept +DataFieldString::SetValue(const char *Value) noexcept { mValue = Value; } -const TCHAR * +const char * DataFieldString::GetAsString() const noexcept { return GetValue(); diff --git a/src/Form/DataField/String.hpp b/src/Form/DataField/String.hpp index d2ed3f5be37..7aac503da2a 100644 --- a/src/Form/DataField/String.hpp +++ b/src/Form/DataField/String.hpp @@ -13,22 +13,22 @@ class DataFieldString: public DataField StaticString mValue; protected: - DataFieldString(Type _type, const TCHAR *_value, + DataFieldString(Type _type, const char *_value, DataFieldListener *listener=nullptr) noexcept :DataField(_type, false, listener), mValue(_value) {} public: - DataFieldString(const TCHAR *_value, + DataFieldString(const char *_value, DataFieldListener *listener=nullptr) noexcept :DataField(Type::STRING, false, listener), mValue(_value) {} - const TCHAR *GetValue() const noexcept { + const char *GetValue() const noexcept { return mValue.c_str(); } - void SetValue(const TCHAR *new_value) noexcept; - void ModifyValue(const TCHAR *new_value) noexcept; + void SetValue(const char *new_value) noexcept; + void ModifyValue(const char *new_value) noexcept; /* virtual methods from class DataField */ - const TCHAR *GetAsString() const noexcept override; + const char *GetAsString() const noexcept override; }; diff --git a/src/Form/DataField/Time.cpp b/src/Form/DataField/Time.cpp index d84ab277656..5a30dda6817 100644 --- a/src/Form/DataField/Time.cpp +++ b/src/Form/DataField/Time.cpp @@ -9,14 +9,14 @@ static bool data_field_key_up = false; -const TCHAR * +const char * DataFieldTime::GetAsString() const noexcept { - StringFormatUnsafe(string_buffer, _T("%d"), value); + StringFormatUnsafe(string_buffer, "%d", value); return string_buffer; } -const TCHAR * +const char * DataFieldTime::GetAsDisplayString() const noexcept { FormatTimespanSmart(string_buffer, std::chrono::seconds{value}, max_tokens); @@ -61,7 +61,7 @@ DataFieldTime::SpeedUp(bool key_up) noexcept void DataFieldTime::SetFromCombo(int data_field_index, - [[maybe_unused]] const TCHAR *value_string) noexcept + [[maybe_unused]] const char *value_string) noexcept { ModifyValue(std::chrono::seconds{data_field_index}); } @@ -70,14 +70,14 @@ void DataFieldTime::AppendComboValue(ComboList &combo_list, std::chrono::seconds value) const noexcept { - TCHAR buffer2[32]; - StringFormatUnsafe(buffer2, _T("%ld"), (long)value.count()); + char buffer2[32]; + StringFormatUnsafe(buffer2, "%ld", (long)value.count()); combo_list.Append(value.count(), buffer2, FormatTimespanSmart(value, max_tokens)); } ComboList -DataFieldTime::CreateComboList(const TCHAR *reference_string) const noexcept +DataFieldTime::CreateComboList(const char *reference_string) const noexcept { const auto reference = reference_string != nullptr ? std::chrono::seconds{ParseInt(reference_string)} @@ -94,7 +94,7 @@ DataFieldTime::CreateComboList(const TCHAR *reference_string) const noexcept auto first = corrected_value - (int)surrounding_items * step; if (first > min) /* there are values before "first" - give the user a choice */ - combo_list.Append(ComboList::Item::PREVIOUS_PAGE, _T("<>")); + combo_list.Append(ComboList::Item::PREVIOUS_PAGE, "<>"); else if (first < min) first = min; @@ -123,7 +123,7 @@ DataFieldTime::CreateComboList(const TCHAR *reference_string) const noexcept if (last < max) /* there are values after "last" - give the user a choice */ - combo_list.Append(ComboList::Item::NEXT_PAGE, _T("<>")); + combo_list.Append(ComboList::Item::NEXT_PAGE, "<>"); return combo_list; } diff --git a/src/Form/DataField/Time.hpp b/src/Form/DataField/Time.hpp index 64d15207ecf..9ac84d29c09 100644 --- a/src/Form/DataField/Time.hpp +++ b/src/Form/DataField/Time.hpp @@ -16,7 +16,7 @@ class DataFieldTime final : public DataField { PeriodClock last_step; uint8_t speedup; - mutable TCHAR string_buffer[OUTBUFFERSIZE + 1]; + mutable char string_buffer[OUTBUFFERSIZE + 1]; protected: int SpeedUp(bool keyup) noexcept; @@ -64,10 +64,10 @@ class DataFieldTime final : public DataField { /* virtual methods from class DataField */ void Inc() noexcept override; void Dec() noexcept override; - const TCHAR *GetAsString() const noexcept override; - const TCHAR *GetAsDisplayString() const noexcept override; - ComboList CreateComboList(const TCHAR *reference) const noexcept override; - void SetFromCombo(int data_field_index, const TCHAR *value_string) noexcept override; + const char *GetAsString() const noexcept override; + const char *GetAsDisplayString() const noexcept override; + ComboList CreateComboList(const char *reference) const noexcept override; + void SetFromCombo(int data_field_index, const char *value_string) noexcept override; protected: void AppendComboValue(ComboList &combo_list, std::chrono::seconds value) const noexcept; diff --git a/src/Form/DigitEntry.cpp b/src/Form/DigitEntry.cpp index ab4de246f48..6259ce3cde6 100644 --- a/src/Form/DigitEntry.cpp +++ b/src/Form/DigitEntry.cpp @@ -244,7 +244,7 @@ DigitEntry::CalculateLayout() const unsigned min_value_height = control_height * 3 / 2; - PixelSize digit_size = look.text_font.TextSize(_T("8")); + PixelSize digit_size = look.text_font.TextSize("8"); digit_size.height += 2 * padding; if (digit_size.height < min_value_height) digit_size.height = min_value_height; @@ -903,13 +903,11 @@ DigitEntry::OnKeyCheck(unsigned key_code) const noexcept switch (key_code) { case KEY_UP: case KEY_DOWN: - return true; - case KEY_LEFT: - return cursor > 0; - case KEY_RIGHT: - return cursor < length - 1; + case KEY_RETURN: + return true; + default: return PaintWindow::OnKeyCheck(key_code); @@ -934,14 +932,22 @@ DigitEntry::OnKeyDown(unsigned key_code) noexcept case KEY_LEFT: i = FindEditableLeft(cursor - 1); - if (i >= 0) + if (i >= 0) { SetCursor(i); + } else if (left_overflow) { + left_overflow(); + cursor = length - 1; + } return true; case KEY_RIGHT: i = FindEditableRight(cursor + 1); - if (i >= 0) + if (i >= 0) { SetCursor(i); + } else if (right_overflow) { + right_overflow(); + cursor = 0; + } return true; case KEY_RETURN: @@ -990,7 +996,7 @@ DigitEntry::OnPaint(Canvas &canvas) noexcept rc.top = top; rc.bottom = bottom; - TCHAR buffer[5]; + char buffer[5]; for (unsigned i = 0; i < length; ++i) { const Column &c = columns[i]; @@ -1009,71 +1015,71 @@ DigitEntry::OnPaint(Canvas &canvas) noexcept canvas.SetBackgroundColor(look.background_color); } - const TCHAR *text = buffer; - buffer[1] = _T('\0'); + const char *text = buffer; + buffer[1] = '\0'; switch (c.type) { case Column::Type::DIGIT: case Column::Type::DIGIT6: assert(c.value < 10); - buffer[0] = _T('0') + c.value; + buffer[0] = '0' + c.value; break; case Column::Type::HOUR: assert(c.value < 24); - _stprintf(buffer, _T("%02u"), c.value); + _stprintf(buffer, "%02u", c.value); break; case Column::Type::DIGIT36: assert(c.value < 36); - _stprintf(buffer, _T("%02u"), c.value); + _stprintf(buffer, "%02u", c.value); break; case Column::Type::DIGIT19: assert(c.value < 19); - _stprintf(buffer, _T("%02u"), c.value); + _stprintf(buffer, "%02u", c.value); break; case Column::Type::SIGN: - buffer[0] = c.IsNegative() ? _T('-') : _T('+'); + buffer[0] = c.IsNegative() ? '-' : '+'; break; case Column::Type::DECIMAL_POINT: - buffer[0] = _T('.'); + buffer[0] = '.'; break; case Column::Type::COLON: - buffer[0] = _T(':'); + buffer[0] = ':'; break; case Column::Type::NORTH_SOUTH: - buffer[0] = c.IsNegative() ? _T('S') : _T('N'); + buffer[0] = c.IsNegative() ? 'S' : 'N'; break; case Column::Type::EAST_WEST: - buffer[0] = c.IsNegative() ? _T('W') : _T('E'); + buffer[0] = c.IsNegative() ? 'W' : 'E'; break; case Column::Type::DEGREES: - text = _T("°"); + text = "°"; break; case Column::Type::APOSTROPHE: - text = _T("'"); + text = "'"; break; case Column::Type::QUOTE: - text = _T("\""); + text = "\""; break; case Column::Type::DAY: - _stprintf(buffer, _T("%02u"), c.value + 1); + _stprintf(buffer, "%02u", c.value + 1); break; case Column::Type::MONTH: - _stprintf(buffer, _T("%02u"), c.value + 1); + _stprintf(buffer, "%02u", c.value + 1); break; case Column::Type::YEAR: - _stprintf(buffer, _T("%04u"), c.value + 1900); + _stprintf(buffer, "%04u", c.value + 1900); break; case Column::Type::UNIT: @@ -1083,7 +1089,7 @@ DigitEntry::OnPaint(Canvas &canvas) noexcept } if (c.IsEditable() && !valid) - buffer[0] = _T('\0'); + buffer[0] = '\0'; const int x = (c.left + c.right - canvas.CalcTextWidth(text)) / 2; diff --git a/src/Form/DigitEntry.hpp b/src/Form/DigitEntry.hpp index 538911d7a17..32316c7ef6e 100644 --- a/src/Form/DigitEntry.hpp +++ b/src/Form/DigitEntry.hpp @@ -151,6 +151,9 @@ class DigitEntry : public PaintWindow { std::function callback; + std::function left_overflow; + std::function right_overflow; + /** * Total number of columns. */ @@ -214,6 +217,12 @@ class DigitEntry : public PaintWindow { void SetCallback(std::function _callback) noexcept { callback = std::move(_callback); } + void SetLeftOverflow(std::function _callback) noexcept { + left_overflow = std::move(_callback); + } + void SetRightOverflow(std::function _callback) noexcept { + right_overflow = std::move(_callback); + } void SetCursor(unsigned cursor); diff --git a/src/Form/Edit.cpp b/src/Form/Edit.cpp index f308bb64e1a..a599c286159 100644 --- a/src/Form/Edit.cpp +++ b/src/Form/Edit.cpp @@ -75,7 +75,7 @@ WndProperty::OnKillFocus() noexcept } WndProperty::WndProperty(ContainerWindow &parent, const DialogLook &_look, - const TCHAR *Caption, + const char *Caption, const PixelRect &rc, int CaptionWidth, const WindowStyle style) noexcept @@ -97,7 +97,7 @@ WndProperty::WndProperty(const DialogLook &_look) noexcept void WndProperty::Create(ContainerWindow &parent, const PixelRect &rc, - const TCHAR *_caption, + const char *_caption, unsigned _caption_width, const WindowStyle style=WindowStyle()) noexcept { @@ -340,7 +340,7 @@ WndProperty::OnPaint(Canvas &canvas) noexcept } void -WndProperty::SetText(const TCHAR *_value) noexcept +WndProperty::SetText(const char *_value) noexcept { assert(_value != nullptr); diff --git a/src/Form/Edit.hpp b/src/Form/Edit.hpp index 26d9cd71af3..a7edc09de05 100644 --- a/src/Form/Edit.hpp +++ b/src/Form/Edit.hpp @@ -5,7 +5,7 @@ #include "Form/Control.hpp" #include "ui/dim/Rect.hpp" -#include "util/tstring.hpp" +#include struct DialogLook; class DataField; @@ -16,8 +16,8 @@ class ContainerWindow; * an editable field (the Editor). */ class WndProperty : public WindowControl { - typedef bool (*EditCallback)(const TCHAR *caption, DataField &df, - const TCHAR *help_text); + typedef bool (*EditCallback)(const char *caption, DataField &df, + const char *help_text); const DialogLook &look; @@ -27,7 +27,7 @@ class WndProperty : public WindowControl { /** Width reserved for the caption of the Control */ int caption_width; - tstring value; + std::string value; DataField *data_field = nullptr; @@ -45,7 +45,7 @@ class WndProperty : public WindowControl { * @param CaptionWidth Width of the Caption of the Control */ WndProperty(ContainerWindow &parent, const DialogLook &look, - const TCHAR *Caption, + const char *Caption, const PixelRect &rc, int CaptionWidth, const WindowStyle style) noexcept; @@ -55,7 +55,7 @@ class WndProperty : public WindowControl { ~WndProperty() noexcept; void Create(ContainerWindow &parent, const PixelRect &rc, - const TCHAR *_caption, + const char *_caption, unsigned _caption_width, const WindowStyle style) noexcept; @@ -126,7 +126,7 @@ class WndProperty : public WindowControl { edit_callback = _ec; } - const TCHAR *GetText() const noexcept { + const char *GetText() const noexcept { return value.c_str(); } @@ -134,7 +134,7 @@ class WndProperty : public WindowControl { * Sets the Editors text to the given Value * @param Value The new text of the Editor Control */ - void SetText(const TCHAR *_value) noexcept; + void SetText(const char *_value) noexcept; private: /** diff --git a/src/Form/Form.cpp b/src/Form/Form.cpp index 307fa97abe5..65dd2b869b0 100644 --- a/src/Form/Form.cpp +++ b/src/Form/Form.cpp @@ -46,7 +46,7 @@ WndForm::WndForm(const DialogLook &_look) WndForm::WndForm(SingleWindow &main_window, const DialogLook &_look, const PixelRect &rc, - const TCHAR *Caption, + const char *Caption, const WindowStyle style) :look(_look) { @@ -54,7 +54,7 @@ WndForm::WndForm(SingleWindow &main_window, const DialogLook &_look, } WndForm::WndForm(SingleWindow &main_window, const DialogLook &_look, - const TCHAR *caption, + const char *caption, const WindowStyle style) noexcept :WndForm(main_window, _look, main_window.GetClientRect(), caption, style) { @@ -62,7 +62,7 @@ WndForm::WndForm(SingleWindow &main_window, const DialogLook &_look, void WndForm::Create(SingleWindow &main_window, const PixelRect &rc, - const TCHAR *_caption, const WindowStyle style) + const char *_caption, const WindowStyle style) { if (_caption != nullptr) caption = _caption; @@ -78,7 +78,7 @@ WndForm::Create(SingleWindow &main_window, const PixelRect &rc, void WndForm::Create(SingleWindow &main_window, - const TCHAR *_caption, const WindowStyle style) + const char *_caption, const WindowStyle style) { Create(main_window, main_window.GetClientRect(), _caption, style); } @@ -525,10 +525,10 @@ WndForm::OnPaint(Canvas &canvas) noexcept } void -WndForm::SetCaption(const TCHAR *_caption) +WndForm::SetCaption(const char *_caption) { if (_caption == nullptr) - _caption = _T(""); + _caption = ""; if (caption != _caption) { caption = _caption; diff --git a/src/Form/Form.hpp b/src/Form/Form.hpp index 54f94669c6a..47864cae128 100644 --- a/src/Form/Form.hpp +++ b/src/Form/Form.hpp @@ -5,7 +5,8 @@ #include "ui/window/ContainerWindow.hpp" #include "ui/window/SolidContainerWindow.hpp" -#include "util/tstring.hpp" +#include +#include "Form/Button.hpp" #include #include @@ -28,6 +29,9 @@ class WndForm : public ContainerWindow typedef std::function KeyDownFunction; typedef std::function CharacterFunction; + Button *first_button = nullptr; + Button *last_button = nullptr; + protected: const DialogLook &look; @@ -61,7 +65,7 @@ class WndForm : public ContainerWindow void OnPaint(Canvas &canvas) noexcept override; - tstring caption; + std::string caption; public: WndForm(const DialogLook &_look); @@ -73,25 +77,25 @@ class WndForm : public ContainerWindow */ WndForm(UI::SingleWindow &_main_window, const DialogLook &_look, const PixelRect &rc, - const TCHAR *caption=nullptr, + const char *caption=nullptr, const WindowStyle style = WindowStyle()); /** * Construct a full-screen dialog. */ WndForm(UI::SingleWindow &_main_window, const DialogLook &_look, - const TCHAR *caption=nullptr, + const char *caption=nullptr, const WindowStyle style={}) noexcept; void Create(UI::SingleWindow &main_window, const PixelRect &rc, - const TCHAR *caption=nullptr, + const char *caption=nullptr, const WindowStyle style=WindowStyle()); /** * Create a full-screen dialog. */ void Create(UI::SingleWindow &main_window, - const TCHAR *caption=nullptr, + const char *caption=nullptr, const WindowStyle style=WindowStyle()); protected: @@ -137,6 +141,13 @@ class WndForm : public ContainerWindow }; } + auto SetFocusButtonCallback(Button *button) noexcept { + return [this, button]() { + if (this->IsDefined() && button != nullptr) + button->SetFocus(); + }; + } + /** * Enables "modeless": dialog will close if mouse is clicked * anywhere on screen outside the dialog @@ -147,12 +158,12 @@ class WndForm : public ContainerWindow int ShowModal(); - const TCHAR *GetCaption() const { + const char *GetCaption() const { return caption.c_str(); } /** Set the titlebar text */ - void SetCaption(const TCHAR *_caption); + void SetCaption(const char *_caption); /** from class Window */ void OnCreate() override; diff --git a/src/Form/Frame.cpp b/src/Form/Frame.cpp index de44d6742d2..d779e99c4b5 100644 --- a/src/Form/Frame.cpp +++ b/src/Form/Frame.cpp @@ -36,7 +36,7 @@ WndFrame::SetVAlignCenter() noexcept } void -WndFrame::SetText(const TCHAR *_text) noexcept +WndFrame::SetText(const char *_text) noexcept { text = _text; text_renderer.InvalidateLayout(); diff --git a/src/Form/Frame.hpp b/src/Form/Frame.hpp index a26e665bdf3..2c00518a4a5 100644 --- a/src/Form/Frame.hpp +++ b/src/Form/Frame.hpp @@ -6,7 +6,7 @@ #include "ui/window/PaintWindow.hpp" #include "ui/canvas/Color.hpp" #include "Renderer/TextRenderer.hpp" -#include "util/tstring.hpp" +#include #include @@ -19,7 +19,7 @@ class WndFrame : public PaintWindow { TextRenderer text_renderer; - tstring text; + std::string text; public: explicit WndFrame(const DialogLook &look) noexcept; @@ -35,11 +35,11 @@ class WndFrame : public PaintWindow { void SetAlignCenter() noexcept; void SetVAlignCenter() noexcept; - const TCHAR *GetText() const noexcept { + const char *GetText() const noexcept { return text.c_str(); } - void SetText(const TCHAR *_text) noexcept; + void SetText(const char *_text) noexcept; void SetTextColor(const Color &color) noexcept { text_color = color; diff --git a/src/Form/TabDisplay.cpp b/src/Form/TabDisplay.cpp index 7009ae38645..53d65b0dcf9 100644 --- a/src/Form/TabDisplay.cpp +++ b/src/Form/TabDisplay.cpp @@ -24,7 +24,7 @@ class TabDisplay::Button { PixelRect rc; public: - Button(const TCHAR *_caption, const MaskedIcon *_icon) noexcept + Button(const char *_caption, const MaskedIcon *_icon) noexcept :icon(_icon) { caption = _caption; @@ -193,13 +193,13 @@ TabDisplay::CalculateLayout() noexcept } void -TabDisplay::Add(const TCHAR *caption, const MaskedIcon *icon) noexcept +TabDisplay::Add(const char *caption, const MaskedIcon *icon) noexcept { buttons.append(new Button(caption, icon)); CalculateLayout(); } -const TCHAR * +const char * TabDisplay::GetCaption(unsigned i) const noexcept { return buttons[i]->caption.c_str(); diff --git a/src/Form/TabDisplay.hpp b/src/Form/TabDisplay.hpp index cd0021fd9fe..cfa85a70bb1 100644 --- a/src/Form/TabDisplay.hpp +++ b/src/Form/TabDisplay.hpp @@ -62,10 +62,10 @@ class TabDisplay final : public PaintWindow void UpdateLayout(const PixelRect &rc, bool _vertical) noexcept; - void Add(const TCHAR *caption, const MaskedIcon *icon=nullptr) noexcept; + void Add(const char *caption, const MaskedIcon *icon=nullptr) noexcept; [[gnu::pure]] - const TCHAR *GetCaption(unsigned i) const noexcept; + const char *GetCaption(unsigned i) const noexcept; void SetCurrentIndex(unsigned i) noexcept { if (i == current_index) diff --git a/src/Form/TabMenuData.hpp b/src/Form/TabMenuData.hpp index 219b3fd3bd3..41f1999fad7 100644 --- a/src/Form/TabMenuData.hpp +++ b/src/Form/TabMenuData.hpp @@ -10,13 +10,13 @@ class Widget; struct TabMenuPage { - const TCHAR *menu_caption; + const char *menu_caption; std::unique_ptr (*Load)(); }; struct TabMenuGroup { - const TCHAR *caption; + const char *caption; const TabMenuPage *pages; }; diff --git a/src/Form/TabMenuDisplay.cpp b/src/Form/TabMenuDisplay.cpp index 1d9df6b9dd8..fb3ee7c0f7d 100644 --- a/src/Form/TabMenuDisplay.cpp +++ b/src/Form/TabMenuDisplay.cpp @@ -47,13 +47,13 @@ TabMenuDisplay::InitMenu(const TabMenuGroup groups[], } } -const TCHAR * -TabMenuDisplay::GetCaption(TCHAR buffer[], size_t size) const noexcept +const char * +TabMenuDisplay::GetCaption(char buffer[], size_t size) const noexcept { const unsigned page = pager.GetCurrentIndex(); if (page >= PAGE_OFFSET) { const unsigned i = page - PAGE_OFFSET; - StringFormat(buffer, size, _T("%s > %s"), + StringFormat(buffer, size, "%s > %s", gettext(GetPageParentCaption(i)), buttons[i].caption); return buffer; diff --git a/src/Form/TabMenuDisplay.hpp b/src/Form/TabMenuDisplay.hpp index e0b3d771934..e67a71d3dfb 100644 --- a/src/Form/TabMenuDisplay.hpp +++ b/src/Form/TabMenuDisplay.hpp @@ -14,7 +14,12 @@ class PagerWidget; class TabMenuDisplay final : public PaintWindow { /* excludes "Main Menu" which is a "super menu" */ +#ifdef IS_OPENVARIO + static constexpr unsigned MAX_MAIN_MENU_ITEMS = 8; +#else static constexpr unsigned MAX_MAIN_MENU_ITEMS = 7; +#endif + static constexpr unsigned SUB_MAIN_MENU_BUTTOMS = 40; /** * The offset from a page number in the #TabMenuDisplay to a page @@ -28,7 +33,7 @@ class TabMenuDisplay final : public PaintWindow struct SubMenuButton { //TODO MainMenuButton *group; unsigned main_menu_index; - const TCHAR *caption; + const char *caption; PixelRect rc; @@ -45,7 +50,7 @@ class TabMenuDisplay final : public PaintWindow * class that holds the main menu button and info */ struct MainMenuButton { - const TCHAR *caption; + const char *caption; PixelRect rc; @@ -116,7 +121,7 @@ class TabMenuDisplay final : public PaintWindow PagerWidget &pager; const DialogLook &look; - StaticArray buttons; + StaticArray buttons; /* holds info and buttons for the main menu. not on child menus */ StaticArray main_menu_buttons; @@ -146,7 +151,7 @@ class TabMenuDisplay final : public PaintWindow */ void InitMenu(const TabMenuGroup groups[], unsigned n_groups) noexcept; - const TCHAR *GetCaption(TCHAR buffer[], size_t size) const noexcept; + const char *GetCaption(char buffer[], size_t size) const noexcept; /** * Call this from PagerWidget's OnPageFlipped callback. It moves @@ -176,7 +181,7 @@ class TabMenuDisplay final : public PaintWindow return buttons.size(); } - const TCHAR *GetPageParentCaption(unsigned page) const noexcept { + const char *GetPageParentCaption(unsigned page) const noexcept { assert(page < GetNumPages()); return main_menu_buttons[buttons[page].main_menu_index].caption; diff --git a/src/Formatter/AirspaceFormatter.cpp b/src/Formatter/AirspaceFormatter.cpp index 0dfdbb40bc1..30e05eb8845 100644 --- a/src/Formatter/AirspaceFormatter.cpp +++ b/src/Formatter/AirspaceFormatter.cpp @@ -5,25 +5,25 @@ #include "Engine/Airspace/AbstractAirspace.hpp" #include "util/Macros.hpp" -static const TCHAR *const airspace_class_names[] = { - _T("Unknown"), - _T("Restricted"), - _T("Prohibited"), - _T("Danger Area"), - _T("Class A"), - _T("Class B"), - _T("Class C"), - _T("Class D"), - _T("No Gliders"), - _T("CTR"), - _T("Wave"), - _T("Task Area"), - _T("Class E"), - _T("Class F"), - _T("Transponder Mandatory Zone"), - _T("Class G"), - _T("Military Aerodrome Traffic Zone"), - _T("Radio Mandatory Zone"), +static const char *const airspace_class_names[] = { + "Unknown", + "Restricted", + "Prohibited", + "Danger Area", + "Class A", + "Class B", + "Class C", + "Class D", + "No Gliders", + "CTR", + "Wave", + "Task Area", + "Class E", + "Class F", + "Transponder Mandatory Zone", + "Class G", + "Military Aerodrome Traffic Zone", + "Radio Mandatory Zone", }; static_assert(ARRAY_SIZE(airspace_class_names) == @@ -31,25 +31,25 @@ static_assert(ARRAY_SIZE(airspace_class_names) == "number of airspace class names does not match number of " "airspace classes"); -static const TCHAR *const airspace_class_short_names[] = { - _T("?"), - _T("R"), - _T("P"), - _T("Q"), - _T("A"), - _T("B"), - _T("C"), - _T("D"), - _T("GP"), - _T("CTR"), - _T("W"), - _T("AAT"), - _T("E"), - _T("F"), - _T("TMZ"), - _T("G"), - _T("MATZ"), - _T("RMZ"), +static const char *const airspace_class_short_names[] = { + "?", + "R", + "P", + "Q", + "A", + "B", + "C", + "D", + "GP", + "CTR", + "W", + "AAT", + "E", + "F", + "TMZ", + "G", + "MATZ", + "RMZ", }; static_assert(ARRAY_SIZE(airspace_class_short_names) == @@ -57,7 +57,7 @@ static_assert(ARRAY_SIZE(airspace_class_short_names) == "number of airspace class short names does not match number of " "airspace classes"); -const TCHAR * +const char * AirspaceFormatter::GetClass(AirspaceClass airspace_class) { unsigned i = (unsigned)airspace_class; @@ -66,7 +66,7 @@ AirspaceFormatter::GetClass(AirspaceClass airspace_class) airspace_class_names[i] : NULL; } -const TCHAR * +const char * AirspaceFormatter::GetClassShort(AirspaceClass airspace_class) { unsigned i = (unsigned)airspace_class; @@ -75,19 +75,19 @@ AirspaceFormatter::GetClassShort(AirspaceClass airspace_class) airspace_class_short_names[i] : NULL; } -const TCHAR * +const char * AirspaceFormatter::GetClass(const AbstractAirspace &airspace) { return GetClass(airspace.GetClass()); } -const TCHAR * +const char * AirspaceFormatter::GetClassShort(const AbstractAirspace &airspace) { return GetClassShort(airspace.GetClass()); } -const TCHAR * +const char * AirspaceFormatter::GetType(const AbstractAirspace &airspace) { return airspace.GetType(); diff --git a/src/Formatter/AirspaceFormatter.hpp b/src/Formatter/AirspaceFormatter.hpp index 4a8801953c9..25feba521d5 100644 --- a/src/Formatter/AirspaceFormatter.hpp +++ b/src/Formatter/AirspaceFormatter.hpp @@ -14,28 +14,28 @@ namespace AirspaceFormatter { /** Returns the airspace class as text. */ [[gnu::const]] -const TCHAR *GetClass(AirspaceClass airspace_class); +const char *GetClass(AirspaceClass airspace_class); /** Returns the airspace class as short text. */ [[gnu::const]] -const TCHAR *GetClassShort(AirspaceClass airspace_class); +const char *GetClassShort(AirspaceClass airspace_class); /** Returns the class of the airspace as text. */ [[gnu::pure]] -const TCHAR *GetClass(const AbstractAirspace &airspace); +const char *GetClass(const AbstractAirspace &airspace); /** Returns the class of the airspace as short text. */ [[gnu::pure]] -const TCHAR *GetClassShort(const AbstractAirspace &airspace); +const char *GetClassShort(const AbstractAirspace &airspace); /** Returns the airspace altitude limit as text with unit. */ - void FormatAltitude(TCHAR *buffer, const AirspaceAltitude &altitude); + void FormatAltitude(char *buffer, const AirspaceAltitude &altitude); /** Returns the airspace altitude limit as short text with unit. */ - void FormatAltitudeShort(TCHAR *buffer, const AirspaceAltitude &altitude, + void FormatAltitudeShort(char *buffer, const AirspaceAltitude &altitude, bool include_unit = true); /** Returns the type of the airspace as text. */ [[gnu::pure]] -const TCHAR *GetType(const AbstractAirspace &airspace); +const char *GetType(const AbstractAirspace &airspace); } diff --git a/src/Formatter/AirspaceUserUnitsFormatter.cpp b/src/Formatter/AirspaceUserUnitsFormatter.cpp index b709e0faba4..165e601001e 100644 --- a/src/Formatter/AirspaceUserUnitsFormatter.cpp +++ b/src/Formatter/AirspaceUserUnitsFormatter.cpp @@ -11,42 +11,42 @@ #include void -AirspaceFormatter::FormatAltitudeShort(TCHAR *buffer, +AirspaceFormatter::FormatAltitudeShort(char *buffer, const AirspaceAltitude &altitude, bool include_unit) { switch (altitude.reference) { case AltitudeReference::AGL: if (altitude.altitude_above_terrain <= 0) - _tcscpy(buffer, _T("GND")); + strcpy(buffer, "GND"); else if (include_unit) - StringFormatUnsafe(buffer, _T("%d %s AGL"), + StringFormatUnsafe(buffer, "%d %s AGL", iround(Units::ToUserAltitude(altitude.altitude_above_terrain)), Units::GetAltitudeName()); else - StringFormatUnsafe(buffer, _T("%d AGL"), + StringFormatUnsafe(buffer, "%d AGL", iround(Units::ToUserAltitude(altitude.altitude_above_terrain))); break; case AltitudeReference::STD: - StringFormatUnsafe(buffer, _T("FL%d"), iround(altitude.flight_level)); + StringFormatUnsafe(buffer, "FL%d", iround(altitude.flight_level)); break; case AltitudeReference::MSL: if (include_unit) - StringFormatUnsafe(buffer, _T("%d %s"), + StringFormatUnsafe(buffer, "%d %s", iround(Units::ToUserAltitude(altitude.altitude)), Units::GetAltitudeName()); else - StringFormatUnsafe(buffer, _T("%d"), + StringFormatUnsafe(buffer, "%d", iround(Units::ToUserAltitude(altitude.altitude))); break; } } void -AirspaceFormatter::FormatAltitude(TCHAR *buffer, +AirspaceFormatter::FormatAltitude(char *buffer, const AirspaceAltitude &altitude) { FormatAltitudeShort(buffer, altitude); @@ -56,13 +56,13 @@ AirspaceFormatter::FormatAltitude(TCHAR *buffer, Units::GetUserAltitudeUnit() == Unit::METER) /* additionally show airspace altitude in feet, because aviation charts usually print altitudes in feet */ - StringFormatUnsafe(buffer + _tcslen(buffer), _T(" (%d %s)"), + StringFormatUnsafe(buffer + strlen(buffer), " (%d %s)", iround(Units::ToUserUnit(altitude.altitude, Unit::FEET)), Units::GetUnitName(Unit::FEET)); if (altitude.reference != AltitudeReference::MSL && altitude.altitude > 0) - StringFormatUnsafe(buffer + _tcslen(buffer), _T(" %d %s"), + StringFormatUnsafe(buffer + strlen(buffer), " %d %s", iround(Units::ToUserAltitude(altitude.altitude)), Units::GetAltitudeName()); } diff --git a/src/Formatter/AngleFormatter.cpp b/src/Formatter/AngleFormatter.cpp index de6467c1f2f..6dae4c171a9 100644 --- a/src/Formatter/AngleFormatter.cpp +++ b/src/Formatter/AngleFormatter.cpp @@ -9,48 +9,48 @@ #include void -FormatBearing(TCHAR *buffer, size_t size, unsigned value_degrees, - const TCHAR *suffix) +FormatBearing(char *buffer, size_t size, unsigned value_degrees, + const char *suffix) { assert(buffer != NULL); assert(size >= 8); if (suffix != NULL) - StringFormat(buffer, size, _T("%u° %s"), value_degrees, suffix); + StringFormat(buffer, size, "%u° %s", value_degrees, suffix); else - StringFormat(buffer, size, _T("%u°"), value_degrees); + StringFormat(buffer, size, "%u°", value_degrees); } void -FormatBearing(TCHAR *buffer, size_t size, Angle value, const TCHAR *suffix) +FormatBearing(char *buffer, size_t size, Angle value, const char *suffix) { FormatBearing(buffer, size, lround(value.AsBearing().Degrees()), suffix); } void -FormatAngleDelta(TCHAR *buffer, size_t size, Angle value) +FormatAngleDelta(char *buffer, size_t size, Angle value) { assert(buffer != NULL); assert(size >= 8); auto degrees = lround(value.AsDelta().Degrees()); if (degrees > 1) - StringFormat(buffer, size, _T("%u°»"), unsigned(degrees)); + StringFormat(buffer, size, "%u°»", unsigned(degrees)); else if (degrees < -1) - StringFormat(buffer, size, _T("«%u°"), unsigned(-degrees)); + StringFormat(buffer, size, "«%u°", unsigned(-degrees)); else - _tcscpy(buffer, _T("«»")); + strcpy(buffer, "« * »"); } void -FormatVerticalAngleDelta(TCHAR *buffer, size_t size, Angle value) +FormatVerticalAngleDelta(char *buffer, size_t size, Angle value) { assert(buffer != NULL); assert(size >= 8); auto degrees = lround(value.AsDelta().Degrees()); if (degrees < -1 || degrees > 1) - StringFormat(buffer, size, _T("%+d°"), int(degrees)); + StringFormat(buffer, size, "%+d°", int(degrees)); else - _tcscpy(buffer, _T("--")); + strcpy(buffer, "--"); } diff --git a/src/Formatter/AngleFormatter.hpp b/src/Formatter/AngleFormatter.hpp index 21491ac9015..4d9ee0f2b46 100644 --- a/src/Formatter/AngleFormatter.hpp +++ b/src/Formatter/AngleFormatter.hpp @@ -13,42 +13,42 @@ class Angle; void -FormatBearing(TCHAR *buffer, size_t size, unsigned degrees_value, - const TCHAR *suffix = NULL); +FormatBearing(char *buffer, size_t size, unsigned degrees_value, + const char *suffix = NULL); void -FormatBearing(TCHAR *buffer, size_t size, Angle value, - const TCHAR *suffix = NULL); +FormatBearing(char *buffer, size_t size, Angle value, + const char *suffix = NULL); [[gnu::const]] -static inline BasicStringBuffer +static inline BasicStringBuffer FormatBearing(unsigned degrees_value) { - BasicStringBuffer buffer; + BasicStringBuffer buffer; FormatBearing(buffer.data(), buffer.capacity(), degrees_value); return buffer; } [[gnu::const]] -static inline BasicStringBuffer +static inline BasicStringBuffer FormatBearing(Angle value) { - BasicStringBuffer buffer; + BasicStringBuffer buffer; FormatBearing(buffer.data(), buffer.capacity(), value); return buffer; } void -FormatAngleDelta(TCHAR *buffer, size_t size, Angle value); +FormatAngleDelta(char *buffer, size_t size, Angle value); [[gnu::const]] -static inline BasicStringBuffer +static inline BasicStringBuffer FormatAngleDelta(Angle value) { - BasicStringBuffer buffer; + BasicStringBuffer buffer; FormatAngleDelta(buffer.data(), buffer.capacity(), value); return buffer; } void -FormatVerticalAngleDelta(TCHAR *buffer, size_t size, Angle value); +FormatVerticalAngleDelta(char *buffer, size_t size, Angle value); diff --git a/src/Formatter/ByteSizeFormatter.cpp b/src/Formatter/ByteSizeFormatter.cpp index f05c4bf39bf..0adbe8afc57 100644 --- a/src/Formatter/ByteSizeFormatter.cpp +++ b/src/Formatter/ByteSizeFormatter.cpp @@ -8,28 +8,28 @@ #include void -FormatByteSize(TCHAR *buffer, size_t size, unsigned long bytes, bool simple) +FormatByteSize(char *buffer, size_t size, unsigned long bytes, bool simple) { assert(buffer != NULL); assert(size >= 8); - static const TCHAR *const units[] = { _T("B"), _T("KB"), _T("MB"), _T("GB") }; - static const TCHAR *const simple_units[] = { _T("B"), _T("K"), _T("M"), _T("G") }; + static const char *const units[] = { "B", "KB", "MB", "GB" }; + static const char *const simple_units[] = { "B", "K", "M", "G" }; double value = bytes; unsigned i = 0; for (; value >= 1024 && i < ARRAY_SIZE(units)-1; i++, value /= 1024); - const TCHAR *unit = simple ? simple_units[i] : units[i]; + const char *unit = simple ? simple_units[i] : units[i]; - const TCHAR *format; + const char *format; if (value >= 100 || i == 0) - format = simple ? _T("%.0f%s") : _T("%.0f %s"); + format = simple ? "%.0f%s" : "%.0f %s"; else if (value >= 10) - format = simple ? _T("%.1f%s") : _T("%.1f %s"); + format = simple ? "%.1f%s" : "%.1f %s"; else - format = simple ? _T("%.1f%s") : _T("%.2f %s"); + format = simple ? "%.1f%s" : "%.2f %s"; StringFormat(buffer, size, format, value, unit); } diff --git a/src/Formatter/ByteSizeFormatter.hpp b/src/Formatter/ByteSizeFormatter.hpp index fc477a9cef9..cdcf70c450d 100644 --- a/src/Formatter/ByteSizeFormatter.hpp +++ b/src/Formatter/ByteSizeFormatter.hpp @@ -6,5 +6,5 @@ #include #include -void FormatByteSize(TCHAR *buffer, size_t size, +void FormatByteSize(char *buffer, size_t size, unsigned long bytes, bool simple = false); diff --git a/src/Formatter/CMakeLists.txt b/src/Formatter/CMakeLists.txt new file mode 100644 index 00000000000..0b7e1f84f97 --- /dev/null +++ b/src/Formatter/CMakeLists.txt @@ -0,0 +1,49 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/Formatter/CMakeSource.cmake b/src/Formatter/CMakeSource.cmake new file mode 100644 index 00000000000..466d9f6f257 --- /dev/null +++ b/src/Formatter/CMakeSource.cmake @@ -0,0 +1,22 @@ +set(_SOURCES + Formatter/AirspaceFormatter.cpp + Formatter/AirspaceUserUnitsFormatter.cpp + Formatter/AngleFormatter.cpp + Formatter/ByteSizeFormatter.cpp + Formatter/GeoPointFormatter.cpp + Formatter/GlideRatioFormatter.cpp + Formatter/HexColor.cpp + Formatter/NMEAFormatter.cpp + Formatter/IGCFilenameFormatter.cpp + Formatter/LocalTimeFormatter.cpp + Formatter/TimeFormatter.cpp + Formatter/Units.cpp + Formatter/UserGeoPointFormatter.cpp + Formatter/UserUnits.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake +) + + diff --git a/src/Formatter/GeoPointFormatter.cpp b/src/Formatter/GeoPointFormatter.cpp index 201178c1994..fba008a650a 100644 --- a/src/Formatter/GeoPointFormatter.cpp +++ b/src/Formatter/GeoPointFormatter.cpp @@ -24,13 +24,13 @@ #include "util/StringAPI.hxx" bool -FormatLongitude(Angle longitude, TCHAR *buffer, size_t size, +FormatLongitude(Angle longitude, char *buffer, size_t size, CoordinateFormat format) { int dd, mm, ss; // Calculate Longitude sign - TCHAR sign = longitude.IsNegative() ? _T('W') : _T('E'); + char sign = longitude.IsNegative() ? 'W' : 'E'; double mlong(longitude.AbsoluteDegrees()); @@ -53,7 +53,7 @@ FormatLongitude(Angle longitude, TCHAR *buffer, size_t size, mm -= 60; } // Save the string to the buffer - StringFormat(buffer, size, _T("%03d" ) _T(DEG) _T("%02d'%02d\" %c"), + StringFormat(buffer, size, "%03d" DEG "%02d'%02d\" %c", dd, mm, ss, sign); break; @@ -66,7 +66,7 @@ FormatLongitude(Angle longitude, TCHAR *buffer, size_t size, // Calculate seconds mlong = (mlong - mm) * 60.0; // Save the string to the buffer - StringFormat(buffer, size, _T("%03d") _T(DEG) _T("%02d'%04.1f\" %c"), + StringFormat(buffer, size, "%03d" DEG "%02d'%04.1f\" %c", dd, mm, mlong, sign); break; @@ -76,13 +76,13 @@ FormatLongitude(Angle longitude, TCHAR *buffer, size_t size, // Calculate minutes mlong = (mlong - dd) * 60.0; // Save the string to the buffer - StringFormat(buffer, size, _T("%03d") _T(DEG) _T("%06.3f' %c"), + StringFormat(buffer, size, "%03d" DEG "%06.3f' %c", dd, mlong, sign); break; case CoordinateFormat::DD_DDDDD: // Save the string to the buffer - StringFormat(buffer, size, _T("%09.5f" DEG " %c"), mlong, sign); + StringFormat(buffer, size, "%09.5f" DEG " %c", mlong, sign); break; case CoordinateFormat::UTM: @@ -93,13 +93,13 @@ FormatLongitude(Angle longitude, TCHAR *buffer, size_t size, } bool -FormatLatitude(Angle latitude, TCHAR *buffer, size_t size, +FormatLatitude(Angle latitude, char *buffer, size_t size, CoordinateFormat format) { int dd, mm, ss; // Calculate Latitude sign - TCHAR sign = latitude.IsNegative() ? _T('S') : _T('N'); + char sign = latitude.IsNegative() ? 'S' : 'N'; double mlat(latitude.AbsoluteDegrees()); @@ -122,7 +122,7 @@ FormatLatitude(Angle latitude, TCHAR *buffer, size_t size, mm -= 60; } // Save the string to the buffer - StringFormat(buffer, size, _T("%02d") _T(DEG) _T("%02d'%02d\" %c"), + StringFormat(buffer, size, "%02d" DEG "%02d'%02d\" %c", dd, mm, ss, sign); break; @@ -135,7 +135,7 @@ FormatLatitude(Angle latitude, TCHAR *buffer, size_t size, // Calculate seconds mlat = (mlat - mm) * 60.0; // Save the string to the buffer - StringFormat(buffer, size, _T("%02d") _T(DEG) _T("%02d'%04.1f\" %c"), + StringFormat(buffer, size, "%02d" DEG "%02d'%04.1f\" %c", dd, mm, mlat, sign); break; @@ -145,13 +145,13 @@ FormatLatitude(Angle latitude, TCHAR *buffer, size_t size, // Calculate minutes mlat = (mlat - dd) * 60.0; // Save the string to the buffer - StringFormat(buffer, size, _T("%02d") _T(DEG) _T("%06.3f' %c"), + StringFormat(buffer, size, "%02d" DEG "%06.3f' %c", dd, mlat, sign); break; case CoordinateFormat::DD_DDDDD: // Save the string to the buffer - StringFormat(buffer, size, _T("%08.5f" DEG " %c"), mlat, sign); + StringFormat(buffer, size, "%08.5f" DEG " %c", mlat, sign); break; case CoordinateFormat::UTM: @@ -161,21 +161,21 @@ FormatLatitude(Angle latitude, TCHAR *buffer, size_t size, return true; } -static TCHAR * -FormatUTM(const GeoPoint &location, TCHAR *buffer, size_t size, - TCHAR separator = _T(' ')) +static char * +FormatUTM(const GeoPoint &location, char *buffer, size_t size, + char separator = ' ') { UTM utm = UTM::FromGeoPoint(location); - StringFormat(buffer, size, _T("%u%c%c%.0f%c%.0f"), + StringFormat(buffer, size, "%u%c%c%.0f%c%.0f", utm.zone_number, utm.zone_letter, separator, (double)utm.easting, separator, (double)utm.northing); return buffer; } -TCHAR * -FormatGeoPoint(const GeoPoint &location, TCHAR *buffer, size_t size, - CoordinateFormat format, TCHAR separator) +char * +FormatGeoPoint(const GeoPoint &location, char *buffer, size_t size, + CoordinateFormat format, char separator) { if (format == CoordinateFormat::UTM) return FormatUTM(location, buffer, size, separator); @@ -183,7 +183,7 @@ FormatGeoPoint(const GeoPoint &location, TCHAR *buffer, size_t size, if (!FormatLatitude(location.latitude, buffer, size, format)) return nullptr; - TCHAR *end = buffer + size, *p = buffer + StringLength(buffer); + char *end = buffer + size, *p = buffer + StringLength(buffer); if (p >= end) return nullptr; diff --git a/src/Formatter/GeoPointFormatter.hpp b/src/Formatter/GeoPointFormatter.hpp index 31b23bd2344..12a22baac75 100644 --- a/src/Formatter/GeoPointFormatter.hpp +++ b/src/Formatter/GeoPointFormatter.hpp @@ -18,7 +18,7 @@ struct GeoPoint; * @param buffer buffer string to write to (pointer) * @param size Size of the buffer */ -bool FormatLongitude(Angle longitude, TCHAR *buffer, size_t size, +bool FormatLongitude(Angle longitude, char *buffer, size_t size, CoordinateFormat format); /** @@ -27,21 +27,21 @@ bool FormatLongitude(Angle longitude, TCHAR *buffer, size_t size, * @param buffer buffer string to write to (pointer) * @param size Size of the buffer */ -bool FormatLatitude(Angle latitude, TCHAR *buffer, size_t size, +bool FormatLatitude(Angle latitude, char *buffer, size_t size, CoordinateFormat format); /** * Convert a GeoPoint into a formatted string. */ -TCHAR *FormatGeoPoint(const GeoPoint &location, TCHAR *buffer, size_t size, - CoordinateFormat format, TCHAR separator = _T(' ')); +char *FormatGeoPoint(const GeoPoint &location, char *buffer, size_t size, + CoordinateFormat format, char separator = ' '); [[gnu::pure]] -static inline BasicStringBuffer +static inline BasicStringBuffer FormatGeoPoint(const GeoPoint &location, CoordinateFormat format, - TCHAR separator = _T(' ')) + char separator = ' ') { - BasicStringBuffer buffer; + BasicStringBuffer buffer; auto result = FormatGeoPoint(location, buffer.data(), buffer.capacity(), format, separator); if (result == nullptr) diff --git a/src/Formatter/GlideRatioFormatter.cpp b/src/Formatter/GlideRatioFormatter.cpp index 8c15bc83735..e43bac94e4d 100644 --- a/src/Formatter/GlideRatioFormatter.cpp +++ b/src/Formatter/GlideRatioFormatter.cpp @@ -8,11 +8,11 @@ #include void -FormatGlideRatio(TCHAR *buffer, size_t size, double gr) +FormatGlideRatio(char *buffer, size_t size, double gr) { assert(buffer != NULL); assert(size >= 8); StringFormat(buffer, size, - fabs(gr) < 100 ? _T("%.1f") : _T("%.0f"), (double) gr); + fabs(gr) < 100 ? "%.1f" : "%.0f", (double) gr); } diff --git a/src/Formatter/GlideRatioFormatter.hpp b/src/Formatter/GlideRatioFormatter.hpp index f990bbb4044..c1fc5671205 100644 --- a/src/Formatter/GlideRatioFormatter.hpp +++ b/src/Formatter/GlideRatioFormatter.hpp @@ -7,4 +7,4 @@ #include void -FormatGlideRatio(TCHAR *buffer, size_t size, double gr); +FormatGlideRatio(char *buffer, size_t size, double gr); diff --git a/src/Formatter/HexColor.cpp b/src/Formatter/HexColor.cpp index 158c87e7ef7..7beaaae0186 100644 --- a/src/Formatter/HexColor.cpp +++ b/src/Formatter/HexColor.cpp @@ -38,27 +38,3 @@ ParseHexColor(const char *buffer, RGB8Color &color) return true; } -#ifdef _UNICODE - -bool -ParseHexColor(const TCHAR *buffer, RGB8Color &color) -{ - if (*buffer != _T('#')) - return false; - - buffer++; - - TCHAR *endptr; - unsigned value = ParseUnsigned(buffer, &endptr, 16); - if (endptr != buffer + 6) - return false; - - uint8_t r = value >> 16; - uint8_t g = value >> 8; - uint8_t b = value; - - color = RGB8Color(r, g, b); - return true; -} - -#endif diff --git a/src/Formatter/HexColor.hpp b/src/Formatter/HexColor.hpp index c8f3e457a9b..458dc9c8b03 100644 --- a/src/Formatter/HexColor.hpp +++ b/src/Formatter/HexColor.hpp @@ -3,10 +3,6 @@ #pragma once -#ifdef _UNICODE -#include -#endif - #include class RGB8Color; @@ -20,9 +16,3 @@ FormatHexColor(char *buffer, size_t size, const RGB8Color color); bool ParseHexColor(const char *buffer, RGB8Color &color); -#ifdef _UNICODE - -bool -ParseHexColor(const TCHAR *buffer, RGB8Color &color); - -#endif diff --git a/src/Formatter/IGCFilenameFormatter.cpp b/src/Formatter/IGCFilenameFormatter.cpp index e6d48b6203b..3453fd24af9 100644 --- a/src/Formatter/IGCFilenameFormatter.cpp +++ b/src/Formatter/IGCFilenameFormatter.cpp @@ -5,100 +5,55 @@ #include "time/BrokenDate.hpp" #include "util/StringFormat.hpp" -#ifdef _UNICODE -#include -#endif - #include #include -static TCHAR +static char NumToIGCChar(unsigned num) { assert(num <= 35); if (num < 10) - return _T('1') + (num - 1); + return '1' + (num - 1); - return _T('A') + (num - 10); + return 'A' + (num - 10); } void -FormatIGCFilename(TCHAR* buffer, const BrokenDate &date, - TCHAR manufacturer, const TCHAR *logger_id, +FormatIGCFilename(char* buffer, const BrokenDate &date, + char manufacturer, const char *logger_id, unsigned flight_number) { assert(logger_id != NULL); - assert(_tcslen(logger_id) == 3); + assert(strlen(logger_id) == 3); - TCHAR cyear = NumToIGCChar(date.year % 10); - TCHAR cmonth = NumToIGCChar(date.month); - TCHAR cday = NumToIGCChar(date.day); - TCHAR cflight = NumToIGCChar(flight_number); + char cyear = NumToIGCChar(date.year % 10); + char cmonth = NumToIGCChar(date.month); + char cday = NumToIGCChar(date.day); + char cflight = NumToIGCChar(flight_number); - StringFormatUnsafe(buffer, _T("%c%c%c%c%s%c.igc"), + StringFormatUnsafe(buffer, "%c%c%c%c%s%c.igc", cyear, cmonth, cday, manufacturer, logger_id, cflight); } void -FormatIGCFilenameLong(TCHAR* buffer, const BrokenDate &date, - const TCHAR *manufacturer, const TCHAR *logger_id, +FormatIGCFilenameLong(char* buffer, const BrokenDate &date, + const char *manufacturer, const char *logger_id, unsigned flight_number) { // 2003-12-31-XYZ-987-01.igc // long filename form of IGC file. // XYZ represents manufacturer code - assert(manufacturer != NULL); - assert(_tcslen(manufacturer) == 3); - - assert(logger_id != NULL); - assert(_tcslen(logger_id) == 3); - - StringFormatUnsafe(buffer, _T("%04u-%02u-%02u-%s-%s-%02u.igc"), - date.year, date.month, date.day, - manufacturer, logger_id, flight_number); -} - -#ifdef _UNICODE - -void -FormatIGCFilename(TCHAR* buffer, const BrokenDate &date, - char manufacturer, const char *logger_id, - unsigned flight_number) -{ - assert(logger_id != NULL); - assert(strlen(logger_id) == 3); - - TCHAR logger_id_t[4]; - /* poor man's char->TCHAR converted; this works because we know - we're dealing with ASCII only */ - std::copy_n(logger_id, 4, logger_id_t); - - FormatIGCFilename(buffer, date, (TCHAR)manufacturer, logger_id_t, - flight_number); -} - -void -FormatIGCFilenameLong(TCHAR* buffer, const BrokenDate &date, - const char *manufacturer, const char *logger_id, - unsigned flight_number) -{ assert(manufacturer != NULL); assert(strlen(manufacturer) == 3); assert(logger_id != NULL); assert(strlen(logger_id) == 3); - TCHAR manufacturer_t[4], logger_id_t[4]; - /* poor man's char->TCHAR converted; this works because we know - we're dealing with ASCII only */ - std::copy_n(manufacturer, 4, manufacturer_t); - std::copy_n(logger_id, 4, logger_id_t); - - FormatIGCFilenameLong(buffer, date, manufacturer_t, logger_id_t, - flight_number); + StringFormatUnsafe(buffer, "%04u-%02u-%02u-%s-%s-%02u.igc", + date.year, date.month, date.day, + manufacturer, logger_id, flight_number); } -#endif diff --git a/src/Formatter/IGCFilenameFormatter.hpp b/src/Formatter/IGCFilenameFormatter.hpp index eae431d1fcb..d5c92f38ff8 100644 --- a/src/Formatter/IGCFilenameFormatter.hpp +++ b/src/Formatter/IGCFilenameFormatter.hpp @@ -7,20 +7,10 @@ struct BrokenDate; -void FormatIGCFilename(TCHAR* buffer, const BrokenDate &date, - TCHAR manufacturer, const TCHAR *logger_id, - unsigned flight_number); -void FormatIGCFilenameLong(TCHAR* buffer, const BrokenDate &date, - const TCHAR *manufacturer, const TCHAR *logger_id, - unsigned flight_number); - -#ifdef _UNICODE - -void FormatIGCFilename(TCHAR* buffer, const BrokenDate &date, +void FormatIGCFilename(char* buffer, const BrokenDate &date, char manufacturer, const char *logger_id, unsigned flight_number); -void FormatIGCFilenameLong(TCHAR* buffer, const BrokenDate &date, +void FormatIGCFilenameLong(char* buffer, const BrokenDate &date, const char *manufacturer, const char *logger_id, unsigned flight_number); -#endif diff --git a/src/Formatter/LocalTimeFormatter.cpp b/src/Formatter/LocalTimeFormatter.cpp index 9b3be827e06..5cb219c3982 100644 --- a/src/Formatter/LocalTimeFormatter.cpp +++ b/src/Formatter/LocalTimeFormatter.cpp @@ -7,7 +7,7 @@ #include "time/RoughTime.hpp" void -FormatLocalTimeHHMM(TCHAR *buffer, TimeStamp time, +FormatLocalTimeHHMM(char *buffer, TimeStamp time, RoughTimeDelta utc_offset) noexcept { FormatTimeHHMM(buffer, TimeLocal(time, utc_offset)); diff --git a/src/Formatter/LocalTimeFormatter.hpp b/src/Formatter/LocalTimeFormatter.hpp index 3d0f0c3e576..eae8d44be67 100644 --- a/src/Formatter/LocalTimeFormatter.hpp +++ b/src/Formatter/LocalTimeFormatter.hpp @@ -18,15 +18,15 @@ class RoughTimeDelta; * @param time UTC time of day [seconds] */ void -FormatLocalTimeHHMM(TCHAR *buffer, TimeStamp time, +FormatLocalTimeHHMM(char *buffer, TimeStamp time, RoughTimeDelta utc_offset) noexcept; [[gnu::const]] -static inline BasicStringBuffer +static inline BasicStringBuffer FormatLocalTimeHHMM(TimeStamp time, RoughTimeDelta utc_offset) noexcept { - BasicStringBuffer buffer; + BasicStringBuffer buffer; FormatLocalTimeHHMM(buffer.data(), time, utc_offset); return buffer; } diff --git a/src/Formatter/NMEAFormatter.cpp b/src/Formatter/NMEAFormatter.cpp index 54b42658efc..12e655f3c9f 100644 --- a/src/Formatter/NMEAFormatter.cpp +++ b/src/Formatter/NMEAFormatter.cpp @@ -82,7 +82,7 @@ FormatGPGSA(char *buffer, size_t buffer_size, const NMEAInfo &info) noexcept else gps_status = 3; - NarrowString<256> sat_ids; + StaticString<256> sat_ids; sat_ids.clear(); for (unsigned i = 0; i < GPSState::MAXSATELLITES; ++i) { if (info.gps.satellite_ids[i] > 0 && info.gps.satellite_ids_available) { diff --git a/src/Formatter/TimeFormatter.cpp b/src/Formatter/TimeFormatter.cpp index 3357fee6bee..97fb9a49d57 100644 --- a/src/Formatter/TimeFormatter.cpp +++ b/src/Formatter/TimeFormatter.cpp @@ -17,15 +17,6 @@ FormatISO8601(char *buffer, const BrokenDate &date) noexcept date.year, date.month, date.day); } -#ifdef _UNICODE -void -FormatISO8601(TCHAR *buffer, const BrokenDate &date) noexcept -{ - _stprintf(buffer, _T("%04u-%02u-%02u"), - date.year, date.month, date.day); -} -#endif - void FormatISO8601(char *buffer, const BrokenDateTime &stamp) noexcept { @@ -34,34 +25,24 @@ FormatISO8601(char *buffer, const BrokenDateTime &stamp) noexcept stamp.hour, stamp.minute, stamp.second); } -#ifdef _UNICODE -void -FormatISO8601(TCHAR *buffer, const BrokenDateTime &stamp) noexcept -{ - _stprintf(buffer, _T("%04u-%02u-%02uT%02u:%02u:%02uZ"), - stamp.year, stamp.month, stamp.day, - stamp.hour, stamp.minute, stamp.second); -} -#endif - void -FormatTime(TCHAR *buffer, FloatDuration _time) noexcept +FormatTime(char *buffer, FloatDuration _time) noexcept { if (_time.count() < 0) { - *buffer++ = _T('-'); + *buffer++ = '-'; _time = -_time; } const BrokenTime time = BrokenTime::FromSinceMidnightChecked(_time); - _stprintf(buffer, _T("%02u:%02u:%02u"), + _stprintf(buffer, "%02u:%02u:%02u", time.hour, time.minute, time.second); } void -FormatTimeLong(TCHAR *buffer, FloatDuration _time) noexcept +FormatTimeLong(char *buffer, FloatDuration _time) noexcept { if (_time.count() < 0) { - *buffer++ = _T('-'); + *buffer++ = '-'; _time = -_time; } @@ -70,37 +51,37 @@ FormatTimeLong(TCHAR *buffer, FloatDuration _time) noexcept _time -= FloatDuration{trunc(_time.count())}; unsigned millisecond = uround(_time.count() * 1000); - _stprintf(buffer, _T("%02u:%02u:%02u.%03u"), + _stprintf(buffer, "%02u:%02u:%02u.%03u", time.hour, time.minute, time.second, millisecond); } void -FormatSignedTimeHHMM(TCHAR *buffer, std::chrono::seconds _time) noexcept +FormatSignedTimeHHMM(char *buffer, std::chrono::seconds _time) noexcept { if (_time.count() < 0) { - *buffer++ = _T('-'); + *buffer++ = '-'; _time = -_time; } const BrokenTime time = BrokenTime::FromSinceMidnightChecked(_time); - _stprintf(buffer, _T("%02u:%02u"), time.hour, time.minute); + _stprintf(buffer, "%02u:%02u", time.hour, time.minute); } void -FormatTimeTwoLines(TCHAR *buffer1, TCHAR *buffer2, std::chrono::seconds _time) noexcept +FormatTimeTwoLines(char *buffer1, char *buffer2, std::chrono::seconds _time) noexcept { if (_time >= std::chrono::hours{24}) { - _tcscpy(buffer1, _T(">24h")); + strcpy(buffer1, ">24h"); buffer2[0] = '\0'; return; } if (_time <= -std::chrono::hours{24}) { - _tcscpy(buffer1, _T("<-24h")); + strcpy(buffer1, "<-24h"); buffer2[0] = '\0'; return; } if (_time.count() < 0) { - *buffer1++ = _T('-'); + *buffer1++ = '-'; _time = -_time; } @@ -108,10 +89,10 @@ FormatTimeTwoLines(TCHAR *buffer1, TCHAR *buffer2, std::chrono::seconds _time) n if (time.hour > 0) { // hh:mm, ss // Set Value - _stprintf(buffer1, _T("%02u:%02u"), time.hour, time.minute); - _stprintf(buffer2, _T("%02u"), time.second); + _stprintf(buffer1, "%02u:%02u", time.hour, time.minute); + _stprintf(buffer2, "%02u", time.second); } else { // mm'ss - _stprintf(buffer1, _T("%02u'%02u"), time.minute, time.second); + _stprintf(buffer1, "%02u'%02u", time.minute, time.second); buffer2[0] = '\0'; } } @@ -142,9 +123,9 @@ CalculateTimespanComponents(unsigned timespan, unsigned &days, unsigned &hours, } void -FormatTimespanSmart(TCHAR *buffer, std::chrono::seconds timespan, +FormatTimespanSmart(char *buffer, std::chrono::seconds timespan, unsigned max_tokens, - const TCHAR *separator) noexcept + const char *separator) noexcept { assert(max_tokens > 0 && max_tokens <= 4); @@ -196,40 +177,40 @@ FormatTimespanSmart(TCHAR *buffer, std::chrono::seconds timespan, // Output if (timespan.count() < 0) { - *buffer = _T('-'); + *buffer = '-'; buffer++; } - *buffer = _T('\0'); + *buffer = '\0'; StaticString<16> component_buffer; if (show_days) { - component_buffer.Format(_T("%u days"), days); - _tcscat(buffer, component_buffer); + component_buffer.Format("%u days", days); + strcat(buffer, component_buffer); } if (show_hours) { if (!StringIsEmpty(buffer)) - _tcscat(buffer, separator); + strcat(buffer, separator); - component_buffer.Format(_T("%u h"), hours); - _tcscat(buffer, component_buffer); + component_buffer.Format("%u h", hours); + strcat(buffer, component_buffer); } if (show_minutes) { if (!StringIsEmpty(buffer)) - _tcscat(buffer, separator); + strcat(buffer, separator); - component_buffer.Format(_T("%u min"), minutes); - _tcscat(buffer, component_buffer); + component_buffer.Format("%u min", minutes); + strcat(buffer, component_buffer); } if (show_seconds) { if (!StringIsEmpty(buffer)) - _tcscat(buffer, separator); + strcat(buffer, separator); - component_buffer.Format(_T("%u sec"), seconds); - _tcscat(buffer, component_buffer); + component_buffer.Format("%u sec", seconds); + strcat(buffer, component_buffer); } } diff --git a/src/Formatter/TimeFormatter.hpp b/src/Formatter/TimeFormatter.hpp index 3a73cb431b0..aff881d0d2e 100644 --- a/src/Formatter/TimeFormatter.hpp +++ b/src/Formatter/TimeFormatter.hpp @@ -14,36 +14,23 @@ struct BrokenDateTime; void FormatISO8601(char *buffer, const BrokenDate &date) noexcept; -#ifdef _UNICODE -void -FormatISO8601(TCHAR *buffer, const BrokenDate &date) noexcept; -#endif - /** * Format a UTC time stamp in ISO 8601 format (YYYY-MM-DDTHH:MM:SSZ). */ void FormatISO8601(char *buffer, const BrokenDateTime &stamp) noexcept; -#ifdef _UNICODE -/** - * Format a UTC time stamp in ISO 8601 format (YYYY-MM-DDTHH:MM:SSZ). - */ -void -FormatISO8601(TCHAR *buffer, const BrokenDateTime &stamp) noexcept; -#endif - void -FormatTime(TCHAR *buffer, FloatDuration time) noexcept; +FormatTime(char *buffer, FloatDuration time) noexcept; static inline void -FormatTime(TCHAR *buffer, TimeStamp time) noexcept +FormatTime(char *buffer, TimeStamp time) noexcept { FormatTime(buffer, time.ToDuration()); } void -FormatTimeLong(TCHAR *buffer, FloatDuration time) noexcept; +FormatTimeLong(char *buffer, FloatDuration time) noexcept; /** * precedes with "-" if time is negative @@ -51,13 +38,13 @@ FormatTimeLong(TCHAR *buffer, FloatDuration time) noexcept; * @param time input seconds */ void -FormatSignedTimeHHMM(TCHAR *buffer, std::chrono::seconds time) noexcept; +FormatSignedTimeHHMM(char *buffer, std::chrono::seconds time) noexcept; [[gnu::const]] -static inline BasicStringBuffer +static inline BasicStringBuffer FormatSignedTimeHHMM(std::chrono::seconds time) noexcept { - BasicStringBuffer buffer; + BasicStringBuffer buffer; FormatSignedTimeHHMM(buffer.data(), time); return buffer; } @@ -70,7 +57,7 @@ FormatSignedTimeHHMM(FloatDuration time) noexcept } static inline void -FormatTimeHHMM(TCHAR *buffer, TimeStamp time) noexcept +FormatTimeHHMM(char *buffer, TimeStamp time) noexcept { FormatSignedTimeHHMM(buffer, time.Cast()); } @@ -96,20 +83,20 @@ FormatTimeHHMM(TimeStamp time) noexcept * @param d input seconds */ void -FormatTimeTwoLines(TCHAR *buffer1, TCHAR *buffer2, +FormatTimeTwoLines(char *buffer1, char *buffer2, std::chrono::seconds time) noexcept; void -FormatTimespanSmart(TCHAR *buffer, std::chrono::seconds timespan, +FormatTimespanSmart(char *buffer, std::chrono::seconds timespan, unsigned max_tokens = 1, - const TCHAR *separator = _T(" ")) noexcept; + const char *separator = " ") noexcept; [[gnu::const]] -static inline BasicStringBuffer +static inline BasicStringBuffer FormatTimespanSmart(std::chrono::seconds timespan, unsigned max_tokens = 1, - const TCHAR *separator = _T(" ")) noexcept + const char *separator = " ") noexcept { - BasicStringBuffer buffer; + BasicStringBuffer buffer; FormatTimespanSmart(buffer.data(), timespan, max_tokens, separator); return buffer; } @@ -117,7 +104,7 @@ FormatTimespanSmart(std::chrono::seconds timespan, unsigned max_tokens = 1, [[gnu::const]] static inline auto FormatTimespanSmart(FloatDuration timespan, unsigned max_tokens = 1, - const TCHAR *separator = _T(" ")) noexcept + const char *separator = " ") noexcept { return FormatTimespanSmart(std::chrono::duration_cast(timespan), max_tokens, separator); diff --git a/src/Formatter/Units.cpp b/src/Formatter/Units.cpp index 4569ef86e2f..54a1fd8c45f 100644 --- a/src/Formatter/Units.cpp +++ b/src/Formatter/Units.cpp @@ -9,7 +9,7 @@ #include "util/StringFormat.hpp" static void -FormatInteger(TCHAR *buffer, +FormatInteger(char *buffer, const double value, const Unit unit, bool include_unit, bool include_sign) { @@ -17,58 +17,58 @@ FormatInteger(TCHAR *buffer, const int ivalue = iround(uvalue); if (include_unit) - StringFormatUnsafe(buffer, include_sign ? _T("%+d %s") : _T("%d %s"), + StringFormatUnsafe(buffer, include_sign ? "%+d %s" : "%d %s", ivalue, Units::GetUnitName(unit)); else - StringFormatUnsafe(buffer, include_sign ? _T("%+d") : _T("%d"), ivalue); + StringFormatUnsafe(buffer, include_sign ? "%+d" : "%d", ivalue); } void -FormatMass(TCHAR *buffer, double value, Unit unit, +FormatMass(char *buffer, double value, Unit unit, bool include_unit) { FormatInteger(buffer, value, unit, include_unit, false); } void -FormatWingLoading(TCHAR *buffer, double value, Unit unit, +FormatWingLoading(char *buffer, double value, Unit unit, bool include_unit) { const auto uvalue = Units::ToUserUnit(value, unit); int precision = uvalue > 20 ? 0 : 1; if (include_unit) - _stprintf(buffer, _T("%.*f %s"), precision, (double)uvalue, + _stprintf(buffer, "%.*f %s", precision, (double)uvalue, Units::GetUnitName(unit)); else - _stprintf(buffer, _T("%.*f"), precision, (double)uvalue); + _stprintf(buffer, "%.*f", precision, (double)uvalue); } void -FormatAltitude(TCHAR *buffer, double value, Unit unit, +FormatAltitude(char *buffer, double value, Unit unit, bool include_unit) { FormatInteger(buffer, value, unit, include_unit, false); } void -FormatRelativeAltitude(TCHAR *buffer, double value, +FormatRelativeAltitude(char *buffer, double value, Unit unit, bool include_unit) { FormatInteger(buffer, value, unit, include_unit, true); } void -FormatDistance(TCHAR *buffer, double value, Unit unit, +FormatDistance(char *buffer, double value, Unit unit, bool include_unit, int precision) { value = Units::ToUserUnit(value, unit); if (include_unit) - StringFormatUnsafe(buffer, _T("%.*f %s"), precision, (double)value, + StringFormatUnsafe(buffer, "%.*f %s", precision, (double)value, Units::GetUnitName(unit)); else - StringFormatUnsafe(buffer, _T("%.*f"), precision, (double)value); + StringFormatUnsafe(buffer, "%.*f", precision, (double)value); } [[gnu::const]] @@ -89,17 +89,17 @@ GetSmallerDistanceUnit(Unit unit) } Unit -FormatSmallDistance(TCHAR *buffer, double value, Unit unit, +FormatSmallDistance(char *buffer, double value, Unit unit, bool include_unit, int precision) { unit = GetSmallerDistanceUnit(unit); value = Units::ToUserUnit(value, unit); if (include_unit) - StringFormatUnsafe(buffer, _T("%.*f %s"), precision, (double)value, + StringFormatUnsafe(buffer, "%.*f %s", precision, (double)value, Units::GetUnitName(unit)); else - StringFormatUnsafe(buffer, _T("%.*f"), precision, (double)value); + StringFormatUnsafe(buffer, "%.*f", precision, (double)value); return unit; } @@ -128,7 +128,7 @@ GetBestDistancePrecision(double value, Unit unit, double threshold = 100) } Unit -FormatDistanceSmart(TCHAR *buffer, double value, Unit unit, +FormatDistanceSmart(char *buffer, double value, Unit unit, bool include_unit, double small_unit_threshold, double precision_threshold) { @@ -140,27 +140,27 @@ FormatDistanceSmart(TCHAR *buffer, double value, Unit unit, } void -FormatSpeed(TCHAR *buffer, +FormatSpeed(char *buffer, double value, const Unit unit, bool include_unit, bool precision) { value = Units::ToUserUnit(value, unit); const int prec = precision && value < 100; if (include_unit) - StringFormatUnsafe(buffer, _T("%.*f %s"), prec, (double)value, + StringFormatUnsafe(buffer, "%.*f %s", prec, (double)value, Units::GetUnitName(unit)); else - StringFormatUnsafe(buffer, _T("%.*f"), prec, (double)value); + StringFormatUnsafe(buffer, "%.*f", prec, (double)value); } -const TCHAR* +const char* GetVerticalSpeedFormat(Unit unit, bool include_unit, bool include_sign) { - static const TCHAR *const format[2][2][2]= { + static const char *const format[2][2][2]= { // 0 0 0 0 0 1 0 1 0 0 1 1 - { { _T("%.1f"), _T("%+.1f") }, { _T("%.1f %s"), _T("%+.1f %s") } }, + { { "%.1f", "%+.1f" }, { "%.1f %s", "%+.1f %s" } }, // 1 0 0 1 0 1 1 1 0 1 1 1 - { { _T("%.0f"), _T("%+.0f") }, { _T("%.0f %s"), _T("%+.0f %s") } } + { { "%.0f", "%+.0f" }, { "%.0f %s", "%+.0f %s" } } }; return format[unit == Unit::FEET_PER_MINUTE] @@ -182,7 +182,7 @@ GetVerticalSpeedStep(Unit unit) } void -FormatVerticalSpeed(TCHAR *buffer, double value, Unit unit, +FormatVerticalSpeed(char *buffer, double value, Unit unit, bool include_unit, bool include_sign) { value = Units::ToUserUnit(value, unit); @@ -198,20 +198,20 @@ FormatVerticalSpeed(TCHAR *buffer, double value, Unit unit, } void -FormatTemperature(TCHAR *buffer, double value, Unit unit, +FormatTemperature(char *buffer, double value, Unit unit, bool include_unit) { value = Units::ToUserUnit(value, unit); if (include_unit) - StringFormatUnsafe(buffer, _T("%.0f %s"), + StringFormatUnsafe(buffer, "%.0f %s", (double)value, Units::GetUnitName(unit)); else - StringFormatUnsafe(buffer, _T("%.0f"), (double)value); + StringFormatUnsafe(buffer, "%.0f", (double)value); } void -FormatPressure(TCHAR *buffer, AtmosphericPressure pressure, +FormatPressure(char *buffer, AtmosphericPressure pressure, Unit unit, bool include_unit) { auto _pressure = Units::ToUserUnit(pressure.GetHectoPascal(), unit); @@ -225,13 +225,13 @@ FormatPressure(TCHAR *buffer, AtmosphericPressure pressure, (double)_pressure); } -const TCHAR* +const char* GetPressureFormat(Unit unit, bool include_unit) { if (include_unit) - return unit == Unit::INCH_MERCURY ? _T("%.2f %s") : _T("%.f %s"); + return unit == Unit::INCH_MERCURY ? "%.2f %s" : "%.f %s"; else - return unit == Unit::INCH_MERCURY ? _T("%.2f") : _T("%.f"); + return unit == Unit::INCH_MERCURY ? "%.2f" : "%.f"; } double diff --git a/src/Formatter/Units.hpp b/src/Formatter/Units.hpp index bc63dc1231e..c73c0f4dee5 100644 --- a/src/Formatter/Units.hpp +++ b/src/Formatter/Units.hpp @@ -18,7 +18,7 @@ class AtmosphericPressure; * @param include_unit include the unit into the string? */ void -FormatAltitude(TCHAR *buffer, double value, Unit unit, +FormatAltitude(char *buffer, double value, Unit unit, bool include_unit = true); /** @@ -30,7 +30,7 @@ FormatAltitude(TCHAR *buffer, double value, Unit unit, * @param include_unit include the unit into the string? */ void -FormatMass(TCHAR *buffer, double value, Unit unit, +FormatMass(char *buffer, double value, Unit unit, bool include_unit = true); /** @@ -42,7 +42,7 @@ FormatMass(TCHAR *buffer, double value, Unit unit, * @param include_unit include the unit into the string? */ void -FormatWingLoading(TCHAR *buffer, double value, Unit unit, +FormatWingLoading(char *buffer, double value, Unit unit, bool include_unit = true); /** @@ -54,7 +54,7 @@ FormatWingLoading(TCHAR *buffer, double value, Unit unit, * @param include_unit include the unit into the string? */ void -FormatRelativeAltitude(TCHAR *buffer, double value, Unit unit, +FormatRelativeAltitude(char *buffer, double value, Unit unit, bool include_unit = true); /** @@ -67,7 +67,7 @@ FormatRelativeAltitude(TCHAR *buffer, double value, Unit unit, * @param precision the number of decimal places */ void -FormatDistance(TCHAR *buffer, double value, const Unit unit, +FormatDistance(char *buffer, double value, const Unit unit, bool include_unit = true, int precision = 0); /** @@ -82,7 +82,7 @@ FormatDistance(TCHAR *buffer, double value, const Unit unit, * @return the unit used for output formatting */ Unit -FormatSmallDistance(TCHAR *buffer, double value, Unit unit, +FormatSmallDistance(char *buffer, double value, Unit unit, bool include_unit = true, int precision = 0); /** @@ -96,7 +96,7 @@ FormatSmallDistance(TCHAR *buffer, double value, Unit unit, * @return the unit used for output formatting */ Unit -FormatDistanceSmart(TCHAR *buffer, double value, Unit unit, +FormatDistanceSmart(char *buffer, double value, Unit unit, bool include_unit = true, double small_unit_threshold = 0, double precision_threshold = 100); @@ -111,7 +111,7 @@ FormatDistanceSmart(TCHAR *buffer, double value, Unit unit, * @param precision if true shows one decimal place if the speed is low */ void -FormatSpeed(TCHAR *buffer, double value, const Unit unit, +FormatSpeed(char *buffer, double value, const Unit unit, bool include_unit = true, bool precision = false); /** @@ -121,7 +121,7 @@ FormatSpeed(TCHAR *buffer, double value, const Unit unit, * @param include_sign include the sign into the string? * @return the format */ -const TCHAR* GetVerticalSpeedFormat(Unit unit, bool include_unit = false, +const char* GetVerticalSpeedFormat(Unit unit, bool include_unit = false, bool include_sign = true); /** @@ -142,7 +142,7 @@ GetVerticalSpeedStep(Unit unit); * @param include_sign include the sign into the string? */ void -FormatVerticalSpeed(TCHAR *buffer, double value, Unit unit, +FormatVerticalSpeed(char *buffer, double value, Unit unit, bool include_unit = true, bool include_sign = true); /** @@ -154,7 +154,7 @@ FormatVerticalSpeed(TCHAR *buffer, double value, Unit unit, * @param include_unit include the unit into the string? */ void -FormatTemperature(TCHAR *buffer, double value, Unit unit, +FormatTemperature(char *buffer, double value, Unit unit, bool include_unit = true); /** @@ -165,7 +165,7 @@ FormatTemperature(TCHAR *buffer, double value, Unit unit, * @param unit the pressure unit (e.g. meters, feet, ...) * @param include_unit include the unit into the string? */ -void FormatPressure(TCHAR *buffer, AtmosphericPressure value, Unit unit, +void FormatPressure(char *buffer, AtmosphericPressure value, Unit unit, bool include_unit = true); /** @@ -173,7 +173,7 @@ void FormatPressure(TCHAR *buffer, AtmosphericPressure value, Unit unit, * @param unit the pressure unit * @return the format */ -const TCHAR* GetPressureFormat(Unit unit, bool include_unit = false); +const char* GetPressureFormat(Unit unit, bool include_unit = false); /** * Give the basic step size for pressure editing diff --git a/src/Formatter/UserGeoPointFormatter.cpp b/src/Formatter/UserGeoPointFormatter.cpp index 9045ce6ab9e..ea2e255efa1 100644 --- a/src/Formatter/UserGeoPointFormatter.cpp +++ b/src/Formatter/UserGeoPointFormatter.cpp @@ -20,20 +20,20 @@ SetUserCoordinateFormat(CoordinateFormat _fmt) } bool -FormatLongitude(Angle longitude, TCHAR *buffer, size_t size) +FormatLongitude(Angle longitude, char *buffer, size_t size) { return FormatLongitude(longitude, buffer, size, user_coordinate_format); } bool -FormatLatitude(Angle latitude, TCHAR *buffer, size_t size) +FormatLatitude(Angle latitude, char *buffer, size_t size) { return FormatLatitude(latitude, buffer, size, user_coordinate_format); } -TCHAR * -FormatGeoPoint(const GeoPoint &location, TCHAR *buffer, size_t size, - TCHAR separator) +char * +FormatGeoPoint(const GeoPoint &location, char *buffer, size_t size, + char separator) { return FormatGeoPoint(location, buffer, size, user_coordinate_format, separator); diff --git a/src/Formatter/UserGeoPointFormatter.hpp b/src/Formatter/UserGeoPointFormatter.hpp index ce4d6dd79b5..e30b9c7ba54 100644 --- a/src/Formatter/UserGeoPointFormatter.hpp +++ b/src/Formatter/UserGeoPointFormatter.hpp @@ -21,7 +21,7 @@ SetUserCoordinateFormat(CoordinateFormat _fmt); * @param buffer buffer string to write to (pointer) * @param size Size of the buffer */ -bool FormatLongitude(Angle longitude, TCHAR *buffer, size_t size); +bool FormatLongitude(Angle longitude, char *buffer, size_t size); /** * Converts a double-based Latitude into a formatted string @@ -29,19 +29,19 @@ bool FormatLongitude(Angle longitude, TCHAR *buffer, size_t size); * @param buffer buffer string to write to (pointer) * @param size Size of the buffer */ -bool FormatLatitude(Angle latitude, TCHAR *buffer, size_t size); +bool FormatLatitude(Angle latitude, char *buffer, size_t size); /** * Convert a GeoPoint into a formatted string. */ -TCHAR *FormatGeoPoint(const GeoPoint &location, TCHAR *buffer, size_t size, - TCHAR separator = _T(' ')); +char *FormatGeoPoint(const GeoPoint &location, char *buffer, size_t size, + char separator = ' '); [[gnu::pure]] -static inline BasicStringBuffer -FormatGeoPoint(const GeoPoint &location, TCHAR separator = _T(' ')) +static inline BasicStringBuffer +FormatGeoPoint(const GeoPoint &location, char separator = ' ') { - BasicStringBuffer buffer; + BasicStringBuffer buffer; auto result = FormatGeoPoint(location, buffer.data(), buffer.capacity(), separator); if (result == nullptr) diff --git a/src/Formatter/UserUnits.cpp b/src/Formatter/UserUnits.cpp index f8203fa0626..65e43aa23d8 100644 --- a/src/Formatter/UserUnits.cpp +++ b/src/Formatter/UserUnits.cpp @@ -9,20 +9,20 @@ #include void -FormatUserWingLoading(double value, TCHAR *buffer, bool include_unit) noexcept +FormatUserWingLoading(double value, char *buffer, bool include_unit) noexcept { FormatWingLoading(buffer, value, Units::GetUserWingLoadingUnit(), include_unit); } void -FormatUserMass(double value, TCHAR *buffer, bool include_unit) noexcept +FormatUserMass(double value, char *buffer, bool include_unit) noexcept { FormatMass(buffer, value, Units::GetUserMassUnit(), include_unit); } void -FormatUserAltitude(double value, TCHAR *buffer, bool include_unit) noexcept +FormatUserAltitude(double value, char *buffer, bool include_unit) noexcept { FormatAltitude(buffer, value, Units::GetUserAltitudeUnit(), include_unit); } @@ -43,7 +43,7 @@ GetAlternateAltitudeUnit(Unit unit) noexcept } void -FormatAlternateUserAltitude(double value, TCHAR *buffer, bool include_unit) noexcept +FormatAlternateUserAltitude(double value, char *buffer, bool include_unit) noexcept { FormatAltitude(buffer, value, GetAlternateAltitudeUnit(Units::GetUserAltitudeUnit()), @@ -51,21 +51,21 @@ FormatAlternateUserAltitude(double value, TCHAR *buffer, bool include_unit) noex } void -FormatRelativeUserAltitude(double value, TCHAR *buffer, bool include_unit) noexcept +FormatRelativeUserAltitude(double value, char *buffer, bool include_unit) noexcept { FormatRelativeAltitude(buffer, value, Units::GetUserAltitudeUnit(), include_unit); } void -FormatUserDistance(double value, TCHAR *buffer, bool include_unit, int precision) noexcept +FormatUserDistance(double value, char *buffer, bool include_unit, int precision) noexcept { FormatDistance(buffer, value, Units::GetUserDistanceUnit(), include_unit, precision); } Unit -FormatSmallUserDistance(TCHAR *buffer, double value, bool include_unit, +FormatSmallUserDistance(char *buffer, double value, bool include_unit, int precision) noexcept { return FormatSmallDistance(buffer, value, Units::GetUserDistanceUnit(), @@ -73,7 +73,7 @@ FormatSmallUserDistance(TCHAR *buffer, double value, bool include_unit, } Unit -FormatUserDistanceSmart(double value, TCHAR *buffer, bool include_unit, +FormatUserDistanceSmart(double value, char *buffer, bool include_unit, double small_unit_threshold, double precision_threshold) noexcept { return FormatDistanceSmart(buffer, value, Units::GetUserDistanceUnit(), @@ -82,21 +82,21 @@ FormatUserDistanceSmart(double value, TCHAR *buffer, bool include_unit, } Unit -FormatUserMapScale(double value, TCHAR *buffer, bool include_unit) noexcept +FormatUserMapScale(double value, char *buffer, bool include_unit) noexcept { return FormatDistanceSmart(buffer, value, Units::GetUserDistanceUnit(), include_unit, 1000, 9.999); } void -FormatUserSpeed(double value, TCHAR *buffer, bool include_unit, bool precision) noexcept +FormatUserSpeed(double value, char *buffer, bool include_unit, bool precision) noexcept { FormatSpeed(buffer, value, Units::GetUserSpeedUnit(), include_unit, precision); } void -FormatUserWindSpeed(double value, TCHAR *buffer, bool include_unit, +FormatUserWindSpeed(double value, char *buffer, bool include_unit, bool precision) noexcept { FormatSpeed(buffer, value, Units::GetUserWindSpeedUnit(), include_unit, @@ -104,14 +104,14 @@ FormatUserWindSpeed(double value, TCHAR *buffer, bool include_unit, } void -FormatUserTaskSpeed(double value, TCHAR *buffer, bool include_unit, +FormatUserTaskSpeed(double value, char *buffer, bool include_unit, bool precision) noexcept { FormatSpeed(buffer, value, Units::GetUserTaskSpeedUnit(), include_unit, precision); } -const TCHAR * +const char * GetUserVerticalSpeedFormat(bool include_unit, bool include_sign) noexcept { return GetVerticalSpeedFormat(Units::GetUserVerticalSpeedUnit(), include_unit, @@ -125,7 +125,7 @@ GetUserVerticalSpeedStep() noexcept } void -FormatUserVerticalSpeed(double value, TCHAR *buffer, bool include_unit, +FormatUserVerticalSpeed(double value, char *buffer, bool include_unit, bool include_sign) noexcept { FormatVerticalSpeed(buffer, value, Units::GetUserVerticalSpeedUnit(), @@ -133,20 +133,20 @@ FormatUserVerticalSpeed(double value, TCHAR *buffer, bool include_unit, } void -FormatUserTemperature(double value, TCHAR *buffer, bool include_unit) noexcept +FormatUserTemperature(double value, char *buffer, bool include_unit) noexcept { FormatTemperature(buffer, value, Units::GetUserTemperatureUnit(), include_unit); } void -FormatUserPressure(AtmosphericPressure pressure, TCHAR *buffer, +FormatUserPressure(AtmosphericPressure pressure, char *buffer, bool include_unit) noexcept { FormatPressure(buffer, pressure, Units::GetUserPressureUnit(), include_unit); } -const TCHAR * +const char * GetUserPressureFormat(bool include_unit) noexcept { return GetPressureFormat(Units::GetUserPressureUnit(), include_unit); diff --git a/src/Formatter/UserUnits.hpp b/src/Formatter/UserUnits.hpp index d5258ad36df..c96c7d424d4 100644 --- a/src/Formatter/UserUnits.hpp +++ b/src/Formatter/UserUnits.hpp @@ -18,7 +18,7 @@ class AtmosphericPressure; * @param size Size of the buffer */ void -FormatUserWingLoading(double value, TCHAR *buffer, +FormatUserWingLoading(double value, char *buffer, bool include_unit = true) noexcept; /** @@ -28,7 +28,7 @@ FormatUserWingLoading(double value, TCHAR *buffer, * @param size Size of the buffer */ void -FormatUserMass(double value, TCHAR *buffer, +FormatUserMass(double value, char *buffer, bool include_unit = true) noexcept; /** @@ -38,14 +38,14 @@ FormatUserMass(double value, TCHAR *buffer, * @param size Size of the buffer */ void -FormatUserAltitude(double value, TCHAR *buffer, +FormatUserAltitude(double value, char *buffer, bool include_unit = true) noexcept; [[gnu::const]] static inline auto FormatUserAltitude(double value) noexcept { - BasicStringBuffer buffer; + BasicStringBuffer buffer; FormatUserAltitude(value, buffer.data()); return buffer; } @@ -58,7 +58,7 @@ FormatUserAltitude(double value) noexcept * @param size Size of the buffer */ void -FormatAlternateUserAltitude(double value, TCHAR *buffer, +FormatAlternateUserAltitude(double value, char *buffer, bool include_unit = true) noexcept; /** @@ -68,7 +68,7 @@ FormatAlternateUserAltitude(double value, TCHAR *buffer, * @param size Size of the buffer */ void -FormatRelativeUserAltitude(double value, TCHAR *buffer, +FormatRelativeUserAltitude(double value, char *buffer, bool include_unit = true) noexcept; /** @@ -79,7 +79,7 @@ FormatRelativeUserAltitude(double value, TCHAR *buffer, * @param precision the number of decimal places */ void -FormatUserDistance(double value, TCHAR *buffer, +FormatUserDistance(double value, char *buffer, bool include_unit = true, int precision = 0) noexcept; [[gnu::const]] @@ -87,7 +87,7 @@ static inline auto FormatUserDistance(double value, bool include_unit = true, int precision = 0) noexcept { - BasicStringBuffer buffer; + BasicStringBuffer buffer; FormatUserDistance(value, buffer.data(), include_unit, precision); return buffer; } @@ -103,7 +103,7 @@ FormatUserDistance(double value, * @return the unit used for output formatting */ Unit -FormatSmallUserDistance(TCHAR *buffer, double value, +FormatSmallUserDistance(char *buffer, double value, bool include_unit = true, int precision = 0) noexcept; /** @@ -113,7 +113,7 @@ FormatSmallUserDistance(TCHAR *buffer, double value, * @param size Size of the buffer */ Unit -FormatUserDistanceSmart(double value, TCHAR *buffer, +FormatUserDistanceSmart(double value, char *buffer, bool include_unit = true, double small_unit_threshold = 0, double precision_threshold = 100) noexcept; @@ -124,14 +124,14 @@ FormatUserDistanceSmart(double value, bool include_unit = true, double small_unit_threshold = 0, double precision_threshold = 100) noexcept { - BasicStringBuffer buffer; + BasicStringBuffer buffer; FormatUserDistanceSmart(value, buffer.data(), include_unit, small_unit_threshold, precision_threshold); return buffer; } Unit -FormatUserMapScale(double value, TCHAR *buffer, +FormatUserMapScale(double value, char *buffer, bool include_unit = true) noexcept; /** @@ -142,14 +142,14 @@ FormatUserMapScale(double value, TCHAR *buffer, * @return True if buffer long enough, False otherwise */ void -FormatUserSpeed(double value, TCHAR *buffer, +FormatUserSpeed(double value, char *buffer, bool include_unit = true, bool Precision = true) noexcept; [[gnu::const]] static inline auto FormatUserSpeed(double value, bool precision=true) noexcept { - BasicStringBuffer buffer; + BasicStringBuffer buffer; FormatUserSpeed(value, buffer.data(), true, precision); return buffer; } @@ -162,14 +162,14 @@ FormatUserSpeed(double value, bool precision=true) noexcept * @return True if buffer long enough, False otherwise */ void -FormatUserWindSpeed(double value, TCHAR *buffer, +FormatUserWindSpeed(double value, char *buffer, bool include_unit = true, bool Precision = true) noexcept; [[gnu::const]] static inline auto FormatUserWindSpeed(double value, bool include_unit = true, bool precision=true) noexcept { - BasicStringBuffer buffer; + BasicStringBuffer buffer; FormatUserWindSpeed(value, buffer.data(), include_unit, precision); return buffer; } @@ -181,14 +181,14 @@ FormatUserWindSpeed(double value, bool include_unit = true, bool precision=true) * @param value the speed value [m/s] */ void -FormatUserTaskSpeed(double value, TCHAR *buffer, +FormatUserTaskSpeed(double value, char *buffer, bool include_unit=true, bool precision=true) noexcept; [[gnu::const]] static inline auto FormatUserTaskSpeed(double value, bool precision=true) noexcept { - BasicStringBuffer buffer; + BasicStringBuffer buffer; FormatUserTaskSpeed(value, buffer.data(), true, precision); return buffer; } @@ -199,7 +199,7 @@ FormatUserTaskSpeed(double value, bool precision=true) noexcept * @param include_sign include the sign into the string? * @return the format */ -const TCHAR * +const char * GetUserVerticalSpeedFormat(bool include_unit = false, bool include_sign = true) noexcept; @@ -219,14 +219,14 @@ GetUserVerticalSpeedStep() noexcept; * @return True if buffer long enough, False otherwise */ void -FormatUserVerticalSpeed(double value, TCHAR *buffer, +FormatUserVerticalSpeed(double value, char *buffer, bool include_unit = true, bool include_sign = true) noexcept; [[gnu::const]] static inline auto FormatUserVerticalSpeed(double value, bool include_unit = true, bool include_sign = true) noexcept { - BasicStringBuffer buffer; + BasicStringBuffer buffer; FormatUserVerticalSpeed(value, buffer.data(), include_unit, include_sign); return buffer; } @@ -238,7 +238,7 @@ FormatUserVerticalSpeed(double value, bool include_unit = true, bool include_sig * @param size Size of the buffer */ void -FormatUserTemperature(double value, TCHAR *buffer, +FormatUserTemperature(double value, char *buffer, bool include_unit = true) noexcept; /** @@ -247,7 +247,7 @@ FormatUserTemperature(double value, TCHAR *buffer, * @param buffer buffer string to write to (pointer) * @param size Size of the buffer */ -void FormatUserPressure(AtmosphericPressure value, TCHAR *buffer, +void FormatUserPressure(AtmosphericPressure value, char *buffer, bool include_unit = true) noexcept; /** @@ -256,7 +256,7 @@ void FormatUserPressure(AtmosphericPressure value, TCHAR *buffer, * @param size Size of the buffer * @return True if buffer long enough, False otherwise */ -const TCHAR * +const char * GetUserPressureFormat(bool include_unit = false) noexcept; /** diff --git a/src/Gauge/BigThermalAssistantWindow.cpp b/src/Gauge/BigThermalAssistantWindow.cpp index 16551cc49fe..1167096062f 100644 --- a/src/Gauge/BigThermalAssistantWindow.cpp +++ b/src/Gauge/BigThermalAssistantWindow.cpp @@ -31,7 +31,7 @@ BigThermalAssistantWindow::OnMouseUp([[maybe_unused]] PixelPoint p) noexcept if (dragging) { StopDragging(); - const TCHAR *gesture = gestures.Finish(); + const char *gesture = gestures.Finish(); if (gesture && InputEvents::processGesture(gesture)) return true; } diff --git a/src/Gauge/BigTrafficWidget.cpp b/src/Gauge/BigTrafficWidget.cpp index 18942abd580..3ed9eb35859 100644 --- a/src/Gauge/BigTrafficWidget.cpp +++ b/src/Gauge/BigTrafficWidget.cpp @@ -108,7 +108,7 @@ class FlarmTrafficControl : public FlarmTrafficWindow { } protected: - bool OnMouseGesture(const TCHAR* gesture); + bool OnMouseGesture(const char* gesture); /* virtual methods from class Window */ void OnCreate() noexcept override; @@ -325,7 +325,7 @@ FlarmTrafficControl::PaintDistance(Canvas &canvas, PixelRect rc, double distance) const { // Format distance - TCHAR buffer[20]; + char buffer[20]; Unit unit = FormatUserDistanceSmart(distance, buffer, false, 1000); // Calculate unit size @@ -368,7 +368,7 @@ FlarmTrafficControl::PaintRelativeAltitude(Canvas &canvas, PixelRect rc, double relative_altitude) const { // Format relative altitude - TCHAR buffer[20]; + char buffer[20]; Unit unit = Units::GetUserAltitudeUnit(); FormatRelativeUserAltitude(relative_altitude, buffer, false); @@ -413,14 +413,14 @@ void FlarmTrafficControl::PaintID(Canvas &canvas, PixelRect rc, const FlarmTraffic &traffic) const { - TCHAR buffer[20]; + char buffer[20]; unsigned font_size; if (traffic.HasName()) { canvas.Select(look.call_sign_font); font_size = look.call_sign_font.GetHeight(); - _tcscpy(buffer, traffic.name); + strcpy(buffer, traffic.name); } else { canvas.Select(look.info_labels_font); font_size = look.info_labels_font.GetHeight(); @@ -546,7 +546,7 @@ FlarmTrafficControl::OpenDetails() static Button MakeSymbolButton(ContainerWindow &parent, const ButtonLook &look, - const TCHAR *caption, + const char *caption, const PixelRect &rc, Button::Callback callback) noexcept { @@ -565,16 +565,16 @@ struct TrafficWidget::Windows { Windows(TrafficWidget &widget, ContainerWindow &parent, const PixelRect &r, const ButtonLook &button_look, const FlarmTrafficLook &flarm_look) - :zoom_in_button(MakeSymbolButton(parent, button_look, _T("+"), r, + :zoom_in_button(MakeSymbolButton(parent, button_look, "+", r, [&widget](){ widget.ZoomIn(); })), zoom_out_button(MakeSymbolButton(parent, button_look, - _T("-"), r, + "-", r, [&widget](){ widget.ZoomOut(); })), previous_item_button(MakeSymbolButton(parent, button_look, - _T("<"), r, + "<", r, [&widget](){ widget.PreviousTarget(); })), next_item_button(MakeSymbolButton(parent, button_look, - _T(">"), r, + ">", r, [&widget](){ widget.NextTarget(); })), details_button(parent, button_look, _("Details"), r, WindowStyle(), @@ -789,7 +789,7 @@ FlarmTrafficControl::OnMouseUp(PixelPoint p) noexcept if (dragging) { StopDragging(); - const TCHAR *gesture = gestures.Finish(); + const char *gesture = gestures.Finish(); if (gesture && OnMouseGesture(gesture)) return true; } @@ -809,25 +809,25 @@ FlarmTrafficControl::OnMouseDouble([[maybe_unused]] PixelPoint p) noexcept } bool -FlarmTrafficControl::OnMouseGesture(const TCHAR* gesture) +FlarmTrafficControl::OnMouseGesture(const char* gesture) { - if (StringIsEqual(gesture, _T("U"))) { + if (StringIsEqual(gesture, "U")) { ZoomIn(); return true; } - if (StringIsEqual(gesture, _T("D"))) { + if (StringIsEqual(gesture, "D")) { ZoomOut(); return true; } - if (StringIsEqual(gesture, _T("UD"))) { + if (StringIsEqual(gesture, "UD")) { SetAutoZoom(true); return true; } - if (StringIsEqual(gesture, _T("DR"))) { + if (StringIsEqual(gesture, "DR")) { OpenDetails(); return true; } - if (StringIsEqual(gesture, _T("RL"))) { + if (StringIsEqual(gesture, "RL")) { SwitchData(); return true; } diff --git a/src/Gauge/CMakeLists.txt b/src/Gauge/CMakeLists.txt new file mode 100644 index 00000000000..8ec3e94e6d4 --- /dev/null +++ b/src/Gauge/CMakeLists.txt @@ -0,0 +1,52 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) + +target_link_libraries(${TARGET_NAME} PUBLIC Math) + +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/Gauge/CMakeSource.cmake b/src/Gauge/CMakeSource.cmake new file mode 100644 index 00000000000..da8007cc150 --- /dev/null +++ b/src/Gauge/CMakeSource.cmake @@ -0,0 +1,20 @@ +set(_SOURCES + Gauge/BigThermalAssistantWidget.cpp + Gauge/BigThermalAssistantWindow.cpp + Gauge/BigTrafficWidget.cpp + Gauge/FlarmTrafficWindow.cpp + Gauge/GaugeFLARM.cpp + Gauge/GaugeThermalAssistant.cpp + Gauge/GaugeVario.cpp + Gauge/GlueGaugeVario.cpp + Gauge/LogoView.cpp + Gauge/TaskView.cpp + Gauge/ThermalAssistantRenderer.cpp + Gauge/ThermalAssistantWindow.cpp + Gauge/TrafficSettings.cpp + Gauge/VarioSettings.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake +) diff --git a/src/Gauge/FlarmTrafficWindow.cpp b/src/Gauge/FlarmTrafficWindow.cpp index c0dcb65defd..2c2eed11631 100644 --- a/src/Gauge/FlarmTrafficWindow.cpp +++ b/src/Gauge/FlarmTrafficWindow.cpp @@ -206,7 +206,7 @@ FlarmTrafficWindow::PaintRadarNoTraffic(Canvas &canvas) const noexcept if (small) return; - const TCHAR* str = _("No Traffic"); + const char* str = _("No Traffic"); canvas.Select(look.no_traffic_font); PixelSize ts = canvas.CalcTextSize(str); canvas.SetTextColor(look.default_color); @@ -409,7 +409,7 @@ FlarmTrafficWindow::PaintRadarTarget(Canvas &canvas, canvas.Select(look.side_info_font); // Format string - TCHAR tmp[10]; + char tmp[10]; if (side_display_type == SideInfoType::VARIO) FormatUserVerticalSpeed(traffic.climb_rate_avg30s, tmp, false); @@ -450,7 +450,7 @@ FlarmTrafficWindow::PaintTargetInfoSmall(Canvas &canvas, // Write the relativ altitude devided by 100 to the Buffer StaticString<10> buffer; - const auto relalt_s = buffer.Format(_T("%d"), abs(relalt)); + const auto relalt_s = buffer.Format("%d", abs(relalt)); // Select font canvas.SetBackgroundTransparent(); @@ -611,14 +611,14 @@ FlarmTrafficWindow::PaintNorth(Canvas &canvas) const noexcept const auto radar_mid = radar_renderer.GetCenter(); const PixelPoint q = radar_mid + iround(p * radar_renderer.GetRadius()); - PixelSize s = canvas.CalcTextSize(_T("N")); + PixelSize s = canvas.CalcTextSize("N"); canvas.DrawCircle(q, s.height * 0.65); - canvas.DrawText(q - s / 2u, _T("N")); + canvas.DrawText(q - s / 2u, "N"); } static void DrawCircleLabel(Canvas &canvas, PixelPoint p, - tstring_view text) noexcept + std::string_view text) noexcept { const auto size = canvas.CalcTextSize(text); p.x -= size.width / 2; diff --git a/src/Gauge/GaugeThermalAssistant.cpp b/src/Gauge/GaugeThermalAssistant.cpp index 88966a3918f..d92d4175a12 100644 --- a/src/Gauge/GaugeThermalAssistant.cpp +++ b/src/Gauge/GaugeThermalAssistant.cpp @@ -81,7 +81,7 @@ GaugeThermalAssistantWindow::OnMouseUp([[maybe_unused]] PixelPoint p) noexcept ReleaseCapture(); if (was_pressed) - InputEvents::eventThermalAssistant(_T("")); + InputEvents::eventThermalAssistant(""); return true; } diff --git a/src/Gauge/GaugeVario.cpp b/src/Gauge/GaugeVario.cpp index 323a19f8fc4..e07c13ee580 100644 --- a/src/Gauge/GaugeVario.cpp +++ b/src/Gauge/GaugeVario.cpp @@ -14,8 +14,8 @@ static constexpr double DELTA_V_STEP = 4.0; static constexpr double DELTA_V_LIMIT = 16.0; -#define TEXT_BUG _T("Bug") -#define TEXT_BALLAST _T("Bal") +#define TEXT_BUG "Bug" +#define TEXT_BALLAST "Bal" inline GaugeVario::BallastGeometry::BallastGeometry(const VarioLook &look, @@ -56,7 +56,7 @@ GaugeVario::BallastGeometry::BallastGeometry(const VarioLook &look, look.text_font->GetCapitalHeight(); // get max value size - tSize = look.text_font->TextSize(_T("100%")); + tSize = look.text_font->TextSize("100%"); value_rect.right = value_rect.left + tSize.width; // update back rect with max label size @@ -96,7 +96,7 @@ GaugeVario::BugsGeometry::BugsGeometry(const VarioLook &look, + look.text_font->GetHeight() - look.text_font->GetAscentHeight(); - tSize = look.text_font->TextSize(_T("100%")); + tSize = look.text_font->TextSize("100%"); value_rect.right = value_rect.left + tSize.width; value_rect.bottom = value_rect.top + @@ -231,8 +231,8 @@ GaugeVario::RenderBackground(Canvas &canvas, const PixelRect &rc) noexcept TransformRotatedPoint(r.Rotate(tick_end), geometry.offset)); - TCHAR label[16]; - StringFormatUnsafe(label, _T("%d"), i * tick_value_step); + char label[16]; + StringFormatUnsafe(label, "%d", i * tick_value_step); const auto label_size = canvas.CalcTextSize(label); @@ -258,14 +258,14 @@ GaugeVario::OnPaintBuffer(Canvas &canvas) noexcept // JMW averager now displays netto average if not circling RenderValue(canvas, geometry.average, average_di, Units::ToUserVSpeed(Calculated().circling ? Calculated().average : Calculated().netto_average), - Calculated().circling ? _T("Avg") : _T("NetAvg")); + Calculated().circling ? "Avg" : "NetAvg"); } if (Settings().show_mc) { auto mc = Units::ToUserVSpeed(GetGlidePolar().GetMC()); RenderValue(canvas, geometry.mc, mc_di, mc, - GetComputerSettings().task.auto_mc ? _T("Auto MC") : _T("MC")); + GetComputerSettings().task.auto_mc ? "Auto MC" : "MC"); } if (Settings().show_speed_to_fly) @@ -336,7 +336,7 @@ GaugeVario::OnPaintBuffer(Canvas &canvas) noexcept RenderValue(canvas, geometry.gross, gross_di, vvaldisplay, - _T("Gross")); + "Gross"); } RenderZero(canvas); @@ -484,7 +484,7 @@ GaugeVario::RenderNeedle(Canvas &canvas, int i, bool average, void GaugeVario::RenderValue(Canvas &canvas, const LabelValueGeometry &g, LabelValueDrawInfo &di, - double value, const TCHAR *label) noexcept + double value, const char *label) noexcept { value = (double)iround(value * 10) / 10; // prevent the -0.0 case @@ -507,17 +507,17 @@ GaugeVario::RenderValue(Canvas &canvas, const LabelValueGeometry &g, canvas.SetBackgroundColor(look.background_color); canvas.DrawOpaqueText(text_position, rc, label); di.label.last_width = width; - _tcscpy(di.label.last_text, label); + strcpy(di.label.last_text, label); } else { canvas.DrawText(text_position, label); } } if (!IsPersistent() || (dirty && di.value.last_value != value)) { - TCHAR buffer[18]; + char buffer[18]; canvas.SetBackgroundColor(look.background_color); canvas.SetTextColor(look.text_color); - _stprintf(buffer, _T("%.1f"), (double)value); + _stprintf(buffer, "%.1f", (double)value); canvas.Select(look.value_font); const unsigned width = canvas.CalcTextSize(buffer).width; @@ -703,8 +703,8 @@ GaugeVario::RenderBallast(Canvas &canvas) noexcept // new ballast 0, hide value if (ballast > 0) { - TCHAR buffer[18]; - _stprintf(buffer, _T("%u%%"), ballast); + char buffer[18]; + _stprintf(buffer, "%u%%", ballast); canvas.SetTextColor(look.text_color); if (IsPersistent()) @@ -746,8 +746,8 @@ GaugeVario::RenderBugs(Canvas &canvas) noexcept } if (bugs > 0) { - TCHAR buffer[18]; - _stprintf(buffer, _T("%d%%"), bugs); + char buffer[18]; + _stprintf(buffer, "%d%%", bugs); canvas.SetTextColor(look.text_color); if (IsPersistent()) canvas.DrawOpaqueText(g.value_pos, g.value_rect, buffer); diff --git a/src/Gauge/GaugeVario.hpp b/src/Gauge/GaugeVario.hpp index 651b454d42a..3c56635b39c 100644 --- a/src/Gauge/GaugeVario.hpp +++ b/src/Gauge/GaugeVario.hpp @@ -68,7 +68,7 @@ class GaugeVario : public AntiFlickerWindow struct DrawInfo { unsigned last_width; double last_value; - TCHAR last_text[32]; + char last_text[32]; Unit last_unit; void Reset() noexcept { @@ -152,7 +152,7 @@ class GaugeVario : public AntiFlickerWindow void RenderZero(Canvas &canvas) noexcept; void RenderValue(Canvas &canvas, const LabelValueGeometry &g, LabelValueDrawInfo &di, - double Value, const TCHAR *Label) noexcept; + double Value, const char *Label) noexcept; void RenderSpeedToFly(Canvas &canvas, int x, int y) noexcept; void RenderBallast(Canvas &canvas) noexcept; void RenderBugs(Canvas &canvas) noexcept; diff --git a/src/Gauge/LogoView.cpp b/src/Gauge/LogoView.cpp index abcd332e8c0..1af74ed92aa 100644 --- a/src/Gauge/LogoView.cpp +++ b/src/Gauge/LogoView.cpp @@ -15,9 +15,7 @@ LogoView::LogoView() noexcept try :logo(IDB_LOGO), big_logo(IDB_LOGO_HD), title(IDB_TITLE), big_title(IDB_TITLE_HD) { -#ifndef USE_GDI font.Load(FontDescription(Layout::FontScale(10))); -#endif } catch (...) { /* ignore Bitmap/Font loader exceptions */ } @@ -143,14 +141,12 @@ LogoView::draw(Canvas &canvas, const PixelRect &rc) noexcept // Draw full XCSoar version number -#ifndef USE_GDI if (!font.IsDefined()) return; canvas.Select(font); -#endif canvas.SetTextColor(COLOR_BLACK); canvas.SetBackgroundTransparent(); - canvas.DrawText({2, 2}, XCSoar_ProductToken); + canvas.DrawText({2, 2}, OpenSoar_ProductToken); } diff --git a/src/Gauge/LogoView.hpp b/src/Gauge/LogoView.hpp index d8179376854..042f3422779 100644 --- a/src/Gauge/LogoView.hpp +++ b/src/Gauge/LogoView.hpp @@ -12,9 +12,7 @@ class Canvas; class LogoView { Bitmap logo, big_logo, title, big_title; -#ifndef USE_GDI Font font; -#endif public: LogoView() noexcept; diff --git a/src/Gauge/ThermalAssistantRenderer.cpp b/src/Gauge/ThermalAssistantRenderer.cpp index 32bc6b1d836..51f308bb9e4 100644 --- a/src/Gauge/ThermalAssistantRenderer.cpp +++ b/src/Gauge/ThermalAssistantRenderer.cpp @@ -80,7 +80,7 @@ ThermalAssistantRenderer::NormalizeLift(double lift, double max_lift) noexcept static void DrawCircleLabel(Canvas &canvas, PixelPoint p, - tstring_view text) noexcept + std::string_view text) noexcept { const auto size = canvas.CalcTextSize(text); p.x -= size.width / 2; @@ -92,7 +92,7 @@ DrawCircleLabel(Canvas &canvas, PixelPoint p, static void DrawCircleLabelVSpeed(Canvas &canvas, PixelPoint p, double value) noexcept { - TCHAR buffer[10]; + char buffer[10]; FormatUserVerticalSpeed(value, buffer); DrawCircleLabel(canvas, p, buffer); } @@ -177,7 +177,7 @@ ThermalAssistantRenderer::PaintNotCircling(Canvas &canvas) const if (small) return; - const TCHAR* str = _("Not Circling"); + const char* str = _("Not Circling"); canvas.Select(look.overlay_font); canvas.SetTextColor(look.text_color); diff --git a/src/Geo/CMakeLists.txt b/src/Geo/CMakeLists.txt new file mode 100644 index 00000000000..25827c58590 --- /dev/null +++ b/src/Geo/CMakeLists.txt @@ -0,0 +1,54 @@ +cmake_minimum_required(VERSION 3.15) +get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + +include(CMakeSource.cmake) +# organize the files in subdirectories +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} + PROPERTIES FOLDER Libs + DEPENDENCIES curl +) + +target_link_libraries(${TARGET_NAME} PUBLIC Math) + +add_dependencies(${TARGET_NAME} util) + diff --git a/src/Geo/CMakeSource.cmake b/src/Geo/CMakeSource.cmake new file mode 100644 index 00000000000..823d8442ee7 --- /dev/null +++ b/src/Geo/CMakeSource.cmake @@ -0,0 +1,31 @@ +set(_SOURCES + Geo/Boost/RangeBox.cpp + Geo/ConvexHull/GrahamScan.cpp + Geo/ConvexHull/PolygonInterior.cpp + Geo/Flat/FlatBoundingBox.cpp + Geo/Flat/FlatEllipse.cpp + Geo/Flat/FlatGeoPoint.cpp + Geo/Flat/FlatLine.cpp + Geo/Flat/FlatPoint.cpp + Geo/Flat/FlatProjection.cpp + Geo/Flat/FlatRay.cpp + Geo/Flat/TaskProjection.cpp + Geo/GeoBounds.cpp + Geo/GeoClip.cpp + Geo/GeoEllipse.cpp + Geo/Geoid.cpp + Geo/GeoPoint.cpp + Geo/GeoVector.cpp + Geo/Math.cpp # aug: von mir umgenannt + Geo/Memento/DistanceMemento.cpp + Geo/Memento/GeoVectorMemento.cpp + Geo/Quadrilateral.cpp + Geo/SearchPoint.cpp + Geo/SearchPointVector.cpp + Geo/SimplifiedMath.cpp + Geo/UTM.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake +) diff --git a/src/Hardware/CMakeLists.txt b/src/Hardware/CMakeLists.txt new file mode 100644 index 00000000000..0b7e1f84f97 --- /dev/null +++ b/src/Hardware/CMakeLists.txt @@ -0,0 +1,49 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/Hardware/CMakeSource.cmake b/src/Hardware/CMakeSource.cmake new file mode 100644 index 00000000000..0c3b41e0ae8 --- /dev/null +++ b/src/Hardware/CMakeSource.cmake @@ -0,0 +1,14 @@ +set(_SOURCES + Hardware/Battery.cpp + Hardware/CPU.cpp + Hardware/DisplayDPI.cpp + Hardware/DisplayGlue.cpp + Hardware/RotateDisplay.cpp + Hardware/Vibrator.cpp + Hardware/PowerGlobal.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake +) + diff --git a/src/Hardware/DisplayGlue.cpp b/src/Hardware/DisplayGlue.cpp index 375e6ecf4e2..1462599528c 100644 --- a/src/Hardware/DisplayGlue.cpp +++ b/src/Hardware/DisplayGlue.cpp @@ -45,8 +45,9 @@ Display::LoadOrientation(VerboseOperationEnvironment &env) LogString("Display rotated"); +#ifndef OPENVARIO_DEVICE // remove this after OpenVarioBaseMenu is ready CommonInterface::main_window->Initialise(); - +#endif /* force the progress dialog to update its layout */ env.UpdateLayout(); } @@ -76,7 +77,10 @@ Display::DetectInitialOrientation() { auto orientation = DisplayOrientation::DEFAULT; -#ifdef MESA_KMS +#if defined(IS_OPENVARIO) // && !defined(IS_OPENVARIO_CB2) + // On OpenVario the (SW-)display orientation should be default always + orientation = DisplayOrientation::DEFAULT; +#elif defined(MESA_KMS) // When running in DRM/KMS mode, infer the display orientation from the linux // console rotation. char buf[3]; diff --git a/src/Hardware/RotateDisplay.cpp b/src/Hardware/RotateDisplay.cpp index 4e599119c8b..de6b2297d79 100644 --- a/src/Hardware/RotateDisplay.cpp +++ b/src/Hardware/RotateDisplay.cpp @@ -14,14 +14,19 @@ #include "Kobo/Model.hpp" #endif +#ifdef IS_OPENVARIO +#include "system/FileUtil.hpp" +#endif + #ifdef ENABLE_OPENGL #include "ui/opengl/Features.hpp" -#ifdef SOFTWARE_ROTATE_DISPLAY -#include "UIGlobals.hpp" -#include "ui/window/SingleWindow.hpp" #include "ui/canvas/opengl/Globals.hpp" #endif -#endif + +#include "UIGlobals.hpp" +#include "ui/window/SingleWindow.hpp" + +static DisplayOrientation _rotation = DisplayOrientation::DEFAULT; void Display::RotateInitialize() @@ -46,6 +51,8 @@ Display::RotateSupported() bool Display::Rotate(DisplayOrientation orientation) { + _rotation = orientation; + #if !defined(ANDROID) && !defined(KOBO) if (orientation == DisplayOrientation::DEFAULT) /* leave it as it is */ @@ -157,6 +164,7 @@ Display::Rotate(DisplayOrientation orientation) bool Display::RotateRestore() { + _rotation = DisplayOrientation::DEFAULT; #if defined(ANDROID) return native_view->SetRequestedOrientation(Java::GetEnv(), NativeView::ScreenOrientation::SENSOR); @@ -166,3 +174,9 @@ Display::RotateRestore() return false; #endif } + +DisplayOrientation +Display::GetRotation() +{ + return _rotation; +} diff --git a/src/Hardware/RotateDisplay.hpp b/src/Hardware/RotateDisplay.hpp index 6b28be3a307..3c18cbb97c7 100644 --- a/src/Hardware/RotateDisplay.hpp +++ b/src/Hardware/RotateDisplay.hpp @@ -11,7 +11,8 @@ namespace Display { void RotateInitialize(); [[gnu::const]] - bool RotateSupported(); + bool + RotateSupported(); /** * Change the orientation of the screen. @@ -24,4 +25,10 @@ namespace Display { */ bool RotateRestore(); -} + + /** + * Get the display rotation setting. + */ + DisplayOrientation GetRotation(); + +} // namespace Display diff --git a/src/HexDump.hpp b/src/HexDump.hpp index b36a9695a4d..21ac52d1e79 100644 --- a/src/HexDump.hpp +++ b/src/HexDump.hpp @@ -20,7 +20,7 @@ static inline void HexDumpLine(const char *prefix, unsigned offset, std::span src) noexcept { - NarrowString<128> line; + StaticString<128> line; line.clear(); for (size_t i = 0; i < src.size(); ++i) { diff --git a/src/HorizonWidget.cpp b/src/HorizonWidget.cpp index 20e16d3cc3f..327aa2b145b 100644 --- a/src/HorizonWidget.cpp +++ b/src/HorizonWidget.cpp @@ -98,7 +98,7 @@ HorizonWindow::OnMouseUp([[maybe_unused]] PixelPoint p) noexcept if (dragging) { StopDragging(); - const TCHAR *gesture = gestures.Finish(); + const char *gesture = gestures.Finish(); if (gesture && InputEvents::processGesture(gesture)) return true; } diff --git a/src/IGC/CMakeLists.txt b/src/IGC/CMakeLists.txt new file mode 100644 index 00000000000..a60842e998c --- /dev/null +++ b/src/IGC/CMakeLists.txt @@ -0,0 +1,51 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +target_link_libraries(${TARGET_NAME} PUBLIC Logger) + + # message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/IGC/CMakeSource.cmake b/src/IGC/CMakeSource.cmake new file mode 100644 index 00000000000..e86d8f73b0d --- /dev/null +++ b/src/IGC/CMakeSource.cmake @@ -0,0 +1,11 @@ +set(_SOURCES + IGC/Generator.cpp + IGC/IGCFix.cpp + IGC/IGCParser.cpp + IGC/IGCString.cpp + IGC/IGCWriter.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake +) diff --git a/src/IGC/Generator.cpp b/src/IGC/Generator.cpp index c98a1ad6c29..15c35346e8a 100644 --- a/src/IGC/Generator.cpp +++ b/src/IGC/Generator.cpp @@ -48,7 +48,7 @@ FormatIGCLocation(char *buffer, const GeoPoint &location) noexcept void FormatIGCTaskTurnPoint(std::span dest, const GeoPoint &location, - const TCHAR *name) noexcept + const char *name) noexcept { char *p = dest.data(); char *const end = p + dest.size(); diff --git a/src/IGC/Generator.hpp b/src/IGC/Generator.hpp index d26a1b69f8c..0ca51e52546 100644 --- a/src/IGC/Generator.hpp +++ b/src/IGC/Generator.hpp @@ -41,4 +41,4 @@ FormatIGCLocation(char *buffer, const GeoPoint &location) noexcept; void FormatIGCTaskTurnPoint(std::span dest, const GeoPoint &location, - const TCHAR *name) noexcept; + const char *name) noexcept; diff --git a/src/IGC/IGCDeclaration.hpp b/src/IGC/IGCDeclaration.hpp index 4aa6dbd3aac..261ac8929c7 100644 --- a/src/IGC/IGCDeclaration.hpp +++ b/src/IGC/IGCDeclaration.hpp @@ -21,7 +21,7 @@ struct IGCDeclarationHeader { unsigned num_turnpoints; /** Optional name of the task */ - NarrowString<256> task_name; + StaticString<256> task_name; }; struct IGCDeclarationTurnpoint { @@ -29,5 +29,5 @@ struct IGCDeclarationTurnpoint { GeoPoint location; /** Optional name of the turnpoint */ - NarrowString<256> name; + StaticString<256> name; }; diff --git a/src/IGC/IGCString.cpp b/src/IGC/IGCString.cpp index a644d5f833e..10552a9a333 100644 --- a/src/IGC/IGCString.cpp +++ b/src/IGC/IGCString.cpp @@ -24,25 +24,3 @@ CopyIGCString(char *dest, char *dest_limit, const char *src) noexcept return dest; } -#ifdef _UNICODE - -char * -CopyIGCString(char *dest, char *dest_limit, const TCHAR *src) noexcept -{ - assert(dest != nullptr); - assert(dest_limit > dest); - assert(src != nullptr); - - while (*src != '\0') { - TCHAR ch = *src++; - if (IsValidIGCChar(ch)) { - *dest++ = ch; - if (dest == dest_limit) - break; - } - } - - return dest; -} - -#endif diff --git a/src/IGC/IGCString.hpp b/src/IGC/IGCString.hpp index 0833abcc40a..a1006ab4a36 100644 --- a/src/IGC/IGCString.hpp +++ b/src/IGC/IGCString.hpp @@ -3,10 +3,6 @@ #pragma once -#ifdef _UNICODE -#include -#endif - /** * Is this a "reserved" character? * @@ -34,14 +30,6 @@ IsValidIGCChar(char ch) noexcept return ch >= 0x20 && ch <= 0x7e && !IsReservedIGCChar(ch); } -#ifdef _UNICODE -static constexpr bool -IsValidIGCChar(TCHAR ch) noexcept -{ - return ch >= 0x20 && ch <= 0x7e && !IsReservedIGCChar(char(ch)); -} -#endif - /** * Copy a null-terminated string to a buffer to be written to an IGC * file. If the string is too long for the buffer, it is truncated. @@ -50,7 +38,3 @@ IsValidIGCChar(TCHAR ch) noexcept char * CopyIGCString(char *dest, char *dest_limit, const char *src) noexcept; -#ifdef _UNICODE -char * -CopyIGCString(char *dest, char *dest_limit, const TCHAR *src) noexcept; -#endif diff --git a/src/IGC/IGCWriter.cpp b/src/IGC/IGCWriter.cpp index bd990f227f4..d3e218f4b3b 100644 --- a/src/IGC/IGCWriter.cpp +++ b/src/IGC/IGCWriter.cpp @@ -47,7 +47,7 @@ IGCWriter::WriteLine(const char *line) } void -IGCWriter::WriteLine(const char *a, const TCHAR *b) +IGCWriter::WriteLine(const char *a, const char *b) { size_t a_length = strlen(a); assert(a_length < buffer.size()); @@ -63,12 +63,12 @@ IGCWriter::WriteLine(const char *a, const TCHAR *b) void IGCWriter::WriteHeader(const BrokenDateTime &date_time, - const TCHAR *pilot_name, - const TCHAR *copilot_name, - const TCHAR *aircraft_model, - const TCHAR *aircraft_registration, - const TCHAR *competition_id, - const char *logger_id, const TCHAR *driver_name, + const char *pilot_name, + const char *copilot_name, + const char *aircraft_model, + const char *aircraft_registration, + const char *competition_id, + const char *logger_id, const char *driver_name, bool simulator) { /* @@ -109,7 +109,7 @@ IGCWriter::WriteHeader(const BrokenDateTime &date_time, WriteLine("HFGTYGLIDERTYPE:", aircraft_model); WriteLine("HFGIDGLIDERID:", aircraft_registration); WriteLine("HFCIDCOMPETITIONID:", competition_id); - WriteLine("HFFTYFRTYPE:XCSOAR,XCSOAR ", XCSoar_VersionStringOld); + WriteLine("HFFTYFRTYPE:XCSOAR,XCSOAR ", OpenSoar_VersionStringOld); WriteLine("HFGPS:", driver_name); WriteLine("HFDTM100DATUM:WGS-1984"); @@ -139,7 +139,7 @@ IGCWriter::EndDeclaration() } void -IGCWriter::AddDeclaration(const GeoPoint &location, const TCHAR *id) +IGCWriter::AddDeclaration(const GeoPoint &location, const char *id) { char c_record[64]; FormatIGCTaskTurnPoint(c_record, location, id); @@ -147,7 +147,7 @@ IGCWriter::AddDeclaration(const GeoPoint &location, const TCHAR *id) } void -IGCWriter::LoggerNote(const TCHAR *text) +IGCWriter::LoggerNote(const char *text) { WriteLine("LPLT", text); } diff --git a/src/IGC/IGCWriter.hpp b/src/IGC/IGCWriter.hpp index 74ade5c4ed9..bad5c75bf88 100644 --- a/src/IGC/IGCWriter.hpp +++ b/src/IGC/IGCWriter.hpp @@ -48,7 +48,7 @@ class IGCWriter { void CommitLine(std::string_view line); void WriteLine(const char *line); - void WriteLine(const char *a, const TCHAR *b); + void WriteLine(const char *a, const char *b); static const char *GetHFFXARecord(); static const char *GetIRecord(); @@ -62,20 +62,20 @@ class IGCWriter { * alphanumeric characters (plain ASCII) */ void WriteHeader(const BrokenDateTime &date_time, - const TCHAR *pilot_name, - const TCHAR *copilot_name, - const TCHAR *aircraft_model, - const TCHAR *aircraft_registration, - const TCHAR *competition_id, - const char *logger_id, const TCHAR *driver_name, + const char *pilot_name, + const char *copilot_name, + const char *aircraft_model, + const char *aircraft_registration, + const char *competition_id, + const char *logger_id, const char *driver_name, bool simulator); - void AddDeclaration(const GeoPoint &location, const TCHAR *ID); + void AddDeclaration(const GeoPoint &location, const char *ID); void StartDeclaration(const BrokenDateTime &date_time, const int number_of_turnpoints); void EndDeclaration(); - void LoggerNote(const TCHAR *text); + void LoggerNote(const char *text); void LogPoint(const IGCFix &fix, int epe, int satellites); void LogPoint(const NMEAInfo &gps_info); diff --git a/src/InfoBoxes/CMakeLists.txt b/src/InfoBoxes/CMakeLists.txt new file mode 100644 index 00000000000..13d96f777cf --- /dev/null +++ b/src/InfoBoxes/CMakeLists.txt @@ -0,0 +1,52 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +target_link_libraries(${TARGET_NAME} PUBLIC system) + +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER FrontEnd) + +add_dependencies(${TARGET_NAME} util) +target_link_libraries(${TARGET_NAME} PUBLIC Airspace) diff --git a/src/InfoBoxes/CMakeSource.cmake b/src/InfoBoxes/CMakeSource.cmake new file mode 100644 index 00000000000..bbafd528ff0 --- /dev/null +++ b/src/InfoBoxes/CMakeSource.cmake @@ -0,0 +1,43 @@ +set(_SOURCES + InfoBoxes/Content/Airspace.cpp + InfoBoxes/Content/Alternate.cpp + InfoBoxes/Content/Altitude.cpp + InfoBoxes/Content/Base.cpp + InfoBoxes/Content/Contest.cpp + InfoBoxes/Content/Direction.cpp + InfoBoxes/Content/Engine.cpp + InfoBoxes/Content/Factory.cpp + InfoBoxes/Content/Glide.cpp + InfoBoxes/Content/MacCready.cpp + InfoBoxes/Content/Other.cpp + InfoBoxes/Content/Places.cpp + InfoBoxes/Content/Radio.cpp + InfoBoxes/Content/Speed.cpp + InfoBoxes/Content/Task.cpp + InfoBoxes/Content/Team.cpp + InfoBoxes/Content/Terrain.cpp + InfoBoxes/Content/Thermal.cpp + InfoBoxes/Content/Time.cpp + InfoBoxes/Content/Trace.cpp + InfoBoxes/Content/Weather.cpp + InfoBoxes/Data.cpp + InfoBoxes/Format.cpp + InfoBoxes/InfoBoxLayout.cpp + InfoBoxes/InfoBoxManager.cpp + InfoBoxes/InfoBoxSettings.cpp + InfoBoxes/InfoBoxWindow.cpp + InfoBoxes/Panel/AltitudeInfo.cpp + InfoBoxes/Panel/AltitudeSetup.cpp + InfoBoxes/Panel/AltitudeSimulator.cpp + InfoBoxes/Panel/ATCReference.cpp + InfoBoxes/Panel/ATCSetup.cpp + InfoBoxes/Panel/MacCreadyEdit.cpp + InfoBoxes/Panel/MacCreadySetup.cpp + InfoBoxes/Panel/RadioEdit.cpp + InfoBoxes/Panel/WindEdit.cpp + InfoBoxes/Units.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake +) diff --git a/src/InfoBoxes/Content/Alternate.cpp b/src/InfoBoxes/Content/Alternate.cpp index bdfcce7af8e..f8fe8c717f3 100644 --- a/src/InfoBoxes/Content/Alternate.cpp +++ b/src/InfoBoxes/Content/Alternate.cpp @@ -101,7 +101,7 @@ InfoBoxContentAlternateGR::Update(InfoBoxData &data) noexcept alternate = NULL; } - data.FmtTitle(_T("Altn {} GR"), index + 1); + data.FmtTitle("Altn {} GR", index + 1); if (alternate == NULL) { data.SetInvalid(); @@ -115,7 +115,7 @@ InfoBoxContentAlternateGR::Update(InfoBoxData &data) noexcept if (gradient < 0) { data.SetValueColor(0); - data.SetValue(_T("+++")); + data.SetValue("+++"); return; } if (::GradientValid(gradient)) { diff --git a/src/InfoBoxes/Content/Altitude.cpp b/src/InfoBoxes/Content/Altitude.cpp index 88e0d56226a..55c23ea5845 100644 --- a/src/InfoBoxes/Content/Altitude.cpp +++ b/src/InfoBoxes/Content/Altitude.cpp @@ -148,10 +148,10 @@ UpdateInfoBoxAltitudeFlightLevel(InfoBoxData &data) noexcept data.SetTitleColor(0); // Set Value - data.FmtValue(_T("{:03}"), iround(Altitude / 100)); + data.FmtValue("{:03}", iround(Altitude / 100)); // Set Comment - data.FmtComment(_T("{}ft"), iround(Altitude)); + data.FmtComment("{}ft", iround(Altitude)); } else if (basic.gps_altitude_available && settings_computer.pressure_available) { @@ -163,10 +163,10 @@ UpdateInfoBoxAltitudeFlightLevel(InfoBoxData &data) noexcept data.SetTitleColor(1); // Set Value - data.FmtValue(_T("{:03}"), iround(Altitude / 100)); + data.FmtValue("{:03}", iround(Altitude / 100)); // Set Comment - data.FmtComment(_T("{}ft"), iround(Altitude)); + data.FmtComment("{}ft", iround(Altitude)); } else if ((basic.baro_altitude_available || basic.gps_altitude_available) && !settings_computer.pressure_available) { diff --git a/src/InfoBoxes/Content/Contest.cpp b/src/InfoBoxes/Content/Contest.cpp index 35c1bbea3fa..c922f5cab76 100644 --- a/src/InfoBoxes/Content/Contest.cpp +++ b/src/InfoBoxes/Content/Contest.cpp @@ -71,7 +71,7 @@ InfoBoxContentContest::Update(InfoBoxData &data) noexcept // Set Value data.SetValueFromDistance(result_contest.distance); - data.FmtComment(_T("{:.1f} pts"), result_contest.score); + data.FmtComment("{:.1f} pts", result_contest.score); } const InfoBoxPanel * @@ -106,5 +106,5 @@ InfoBoxContentContestSpeed::Update(InfoBoxData &data) noexcept // Set Value data.SetValueFromTaskSpeed(result_contest.GetSpeed()); - data.FmtComment(_T("{:.1f} pts"), result_contest.score); + data.FmtComment("{:.1f} pts", result_contest.score); } diff --git a/src/InfoBoxes/Content/Direction.cpp b/src/InfoBoxes/Content/Direction.cpp index da42785b39d..0c9ca009bdb 100644 --- a/src/InfoBoxes/Content/Direction.cpp +++ b/src/InfoBoxes/Content/Direction.cpp @@ -42,3 +42,15 @@ InfoBoxContentTrack::HandleKey(const InfoBoxKeyCodes keycode) noexcept return false; } + +void InfoBoxDrift::Update(InfoBoxData &data) noexcept { + const NMEAInfo &basic = CommonInterface::Basic(); + + if (!basic.track_available && !basic.attitude.heading_available) { + data.SetInvalid(); + return; + } + + Angle Value = basic.track - basic.attitude.heading; + data.SetValueFromBearingDifference(Value); +} diff --git a/src/InfoBoxes/Content/Direction.hpp b/src/InfoBoxes/Content/Direction.hpp index 6cb25da22db..e4c681246d0 100644 --- a/src/InfoBoxes/Content/Direction.hpp +++ b/src/InfoBoxes/Content/Direction.hpp @@ -11,3 +11,8 @@ class InfoBoxContentTrack : public InfoBoxContent void Update(InfoBoxData &data) noexcept override; bool HandleKey(const InfoBoxKeyCodes keycode) noexcept override; }; + +class InfoBoxDrift : public InfoBoxContent { +public: + void Update(InfoBoxData &data) noexcept override; +}; diff --git a/src/InfoBoxes/Content/Engine.cpp b/src/InfoBoxes/Content/Engine.cpp index ff5d33899d1..b4d28842e65 100644 --- a/src/InfoBoxes/Content/Engine.cpp +++ b/src/InfoBoxes/Content/Engine.cpp @@ -21,7 +21,7 @@ UpdateInfoBoxContentCHT(InfoBoxData &data) noexcept return; } - data.FmtValue(_T("{:3.0f}"), basic.engine.cht_temperature.ToUser()); + data.FmtValue("{:3.0f}", basic.engine.cht_temperature.ToUser()); data.SetValueUnit(Units::current.temperature_unit); } @@ -35,7 +35,7 @@ UpdateInfoBoxContentEGT(InfoBoxData &data) noexcept return; } - data.FmtValue(_T("{:3.0f}"), basic.engine.egt_temperature.ToUser()); + data.FmtValue("{:3.0f}", basic.engine.egt_temperature.ToUser()); data.SetValueUnit(Units::current.temperature_unit); } @@ -49,6 +49,6 @@ UpdateInfoBoxContentRPM(InfoBoxData &data) noexcept return; } - data.FmtValue(_T("{}"), Units::ToUserRotation(basic.engine.revolutions_per_second)); + data.FmtValue("{}", Units::ToUserRotation(basic.engine.revolutions_per_second)); data.SetValueUnit(Units::current.rotation_unit); } diff --git a/src/InfoBoxes/Content/Factory.cpp b/src/InfoBoxes/Content/Factory.cpp index e294396c34e..4452c9256f5 100644 --- a/src/InfoBoxes/Content/Factory.cpp +++ b/src/InfoBoxes/Content/Factory.cpp @@ -70,9 +70,9 @@ struct IBFHelperInt { using namespace InfoBoxFactory; struct MetaData { - const TCHAR *name; - const TCHAR *caption; - const TCHAR *description; + const char *name; + const char *caption; + const char *description; InfoBoxContent *(*create)() noexcept; void (*update)(InfoBoxData &data) noexcept; const InfoBoxPanel *panels; @@ -84,23 +84,23 @@ struct MetaData { */ MetaData() = delete; - constexpr MetaData(const TCHAR *_name, - const TCHAR *_caption, - const TCHAR *_description, + constexpr MetaData(const char *_name, + const char *_caption, + const char *_description, InfoBoxContent *(*_create)() noexcept) noexcept :name(_name), caption(_caption), description(_description), create(_create), update(nullptr), panels(nullptr) {} - constexpr MetaData(const TCHAR *_name, - const TCHAR *_caption, - const TCHAR *_description, + constexpr MetaData(const char *_name, + const char *_caption, + const char *_description, void (*_update)(InfoBoxData &data) noexcept) noexcept :name(_name), caption(_caption), description(_description), create(nullptr), update(_update), panels(nullptr) {} - constexpr MetaData(const TCHAR *_name, - const TCHAR *_caption, - const TCHAR *_description, + constexpr MetaData(const char *_name, + const char *_caption, + const char *_description, void (*_update)(InfoBoxData &data) noexcept, const InfoBoxPanel _panels[]) noexcept :name(_name), caption(_caption), description(_description), @@ -112,6 +112,7 @@ struct MetaData { */ static constexpr MetaData meta_data[] = { + // 0..9 // e_HeightGPS { N_("Altitude GPS"), @@ -194,6 +195,7 @@ static constexpr MetaData meta_data[] = { UpdateInfoBoxThermalLastTime, }, + // 10..19 // e_MacCready { N_("MacCready setting"), @@ -271,12 +273,13 @@ static constexpr MetaData meta_data[] = { // e_Fin_GR_TE { - _T("Final GR (TE) deprecated"), - _T("---"), - _T("Deprecated, there is no TE compensation on GR, you should switch to the \"Final GR\" info box."), + "Final GR (TE) deprecated", + "---", + "Deprecated, there is no TE compensation on GR, you should switch to the \"Final GR\" info box.", UpdateInfoBoxFinalGR, }, + // 20..29 // e_H_Terrain { N_("Terrain elevation"), @@ -321,7 +324,10 @@ static constexpr MetaData meta_data[] = { { N_("Wind speed"), N_("Wind"), - N_("Wind speed estimated by XCSoar. Manual adjustment is possible with the connected InfoBox dialogue. Pressing the up/down cursor keys to cycle through settings, adjust the values with left/right cursor keys."), + N_("Wind speed estimated by XCSoar or external sensor (if available). " + "Manual adjustment is possible with the connected InfoBox dialogue. " + "Pressing the up/down cursor keys to cycle through settings, adjust " + "the values with left/right cursor keys."), UpdateInfoBoxWindSpeed, wind_infobox_panels, }, @@ -330,7 +336,10 @@ static constexpr MetaData meta_data[] = { { N_("Wind bearing"), N_("Wind"), - N_("Wind bearing estimated by XCSoar. Manual adjustment is possible with the connected InfoBox dialogue. Pressing the up/down cursor keys to cycle through settings, adjust the values with left/right cursor keys."), + N_("Wind bearing estimated by XCSoar or external sensor (if available). " + "Manual adjustment is possible with the connected InfoBox dialogue. " + "Pressing the up/down cursor keys to cycle through settings, adjust " + "the values with left/right cursor keys."), UpdateInfoBoxWindBearing, wind_infobox_panels, }, @@ -359,6 +368,7 @@ static constexpr MetaData meta_data[] = { UpdateInfoBoxTaskAADistanceMin, }, + // 30..39 // e_AA_SpeedMax { N_("AAT speed max. distance"), @@ -441,6 +451,7 @@ static constexpr MetaData meta_data[] = { UpdateInfoBoxTimeLocal, }, + // 40..49 // e_TimeUTC { N_("Time UTC"), @@ -523,6 +534,7 @@ static constexpr MetaData meta_data[] = { UpdateInfoBoxHumidity, }, + // 50..59 // e_Home_Temperature { N_("Forecast temperature"), @@ -603,6 +615,7 @@ static constexpr MetaData meta_data[] = { UpdateInfoBoxTaskSpeedInstant, }, + // 60..69 // e_Home_Distance { N_("Distance home"), @@ -683,6 +696,7 @@ static constexpr MetaData meta_data[] = { IBFHelperInt::Create, }, + // 70..79 // e_H_QFE { N_("Height above take-off"), @@ -766,6 +780,7 @@ static constexpr MetaData meta_data[] = { IBFHelper::Create, }, + // 80..89 // e_Vario_spark { N_("Vario trace"), @@ -847,6 +862,7 @@ static constexpr MetaData meta_data[] = { UpdateInfoBoxNearestAirspaceHorizontal, }, + // 90..99 // e_NearestAirspaceVertical { N_("Nearest airspace vertical"), @@ -873,7 +889,7 @@ static constexpr MetaData meta_data[] = { wind_infobox_panels, }, - // TerrainCollision + // e_TerrainCollision { N_("Terrain collision"), N_("Terr Coll"), @@ -881,6 +897,7 @@ static constexpr MetaData meta_data[] = { UpdateInfoBoxTerrainCollision, }, + // e_NavAltitude { N_("Altitude (Auto)"), N_("Alt Auto"), @@ -889,7 +906,7 @@ static constexpr MetaData meta_data[] = { altitude_infobox_panels, }, - // NextLegEqThermal + // e_NextLegEqThermal { N_("Thermal next leg equivalent"), N_("T Next Leg"), @@ -897,7 +914,7 @@ static constexpr MetaData meta_data[] = { UpdateInfoBoxNextLegEqThermal, }, - // HeadWindSimplified + // e_HeadWindSimplified { N_("Wind, head component (simplified)"), N_("Head Wind *"), @@ -906,6 +923,7 @@ static constexpr MetaData meta_data[] = { wind_infobox_panels, }, + // e_CruiseEfficiency { N_("Task cruise efficiency"), N_("Cruise Eff"), @@ -915,13 +933,18 @@ static constexpr MetaData meta_data[] = { UpdateInfoBoxCruiseEfficiency, }, + // e_WindArrow { N_("Wind arrow"), N_("Wind"), - N_("Wind speed estimated by XCSoar. Manual adjustment is possible with the connected InfoBox dialogue. Pressing the up/down cursor keys to cycle through settings, adjust the values with left/right cursor keys."), + N_("Wind speed estimated by XCSoar or external sensor (if available). " + "Manual adjustment is possible with the connected InfoBox dialogue. " + "Pressing the up/down cursor keys to cycle through settings, adjust " + "the values with left/right cursor keys."), IBFHelper::Create, }, + // e_ThermalAssistant { N_("Thermal assistant"), N_("Thermal"), @@ -929,6 +952,8 @@ static constexpr MetaData meta_data[] = { IBFHelper::Create, }, + // 100..109 + // e_StartOpenLine { N_("Start open/close countdown"), N_("Start open"), @@ -936,6 +961,7 @@ static constexpr MetaData meta_data[] = { UpdateInfoBoxStartOpen, }, + // e_StartOpenArrivalLine { N_("Start open/close countdown at reaching"), N_("Start reach"), @@ -943,6 +969,7 @@ static constexpr MetaData meta_data[] = { UpdateInfoBoxStartOpenArrival, }, + // e_NextRadial, { N_("Next radial"), N_("Radial"), @@ -951,6 +978,7 @@ static constexpr MetaData meta_data[] = { next_waypoint_infobox_panels, }, + // e_ATC_Radial { N_("ATC radial"), N_("ATC radial"), @@ -959,6 +987,7 @@ static constexpr MetaData meta_data[] = { atc_infobox_panels, }, + // e_TaskSpeedHour { N_("Speed task last hour"), N_("V Task H"), @@ -966,7 +995,7 @@ static constexpr MetaData meta_data[] = { UpdateInfoBoxTaskSpeedHour, }, - // WP_NOMINAL_DIST + // e_WP_NominalDistance { N_("Next distance (nominal)"), N_("WP Dist-N"), @@ -975,6 +1004,7 @@ static constexpr MetaData meta_data[] = { next_waypoint_infobox_panels, }, + // e_CircleDiameter { N_("Circle diameter"), N_("Circle D"), @@ -982,6 +1012,7 @@ static constexpr MetaData meta_data[] = { UpdateInfoBoxCircleDiameter, }, + // e_TakeOffDistance { N_("Distance takeoff"), N_("Takeoff Dist"), @@ -989,7 +1020,7 @@ static constexpr MetaData meta_data[] = { UpdateInfoBoxTakeoffDistance, }, - // CONTEST_SPEED + // e_ContestSpeed { N_("Contest speed"), N_("Cont Speed"), @@ -997,6 +1028,7 @@ static constexpr MetaData meta_data[] = { IBFHelper::Create, }, + // e_Final_MC0_Altitude { N_("Final MC0 altitude difference"), N_("Fin MC0 AltD"), @@ -1004,7 +1036,8 @@ static constexpr MetaData meta_data[] = { UpdateInfoBoxFinalMC0AltitudeDiff, }, - // NEXT_ARROW + // 110..119 + // e_NextWPArrow { N_("Next arrow"), N_("Next arrow"), @@ -1016,7 +1049,7 @@ static constexpr MetaData meta_data[] = { IBFHelper::Create, }, - // e_WP_ETA_VMG + // e_WP_Estimation { N_("Next waypoint arrival time (ground speed)"), N_("WP ETA VMG"), @@ -1057,6 +1090,7 @@ static constexpr MetaData meta_data[] = { IBFHelper::Create, }, + // e_StandbyRadio { N_("Standby Radio Frequency"), N_("Stby Freq"), @@ -1088,6 +1122,8 @@ static constexpr MetaData meta_data[] = { UpdateInfoBoxHeartRate, }, + // 120.. + // e_NUM_TYPES // Last item // Transponder code { N_("Transponder Code"), @@ -1130,41 +1166,94 @@ static constexpr MetaData meta_data[] = { }; -static_assert(ARRAY_SIZE(meta_data) == NUM_TYPES, - "Wrong InfoBox factory size"); +// static_assert(ARRAY_SIZE(meta_data) == NUM_TYPES, "Wrong InfoBox factory size"); + +static constexpr MetaData meta_data_2nd[] = { + // 500.. + // e_DriftAngle - TestBox for Track-Heading + { + N_("Wind - Drift Angle"), + N_("Wind Drift"), + N_("Wind drift angle (Track - True Heading) - for a simple check, " + "how the sensor works."), + IBFHelper::Create, + }, + + // e_InstantaneousWindSpeed + { + N_("Wind - RealTime Speed"), + N_("RealTime Wind"), + N_("Speed of instantaneous wind, estimated from an external sensor."), + UpdateInfoBoxInstWindSpeed, + wind_infobox_panels, + }, + + // e_InstantaneousWindBearing + { + N_("Wind - RealTime Bearing"), + N_("RealTime Wind"), + N_("Bearing of instantaneous wind, estimated from an external sensor."), + UpdateInfoBoxInstWindBearing, + wind_infobox_panels, + }, + + // e_InternalWind + { + N_("Wind - Internal Wind"), + N_("Internal Wind"), + N_("Bearing of instantaneous wind, estimated from an external sensor."), + UpdateInfoBoxInstWindBearing, + wind_infobox_panels, + }, + + // e_InternalZigZagWind + { + N_("Wind - Internal ZigZag Wind"), + N_("ZigZag Wind"), + N_("Bearing of instantaneous wind, estimated from an external sensor."), + UpdateInfoBoxInstWindBearing, + wind_infobox_panels, + }, -const TCHAR * +}; + +// static_assert(ARRAY_SIZE(meta_data_2nd) == NUM_TYPES_2nd - e_NUM_AREA_2nd, "Wrong InfoBox factory size"); + +const char * InfoBoxFactory::GetName(Type type) noexcept { - assert(type < NUM_TYPES); - - return meta_data[type].name; + assert(TypeIsValid(type)); + return (type < NUM_TYPES) ? meta_data[type].name + : meta_data_2nd[type - e_NUM_AREA_2nd].name; } -const TCHAR * +const char * InfoBoxFactory::GetCaption(Type type) noexcept { - assert(type < NUM_TYPES); + assert(TypeIsValid(type)); + return (type < NUM_TYPES) ? meta_data[type].caption : + meta_data_2nd[type - e_NUM_AREA_2nd].caption; - return meta_data[type].caption; } /** * Returns the long description (help text) of the info box type. */ -const TCHAR * +const char * InfoBoxFactory::GetDescription(Type type) noexcept { - assert(type < NUM_TYPES); - - return meta_data[type].description; + assert(TypeIsValid(type)); + return (type < NUM_TYPES) ? meta_data[type].description + : meta_data_2nd[type - e_NUM_AREA_2nd].description; } std::unique_ptr InfoBoxFactory::Create(Type type) noexcept { - assert(type < NUM_TYPES); - const auto &m = meta_data[type]; + assert(TypeIsValid(type)); + + const auto &m = type < NUM_TYPES ? meta_data[type] + : meta_data_2nd[type - e_NUM_AREA_2nd]; assert(m.create != nullptr || m.update != nullptr); @@ -1174,3 +1263,9 @@ InfoBoxFactory::Create(Type type) noexcept else return std::make_unique(m.update, m.panels); } + +bool +InfoBoxFactory::TypeIsValid(Type t) +{ + return (t < e_NUM_TYPES) || ((t >= e_NUM_AREA_2nd) && (t < e_NUM_TYPES_2nd)); +} diff --git a/src/InfoBoxes/Content/Factory.hpp b/src/InfoBoxes/Content/Factory.hpp index f44de526432..f2e7cac78ff 100644 --- a/src/InfoBoxes/Content/Factory.hpp +++ b/src/InfoBoxes/Content/Factory.hpp @@ -16,7 +16,7 @@ namespace InfoBoxFactory * Returns the human-readable name of the info box type. */ [[gnu::const]] - const TCHAR * + const char * GetName(Type type) noexcept; /** @@ -25,14 +25,14 @@ namespace InfoBoxFactory * fit in the small #InfoBoxWindow. */ [[gnu::const]] - const TCHAR * + const char * GetCaption(Type type) noexcept; /** * Returns the long description (help text) of the info box type. */ [[gnu::const]] - const TCHAR * + const char * GetDescription(Type type) noexcept; std::unique_ptr Create(Type infobox_type) noexcept; diff --git a/src/InfoBoxes/Content/Glide.cpp b/src/InfoBoxes/Content/Glide.cpp index 7f606fc9682..f5ec5fc0ac4 100644 --- a/src/InfoBoxes/Content/Glide.cpp +++ b/src/InfoBoxes/Content/Glide.cpp @@ -55,9 +55,9 @@ UpdateInfoBoxGRAvg(InfoBoxData &data) noexcept // Set Value if (average_gr < 0) - data.SetValue(_T("^^^")); + data.SetValue("^^^"); else if (!::GradientValid(average_gr)) - data.SetValue(_T("+++")); + data.SetValue("+++"); else data.SetValueFromGlideRatio(average_gr); } diff --git a/src/InfoBoxes/Content/MacCready.cpp b/src/InfoBoxes/Content/MacCready.cpp index 4f5fcd63ede..d06061706a1 100644 --- a/src/InfoBoxes/Content/MacCready.cpp +++ b/src/InfoBoxes/Content/MacCready.cpp @@ -16,9 +16,9 @@ static void SetVSpeed(InfoBoxData &data, double value) noexcept { - TCHAR buffer[32]; + char buffer[32]; FormatUserVerticalSpeed(value, buffer, false); - data.SetValue(buffer[0] == _T('+') ? buffer + 1 : buffer); + data.SetValue(buffer[0] == '+' ? buffer + 1 : buffer); data.SetValueUnit(Units::current.vertical_speed_unit); } diff --git a/src/InfoBoxes/Content/Other.cpp b/src/InfoBoxes/Content/Other.cpp index 62b85db14dd..4f5a8219892 100644 --- a/src/InfoBoxes/Content/Other.cpp +++ b/src/InfoBoxes/Content/Other.cpp @@ -27,7 +27,7 @@ UpdateInfoBoxHeartRate(InfoBoxData &data) noexcept return; } - data.FmtValue(_T("{}"), basic.heart_rate); + data.FmtValue("{}", basic.heart_rate); } void @@ -39,7 +39,7 @@ UpdateInfoBoxGLoad(InfoBoxData &data) noexcept } // Set Value - data.FmtValue(_T("{:2.2f}"), CommonInterface::Basic().acceleration.g_load); + data.FmtValue("{:2.2f}", CommonInterface::Basic().acceleration.g_load); } void @@ -54,7 +54,7 @@ UpdateInfoBoxBattery(InfoBoxData &data) noexcept switch (external.status) { case Power::ExternalInfo::Status::OFF: if (CommonInterface::Basic().battery_level_available) - data.FmtComment(_T("{}; {}%"), + data.FmtComment("{}; {}%", _("AC Off"), (int)CommonInterface::Basic().battery_level); else @@ -162,7 +162,7 @@ InfoBoxContentHorizon::Update(InfoBoxData &data) noexcept // TODO: merge with original copy from Dialogs/StatusPanels/SystemStatusPanel.cpp [[gnu::pure]] -static const TCHAR * +static const char * GetGPSStatus(const NMEAInfo &basic) noexcept { if (!basic.alive) @@ -187,7 +187,7 @@ UpdateInfoBoxNbrSat(InfoBoxData &data) noexcept data.SetComment(_("No GPS")); else if (gps.satellites_used_available) { // known number of sats - data.FmtValue(_T("{}"), gps.satellites_used); + data.FmtValue("{}", gps.satellites_used); } else { // valid but unknown number of sats data.SetValueInvalid(); diff --git a/src/InfoBoxes/Content/Radio.cpp b/src/InfoBoxes/Content/Radio.cpp index 9d99b38aa96..b55d9bbacf7 100644 --- a/src/InfoBoxes/Content/Radio.cpp +++ b/src/InfoBoxes/Content/Radio.cpp @@ -14,7 +14,7 @@ static void UpdateInfoBoxFrequency(InfoBoxData &data, const RadioFrequency freq, - const TCHAR *freq_name) noexcept + const char *freq_name) noexcept { if(freq.IsDefined()) { freq.Format(data.value.data(), data.value.capacity()); diff --git a/src/InfoBoxes/Content/Task.cpp b/src/InfoBoxes/Content/Task.cpp index eac4f88949f..9da4e18b2f0 100644 --- a/src/InfoBoxes/Content/Task.cpp +++ b/src/InfoBoxes/Content/Task.cpp @@ -122,7 +122,7 @@ InfoBoxContentNextWaypoint::Update(InfoBoxData &data) noexcept // Set Comment if (way_point->radio_frequency.IsDefined()) { const unsigned freq = way_point->radio_frequency.GetKiloHertz(); - data.FmtComment(_T("{}.{:03} {}"), + data.FmtComment("{}.{:03} {}", freq / 1000, freq % 1000, way_point->comment); } else @@ -254,10 +254,10 @@ UpdateInfoBoxNextETA(InfoBoxData &data) noexcept std::chrono::duration_cast(task_stats.current_leg.solution_remaining.time_elapsed); // Set Value - data.FmtValue(_T("{:02}:{:02}"), t.hour, t.minute); + data.FmtValue("{:02}:{:02}", t.hour, t.minute); // Set Comment - data.FmtComment(_T("{:02}"), t.second); + data.FmtComment("{:02}", t.second); } static void @@ -342,7 +342,7 @@ UpdateInfoBoxNextGR(InfoBoxData &data) noexcept auto gradient = CommonInterface::Calculated().task_stats.current_leg.gradient; if (gradient <= 0) { - data.SetValue(_T("+++")); + data.SetValue("+++"); return; } if (::GradientValid(gradient)) { @@ -402,10 +402,10 @@ UpdateInfoBoxFinalETA(InfoBoxData &data) noexcept std::chrono::duration_cast(task_stats.total.solution_remaining.time_elapsed); // Set Value - data.FmtValue(_T("{:02}:{:02}"), t.hour, t.minute); + data.FmtValue("{:02}:{:02}", t.hour, t.minute); // Set Comment - data.FmtComment(_T("{:02}"), t.second); + data.FmtComment("{:02}", t.second); } void @@ -508,7 +508,7 @@ UpdateInfoBoxFinalGR(InfoBoxData &data) noexcept auto gradient = task_stats.total.gradient; if (gradient <= 0) { - data.SetValue(_T("+++")); + data.SetValue("+++"); return; } if (::GradientValid(gradient)) @@ -723,8 +723,8 @@ UpdateInfoBoxNextETAVMG(InfoBoxData &data) noexcept if (now_local.IsPlausible()) { const std::chrono::seconds dd{long(d/v)}; const BrokenTime t = now_local + dd; - data.FmtValue(_T("{:02}:{:02}"), t.hour, t.minute); - data.FmtComment(_T("{:02}"), t.second); + data.FmtValue("{:02}:{:02}", t.hour, t.minute); + data.FmtComment("{:02}", t.second); } } @@ -803,7 +803,7 @@ UpdateInfoBoxStartOpen(InfoBoxData &data) noexcept } else if (open.HasBegun(now)) { if (open.GetEnd().IsValid()) { unsigned seconds = SecondsUntil(now_s, open.GetEnd()); - data.FmtValue(_T("{:02}:{:02}"), seconds / 60, seconds % 60); + data.FmtValue("{:02}:{:02}", seconds / 60, seconds % 60); data.SetValueColor(3); } else data.SetValueInvalid(); @@ -811,7 +811,7 @@ UpdateInfoBoxStartOpen(InfoBoxData &data) noexcept data.SetComment(_("Open")); } else { unsigned seconds = SecondsUntil(now_s, open.GetStart()); - data.FmtValue(_T("{:02}:{:02}"), seconds / 60, seconds % 60); + data.FmtValue("{:02}:{:02}", seconds / 60, seconds % 60); data.SetValueColor(2); data.SetComment(_("Waiting")); } @@ -848,7 +848,7 @@ UpdateInfoBoxStartOpenArrival(InfoBoxData &data) noexcept } else if (open.HasBegun(arrival)) { if (open.GetEnd().IsValid()) { unsigned seconds = SecondsUntil(arrival_s, open.GetEnd()); - data.FmtValue(_T("{:02}:{:02}"), seconds / 60, seconds % 60); + data.FmtValue("{:02}:{:02}", seconds / 60, seconds % 60); data.SetValueColor(3); } else data.SetValueInvalid(); @@ -856,7 +856,7 @@ UpdateInfoBoxStartOpenArrival(InfoBoxData &data) noexcept data.SetComment(_("Open")); } else { unsigned seconds = SecondsUntil(arrival_s, open.GetStart()); - data.FmtValue(_T("{:02}:{:02}"), seconds / 60, seconds % 60); + data.FmtValue("{:02}:{:02}", seconds / 60, seconds % 60); data.SetValueColor(2); data.SetComment(_("Waiting")); } @@ -946,7 +946,7 @@ UpdateInfoTaskETAorAATdT(InfoBoxData& data) noexcept UpdateInfoBoxTaskAATimeDelta(data); data.SetComment(eta_text); - data.SetTitle(_T("AAT delta time")); + data.SetTitle("AAT delta time"); } else - data.SetTitle(_T("Task arrival time")); + data.SetTitle("Task arrival time"); } diff --git a/src/InfoBoxes/Content/Team.cpp b/src/InfoBoxes/Content/Team.cpp index e097327b658..1ff425093b3 100644 --- a/src/InfoBoxes/Content/Team.cpp +++ b/src/InfoBoxes/Content/Team.cpp @@ -115,7 +115,7 @@ UpdateInfoBoxTeamBearing(InfoBoxData &data) noexcept else if (!settings.team_flarm_callsign.empty()) data.SetComment(settings.team_flarm_callsign.c_str()); else - data.SetComment(_T("???")); + data.SetComment("???"); if (flarm.FindTraffic(settings.team_flarm_id) != NULL) data.SetCommentColor(2); @@ -145,7 +145,7 @@ UpdateInfoBoxTeamBearingDiff(InfoBoxData &data) noexcept else if (!StringIsEmpty(settings.team_flarm_callsign)) data.SetComment(settings.team_flarm_callsign); else - data.SetComment(_T("???")); + data.SetComment("???"); if (flarm.FindTraffic(settings.team_flarm_id) != NULL) data.SetCommentColor(2); @@ -172,7 +172,7 @@ UpdateInfoBoxTeamDistance(InfoBoxData &data) noexcept else if (!StringIsEmpty(settings.team_flarm_callsign)) data.SetComment(settings.team_flarm_callsign); else - data.SetComment(_T("???")); + data.SetComment("???"); data.SetCommentColor(teamcode_info.flarm_teammate_code_current ? 2 : 1); } diff --git a/src/InfoBoxes/Content/Thermal.cpp b/src/InfoBoxes/Content/Thermal.cpp index 0f46b9c75cd..823b89e6b75 100644 --- a/src/InfoBoxes/Content/Thermal.cpp +++ b/src/InfoBoxes/Content/Thermal.cpp @@ -16,9 +16,9 @@ static void SetVSpeed(InfoBoxData &data, double value) noexcept { - TCHAR buffer[32]; + char buffer[32]; FormatUserVerticalSpeed(value, buffer, false); - data.SetValue(buffer[0] == _T('+') ? buffer + 1 : buffer); + data.SetValue(buffer[0] == '+' ? buffer + 1 : buffer); data.SetValueUnit(Units::current.vertical_speed_unit); } @@ -210,7 +210,7 @@ UpdateInfoBoxCircleDiameter(InfoBoxData &data) noexcept return; } - TCHAR buffer[32]; + char buffer[32]; Unit unit = FormatSmallUserDistance(buffer, circle_diameter, false, 0); data.SetValue (buffer); data.SetValueUnit(unit); @@ -219,8 +219,8 @@ UpdateInfoBoxCircleDiameter(InfoBoxData &data) noexcept Angle::FullCircle().Native() / turn_rate.Native(); StaticString<16> duration_buffer; - duration_buffer.Format(_T("%u s"), int(circle_duration)); - _tcscpy (buffer, duration_buffer); + duration_buffer.Format("%u s", int(circle_duration)); + strcpy (buffer, duration_buffer); data.SetComment (buffer); } diff --git a/src/InfoBoxes/Content/Time.cpp b/src/InfoBoxes/Content/Time.cpp index bd6bb96aca9..c7fa0f376e3 100644 --- a/src/InfoBoxes/Content/Time.cpp +++ b/src/InfoBoxes/Content/Time.cpp @@ -24,7 +24,7 @@ UpdateInfoBoxTimeLocal(InfoBoxData &data) noexcept FormatLocalTimeHHMM(data.value.buffer(), basic.time, settings.utc_offset); // Set Comment - data.FmtComment(_T("{:02}"), basic.date_time_utc.second); + data.FmtComment("{:02}", basic.date_time_utc.second); } void @@ -39,10 +39,10 @@ UpdateInfoBoxTimeUTC(InfoBoxData &data) noexcept // Set Value const BrokenDateTime t = basic.date_time_utc; - data.FmtValue(_T("{:02}:{:02}"), t.hour, t.minute); + data.FmtValue("{:02}:{:02}", t.hour, t.minute); // Set Comment - data.FmtComment(_T("{:02}"), t.second); + data.FmtComment("{:02}", t.second); } void diff --git a/src/InfoBoxes/Content/Trace.cpp b/src/InfoBoxes/Content/Trace.cpp index 59f51d7fec0..1f509d600eb 100644 --- a/src/InfoBoxes/Content/Trace.cpp +++ b/src/InfoBoxes/Content/Trace.cpp @@ -114,7 +114,7 @@ void InfoBoxContentBarogram::Update(InfoBoxData &data) noexcept { const MoreData &basic = CommonInterface::Basic(); - TCHAR sTmp[32]; + char sTmp[32]; if (basic.NavAltitudeAvailable()) { FormatUserAltitude(basic.nav_altitude, sTmp); diff --git a/src/InfoBoxes/Content/Type.hpp b/src/InfoBoxes/Content/Type.hpp index 7d981feee82..c20027167bd 100644 --- a/src/InfoBoxes/Content/Type.hpp +++ b/src/InfoBoxes/Content/Type.hpp @@ -6,164 +6,163 @@ namespace InfoBoxFactory { enum Type { - /* 0..9 */ - e_HeightGPS, /* This is the height above mean sea level reported by the GPS. Touchscreen/PC only: in simulation mode, this value is adjustable with the up/down arrow keys and the right/left arrow keys also cause the glider to turn */ - e_HeightAGL, /* This is the navigation altitude minus the terrain height obtained from the terrain file. The value is coloured red when the glider is below the terrain safety clearance height */ - e_Thermal_30s, /* A 30 second rolling average climb rate based of the reported GPS altitude, or vario if available */ - e_Bearing, /* True bearing of the next waypoint. For AAT tasks, this is the true bearing to the target within the AAT sector */ - e_GR_Instantaneous, /* Instantaneous glide ratio over ground, given by the ground speed divided by the vertical speed (GPS speed) over the last 20 seconds. Negative values indicate climbing cruise. If the vertical speed is close to zero, the displayed value is '---' */ - e_GR_Cruise, /* The distance from the top of the last thermal, divided by the altitude lost since the top of the last thermal. Negative values indicate climbing cruise (height gain since leaving the last thermal). If the vertical speed is close to zero, the displayed value is '---' */ - e_Speed_GPS, /* Ground speed measured by the GPS. If this infobox is active in simulation mode, pressing the up and down arrows adjusts the speed, and left and right turn the glider */ - e_TL_Avg, /* Total altitude gain/loss in the last thermal divided by the time spent circling */ - e_TL_Gain, /* Total altitude gain/loss in the last thermal */ - e_TL_Time, /* Time spent circling in the last thermal */ - /* 10..19 */ - e_MacCready, /* The current MacCready setting. This infobox also shows whether MacCready is manual or auto. (Touchscreen/PC only) Also used to adjust the MacCready Setting if the infobox is active, by using the up/down cursor keys */ - e_WP_Distance, /* The distance to the currently selected waypoint. For AAT tasks, this is the distance to the target within the AAT sector */ - e_WP_AltDiff, /* Next Altitude Difference - Arrival altitude at the next waypoint relative to the safety arrival height */ - e_WP_AltReq, /* Additional altitude required to reach the next turn point */ - e_WP_Name, /* The name of the currently selected turn point. When this infobox is active, using the up/down cursor keys selects the next/previous waypoint in the task. (Touchscreen/PC only) Pressing the enter cursor key brings up the waypoint details */ - e_Fin_AltDiff, /* Arrival altitude at the final task turn point relative to the safety arrival height */ - e_Fin_AltReq, /* Additional altitude required to finish the task */ - e_SpeedTaskAvg, /* Average cross country speed while on current task, compensated for altitude */ - e_Fin_Distance, /* Distance to finish around remaining turn points */ - e_Fin_GR_TE, /* Deprecated */ - /* 20..29 */ - e_H_Terrain, /* This is the elevation of the terrain above mean sea level, obtained from the terrain file at the current GPS location */ - e_Thermal_Avg, /* Altitude gained/lost in the current thermal, divided by time spent thermaling */ - e_Thermal_Gain, /* The altitude gained/lost in the current thermal */ - e_Track_GPS, /* Magnetic track reported by the GPS. (Touchscreen/PC only) If this infobox is active in simulation mode, pressing the up and down arrows adjusts the track */ - e_VerticalSpeed_GPS, /* Instantaneous vertical speed, as reported by the GPS, or the intelligent vario total energy vario value if connected to one */ - e_WindSpeed_Est, /* Wind speed estimated by XCSoar. (Touchscreen/PC only) Manual adjustment is possible by pressing the up/down cursor keys to adjust magnitude and left/right cursor keys to adjust bearing when the infobox is active. Pressing the enter cursor key saves the wind value as the initial value when XCSoar next starts */ - e_WindBearing_Est, /* Wind bearing estimated by XCSoar. (Touchscreen/PC only) Manual adjustment is possible by pressing the up/down cursor keys to adjust bearing when the infobox is active */ - e_AA_Time, /* Assigned Area Task time remaining. Goes red when time remaining has expired */ - e_AA_DistanceMax, /* Assigned Area Task maximum distance possible for remainder of task */ - e_AA_DistanceMin, /* Assigned Area Task minimum distance possible for remainder of task */ - /* 30..39 */ - e_AA_SpeedMax, /* Assigned Area Task average speed achievable if flying maximum possible distance remaining in minimum AAT time */ - e_AA_SpeedMin, /* Assigned Area Task average speed achievable if flying minimum possible distance remaining in minimum AAT time */ - e_AirSpeed_Ext, /* Indicated Airspeed reported by a supported external intelligent vario */ - e_H_Baro, /* This is the barometric altitude obtained from a GPS equipped with pressure sensor, or a supported external intelligent vario */ - e_WP_Speed_MC, /* The MacCready speed-to-fly for optimal flight to the next waypoint. In cruise flight mode, this speed-to-fly is calculated for maintaining altitude. In final glide mode, this speed-to-fly is calculated for descent */ - e_Climb_Perc, /* Percentage of time spent in climb mode. These statistics are reset upon starting the task */ - e_TimeSinceTakeoff, /* Time elapsed since takeoff was detected */ - e_Load_G, /* Magnitude of G loading reported by a supported external intelligent vario. This value is negative for pitch-down manoeuvres */ - e_WP_GR, /* The required glide ratio over ground to reach the next waypoint, given by the distance to next waypoint divided by the height required to arrive at the safety arrival height. Negative values indicate a climb is necessary to reach the waypoint. If the height required is close to zero, the displayed value is '---'. Note that this calculation may be optimistic because it reduces the height required to reach the waypoint by the excess energy height of the glider if its true airspeed is greater than the MacCready and best LD speeds */ - e_TimeLocal, /* GPS time expressed in local time zone */ - /* 40..49 */ - e_TimeUTC, /* GPS time expressed in UTC */ - e_Fin_Time, /* Estimated time required to complete task, assuming performance of ideal MacCready cruise/climb cycle */ - e_WP_Time, /* Estimated time required to reach next waypoint, assuming performance of ideal MacCready cruise/climb cycle */ - e_Act_Speed, /* The instantaneous MacCready speed-to-fly, making use of Netto vario calculations to determine dolphin cruise speed in the glider's current bearing. In cruise flight mode, this speed-to-fly is calculated for maintaining altitude. In final glide mode, this speed-to-fly is calculated for descent. In climb mode, this switches to the speed for minimum sink at the current load factor (if an accelerometer is connected). When Block mode speed to fly is selected, this infobox displays the MacCready speed */ - e_VerticalSpeed_Netto, /* Instantaneous vertical speed of air-mass, equal to vario value less the glider's estimated sink rate. Best used if airspeed, accelerometers and vario are connected, otherwise calculations are based on GPS measurements and wind estimates */ - e_Fin_TimeLocal, /* Estimated arrival local time at task completion, assuming performance of ideal MacCready cruise/climb cycle */ - e_WP_TimeLocal, /* Estimated arrival local time at next waypoint, assuming performance of ideal MacCready cruise/climb cycle */ - e_WP_BearingDiff, /* The difference between the glider's track bearing, to the bearing of the next waypoint, or for AAT tasks, to the bearing to the target within the AAT sector. GPS navigation is based on the track bearing across the ground, and this track bearing may differ from the glider's heading when there is wind present. Chevrons point to the direction the glider needs to alter course to correct the bearing difference, that is, so that the glider's course made good is pointing directly at the next waypoint. This bearing takes into account the curvature of the Earth */ - e_Temperature, /* Outside air temperature measured by a probe if supported by a connected intelligent variometer */ - e_HumidityRel, /* Relative humidity of the air in percent as measured by a probe if supported by a connected intelligent variometer */ - /* 50..59 */ - e_Home_Temperature, /* Forecast temperature of the ground at the home airfield, used in estimating convection height and cloud base in conjunction with outside air temperature and relative humidity probe. (Touchscreen/PC only) Pressing the up/down cursor keys adjusts this forecast temperature */ - e_Fin_AA_Distance, /* Assigned Area Task distance around target points for remainder of task */ - e_AA_SpeedAvg, /* Assigned Area Task average speed achievable around target points remaining in minimum AAT time */ - e_LD, /* Instantaneous lift/drag ratio, given by the indicated airspeed divided by the total energy vertical speed, when connected to an intelligent variometer. Negative values indicate climbing cruise. If the total energy vario speed is close to zero, the displayed value is '---' */ - e_Speed, /* True Airspeed reported by a supported external intelligent vario */ - e_Team_Code, /* The current Team code for this aircraft. Use this to report to other team members. The last team aircraft code entered is displayed underneath */ - e_Team_Bearing, /* The bearing to the team aircraft location at the last team code report */ - e_Team_BearingDiff, /* The relative bearing to the team aircraft location at the last reported team code */ - e_Team_Range, /* The range to the team aircraft location at the last reported team code */ - e_CC_SpeedInst, /* Instantaneous cross country speed while on current task, compensated for altitude */ - /* 60..69 */ - e_Home_Distance, /* Distance to home waypoint (if defined) */ - e_CC_Speed, /* Achieved cross country speed while on current task, compensated for altitude */ - e_AA_TimeDiff, /* Difference between estimated task time and AAT minimum time. Colored red if negative (expected arrival too early), or blue if in sector and can turn now with estimated arrival time greater than AAT time plus 5 minutes */ - e_Climb_Avg, /* Time-average climb rate in all thermals */ - e_RH_Trend, /* Task Req. Total Height Trend */ - e_Battery, /* Displays percentage of device battery remaining (where applicable) and status/voltage of external power supply */ - e_Fin_GR, /* Geometric gradient to the arrival height above the final waypoint. This is not adjusted for total energy */ - e_Alternate_1_Name, /* Displays name and bearing to the best alternate landing location */ - e_Alternate_2_Name, /* Displays name and bearing to the second alternate landing location */ - e_Alternate_1_GR, /* Geometric gradient to the arrival height above the best alternate. This is not adjusted for total energy */ - /* 70..79 */ - e_H_QFE, /* Height on automatic QFE. This altitude value is constantly reset to 0 on ground BEFORE taking off. After takeoff, it is no more reset automatically even if on ground. During flight you can change QFE with up and down keys. Bottom line shows QNH altitude. Changing QFE does not affect QNH altitude */ - e_GR_Avg, /* The distance made in the configured period of time divided by the altitude lost since then. */ - e_Experimental1, /* Experimental1 */ - e_OC_Distance, /* Online Contest Distance */ - e_Experimental2, /* Experimental2 */ - e_CPU_Load, /* CPU load consumed by XCSoar averaged over 5 seconds */ - e_WP_H, /* Absolute arrival altitude at the next waypoint in final glide */ - e_Free_RAM, /* Free RAM as reported by OS */ - e_FlightLevel, /* Flight Level, also known as pressure altitude */ - e_Barogram, - /* 80..89 */ - e_Vario_spark, - e_NettoVario_spark, - e_CirclingAverage_spark, - e_ThermalBand, - e_TaskProgress, - e_TaskMaxHeightTime, /* Time aircraft has been under the max start height */ - e_Fin_ETE_VMG, - e_WP_ETE_VMG, - e_Horizon, - e_NearestAirspaceHorizontal, - /* 90..99 */ - e_NearestAirspaceVertical, - e_WP_MC0AltDiff, - e_HeadWind, - TerrainCollision, - NavAltitude, - NextLegEqThermal, - HeadWindSimplified, - CruiseEfficiency, - WIND_ARROW, - THERMAL_ASSISTANT, - - START_OPEN_TIME, - START_OPEN_ARRIVAL_TIME, - - NEXT_RADIAL, - ATC_RADIAL, - - TASK_SPEED_HOUR, - WP_NOMINAL_DIST, /* The nominal distance to the currently selected waypoint. For AAT tasks, this is the distance to the origin of the AAT sector */ - - CIRCLE_DIAMETER, - - TAKEOFF_DISTANCE, - CONTEST_SPEED, - - FIN_MC0_ALTD, - - /* 110..119 */ - NEXT_ARROW, - e_WP_ETA_VMG, /* Estimated arrival time at next waypoint assuming current speed is maintained*/ - - e_NonCircling_Climb_Perc, - - e_Climb_Perc_Chart, - - e_NbrSat, /* Number of used Sat by GPS module */ - - e_ActiveRadio, /* Active Radio Frequency */ - - e_StandbyRadio, /* Standby Radio Frequency */ - e_Thermal_Time, /* Time in Thermal*/ - - e_Alternate_2_GR, /* Geometric gradient to the arrival height above the second alternate. This is not adjusted for total energy */ - - e_HeartRate, - - e_TransponderCode, /* Transponder code */ - - e_EngineCHT, /* Engine Cylinder Head Temperature */ - e_EngineEGT, /* Engine Exhaust Gas Temperature */ - e_EngineRPM, /* Engine Revolutions Per Minute */ - - e_AAT_dT_or_ETA, /* Delta time in AAT task and ETA in racing task */ - - e_NUM_TYPES /* Last item */ - }; + // 0..9 + e_HeightGPS, // This is the height above mean sea level reported by... + e_HeightAGL, // This is the navigation altitude minus the terrain ... + e_Thermal_30s, // A 30 second rolling average climb rate based of the ... + e_Bearing, // True bearing of the next waypoint. For AAT tasks, this ... + e_GR_Instantaneous, // Instantaneous glide ratio over ground, given by ... + e_GR_Cruise, // The distance from the top of the last thermal, divided ... + e_Speed_GPS, // Ground speed measured by the GPS. If this infobox is ... + e_TL_Avg, // Total altitude gain/loss in the last thermal divided by ... + e_TL_Gain, // Total altitude gain/loss in the last thermal + e_TL_Time, // Time spent circling in the last thermal + // 10..19 + e_MacCready, // The current MacCready setting. This infobox also shows ... + e_WP_Distance, // The distance to the currently selected waypoint. For ... + e_WP_AltDiff, // Next Altitude Difference - Arrival altitude at the ... + e_WP_AltReq, // Additional altitude required to reach the next turn ... + e_WP_Name, // The name of the currently selected turn point. When this ... + e_Fin_AltDiff, // Arrival altitude at the final task turn point relative... + e_Fin_AltReq, // Additional altitude required to finish the task + e_SpeedTaskAvg, // Average cross country speed while on current task, ... + e_Fin_Distance, // Distance to finish around remaining turn points + e_Fin_GR_TE, // Deprecated + // 20..29 + e_H_Terrain, // This is the elevation of the terrain above mean sea ... + e_Thermal_Avg, // Altitude gained/lost in the current thermal, divided ... + e_Thermal_Gain, // The altitude gained/lost in the current thermal + e_Track_GPS, // Magnetic track reported by the GPS. (Touchscreen/PC ... + e_VerticalSpeed_GPS, // Instantaneous vertical speed, as reported by ... + e_WindSpeed_Est, // Wind speed estimated by XCSoar. (Touchscreen/PC ... + e_WindBearing_Est, // Wind bearing estimated by XCSoar. (Touchscreen/PC ... + e_AA_Time, // Assigned Area Task time remaining. Goes red when time ... + e_AA_DistanceMax, // Assigned Area Task maximum distance possible ... + e_AA_DistanceMin, // Assigned Area Task minimum distance possible ... + // 30..39 + e_AA_SpeedMax, // Assigned Area Task average speed achievable if flying ... + e_AA_SpeedMin, // Assigned Area Task average speed achievable if flying ... + e_AirSpeed_Ext, // Indicated Airspeed reported by a supported external ... + e_H_Baro, // This is the barometric altitude obtained from a GPS ... + e_WP_Speed_MC, // The MacCready speed-to-fly for optimal flight to the ... + e_Climb_Perc, // Percentage of time spent in climb mode. These statist. ... + e_TimeSinceTakeoff, // Time elapsed since takeoff was detected + e_Load_G, // Magnitude of G loading reported by a supported external ... + e_WP_GR, // The required glide ratio over ground to reach the next ... + e_TimeLocal, // GPS time expressed in local time zone + // 40..49 + e_TimeUTC, // GPS time expressed in UTC + e_Fin_Time, // Estimated time required to complete task, assuming ... + e_WP_Time, // Estimated time required to reach next waypoint, assuming ... + e_Act_Speed, // The instantaneous MacCready speed-to-fly, making use of ... + e_VerticalSpeed_Netto, // Instantaneous vertical speed of air-mass ... + e_Fin_TimeLocal, // Estimated arrival local time at task completion, ... + e_WP_TimeLocal, // Estimated arrival local time at next waypoint, ... + e_WP_BearingDiff, // The difference between the glider's track bearing, ... + e_Temperature, // Outside air temperature measured by a probe if ... + e_HumidityRel, // Relative humidity of the air in percent as measured ... + // 50..59 + e_Home_Temperature, // Forecast temperature of the ground at the home ... + e_Fin_AA_Distance, // Assigned Area Task distance around target points ... + e_AA_SpeedAvg, // Assigned Area Task average speed achievable around ... + e_LD, // Instantaneous lift/drag ratio, given by the indicated airspeed ... + e_Speed, // True Airspeed reported by a supported external intelligent ... + e_Team_Code, // The current Team code for this aircraft. Use this to ... + e_Team_Bearing, // The bearing to the team aircraft location at the ... + e_Team_BearingDiff, // The relative bearing to the team aircraft loc ... + e_Team_Range, // The range to the team aircraft location at the last ... + e_CC_SpeedInst, // Instantaneous cross country speed while on current ... + // 60..69 + e_Home_Distance, // Distance to home waypoint (if defined) + e_CC_Speed, // Achieved cross country speed while on current task, ... + e_AA_TimeDiff, // Difference between estimated task time and AAT ... + e_Climb_Avg, // Time-average climb rate in all thermals + e_RH_Trend, // Task Req. Total Height Trend + e_Battery, // Displays percentage of device battery remaining (where ... + e_Fin_GR, // Geometric gradient to the arrival height above the final ... + e_Alternate_1_Name, // Displays name and bearing to the best alternate ... + e_Alternate_2_Name, // Displays name and bearing to the second ... + e_Alternate_1_GR, // Geometric gradient to the arrival height above ... + // 70..79 + e_H_QFE, // Height on automatic QFE. This altitude value is constantly ... + e_GR_Avg, // The distance made in the configured period of time divided ... + e_Experimental1, // Experimental1 + e_OC_Distance, // Online Contest Distance + e_Experimental2, // Experimental2 + e_CPU_Load, // CPU load consumed by XCSoar averaged over 5 seconds + e_WP_H, // Absolute arrival altitude at the next waypoint in final glide + e_Free_RAM, // Free RAM as reported by OS + e_FlightLevel, // Flight Level, also known as pressure altitude + e_Barogram, // Trace of altitude during flight + // 80..89 + e_Vario_spark, // Trace of vertical speed, as reported by the GPS, or ... + e_NettoVario_spark, // Trace of vertical speed of air-mass, equal to ... + e_CirclingAverage_spark, // Trace of average climb rate each turn in ... + e_ThermalBand, // Graph of average circling climb rate (horizontal axis)... + e_TaskProgress, // Clock-like display of distance remaining along task, ... + e_TaskMaxHeightTime, // The contiguous period the ship has been below ... + e_Fin_ETE_VMG, // Estimated time required to complete task, assuming ... + e_WP_ETE_VMG, // Estimated time required to reach next waypoint, assum... + e_Horizon, // Attitude indicator (artificial horizon) display calculated... + e_NearestAirspaceHorizontal, // The horizontal distance to the nearest ... + // 90..99 + e_NearestAirspaceVertical, // The vertical distance to the nearest ... + e_WP_MC0AltDiff, // Arrival altitude at the next waypoint with MC 0 set... + e_HeadWind, // The current head wind component. Head wind is calculated ... + e_TerrainCollision, // The distance to the next terrain collision along ... + e_NavAltitude, // This is the barometric altitude obtained from a device... + e_NextLegEqThermal, // The thermal rate of climb on next leg which is ... + e_HeadWindSimplified, // The current head wind component. The simplified... + e_CruiseEfficiency, // Efficiency of cruise. 100 indicates perfect MacC... + e_WindArrow, // Wind speed estimated by XCSoar. Manual adjustment is ... + e_ThermalAssistant, // A circular thermal assistant that shows the lift ... + // 100..109 + e_StartOpenLine, // Shows the time left until the start point opens or ... + e_StartOpenArrivalLine, // Shows the time left until the start point ... + e_NextRadial, // True bearing from the next waypoint to your position. + e_ATC_Radial, // Bearing from the selected reference location to your ... + e_TaskSpeedHour, // The distance to the currently selected waypoint. ... + e_WP_NominalDistance, // The nominal distance to the currently select ... + e_CircleDiameter, // Circle diameter. Displays estimated circle diameter... + e_TakeOffDistance, // Distance to where take-off was detected. + e_ContestSpeed, // Instantaneous evaluation of the flown speed accord. ... + e_Final_MC0_Altitude, // Arrival altitude at the final waypoint with MC0... + // 110..119 + e_NextWPArrow, // Arrow pointing to the currently selected waypoint... + e_WP_Estimation, // Estimated arrival time at next waypoint assuming ... + e_NonCircling_Climb_Perc, // Percentage of time spent climbing without ... + e_Climb_Perc_Chart, // Pie chart of time circling and climbing, circling... + e_NbrSat, // Number of used Sat by GPS module + e_ActiveRadio, // Active Radio Frequency + e_StandbyRadio, // Standby Radio Frequency + e_Thermal_Time, // Time in Thermal + e_Alternate_2_GR, // Geometric gradient to the arrival height above the ... + e_HeartRate, // Heart rate in beats per minute. + // 120.. + e_TransponderCode, // Transponder code + + e_EngineCHT, // Engine Cylinder Head Temperature + e_EngineEGT, // Engine Exhaust Gas Temperature + e_EngineRPM, // Engine Revolutions Per Minute + e_AAT_dT_or_ETA, // Delta time in AAT task and ETA in racing task + + // =============================================================== + e_NUM_TYPES, // Last item + + e_NUM_AREA_2nd = 500, + e_DriftAngle = e_NUM_AREA_2nd, + e_InstantaneousWindSpeed, + e_InstantaneousWindBearing, + e_InternalWind, + e_InternalZigZagWind, + + e_NUM_TYPES_2nd // Last item 2nd area +}; static constexpr Type NUM_TYPES = e_NUM_TYPES; + static constexpr Type NUM_TYPES_2nd = e_NUM_TYPES_2nd; static constexpr Type MIN_TYPE_VAL = (Type)0; static constexpr Type MAX_TYPE_VAL = (Type)(e_NUM_TYPES - 1); + + bool TypeIsValid(Type t); } diff --git a/src/InfoBoxes/Content/Weather.cpp b/src/InfoBoxes/Content/Weather.cpp index f6387c58c44..1fa72a68dc9 100644 --- a/src/InfoBoxes/Content/Weather.cpp +++ b/src/InfoBoxes/Content/Weather.cpp @@ -29,7 +29,7 @@ UpdateInfoBoxHumidity(InfoBoxData &data) noexcept } // Set Value - data.FmtValue( _T("{}"), (int)basic.humidity); + data.FmtValue( "{}", (int)basic.humidity); } void @@ -42,7 +42,7 @@ UpdateInfoBoxTemperature(InfoBoxData &data) noexcept } // Set Value - data.FmtValue(_T("{:2.1f}"), basic.temperature.ToUser()); + data.FmtValue("{:2.1f}", basic.temperature.ToUser()); data.SetValueUnit(Units::current.temperature_unit); } @@ -51,7 +51,7 @@ void InfoBoxContentTemperatureForecast::Update(InfoBoxData &data) noexcept { auto temperature = CommonInterface::GetComputerSettings().forecast_temperature; - data.FmtValue(_T("{:2.1f}"), temperature.ToUser()); + data.FmtValue("{:2.1f}", temperature.ToUser()); data.SetValueUnit(Units::current.temperature_unit); } @@ -104,7 +104,7 @@ UpdateInfoBoxWindSpeed(InfoBoxData &data) noexcept } // Set Value - data.FmtValue(_T("{:2.0f}"), Units::ToUserWindSpeed(info.wind.norm)); + data.FmtValue("{:2.0f}", Units::ToUserWindSpeed(info.wind.norm)); // Set Unit data.SetValueUnit(Units::current.wind_speed_unit); @@ -124,11 +124,45 @@ UpdateInfoBoxWindBearing(InfoBoxData &data) noexcept data.SetValue(info.wind.bearing); - TCHAR buffer[16]; + char buffer[16]; FormatUserWindSpeed(info.wind.norm, buffer, true, false); data.SetComment(buffer); } +void UpdateInfoBoxInstWindSpeed(InfoBoxData &data) noexcept { + const auto &info = CommonInterface::Basic(); + if (!info.external_instantaneous_wind_available) { + data.SetInvalid(); + return; + } + + // Set Value + data.FmtValue("{:2.0f}", + Units::ToUserWindSpeed(info.external_instantaneous_wind.norm)); + + // Set Unit + data.SetValueUnit(Units::current.wind_speed_unit); + + // Set Comment + data.SetComment(info.external_instantaneous_wind.bearing); +} + +void UpdateInfoBoxInstWindBearing(InfoBoxData &data) noexcept +{ + const auto &info = CommonInterface::Basic(); + if (!info.external_instantaneous_wind_available) { + data.SetInvalid(); + return; + } + + data.SetValue(info.external_instantaneous_wind.bearing); + + char buffer[16]; + FormatUserWindSpeed(info.external_instantaneous_wind.norm, + buffer, true, false); + data.SetComment(buffer); +} + void UpdateInfoBoxHeadWind(InfoBoxData &data) noexcept { @@ -139,7 +173,7 @@ UpdateInfoBoxHeadWind(InfoBoxData &data) noexcept } // Set Value - data.FmtValue(_T("{:2.0f}"), Units::ToUserWindSpeed(info.head_wind)); + data.FmtValue("{:2.0f}", Units::ToUserWindSpeed(info.head_wind)); // Set Unit data.SetValueUnit(Units::current.wind_speed_unit); @@ -157,7 +191,7 @@ UpdateInfoBoxHeadWindSimplified(InfoBoxData &data) noexcept auto value = basic.true_airspeed - basic.ground_speed; // Set Value - data.FmtValue(_T("{:2.0f}"), Units::ToUserWindSpeed(value)); + data.FmtValue("{:2.0f}", Units::ToUserWindSpeed(value)); // Set Unit data.SetValueUnit(Units::current.wind_speed_unit); @@ -176,25 +210,23 @@ InfoBoxContentWindArrow::Update(InfoBoxData &data) noexcept data.SetCustom(info.wind_available.ToInteger() + basic.attitude.heading_available.ToInteger()); - TCHAR speed_buffer[16]; + char speed_buffer[16]; FormatUserWindSpeed(info.wind.norm, speed_buffer, true, false); StaticString<36> buffer; - buffer.Format(_T("%s / %s"), + buffer.Format("%s / %s", FormatBearing(info.wind.bearing).c_str(), speed_buffer); data.SetComment(buffer); } void -InfoBoxContentWindArrow::OnCustomPaint(Canvas &canvas, - const PixelRect &rc) noexcept +PaintWindArrow(Canvas &canvas, const PixelRect &rc, + const SpeedVector &wind, const Brush &brush) noexcept { constexpr unsigned arrow_width = 6; constexpr unsigned arrow_tail_length = 3; - const auto &info = CommonInterface::Calculated(); - const unsigned scale = Layout::Scale(100U); RadarRenderer radar_renderer{Layout::FastScale(10u)}; @@ -204,17 +236,39 @@ InfoBoxContentWindArrow::OnCustomPaint(Canvas &canvas, // by the DrawArrow() function again const unsigned size = radar_renderer.GetRadius() * 100 / scale; - auto angle = info.wind.bearing - CommonInterface::Basic().attitude.heading; + auto angle = wind.bearing - CommonInterface::Basic().attitude.heading; const int length = - std::min(size, std::max(10u, uround(4 * info.wind.norm))); + std::min(size, std::max(10u, uround(4 * wind.norm))); const int offset = -length / 2; - auto style = CommonInterface::GetMapSettings().wind_arrow_style; + const auto style = CommonInterface::GetMapSettings().wind_arrow_style; WindArrowRenderer renderer(UIGlobals::GetLook().wind_arrow_info_box); renderer.DrawArrow(canvas, radar_renderer.GetCenter(), angle, arrow_width, length, arrow_tail_length, - style, offset, scale); + style, offset, scale, brush); +} + +void +InfoBoxContentWindArrow::OnCustomPaint(Canvas &canvas, + const PixelRect &rc) noexcept +{ + + const auto &info = CommonInterface::Calculated(); + const auto &basic = CommonInterface::Basic(); + auto rel_wind = info.wind; + const auto &look = UIGlobals::GetLook().wind_arrow_info_box; + rel_wind.bearing -= basic.attitude.heading; + + PaintWindArrow(canvas, rc, rel_wind, + info.wind_source == DerivedInfo::WindSource::EXTERNAL ? + look.arrow_brush_extern : look.arrow_brush); + if (basic.external_instantaneous_wind_available) { + rel_wind = basic.external_instantaneous_wind; + rel_wind.bearing -= basic.attitude.heading; + PaintWindArrow(canvas, rc, rel_wind, + look.arrow_brush_instantaneous); + } } diff --git a/src/InfoBoxes/Content/Weather.hpp b/src/InfoBoxes/Content/Weather.hpp index 3ea7e231ef0..9ac4496176d 100644 --- a/src/InfoBoxes/Content/Weather.hpp +++ b/src/InfoBoxes/Content/Weather.hpp @@ -5,8 +5,10 @@ #include "InfoBoxes/Content/Base.hpp" -void -UpdateInfoBoxHumidity(InfoBoxData &data) noexcept; +struct SpeedVector; +class Brush; + +void UpdateInfoBoxHumidity(InfoBoxData &data) noexcept; void UpdateInfoBoxTemperature(InfoBoxData &data) noexcept; @@ -26,12 +28,22 @@ UpdateInfoBoxWindSpeed(InfoBoxData &data) noexcept; void UpdateInfoBoxWindBearing(InfoBoxData &data) noexcept; +void +UpdateInfoBoxInstWindSpeed(InfoBoxData &data) noexcept; + +void +UpdateInfoBoxInstWindBearing(InfoBoxData &data) noexcept; + void UpdateInfoBoxHeadWind(InfoBoxData &data) noexcept; void UpdateInfoBoxHeadWindSimplified(InfoBoxData &data) noexcept; +void +PaintWindArrow(Canvas &canvas, const PixelRect &rc, + const SpeedVector &wind, const Brush &brush) noexcept; + class InfoBoxContentWindArrow: public InfoBoxContent { public: diff --git a/src/InfoBoxes/Data.cpp b/src/InfoBoxes/Data.cpp index 2f93bf88606..1dfbd8da557 100644 --- a/src/InfoBoxes/Data.cpp +++ b/src/InfoBoxes/Data.cpp @@ -24,25 +24,25 @@ void InfoBoxData::SetValueInvalid() noexcept { SetValueColor(0); - SetValue(_T("---")); + SetValue("---"); SetValueUnit(Unit::UNDEFINED); } void -InfoBoxData::SetTitle(const TCHAR *_title) noexcept +InfoBoxData::SetTitle(const char *_title) noexcept { title = _title; title.CropIncompleteUTF8(); } void -InfoBoxData::SetValue(const TCHAR *_value) noexcept +InfoBoxData::SetValue(const char *_value) noexcept { value = _value; } void -InfoBoxData::SetComment(const TCHAR *_comment) noexcept +InfoBoxData::SetComment(const char *_comment) noexcept { comment = _comment; comment.CropIncompleteUTF8(); diff --git a/src/InfoBoxes/Data.hpp b/src/InfoBoxes/Data.hpp index 03aa114a2c4..60a125b0301 100644 --- a/src/InfoBoxes/Data.hpp +++ b/src/InfoBoxes/Data.hpp @@ -77,9 +77,9 @@ struct InfoBoxData { * * @param title New value of the InfoBox title */ - void SetTitle(const TCHAR *title) noexcept; + void SetTitle(const char *title) noexcept; - const TCHAR *GetTitle() const { + const char *GetTitle() const { return title; }; @@ -105,7 +105,7 @@ struct InfoBoxData { * Sets the InfoBox value to the given Value * @param Value New value of the InfoBox value */ - void SetValue(const TCHAR *value) noexcept; + void SetValue(const char *value) noexcept; void VFmtValue(fmt_tstring_view format_str, fmt_tformat_args args) noexcept { auto [p, _] = fmt::vformat_to_n(value.begin(), value.capacity() - 1, @@ -128,7 +128,7 @@ struct InfoBoxData { /** * Sets the InfoBox value to the given angle. */ - void SetValue(Angle value, const TCHAR *suffix=_T("")) noexcept; + void SetValue(Angle value, const char *suffix="") noexcept; void SetValueFromBearingDifference(Angle delta) noexcept; @@ -176,7 +176,7 @@ struct InfoBoxData { * Sets the InfoBox comment to the given Value * @param Value New value of the InfoBox comment */ - void SetComment(const TCHAR *comment) noexcept; + void SetComment(const char *comment) noexcept; void VFmtComment(fmt_tstring_view format_str, fmt_tformat_args args) noexcept { auto [p, _] = fmt::vformat_to_n(comment.begin(), comment.capacity() - 1, @@ -199,7 +199,7 @@ struct InfoBoxData { /** * Sets the InfoBox comment to the given angle. */ - void SetComment(Angle comment, const TCHAR *suffix=_T("")) noexcept; + void SetComment(Angle comment, const char *suffix="") noexcept; void SetCommentFromDistance(double value) noexcept; diff --git a/src/InfoBoxes/Format.cpp b/src/InfoBoxes/Format.cpp index 5294418a585..ff899dc6835 100644 --- a/src/InfoBoxes/Format.cpp +++ b/src/InfoBoxes/Format.cpp @@ -8,7 +8,7 @@ #include "Math/Angle.hpp" void -InfoBoxData::SetValue(Angle _value, const TCHAR *suffix) noexcept +InfoBoxData::SetValue(Angle _value, const char *suffix) noexcept { assert(suffix != NULL); @@ -29,7 +29,7 @@ InfoBoxData::SetValueFromGlideRatio(double gr) noexcept } void -InfoBoxData::SetComment(Angle _value, const TCHAR *suffix) noexcept +InfoBoxData::SetComment(Angle _value, const char *suffix) noexcept { assert(suffix != NULL); @@ -51,19 +51,19 @@ InfoBoxData::SetValueFromTimeTwoLines(std::chrono::seconds dd) noexcept void InfoBoxData::SetValueFromPercent(double dd) noexcept { - FmtValue(_T("{}"), (int)dd); + FmtValue("{}", (int)dd); SetValueUnit(Unit::PERCENT); } void InfoBoxData::SetCommentFromPercent(double dd) noexcept { - FmtComment(_T("{} %"), (int)(dd)); + FmtComment("{} %", (int)(dd)); } void InfoBoxData::SetValueFromVoltage(double dd) noexcept { - FmtValue(_T("{:2.1f}"), dd); + FmtValue("{:2.1f}", dd); SetValueUnit(Unit::VOLT); } diff --git a/src/InfoBoxes/InfoBoxLayout.cpp b/src/InfoBoxes/InfoBoxLayout.cpp index ff3453e2029..ce19c456a68 100644 --- a/src/InfoBoxes/InfoBoxLayout.cpp +++ b/src/InfoBoxes/InfoBoxLayout.cpp @@ -20,6 +20,10 @@ static constexpr unsigned char geometry_counts[] = { 12, // 3 rows X 4 boxes 15, // 3 rows X 5 boxes 18, // 3 rows X 6 boxes + 13, // TOP_8_VARIO_BOTTOM_5: 2 rows X 4 + 1 row x 5 (= 8 + 5) + 18, // TOP_8_VARIO_BOTTOM_10: 2 rows X 4 + 2 row x 5 (= 8 + 10) + 12, // TOP_12_VARIO: 3 rows X 4 boxes (= 12 + 0) + 16, // TOP_16_VARIO: 4 rows X 4 boxes (= 16 + 0) }; namespace InfoBoxLayout { @@ -232,6 +236,74 @@ InfoBoxLayout::Calculate(PixelRect rc, InfoBoxSettings::Geometry geometry) noexc rc.left, rc.top, rc.bottom); break; +//----------------------------- + case InfoBoxSettings::Geometry::TOP_8_VARIO_BOTTOM_5: + layout.vario.left = rc.right - layout.control_size.width; + layout.vario.right = rc.right; + layout.vario.top = rc.top; + layout.vario.bottom = rc.top + layout.control_size.height * 2; + + right = layout.vario.left; + rc.top = MakeTopRow(layout, layout.positions, 4, rc.left, right, rc.top); + rc.top = MakeTopRow(layout, layout.positions + 4, 4, rc.left, right, rc.top); + // layout.control_size.height = layout.control_size.width * 0.9; + + rc.bottom = MakeBottomRow(layout, layout.positions + 8, 5, rc.left, + rc.right, rc.bottom); + break; +//----------------------------- + case InfoBoxSettings::Geometry::TOP_8_VARIO_BOTTOM_10: + layout.vario.left = rc.right - layout.control_size.width; + layout.vario.right = rc.right; + layout.vario.top = rc.top; + layout.vario.bottom = rc.top + layout.control_size.height * 2; + + right = layout.vario.left; + rc.top = MakeTopRow(layout, layout.positions, 4, rc.left, + right, rc.top); + rc.top = MakeTopRow(layout, layout.positions + 4, 4, rc.left, + right, rc.top); + + rc.bottom = MakeBottomRow(layout, layout.positions + 8, 5, rc.left, + rc.right, rc.bottom); + rc.bottom = MakeBottomRow(layout, layout.positions + 13, 5, rc.left, + rc.right, rc.bottom); + break; +//----------------------------- + case InfoBoxSettings::Geometry::TOP_12_VARIO: + layout.vario.left = rc.right - (3 * layout.control_size.width) / 2; + layout.vario.right = rc.right; + layout.vario.top = rc.top; + layout.vario.bottom = rc.top + 4 * layout.control_size.height; + + right = layout.vario.left; + rc.top = MakeTopRow(layout, layout.positions, 4, rc.left, + right, rc.top); + rc.top = MakeTopRow(layout, layout.positions + 4, 4, rc.left, + right, rc.top); + rc.top = MakeTopRow(layout, layout.positions + 8, 4, rc.left, + right, rc.top); + + break; +//----------------------------- + case InfoBoxSettings::Geometry::TOP_16_VARIO: + layout.vario.left = rc.right - (3 * layout.control_size.width) / 2; + layout.vario.right = rc.right; + layout.vario.top = rc.top; + layout.vario.bottom = rc.top + 4 * layout.control_size.height; + + right = layout.vario.left; + rc.top = MakeTopRow(layout, layout.positions, 4, rc.left, + right, rc.top); + rc.top = MakeTopRow(layout, layout.positions + 4, 4, rc.left, + right, rc.top); + rc.top = MakeTopRow(layout, layout.positions + 8, 4, rc.left, + right, rc.top); + rc.top = MakeTopRow(layout, layout.positions + 12, 4, rc.left, + right, rc.top); + + break; +//----------------------------- case InfoBoxSettings::Geometry::BOTTOM_RIGHT_12: case InfoBoxSettings::Geometry::OBSOLETE_BOTTOM_RIGHT_12: if (layout.landscape) { @@ -459,6 +531,11 @@ InfoBoxLayout::ValidateGeometry(InfoBoxSettings::Geometry geometry, case InfoBoxSettings::Geometry::TOP_8_VARIO: return InfoBoxSettings::Geometry::LEFT_6_RIGHT_3_VARIO; + case InfoBoxSettings::Geometry::TOP_8_VARIO_BOTTOM_5: + case InfoBoxSettings::Geometry::TOP_8_VARIO_BOTTOM_10: + case InfoBoxSettings::Geometry::TOP_12_VARIO: + case InfoBoxSettings::Geometry::TOP_16_VARIO: + return InfoBoxSettings::Geometry::LEFT_12_RIGHT_3_VARIO; } } else { /* portrait and square */ @@ -505,6 +582,10 @@ InfoBoxLayout::ValidateGeometry(InfoBoxSettings::Geometry geometry, case InfoBoxSettings::Geometry::OBSOLETE_TOP_LEFT_4: case InfoBoxSettings::Geometry::OBSOLETE_BOTTOM_RIGHT_4: case InfoBoxSettings::Geometry::TOP_8_VARIO: + case InfoBoxSettings::Geometry::TOP_8_VARIO_BOTTOM_5: + case InfoBoxSettings::Geometry::TOP_8_VARIO_BOTTOM_10: + case InfoBoxSettings::Geometry::TOP_12_VARIO: + case InfoBoxSettings::Geometry::TOP_16_VARIO: break; } } @@ -593,6 +674,12 @@ InfoBoxLayout::CalcInfoBoxSizes(Layout &layout, PixelSize screen_size, layout.control_size.width); break; + case InfoBoxSettings::Geometry::TOP_8_VARIO_BOTTOM_5: + case InfoBoxSettings::Geometry::TOP_8_VARIO_BOTTOM_10: + layout.control_size.width = screen_size.width / 5; + // preserve relative shape + layout.control_size.height = layout.control_size.width * 0.9; + break; case InfoBoxSettings::Geometry::TOP_8_VARIO: // calculate control dimensions layout.control_size.width = 2 * screen_size.width / (layout.count + 2); @@ -600,6 +687,14 @@ InfoBoxLayout::CalcInfoBoxSizes(Layout &layout, PixelSize screen_size, layout.control_size.width); break; + case InfoBoxSettings::Geometry::TOP_12_VARIO: + case InfoBoxSettings::Geometry::TOP_16_VARIO: + // calculate control dimensions + // layout.control_size.width = 2 * screen_size.width / (layout.count + 2); + layout.control_size.width = (2 * screen_size.width) / 11; + layout.control_size.height = CalculateInfoBoxRowHeight( + screen_size.height, layout.control_size.width); + break; case InfoBoxSettings::Geometry::RIGHT_9_VARIO: case InfoBoxSettings::Geometry::LEFT_6_RIGHT_3_VARIO: // calculate control dimensions @@ -852,9 +947,21 @@ InfoBoxLayout::GetBorder(InfoBoxSettings::Geometry geometry, bool landscape, break; case InfoBoxSettings::Geometry::TOP_8_VARIO: + case InfoBoxSettings::Geometry::TOP_12_VARIO: + case InfoBoxSettings::Geometry::TOP_16_VARIO: border |= BORDERBOTTOM|BORDERRIGHT; break; + case InfoBoxSettings::Geometry::TOP_8_VARIO_BOTTOM_5: + case InfoBoxSettings::Geometry::TOP_8_VARIO_BOTTOM_10: + if (!((i == 0) || (i == 4))) + border |= BORDERLEFT; + if (i < 8) + border |= BORDERTOP; + else + border |= BORDERBOTTOM; + break; + case InfoBoxSettings::Geometry::LEFT_6_RIGHT_3_VARIO: if (i != 0) border |= BORDERTOP; diff --git a/src/InfoBoxes/InfoBoxManager.cpp b/src/InfoBoxes/InfoBoxManager.cpp index 1b917228ef0..6ff2ec2c2e1 100644 --- a/src/InfoBoxes/InfoBoxManager.cpp +++ b/src/InfoBoxes/InfoBoxManager.cpp @@ -81,8 +81,8 @@ InfoBoxManager::DisplayInfoBox() noexcept // Do not put calculations here! InfoBoxFactory::Type DisplayType = settings.contents[i]; - if ((unsigned)DisplayType > (unsigned)InfoBoxFactory::MAX_TYPE_VAL) - DisplayType = InfoBoxFactory::NavAltitude; + if (!TypeIsValid(DisplayType)) + DisplayType = InfoBoxFactory::e_NavAltitude; bool needupdate = ((DisplayType != DisplayTypeLast[i]) || first); @@ -186,11 +186,19 @@ InfoBoxManager::ShowInfoBoxPicker(const int i) noexcept ComboList list; for (unsigned j = InfoBoxFactory::MIN_TYPE_VAL; j < InfoBoxFactory::NUM_TYPES; j++) { - const TCHAR *desc = InfoBoxFactory::GetDescription((InfoBoxFactory::Type)j); + const char *desc = InfoBoxFactory::GetDescription((InfoBoxFactory::Type)j); list.Append(j, gettext(InfoBoxFactory::GetName((InfoBoxFactory::Type)j)), gettext(InfoBoxFactory::GetName((InfoBoxFactory::Type)j)), desc != NULL ? gettext(desc) : NULL); } + for (unsigned j = InfoBoxFactory::e_NUM_AREA_2nd; + j < InfoBoxFactory::NUM_TYPES_2nd; j++) { + const InfoBoxFactory::Type type = (InfoBoxFactory::Type)(j); + const char *desc = InfoBoxFactory::GetDescription(type); + list.Append(j, gettext(InfoBoxFactory::GetName(type)), + gettext(InfoBoxFactory::GetName(type)), + desc != NULL ? gettext(desc) : NULL); + } list.Sort(); list.current_index = list.LookUp(old_type); @@ -198,7 +206,7 @@ InfoBoxManager::ShowInfoBoxPicker(const int i) noexcept /* let the user select */ StaticString<20> caption; - caption.Format(_T("%s: %d"), _("InfoBox"), i + 1); + caption.Format("%s: %d", _("InfoBox"), i + 1); int result = ComboPicker(caption, list, nullptr, true); if (result < 0) return; diff --git a/src/InfoBoxes/InfoBoxSettings.cpp b/src/InfoBoxes/InfoBoxSettings.cpp index 719bf78eda8..b4ef74f74f1 100644 --- a/src/InfoBoxes/InfoBoxSettings.cpp +++ b/src/InfoBoxes/InfoBoxSettings.cpp @@ -42,11 +42,11 @@ InfoBoxSettings::SetDefaults() noexcept static constexpr unsigned DFLT_CONFIG_BOXES = 9; static constexpr unsigned DFLT_CONFIG_PANELS = 4; static constexpr Type contents[DFLT_CONFIG_PANELS][DFLT_CONFIG_BOXES] = { - { e_WP_Distance, e_TL_Avg, NavAltitude, e_HeightAGL, e_TL_Gain, + { e_WP_Distance, e_TL_Avg, e_NavAltitude, e_HeightAGL, e_TL_Gain, e_MacCready, e_TL_Time, e_Thermal_30s, e_TimeLocal }, - { e_WP_Distance, e_Alternate_1_GR, NavAltitude, e_HeightAGL, e_WP_AltDiff, + { e_WP_Distance, e_Alternate_1_GR, e_NavAltitude, e_HeightAGL, e_WP_AltDiff, e_MacCready, e_Speed_GPS, e_GR_Avg, e_GR_Cruise }, - { e_WP_Distance, e_Alternate_1_GR, NavAltitude, e_HeightAGL, e_Fin_AltDiff, + { e_WP_Distance, e_Alternate_1_GR, e_NavAltitude, e_HeightAGL, e_Fin_AltDiff, e_MacCready, e_Fin_GR, e_GR_Avg, e_Fin_Time }, { e_WP_Name, e_Fin_TimeLocal, e_WP_Distance, e_WP_Time, e_Fin_Distance, e_Fin_Time, e_TimeLocal, e_TimeSinceTakeoff, e_CC_Speed } @@ -60,7 +60,7 @@ InfoBoxSettings::SetDefaults() noexcept panels[2].name = N_("FinalGlide"); for (unsigned i = PREASSIGNED_PANELS; i < MAX_PANELS; i++) - panels[i].name.Format(_T("AUX-%u"), i-2); + panels[i].name.Format("AUX-%u", i-2); for (unsigned i = 0; i < DFLT_CONFIG_PANELS; i++) for (unsigned j = 0; j < DFLT_CONFIG_BOXES; j++) diff --git a/src/InfoBoxes/InfoBoxSettings.hpp b/src/InfoBoxes/InfoBoxSettings.hpp index 4eb07283571..95b96f5eed4 100644 --- a/src/InfoBoxes/InfoBoxSettings.hpp +++ b/src/InfoBoxes/InfoBoxSettings.hpp @@ -107,6 +107,10 @@ struct InfoBoxSettings { /** 18 infoboxes 3X6 split bottom/top or left/right */ SPLIT_3X6 = 26, + TOP_8_VARIO_BOTTOM_5 = 27, + TOP_8_VARIO_BOTTOM_10 = 28, + TOP_12_VARIO = 29, + TOP_16_VARIO = 30, } geometry; bool use_colors; diff --git a/src/InfoBoxes/InfoBoxWindow.cpp b/src/InfoBoxes/InfoBoxWindow.cpp index ffc5bd51b0b..8f478b80ced 100644 --- a/src/InfoBoxes/InfoBoxWindow.cpp +++ b/src/InfoBoxes/InfoBoxWindow.cpp @@ -35,7 +35,7 @@ InfoBoxWindow::InfoBoxWindow(ContainerWindow &parent, PixelRect rc, } void -InfoBoxWindow::SetTitle(const TCHAR *_title) +InfoBoxWindow::SetTitle(const char *_title) { data.SetTitle(_title); Invalidate(title_rect); diff --git a/src/InfoBoxes/InfoBoxWindow.hpp b/src/InfoBoxes/InfoBoxWindow.hpp index 13b14c9ad43..c91d3c1986c 100644 --- a/src/InfoBoxes/InfoBoxWindow.hpp +++ b/src/InfoBoxes/InfoBoxWindow.hpp @@ -91,9 +91,9 @@ class InfoBoxWindow : public LazyPaintWindow * Sets the InfoBox title to the given Value * @param Value New value of the InfoBox title */ - void SetTitle(const TCHAR *title); + void SetTitle(const char *title); - const TCHAR* GetTitle() { + const char* GetTitle() { return data.title; }; diff --git a/src/InfoBoxes/Panel/ATCReference.cpp b/src/InfoBoxes/Panel/ATCReference.cpp index 0dda554dc21..e6aed7104b3 100644 --- a/src/InfoBoxes/Panel/ATCReference.cpp +++ b/src/InfoBoxes/Panel/ATCReference.cpp @@ -41,16 +41,16 @@ ATCReferencePanel::UpdateValues() noexcept ? data_components->waypoints->GetNearest(location, 100) : nullptr; - SetText(WAYPOINT, waypoint != nullptr ? waypoint->name.c_str() : _T("---")); + SetText(WAYPOINT, waypoint != nullptr ? waypoint->name.c_str() : "---"); - const TCHAR *location_string; - TCHAR buffer[64]; + const char *location_string; + char buffer[64]; if (location.IsValid()) { FormatGeoPoint(location, buffer, ARRAY_SIZE(buffer), CommonInterface::GetUISettings().format.coordinate_format); location_string = buffer; } else - location_string = _T("---"); + location_string = "---"; SetText(LOCATION, location_string); } diff --git a/src/InfoBoxes/Panel/ATCSetup.cpp b/src/InfoBoxes/Panel/ATCSetup.cpp index aa8157c3afe..4d616eb298f 100644 --- a/src/InfoBoxes/Panel/ATCSetup.cpp +++ b/src/InfoBoxes/Panel/ATCSetup.cpp @@ -34,7 +34,7 @@ ATCSetupPanel::Prepare(ContainerWindow &parent, AddFloat(_("Mag declination"), _("Magnetic declination used to calculate radial to reference. Negative values are W declination, positive is E."), - _T("%.0f°"), _T("%.0f°"), // unfortunately AngleDataField does not + "%.0f°", "%.0f°", // unfortunately AngleDataField does not -30.0, +30.0, 1.0, false, // support negative values to handle declination.Degrees(), // this formatting more gracefully this); diff --git a/src/InfoBoxes/Panel/AltitudeSimulator.cpp b/src/InfoBoxes/Panel/AltitudeSimulator.cpp index 5c498120fbf..b1ef1d19479 100644 --- a/src/InfoBoxes/Panel/AltitudeSimulator.cpp +++ b/src/InfoBoxes/Panel/AltitudeSimulator.cpp @@ -39,6 +39,6 @@ LoadAltitudeSimulatorPanel([[maybe_unused]] unsigned id) return nullptr; return std::make_unique(UIGlobals::GetDialogLook().button, - _T("%+.0f"), + "%+.0f", 10, 100); } diff --git a/src/InfoBoxes/Panel/Panel.hpp b/src/InfoBoxes/Panel/Panel.hpp index c12244bfe13..dc9af6a199e 100644 --- a/src/InfoBoxes/Panel/Panel.hpp +++ b/src/InfoBoxes/Panel/Panel.hpp @@ -10,9 +10,9 @@ class Widget; struct InfoBoxPanel { constexpr - InfoBoxPanel(const TCHAR *_name, std::unique_ptr (*_load)(unsigned id)) + InfoBoxPanel(const char *_name, std::unique_ptr (*_load)(unsigned id)) :name(_name), load(_load) {}; - const TCHAR *name; + const char *name; std::unique_ptr (*load)(unsigned id); }; diff --git a/src/InfoBoxes/Panel/RadioEdit.cpp b/src/InfoBoxes/Panel/RadioEdit.cpp index 0a88320dfd2..0617bd1980a 100644 --- a/src/InfoBoxes/Panel/RadioEdit.cpp +++ b/src/InfoBoxes/Panel/RadioEdit.cpp @@ -11,7 +11,7 @@ class RadioOffsetButtons final : public OffsetButtonsWidget { public: RadioOffsetButtons(bool active_freq) noexcept - :OffsetButtonsWidget(UIGlobals::GetDialogLook().button, _T("%.0f kHz"), 5, 1000),set_active_freq(active_freq) {} + :OffsetButtonsWidget(UIGlobals::GetDialogLook().button, "%.0f kHz", 5, 1000),set_active_freq(active_freq) {} protected: /* virtual methods from OffsetButtonsWidget */ diff --git a/src/Input/CMakeLists.txt b/src/Input/CMakeLists.txt new file mode 100644 index 00000000000..3db12bf7f50 --- /dev/null +++ b/src/Input/CMakeLists.txt @@ -0,0 +1,51 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + + +# if(NOT HEADER_FILES) # STREQUAL "" + file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h + # message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) + set(HEADER_FILES) + foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) + endforeach() + # message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +# endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) + +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER FrontEnd) + +add_dependencies(${TARGET_NAME} util Data) diff --git a/src/Input/CMakeSource.cmake b/src/Input/CMakeSource.cmake new file mode 100644 index 00000000000..601d3c1f035 --- /dev/null +++ b/src/Input/CMakeSource.cmake @@ -0,0 +1,32 @@ +set(_SOURCES + Input/InputConfig.cpp + Input/InputDefaults.cpp + Input/InputEvents.cpp + Input/InputEventsActions.cpp + Input/InputEventsAirspace.cpp + Input/InputEventsDevice.cpp + Input/InputEventsLua.cpp + Input/InputEventsMap.cpp + Input/InputEventsPage.cpp + Input/InputEventsSettings.cpp + Input/InputEventsTask.cpp + Input/InputEventsThermalAssistant.cpp + Input/InputEventsTraffic.cpp + Input/InputEventsVega.cpp + Input/InputKeys.cpp + Input/InputLookup.cpp + Input/InputParser.cpp + Input/InputQueue.cpp + Input/TaskEventObserver.cpp +) + +if (TARGET_IS_OPENVARIO) + set(DEFAULT_XCI_FILE defaultOV.xci) +else() + set(DEFAULT_XCI_FILE default.xci) +endif() + +set(SCRIPT_FILES + ../../Data/Input/${DEFAULT_XCI_FILE} + CMakeSource.cmake +) diff --git a/src/Input/InputConfig.cpp b/src/Input/InputConfig.cpp index c956cf1d03c..2b6ef16ec17 100644 --- a/src/Input/InputConfig.cpp +++ b/src/Input/InputConfig.cpp @@ -14,10 +14,10 @@ void InputConfig::SetDefaults() noexcept { modes.resize(4); - modes[0] = _T("default"); - modes[1] = _T("pan"); - modes[2] = _T("infobox"); - modes[3] = _T("Menu"); + modes[0] = "default"; + modes[1] = "pan"; + modes[2] = "infobox"; + modes[3] = "Menu"; std::fill_n(&Key2Event[0][0], MAX_MODE*MAX_KEY, 0); #ifdef ENABLE_SDL diff --git a/src/Input/InputConfig.hpp b/src/Input/InputConfig.hpp index 339a6c7656e..b1826cacd2a 100644 --- a/src/Input/InputConfig.hpp +++ b/src/Input/InputConfig.hpp @@ -8,7 +8,7 @@ #include "util/RadixTree.hpp" #include "util/StaticString.hxx" #include "util/TrivialArray.hxx" -#include "util/tstring_view.hxx" +#include #include #include @@ -30,14 +30,14 @@ struct InputConfig { #endif static constexpr std::size_t MAX_EVENTS = 2048; - typedef void (*pt2Event)(const TCHAR *); + typedef void (*pt2Event)(const char *); // Events - What do you want to DO struct Event { // Which function to call (can be any, but should be here) pt2Event event; // Parameters - const TCHAR *misc; + const char *misc; // Next in event list - eg: Macros unsigned next; }; @@ -77,7 +77,7 @@ struct InputConfig { void SetDefaults() noexcept; [[gnu::pure]] - int LookupMode(tstring_view name) const noexcept { + int LookupMode(std::string_view name) const noexcept { for (std::size_t i = 0, size = modes.size(); i < size; ++i) if (name == modes[i].c_str()) return i; @@ -85,7 +85,7 @@ struct InputConfig { return -1; } - int AppendMode(tstring_view name) noexcept { + int AppendMode(std::string_view name) noexcept { if (modes.full()) return -1; @@ -94,7 +94,7 @@ struct InputConfig { } [[gnu::pure]] - int MakeMode(tstring_view name) noexcept { + int MakeMode(std::string_view name) noexcept { int mode = LookupMode(name); if (mode < 0) mode = AppendMode(name); @@ -102,7 +102,7 @@ struct InputConfig { return mode; } - std::size_t AppendEvent(pt2Event handler, const TCHAR *misc, + std::size_t AppendEvent(pt2Event handler, const char *misc, unsigned next) noexcept { if (events.full()) return 0; @@ -115,7 +115,7 @@ struct InputConfig { return events.size() - 1; } - void AppendMenu(std::size_t mode_id, const TCHAR *label, + void AppendMenu(std::size_t mode_id, const char *label, unsigned location, unsigned event_id) noexcept { assert(mode_id < MAX_MODE); diff --git a/src/Input/InputDefaults.cpp b/src/Input/InputDefaults.cpp index 97a54e199f4..656d7616c29 100644 --- a/src/Input/InputDefaults.cpp +++ b/src/Input/InputDefaults.cpp @@ -44,13 +44,13 @@ struct flat_event_map { struct flat_label { unsigned char mode, location; unsigned short event; - const TCHAR *label; + const char *label; }; struct flat_gesture_map { unsigned char mode; unsigned short event; - const TCHAR *data; + const char *data; }; // Make a new label (add to the end each time) @@ -58,7 +58,7 @@ struct flat_gesture_map { // without taking up more data - but when loading from file must copy string static void makeLabel(InputConfig &input_config, - InputEvents::Mode mode_id, const TCHAR* label, + InputEvents::Mode mode_id, const char* label, unsigned location, unsigned event_id) { input_config.AppendMenu(mode_id, label, location, event_id); @@ -66,7 +66,7 @@ makeLabel(InputConfig &input_config, static void apply_defaults(InputConfig &input_config, - const TCHAR *const* default_modes, + const char *const* default_modes, const InputConfig::Event *default_events, unsigned num_default_events, const flat_gesture_map *default_gesture2event, diff --git a/src/Input/InputEvents.cpp b/src/Input/InputEvents.cpp index 060e19f72be..52fd30fc8cb 100644 --- a/src/Input/InputEvents.cpp +++ b/src/Input/InputEvents.cpp @@ -54,7 +54,7 @@ doc/html/advanced/input/ALL http://xcsoar.sourceforge.net/advanced/input/ namespace InputEvents { -static const TCHAR *flavour; +static const char *flavour; static Mode current_mode = InputEvents::MODE_DEFAULT; @@ -81,7 +81,7 @@ UpdateOverlayMode() noexcept; [[gnu::pure]] static unsigned -gesture_to_event(const TCHAR *data) noexcept; +gesture_to_event(const char *data) noexcept; /** * @param full if false, update only the dynamic labels @@ -131,7 +131,7 @@ InputEvents::setMode(Mode mode) noexcept } void -InputEvents::setMode(const TCHAR *mode) noexcept +InputEvents::setMode(const char *mode) noexcept { int m = input_config.LookupMode(mode); if (m >= 0) @@ -145,7 +145,7 @@ InputEvents::UpdatePan() noexcept } void -InputEvents::SetFlavour(const TCHAR *_flavour) noexcept +InputEvents::SetFlavour(const char *_flavour) noexcept { if (flavour == NULL && _flavour == NULL) /* optimised default case */ @@ -162,7 +162,7 @@ InputEvents::SetFlavour(const TCHAR *_flavour) noexcept } bool -InputEvents::IsFlavour(const TCHAR *_flavour) noexcept +InputEvents::IsFlavour(const char *_flavour) noexcept { if (flavour == NULL) return _flavour == NULL; @@ -230,7 +230,7 @@ InputEvents::UpdateOverlayMode() noexcept /* build the "flavoured" mode name from the current "major" mode and the flavour name */ StaticString name; - name.Format(_T("%s.%s"), input_config.modes[current_mode].c_str(), + name.Format("%s.%s", input_config.modes[current_mode].c_str(), flavour); /* see if it exists */ @@ -332,7 +332,7 @@ InputEvents::ProcessKey(Mode mode, unsigned key_code) noexcept #endif if (Lua::FireKey(key_code)) { - // return true; + return true; } // Which key - can be defined locally or at default (fall back to default) @@ -357,19 +357,19 @@ InputEvents::processKey(unsigned key_code) noexcept } unsigned -InputEvents::gesture_to_event(const TCHAR *data) noexcept +InputEvents::gesture_to_event(const char *data) noexcept { return input_config.Gesture2Event.Get(data, 0); } bool -InputEvents::IsGesture(const TCHAR *data) noexcept +InputEvents::IsGesture(const char *data) noexcept { return (Lua::IsGesture(data)) || (gesture_to_event(data) != 0); } bool -InputEvents::processGesture(const TCHAR *data) noexcept +InputEvents::processGesture(const char *data) noexcept { // start with lua event if available! if (Lua::FireGesture(data)) @@ -386,7 +386,7 @@ InputEvents::processGesture(const TCHAR *data) noexcept } /* - InputEvent::processNmea(TCHAR *data) + InputEvent::processNmea(char *data) Take hard coded inputs from NMEA processor. Return = TRUE if we have a valid key match */ @@ -468,7 +468,7 @@ InputEvents::ShowMenu() noexcept } Menu * -InputEvents::GetMenu(const TCHAR *mode) noexcept +InputEvents::GetMenu(const char *mode) noexcept { int m = input_config.LookupMode(mode); if (m >= 0) @@ -501,7 +501,7 @@ InputEvents::ProcessTimer() noexcept } void -InputEvents::eventLockScreen([[maybe_unused]] const TCHAR *mode) +InputEvents::eventLockScreen([[maybe_unused]] const char *mode) { ShowLockBox(); } diff --git a/src/Input/InputEvents.hpp b/src/Input/InputEvents.hpp index 35573c0a673..b0688d4d971 100644 --- a/src/Input/InputEvents.hpp +++ b/src/Input/InputEvents.hpp @@ -10,7 +10,7 @@ struct InputConfig; class Menu; -typedef void (*pt2Event)(const TCHAR *); +typedef void (*pt2Event)(const char *); namespace InputEvents { @@ -31,7 +31,7 @@ void HideMenu() noexcept; Menu * -GetMenu(const TCHAR *mode) noexcept; +GetMenu(const char *mode) noexcept; /** * Load the default input file (Data/Input/default.xci). @@ -47,7 +47,7 @@ void setMode(Mode mode) noexcept; void -setMode(const TCHAR *mode) noexcept; +setMode(const char *mode) noexcept; /** * Update the menu after pan mode has been enabled or disabled. @@ -64,7 +64,7 @@ UpdatePan() noexcept; * @param flavour the new flavour name; may be NULL */ void -SetFlavour(const TCHAR *flavour) noexcept; +SetFlavour(const char *flavour) noexcept; /** * Is the specified flavour currently active? @@ -73,7 +73,7 @@ SetFlavour(const TCHAR *flavour) noexcept; */ [[gnu::pure]] bool -IsFlavour(const TCHAR *flavour) noexcept; +IsFlavour(const char *flavour) noexcept; /** * @return: true if current mode is MODE_DEFAULT @@ -98,10 +98,10 @@ bool processKey(unsigned key) noexcept; bool -processGesture(const TCHAR *data) noexcept; +processGesture(const char *data) noexcept; bool -IsGesture(const TCHAR *data) noexcept; +IsGesture(const char *data) noexcept; bool processNmea_real(unsigned key) noexcept; @@ -120,79 +120,83 @@ void sub_SetZoom(double value); // ------- -void eventAbortTask(const TCHAR *misc); -void eventAdjustForecastTemperature(const TCHAR *misc); -void eventAdjustVarioFilter(const TCHAR *misc); -void eventAdjustWaypoint(const TCHAR *misc); -void eventAnalysis(const TCHAR *misc); -void eventArmAdvance(const TCHAR *misc); -void eventAudioDeadband(const TCHAR *misc); -void eventBallast(const TCHAR *misc); -void eventBugs(const TCHAR *misc); -void eventCalculator(const TCHAR *misc); -void eventChecklist(const TCHAR *misc); -void eventClearAirspaceWarnings(const TCHAR *misc); -void eventClearStatusMessages(const TCHAR *misc); -void eventLogger(const TCHAR *misc); -void eventMacCready(const TCHAR *misc); -void eventMainMenu(const TCHAR *misc); -void eventMarkLocation(const TCHAR *misc); -void eventPilotEvent(const TCHAR *misc); -void eventMode(const TCHAR *misc); -void eventNearestAirspaceDetails(const TCHAR *misc); -void eventNearestWaypointDetails(const TCHAR *misc); -void eventNearestMapItems(const TCHAR *misc); -void eventNull(const TCHAR *misc); -void eventPage(const TCHAR *misc); -void eventPan(const TCHAR *misc); -void eventPlaySound(const TCHAR *misc); -void eventProfileLoad(const TCHAR *misc); -void eventProfileSave(const TCHAR *misc); -void eventRepeatStatusMessage(const TCHAR *misc); -void eventRun(const TCHAR *misc); -void eventScreenModes(const TCHAR *misc); -void eventDevice(const TCHAR *misc); -void eventSendNMEA(const TCHAR *misc); -void eventSendNMEAPort1(const TCHAR *misc); -void eventSendNMEAPort2(const TCHAR *misc); -void eventSetup(const TCHAR *misc); -void eventSnailTrail(const TCHAR *misc); -void eventAirSpace(const TCHAR *misc); // VENTA3 -void eventSounds(const TCHAR *misc); -void eventStatus(const TCHAR *misc); -void eventStatusMessage(const TCHAR *misc); -void eventTaskLoad(const TCHAR *misc); -void eventTaskSave(const TCHAR *misc); -void eventTaskTransition(const TCHAR *misc); -void eventTerrainTopography(const TCHAR *misc); -void eventTerrainTopology(const TCHAR *misc); -void eventWaypointDetails(const TCHAR *misc); -void eventWaypointEditor(const TCHAR *misc); -void eventZoom(const TCHAR *misc); -void eventBrightness(const TCHAR *misc); -void eventDeclutterLabels(const TCHAR *misc); -void eventExit(const TCHAR *misc); -void eventFLARMRadar(const TCHAR *misc); -void eventThermalAssistant(const TCHAR *misc); -void eventBeep(const TCHAR *misc); -void eventUserDisplayModeForce(const TCHAR *misc); -void eventAirspaceDisplayMode(const TCHAR *misc); -void eventAutoLogger(const TCHAR *misc); -void eventGotoLookup(const TCHAR *misc); -void eventAddWaypoint(const TCHAR *misc); -void eventOrientation(const TCHAR *misc); -void eventTraffic(const TCHAR *misc); -void eventFlarmTraffic(const TCHAR *misc); -void eventFlarmDetails(const TCHAR *misc); -void eventCredits(const TCHAR *misc); -void eventWeather(const TCHAR *misc); -void eventQuickMenu(const TCHAR *misc); -void eventFileManager(const TCHAR *misc); -void eventRunLuaFile(const TCHAR *misc); -void eventResetTask(const TCHAR *misc); -void eventLockScreen(const TCHAR *misc); -void eventExchangeFrequencies(const TCHAR *misc); -void eventUploadIGCFile(const TCHAR *misc); +void eventAbortTask(const char *misc); +void eventAdjustForecastTemperature(const char *misc); +void eventAdjustVarioFilter(const char *misc); +void eventAdjustWaypoint(const char *misc); +void eventAnalysis(const char *misc); +void eventArmAdvance(const char *misc); +void eventAudioDeadband(const char *misc); +void eventBallast(const char *misc); +void eventBugs(const char *misc); +void eventCalculator(const char *misc); +void eventChecklist(const char *misc); +void eventClearAirspaceWarnings(const char *misc); +void eventClearStatusMessages(const char *misc); +void eventLogger(const char *misc); +void eventMacCready(const char *misc); +void eventMainMenu(const char *misc); +void eventMarkLocation(const char *misc); +void eventPilotEvent(const char *misc); +void eventMode(const char *misc); +void eventNearestAirspaceDetails(const char *misc); +void eventNearestWaypointDetails(const char *misc); +void eventNearestMapItems(const char *misc); +void eventNull(const char *misc); +void eventPage(const char *misc); +void eventPan(const char *misc); +void eventPlaySound(const char *misc); +void eventProfileLoad(const char *misc); +void eventProfileSave(const char *misc); +void eventRepeatStatusMessage(const char *misc); +void eventRun(const char *misc); +void eventScreenModes(const char *misc); +void eventDevice(const char *misc); +void eventSendNMEA(const char *misc); +void eventSendNMEAPort1(const char *misc); +void eventSendNMEAPort2(const char *misc); +void eventSetup(const char *misc); +void eventSnailTrail(const char *misc); +void eventAirSpace(const char *misc); // VENTA3 +void eventSounds(const char *misc); +void eventStatus(const char *misc); +void eventStatusMessage(const char *misc); +void eventTaskLoad(const char *misc); +void eventTaskSave(const char *misc); +void eventTaskTransition(const char *misc); +void eventTerrainTopography(const char *misc); +void eventTerrainTopology(const char *misc); +void eventWaypointDetails(const char *misc); +void eventWaypointEditor(const char *misc); +void eventZoom(const char *misc); +void eventBrightness(const char *misc); +void eventDeclutterLabels(const char *misc); +void eventExit(const char *misc); +void eventFLARMRadar(const char *misc); +void eventThermalAssistant(const char *misc); +void eventBeep(const char *misc); +void eventUserDisplayModeForce(const char *misc); +void eventAirspaceDisplayMode(const char *misc); +void eventAutoLogger(const char *misc); +void eventGotoLookup(const char *misc); +void eventAddWaypoint(const char *misc); +void eventOrientation(const char *misc); +void eventTraffic(const char *misc); +void eventFlarmTraffic(const char *misc); +void eventFlarmDetails(const char *misc); +void eventCredits(const char *misc); +void eventWeather(const char *misc); +void eventQuickMenu(const char *misc); +void eventFileManager(const char *misc); +void eventRunLuaFile(const char *misc); +void eventResetTask(const char *misc); +void eventLockScreen(const char *misc); +void eventExchangeFrequencies(const char *misc); +#if 1 // def IS_OPENVARIO +void eventShutdown(const char *misc); +#endif +void eventUploadIGCFile(const char *misc); +void eventKeyPressed(const char *misc); // ------- } // namespace InputEvents diff --git a/src/Input/InputEventsActions.cpp b/src/Input/InputEventsActions.cpp index 18617a50421..97db9aa60e6 100644 --- a/src/Input/InputEventsActions.cpp +++ b/src/Input/InputEventsActions.cpp @@ -148,11 +148,11 @@ SuspendAppendSaveWaypoint(Waypoint &&wp) // TODO code: Keep marker text for use in log file etc. void -InputEvents::eventMarkLocation(const TCHAR *misc) +InputEvents::eventMarkLocation(const char *misc) { const NMEAInfo &basic = CommonInterface::Basic(); - if (StringIsEqual(misc, _T("reset"))) { + if (StringIsEqual(misc, "reset")) { ScopeSuspendAllThreads suspend; data_components->waypoints->EraseUserMarkers(); } else { @@ -167,10 +167,10 @@ InputEvents::eventMarkLocation(const TCHAR *misc) Waypoint wp = factory.Create(location); factory.FallbackElevation(wp); - TCHAR name[64] = _T("Marker"); + char name[64] = "Marker"; if (basic.date_time_utc.IsPlausible()) { auto *p = name + StringLength(name); - *p++ = _T(' ' ); + *p++ = ' ' ; FormatISO8601(p, basic.date_time_utc); } @@ -180,14 +180,14 @@ InputEvents::eventMarkLocation(const TCHAR *misc) SuspendAppendSaveWaypoint(std::move(wp)); if (CommonInterface::GetUISettings().sound.sound_modes_enabled) - PlayResource(_T("IDR_WAV_CLEAR")); + PlayResource("IDR_WAV_CLEAR"); } trigger_redraw(); } void -InputEvents::eventPilotEvent([[maybe_unused]] const TCHAR *misc) +InputEvents::eventPilotEvent([[maybe_unused]] const char *misc) try { // Configure start window const OrderedTaskSettings &ots = @@ -228,7 +228,7 @@ try { } void -InputEvents::eventScreenModes(const TCHAR *misc) +InputEvents::eventScreenModes(const char *misc) { // toggle switches like this: // -- normal infobox @@ -238,27 +238,27 @@ InputEvents::eventScreenModes(const TCHAR *misc) const UIState &ui_state = CommonInterface::GetUIState(); - if (StringIsEqual(misc, _T("normal"))) { + if (StringIsEqual(misc, "normal")) { PageActions::OpenLayout(PageLayout::Default()); - } else if (StringIsEqual(misc, _T("auxilary"))) { + } else if (StringIsEqual(misc, "auxilary")) { PageActions::OpenLayout(PageLayout::Aux()); - } else if (StringIsEqual(misc, _T("toggleauxiliary"))) { + } else if (StringIsEqual(misc, "toggleauxiliary")) { PageActions::OpenLayout(ui_state.auxiliary_enabled ? PageLayout::Default() : PageLayout::Aux()); - } else if (StringIsEqual(misc, _T("full"))) { + } else if (StringIsEqual(misc, "full")) { PageActions::OpenLayout(PageLayout::FullScreen()); - } else if (StringIsEqual(misc, _T("togglefull"))) { + } else if (StringIsEqual(misc, "togglefull")) { CommonInterface::main_window->SetFullScreen( !CommonInterface::main_window->GetFullScreen()); - } else if (StringIsEqual(misc, _T("show"))) { + } else if (StringIsEqual(misc, "show")) { if (CommonInterface::main_window->GetFullScreen()) Message::AddMessage(_("Screen Mode Full")); else if (ui_state.auxiliary_enabled) Message::AddMessage(_("Auxiliary InfoBoxes")); else Message::AddMessage(_("Default InfoBoxes")); - } else if (StringIsEqual(misc, _T("previous"))) + } else if (StringIsEqual(misc, "previous")) PageActions::Prev(); else PageActions::Next(); @@ -269,7 +269,7 @@ InputEvents::eventScreenModes(const TCHAR *misc) // ClearStatusMessages // Do Clear Event Warnings void -InputEvents::eventClearStatusMessages([[maybe_unused]] const TCHAR *misc) +InputEvents::eventClearStatusMessages([[maybe_unused]] const char *misc) { // TODO enhancement: allow selection of specific messages (here we are acknowledging all) if (CommonInterface::main_window->popup != nullptr) @@ -281,7 +281,7 @@ InputEvents::eventClearStatusMessages([[maybe_unused]] const TCHAR *misc) // The argument is the label of the mode to activate. // This is used to activate menus/submenus of buttons void -InputEvents::eventMode(const TCHAR *misc) +InputEvents::eventMode(const char *misc) { assert(misc != NULL); @@ -292,7 +292,7 @@ InputEvents::eventMode(const TCHAR *misc) // Don't think we need this. void -InputEvents::eventMainMenu([[maybe_unused]] const TCHAR *misc) +InputEvents::eventMainMenu([[maybe_unused]] const char *misc) { // todo: popup main menu } @@ -301,7 +301,7 @@ InputEvents::eventMainMenu([[maybe_unused]] const TCHAR *misc) // Displays the checklist dialog // See the checklist dialog section of the reference manual for more info. void -InputEvents::eventChecklist([[maybe_unused]] const TCHAR *misc) +InputEvents::eventChecklist([[maybe_unused]] const char *misc) { dlgChecklistShowModal(); } @@ -314,13 +314,13 @@ InputEvents::eventChecklist([[maybe_unused]] const TCHAR *misc) // See the status dialog section of the reference manual for more info // on these. void -InputEvents::eventStatus(const TCHAR *misc) +InputEvents::eventStatus(const char *misc) { - if (StringIsEqual(misc, _T("system"))) { + if (StringIsEqual(misc, "system")) { dlgStatusShowModal(1); - } else if (StringIsEqual(misc, _T("task"))) { + } else if (StringIsEqual(misc, "task")) { dlgStatusShowModal(2); - } else if (StringIsEqual(misc, _T("aircraft"))) { + } else if (StringIsEqual(misc, "aircraft")) { dlgStatusShowModal(0); } else { dlgStatusShowModal(-1); @@ -332,7 +332,7 @@ InputEvents::eventStatus(const TCHAR *misc) // See the analysis dialog section of the reference manual // for more info. void -InputEvents::eventAnalysis([[maybe_unused]] const TCHAR *misc) +InputEvents::eventAnalysis([[maybe_unused]] const char *misc) { dlgAnalysisShowModal(*CommonInterface::main_window, CommonInterface::main_window->GetLook(), @@ -350,7 +350,7 @@ InputEvents::eventAnalysis([[maybe_unused]] const TCHAR *misc) // See the waypoint dialog section of the reference manual // for more info. void -InputEvents::eventWaypointDetails(const TCHAR *misc) +InputEvents::eventWaypointDetails(const char *misc) { const NMEAInfo &basic = CommonInterface::Basic(); WaypointPtr wp; @@ -358,7 +358,7 @@ InputEvents::eventWaypointDetails(const TCHAR *misc) bool allow_navigation = true; bool allow_edit = true; - if (StringIsEqual(misc, _T("current"))) { + if (StringIsEqual(misc, "current")) { if (!backend_components->protected_task_manager) return; @@ -374,7 +374,7 @@ InputEvents::eventWaypointDetails(const TCHAR *misc) editor doesn't know how to do that */ allow_navigation = false; allow_edit = false; - } else if (StringIsEqual(misc, _T("select"))) { + } else if (StringIsEqual(misc, "select")) { wp = ShowWaypointListDialog(*data_components->waypoints, basic.location); } if (wp) @@ -384,7 +384,7 @@ InputEvents::eventWaypointDetails(const TCHAR *misc) } void -InputEvents::eventWaypointEditor([[maybe_unused]] const TCHAR *misc) +InputEvents::eventWaypointEditor([[maybe_unused]] const char *misc) { dlgConfigWaypointsShowModal(*data_components->waypoints); } @@ -394,7 +394,7 @@ InputEvents::eventWaypointEditor([[maybe_unused]] const TCHAR *misc) // The argument is the text to be displayed. // No punctuation characters are allowed. void -InputEvents::eventStatusMessage(const TCHAR *misc) +InputEvents::eventStatusMessage(const char *misc) { if (misc != NULL) Message::AddMessage(gettext(misc)); @@ -402,13 +402,13 @@ InputEvents::eventStatusMessage(const TCHAR *misc) // Plays a sound from the filename void -InputEvents::eventPlaySound(const TCHAR *misc) +InputEvents::eventPlaySound(const char *misc) { PlayResource(misc); } void -InputEvents::eventAutoLogger(const TCHAR *misc) +InputEvents::eventAutoLogger(const char *misc) { if (is_simulator()) return; @@ -420,7 +420,7 @@ InputEvents::eventAutoLogger(const TCHAR *misc) return; if (auto_logger == LoggerSettings::AutoLogger::START_ONLY && - !StringIsEqual(misc, _T("start"))) + !StringIsEqual(misc, "start")) return; eventLogger(misc); @@ -438,7 +438,7 @@ InputEvents::eventAutoLogger(const TCHAR *misc) // nmea: turns on and off NMEA logging // note: the text following the 'note' characters is added to the log file void -InputEvents::eventLogger(const TCHAR *misc) +InputEvents::eventLogger(const char *misc) try { auto *logger = backend_components->igc_logger.get(); if (logger == nullptr) @@ -451,38 +451,38 @@ try { const ComputerSettings &settings_computer = CommonInterface::GetComputerSettings(); - if (StringIsEqual(misc, _T("start ask"))) + if (StringIsEqual(misc, "start ask")) logger->GUIStartLogger(basic, settings_computer, backend_components->protected_task_manager.get()); - else if (StringIsEqual(misc, _T("start"))) + else if (StringIsEqual(misc, "start")) logger->GUIStartLogger(basic, settings_computer, backend_components->protected_task_manager.get(), true); - else if (StringIsEqual(misc, _T("stop ask"))) + else if (StringIsEqual(misc, "stop ask")) logger->GUIStopLogger(basic); - else if (StringIsEqual(misc, _T("stop"))) + else if (StringIsEqual(misc, "stop")) logger->GUIStopLogger(basic, true); - else if (StringIsEqual(misc, _T("toggle ask"))) + else if (StringIsEqual(misc, "toggle ask")) logger->GUIToggleLogger(basic, settings_computer, backend_components->protected_task_manager.get()); - else if (StringIsEqual(misc, _T("toggle"))) + else if (StringIsEqual(misc, "toggle")) logger->GUIToggleLogger(basic, settings_computer, backend_components->protected_task_manager.get(), true); - else if (StringIsEqual(misc, _T("nmea"))) { + else if (StringIsEqual(misc, "nmea")) { backend_components->nmea_logger->ToggleEnabled(); if (backend_components->nmea_logger->IsEnabled()) { Message::AddMessage(_("NMEA log on")); } else { Message::AddMessage(_("NMEA log off")); } - } else if (StringIsEqual(misc, _T("show"))) + } else if (StringIsEqual(misc, "show")) if (logger->IsLoggerActive()) { Message::AddMessage(_("Logger on")); } else { Message::AddMessage(_("Logger off")); } - else if (StringIsEqual(misc, _T("note"), 4)) + else if (StringIsEqual(misc, "note", 4)) // add note to logger file if available.. logger->LoggerNote(misc + 4); } catch (...) { @@ -493,7 +493,7 @@ try { // Repeats the last status message. If pressed repeatedly, will // repeat previous status messages void -InputEvents::eventRepeatStatusMessage([[maybe_unused]] const TCHAR *misc) +InputEvents::eventRepeatStatusMessage([[maybe_unused]] const char *misc) { // new interface // TODO enhancement: display only by type specified in misc field @@ -504,7 +504,7 @@ InputEvents::eventRepeatStatusMessage([[maybe_unused]] const TCHAR *misc) // NearestWaypointDetails // Displays the waypoint details dialog void -InputEvents::eventNearestWaypointDetails([[maybe_unused]] const TCHAR *misc) +InputEvents::eventNearestWaypointDetails([[maybe_unused]] const char *misc) { const auto location = GetVisibleLocation(); if (!location.IsValid()) @@ -517,7 +517,7 @@ InputEvents::eventNearestWaypointDetails([[maybe_unused]] const TCHAR *misc) // NearestMapItems // Displays the map item list dialog void -InputEvents::eventNearestMapItems([[maybe_unused]] const TCHAR *misc) +InputEvents::eventNearestMapItems([[maybe_unused]] const char *misc) { const auto location = GetVisibleLocation(); if (!location.IsValid()) @@ -530,18 +530,18 @@ InputEvents::eventNearestMapItems([[maybe_unused]] const TCHAR *misc) // The null event does nothing. This can be used to override // default functionality void -InputEvents::eventNull([[maybe_unused]] const TCHAR *misc) +InputEvents::eventNull([[maybe_unused]] const char *misc) { // do nothing } void -InputEvents::eventBeep([[maybe_unused]] const TCHAR *misc) +InputEvents::eventBeep([[maybe_unused]] const char *misc) { #ifdef _WIN32 MessageBeep(MB_ICONEXCLAMATION); #else - PlayResource(_T("IDR_WAV_CLEAR")); + PlayResource("IDR_WAV_CLEAR"); #endif } @@ -553,41 +553,41 @@ InputEvents::eventBeep([[maybe_unused]] const TCHAR *misc) // Airspace: Airspace filter settings // Replay: IGC replay dialog void -InputEvents::eventSetup(const TCHAR *misc) +InputEvents::eventSetup(const char *misc) { - if (StringIsEqual(misc, _T("Basic"))) + if (StringIsEqual(misc, "Basic")) dlgBasicSettingsShowModal(); - else if (StringIsEqual(misc, _T("Wind"))) + else if (StringIsEqual(misc, "Wind")) ShowWindSettingsDialog(); - else if (StringIsEqual(misc, _T("System"))) + else if (StringIsEqual(misc, "System")) SystemConfiguration(); - else if (StringIsEqual(misc, _T("Task"))) + else if (StringIsEqual(misc, "Task")) dlgTaskManagerShowModal(); - else if (StringIsEqual(misc, _T("Airspace"))) + else if (StringIsEqual(misc, "Airspace")) dlgAirspaceShowModal(false); - else if (StringIsEqual(misc, _T("Weather"))) - ShowWeatherDialog(_T("rasp")); - else if (StringIsEqual(misc, _T("Replay"))) { + else if (StringIsEqual(misc, "Weather")) + ShowWeatherDialog("rasp"); + else if (StringIsEqual(misc, "Replay")) { if (!CommonInterface::MovementDetected() && backend_components->replay) ShowReplayDialog(*backend_components->replay); - } else if (StringIsEqual(misc, _T("Switches"))) + } else if (StringIsEqual(misc, "Switches")) dlgSwitchesShowModal(); - else if (StringIsEqual(misc, _T("Teamcode"))) + else if (StringIsEqual(misc, "Teamcode")) dlgTeamCodeShowModal(); - else if (StringIsEqual(misc, _T("Target"))) + else if (StringIsEqual(misc, "Target")) dlgTargetShowModal(); - else if (StringIsEqual(misc, _T("Plane"))) + else if (StringIsEqual(misc, "Plane")) dlgPlanesShowModal(); - else if (StringIsEqual(misc, _T("Profile"))) + else if (StringIsEqual(misc, "Profile")) ProfileListDialog(); - else if (StringIsEqual(misc, _T("Alternates"))) + else if (StringIsEqual(misc, "Alternates")) dlgAlternatesListShowModal(data_components->waypoints.get()); trigger_redraw(); } void -InputEvents::eventCredits([[maybe_unused]] const TCHAR *misc) +InputEvents::eventCredits([[maybe_unused]] const char *misc) { dlgCreditsShowModal(*CommonInterface::main_window); } @@ -596,7 +596,7 @@ InputEvents::eventCredits([[maybe_unused]] const TCHAR *misc) // Runs an external program of the specified filename. // Note that XCSoar will wait until this program exits. void -InputEvents::eventRun(const TCHAR *misc) +InputEvents::eventRun(const char *misc) { #ifdef _WIN32 PROCESS_INFORMATION pi; @@ -617,29 +617,96 @@ InputEvents::eventRun(const TCHAR *misc) } void -InputEvents::eventBrightness([[maybe_unused]] const TCHAR *misc) +InputEvents::eventBrightness([[maybe_unused]] const char *misc) { // not implemented (was only implemented on Altair) } -void -InputEvents::eventExit([[maybe_unused]] const TCHAR *misc) +// Exits for general systems +void +InputEvents::eventExit([[maybe_unused]] const char *misc) +{ + bool force = false; + if (StringIsEqual(misc, "system")) { + UI::TopWindow::SetExitValue(EXIT_SYSTEM); + } else if (StringIsEqual(misc, "force")) { + UI::TopWindow::SetExitValue(EXIT_SYSTEM); + force = true; + } else if (StringIsEqual(misc, "restart")) { + UI::TopWindow::SetExitValue(EXIT_RESTART); +#if defined(IS_OPENVARIO) + } else if (StringIsEqual(misc, "newstart")) { + UI::TopWindow::SetExitValue(EXIT_NEWSTART); +#endif + } + UIActions::SignalShutdown(force); +} + +#if 1 // defined(IS_OPENVARIO) +// Exits with real Shutdown only in systems where this is possible +void +InputEvents::eventShutdown([[maybe_unused]] const char *misc) { - UIActions::SignalShutdown(false); +#if defined(IS_OPENVARIO) + if (StringIsEqual(misc, "reboot")) { + UI::TopWindow::SetExitValue(EXIT_REBOOT); // 20001); + } else if (StringIsEqual(misc, "shutdown")) { + UI::TopWindow::SetExitValue(EXIT_SHUTDOWN); // 20002); + } +#endif + UIActions::SignalShutdown(false); +} + +#include "InputKeys.hpp" +#include "ui/event/KeyCode.hpp" + +void +InputEvents::eventKeyPressed(const char *misc) +{ +// std::map keys; + for (auto *p = misc; *p != 0; p++) { + if (*p != ' ') { + char c[2] = {*p, 0}; + if (!strncmp(p, "LEFT", strlen("LEFT"))) { + c[0] = (char) KEY_LEFT; + p += strlen("LEFT") ; + } else if (!strncmp(p, "RIGHT", strlen("RIGHT"))) { + c[0] = (char) KEY_RIGHT; + p += strlen("RIGHT") ; + } else if (!strncmp(p, "UP", strlen("UP"))) { + c[0] = (char) KEY_UP; + p += strlen("UP") ; + } else if (!strncmp(p, "DOWN", strlen("DOWN"))) { + c[0] = (char) KEY_DOWN; + p += strlen("DOWN") ; + } else if (!strncmp(p, "ESCAPE", strlen("ESCAPE"))) { + c[0] = (char) KEY_ESCAPE; + p += strlen("ESCAPE") ; + } else if (!strncmp(p, "ENTER", strlen("ENTER"))) { + c[0] = (char) KEY_RETURN; + p += strlen("ENTER") ; + } else if (!strncmp(p, "RETURN", strlen("RETURN"))) { + c[0] = (char) KEY_RETURN; + p += strlen("RETURN") ; + } + ProcessKey(MODE_MENU, ParseKeyCode((const char *)c)); + } + } } +#endif void -InputEvents::eventUserDisplayModeForce(const TCHAR *misc) +InputEvents::eventUserDisplayModeForce(const char *misc) { UIState &ui_state = CommonInterface::SetUIState(); - if (StringIsEqual(misc, _T("unforce"))) + if (StringIsEqual(misc, "unforce")) ui_state.force_display_mode = DisplayMode::NONE; - else if (StringIsEqual(misc, _T("forceclimb"))) + else if (StringIsEqual(misc, "forceclimb")) ui_state.force_display_mode = DisplayMode::CIRCLING; - else if (StringIsEqual(misc, _T("forcecruise"))) + else if (StringIsEqual(misc, "forcecruise")) ui_state.force_display_mode = DisplayMode::CRUISE; - else if (StringIsEqual(misc, _T("forcefinal"))) + else if (StringIsEqual(misc, "forcefinal")) ui_state.force_display_mode = DisplayMode::FINAL_GLIDE; ActionInterface::UpdateDisplayMode(); @@ -647,13 +714,13 @@ InputEvents::eventUserDisplayModeForce(const TCHAR *misc) } void -InputEvents::eventAddWaypoint(const TCHAR *misc) +InputEvents::eventAddWaypoint(const char *misc) { const NMEAInfo &basic = CommonInterface::Basic(); const DerivedInfo &calculated = CommonInterface::Calculated(); auto &way_points = *data_components->waypoints; - if (StringIsEqual(misc, _T("takeoff"))) { + if (StringIsEqual(misc, "takeoff")) { if (basic.location_available && calculated.terrain_valid) { ScopeSuspendAllThreads suspend; way_points.AddTakeoffPoint(basic.location, calculated.terrain_altitude); @@ -717,35 +784,35 @@ mph/kts/... // helpers void -InputEvents::eventWeather(const TCHAR *misc) +InputEvents::eventWeather(const char *misc) { ShowWeatherDialog(misc); } void -InputEvents::eventQuickMenu([[maybe_unused]] const TCHAR *misc) +InputEvents::eventQuickMenu(const char *misc) { - dlgQuickMenuShowModal(*CommonInterface::main_window); + dlgQuickMenuShowModal(*CommonInterface::main_window, misc); } void -InputEvents::eventFileManager([[maybe_unused]] const TCHAR *misc) +InputEvents::eventFileManager([[maybe_unused]] const char *misc) { ShowFileManager(); } void -InputEvents::eventExchangeFrequencies([[maybe_unused]] const TCHAR *misc) +InputEvents::eventExchangeFrequencies([[maybe_unused]] const char *misc) { XCSoarInterface::ExchangeRadioFrequencies(true); } void -InputEvents::eventUploadIGCFile([[maybe_unused]] const TCHAR *misc) { +InputEvents::eventUploadIGCFile([[maybe_unused]] const char *misc) { FileDataField df; - df.ScanMultiplePatterns(_T("*.igc\0")); + df.ScanMultiplePatterns("*.igc\0"); df.SetFileType(FileType::IGC); - if (FilePicker(_T("IGC-FilePicker"), df)) { + if (FilePicker("IGC-FilePicker", df)) { auto path = df.GetValue(); if (!path.empty()) if (WeGlide::UploadIGCFile(path)) { diff --git a/src/Input/InputEventsAirspace.cpp b/src/Input/InputEventsAirspace.cpp index 8f58da5d69d..e2fee74edfc 100644 --- a/src/Input/InputEventsAirspace.cpp +++ b/src/Input/InputEventsAirspace.cpp @@ -29,24 +29,24 @@ * but 0 should mean OFF all the way. */ void -InputEvents::eventAirSpace(const TCHAR *misc) +InputEvents::eventAirSpace(const char *misc) { AirspaceRendererSettings &settings = CommonInterface::SetMapSettings().airspace; - if (StringIsEqual(misc, _T("toggle"))) + if (StringIsEqual(misc, "toggle")) settings.enable = !settings.enable; - else if (StringIsEqual(misc, _T("off"))) + else if (StringIsEqual(misc, "off")) settings.enable = false; - else if (StringIsEqual(misc, _T("on"))) + else if (StringIsEqual(misc, "on")) settings.enable = true; - else if (StringIsEqual(misc, _T("show"))) { + else if (StringIsEqual(misc, "show")) { if (!settings.enable) Message::AddMessage(_("Show airspace off")); if (settings.enable) Message::AddMessage(_("Show airspace on")); return; - } else if (StringIsEqual(misc, _T("list"))) { + } else if (StringIsEqual(misc, "list")) { ShowAirspaceListDialog(*data_components->airspaces, backend_components->GetAirspaceWarnings()); return; @@ -58,7 +58,7 @@ InputEvents::eventAirSpace(const TCHAR *misc) // ClearAirspaceWarnings // Clears airspace warnings for the selected airspace void -InputEvents::eventClearAirspaceWarnings([[maybe_unused]] const TCHAR *misc) +InputEvents::eventClearAirspaceWarnings([[maybe_unused]] const char *misc) { if (auto *airspace_warnings = backend_components->GetAirspaceWarnings()) airspace_warnings->AcknowledgeAll(); @@ -72,7 +72,7 @@ InputEvents::eventClearAirspaceWarnings([[maybe_unused]] const TCHAR *misc) // to the nearest exit to the airspace. void -InputEvents::eventNearestAirspaceDetails([[maybe_unused]] const TCHAR *misc) +InputEvents::eventNearestAirspaceDetails([[maybe_unused]] const char *misc) { const MoreData &basic = CommonInterface::Basic(); const DerivedInfo &calculated = CommonInterface::Calculated(); diff --git a/src/Input/InputEventsDevice.cpp b/src/Input/InputEventsDevice.cpp index fa0e5cd5da9..5a56a34cb03 100644 --- a/src/Input/InputEventsDevice.cpp +++ b/src/Input/InputEventsDevice.cpp @@ -18,7 +18,7 @@ // to provide the text in between the '$' and '*'. // void -InputEvents::eventSendNMEA(const TCHAR *misc) +InputEvents::eventSendNMEA(const char *misc) { if (misc != NULL && backend_components->devices != nullptr) { PopupOperationEnvironment env; @@ -27,7 +27,7 @@ InputEvents::eventSendNMEA(const TCHAR *misc) } void -InputEvents::eventSendNMEAPort1(const TCHAR *misc) +InputEvents::eventSendNMEAPort1(const char *misc) { const unsigned i = 0; @@ -38,7 +38,7 @@ InputEvents::eventSendNMEAPort1(const TCHAR *misc) } void -InputEvents::eventSendNMEAPort2(const TCHAR *misc) +InputEvents::eventSendNMEAPort2(const char *misc) { const unsigned i = 1; @@ -49,11 +49,11 @@ InputEvents::eventSendNMEAPort2(const TCHAR *misc) } void -InputEvents::eventDevice(const TCHAR *misc) +InputEvents::eventDevice(const char *misc) { assert(misc != NULL); - if (StringIsEqual(misc, _T("list"))) + if (StringIsEqual(misc, "list")) ShowDeviceList(*backend_components->device_blackboard, backend_components->devices.get()); } diff --git a/src/Input/InputEventsLua.cpp b/src/Input/InputEventsLua.cpp index 85a9dbe43aa..c688dd2a787 100644 --- a/src/Input/InputEventsLua.cpp +++ b/src/Input/InputEventsLua.cpp @@ -28,16 +28,16 @@ class LuaFileVisitor final : public File::Visitor { }; static AllocatedPath -SelectLuaFile(const TCHAR *path) +SelectLuaFile(const char *path) { if (StringIsEmpty(path)) { /* no parameter: let user select a *.lua file */ LuaFileVisitor visitor; - Directory::VisitSpecificFiles(LocalPath(_T("lua")), _T("*.lua"), + Directory::VisitSpecificFiles(LocalPath("lua"), "*.lua", visitor, true); if (visitor.combo_list.empty()) { - ShowMessageBox(_("Not found"), _T("RunLuaFile"), + ShowMessageBox(_("Not found"), "RunLuaFile", MB_OK|MB_ICONINFORMATION); return nullptr; } @@ -47,20 +47,20 @@ SelectLuaFile(const TCHAR *path) return nullptr; return Path(visitor.combo_list[i].string_value.c_str()); - } else if (StringEndsWith(path, _T(".lua"))) { + } else if (StringEndsWith(path, ".lua")) { /* *.lua file specified: run this file */ return Path(path).IsAbsolute() ? AllocatedPath(Path(path)) - : AllocatedPath::Build(LocalPath(_T("lua")), path); + : AllocatedPath::Build(LocalPath("lua"), path); } else { - ShowMessageBox(_T("RunLuaFile expects *.lua parameter"), - _T("RunLuaFile"), MB_OK|MB_ICONINFORMATION); + ShowMessageBox("RunLuaFile expects *.lua parameter", + "RunLuaFile", MB_OK|MB_ICONINFORMATION); return nullptr; } } void -InputEvents::eventRunLuaFile(const TCHAR *misc) +InputEvents::eventRunLuaFile(const char *misc) { const auto path = SelectLuaFile(misc); if (path == nullptr) @@ -69,8 +69,8 @@ InputEvents::eventRunLuaFile(const TCHAR *misc) try { Lua::StartFile(path); } catch (...) { - TCHAR buffer[MAX_PATH]; - StringFormat(buffer, MAX_PATH, _T("RunLuaFile %s"), misc); + char buffer[MAX_PATH]; + StringFormat(buffer, MAX_PATH, "RunLuaFile %s", misc); ShowError(std::current_exception(), buffer); } } diff --git a/src/Input/InputEventsMap.cpp b/src/Input/InputEventsMap.cpp index 65e1a121fb8..93bec92acc0 100644 --- a/src/Input/InputEventsMap.cpp +++ b/src/Input/InputEventsMap.cpp @@ -32,7 +32,7 @@ // n.n - Zoom to a set scale // show - Show current zoom scale void -InputEvents::eventZoom(const TCHAR* misc) +InputEvents::eventZoom(const char* misc) { // JMW pass through to handler in MapWindow // here: @@ -42,47 +42,47 @@ InputEvents::eventZoom(const TCHAR* misc) MapSettings &settings_map = CommonInterface::SetMapSettings(); - if (StringIsEqual(misc, _T("auto toggle"))) + if (StringIsEqual(misc, "auto toggle")) sub_AutoZoom(-1); - else if (StringIsEqual(misc, _T("auto on"))) + else if (StringIsEqual(misc, "auto on")) sub_AutoZoom(1); - else if (StringIsEqual(misc, _T("auto off"))) + else if (StringIsEqual(misc, "auto off")) sub_AutoZoom(0); - else if (StringIsEqual(misc, _T("auto show"))) { + else if (StringIsEqual(misc, "auto show")) { if (settings_map.auto_zoom_enabled) Message::AddMessage(_("Auto. zoom on")); else Message::AddMessage(_("Auto. zoom off")); - } else if (StringIsEqual(misc, _T("slowout"))) + } else if (StringIsEqual(misc, "slowout")) sub_ScaleZoom(-1); - else if (StringIsEqual(misc, _T("slowin"))) + else if (StringIsEqual(misc, "slowin")) sub_ScaleZoom(1); - else if (StringIsEqual(misc, _T("out"))) + else if (StringIsEqual(misc, "out")) sub_ScaleZoom(-1); - else if (StringIsEqual(misc, _T("in"))) + else if (StringIsEqual(misc, "in")) sub_ScaleZoom(1); - else if (StringIsEqual(misc, _T("-"))) + else if (StringIsEqual(misc, "-")) sub_ScaleZoom(-1); - else if (StringIsEqual(misc, _T("+"))) + else if (StringIsEqual(misc, "+")) sub_ScaleZoom(1); - else if (StringIsEqual(misc, _T("--"))) + else if (StringIsEqual(misc, "--")) sub_ScaleZoom(-2); - else if (StringIsEqual(misc, _T("++"))) + else if (StringIsEqual(misc, "++")) sub_ScaleZoom(2); - else if (StringIsEqual(misc, _T("circlezoom toggle"))) { + else if (StringIsEqual(misc, "circlezoom toggle")) { settings_map.circle_zoom_enabled = !settings_map.circle_zoom_enabled; - } else if (StringIsEqual(misc, _T("circlezoom on"))) { + } else if (StringIsEqual(misc, "circlezoom on")) { settings_map.circle_zoom_enabled = true; - } else if (StringIsEqual(misc, _T("circlezoom off"))) { + } else if (StringIsEqual(misc, "circlezoom off")) { settings_map.circle_zoom_enabled = false; - } else if (StringIsEqual(misc, _T("circlezoom show"))) { + } else if (StringIsEqual(misc, "circlezoom show")) { if (settings_map.circle_zoom_enabled) Message::AddMessage(_("Circling zoom on")); else Message::AddMessage(_("Circling zoom off")); } else { - TCHAR *endptr; - double zoom = _tcstod(misc, &endptr); + char *endptr; + double zoom = strtod(misc, &endptr); if (endptr == misc) return; @@ -107,27 +107,27 @@ InputEvents::eventZoom(const TCHAR* misc) * @todo feature: ??? Go to waypoint (eg: next, named) */ void -InputEvents::eventPan(const TCHAR *misc) +InputEvents::eventPan(const char *misc) { - if (StringIsEqual(misc, _T("toggle"))) + if (StringIsEqual(misc, "toggle")) TogglePan(); - else if (StringIsEqual(misc, _T("on"))) + else if (StringIsEqual(misc, "on")) EnterPan(); - else if (StringIsEqual(misc, _T("off"))) + else if (StringIsEqual(misc, "off")) LeavePan(); - else if (StringIsEqual(misc, _T("up"))) + else if (StringIsEqual(misc, "up")) sub_PanCursor(0, 1); - else if (StringIsEqual(misc, _T("down"))) + else if (StringIsEqual(misc, "down")) sub_PanCursor(0, -1); - else if (StringIsEqual(misc, _T("left"))) + else if (StringIsEqual(misc, "left")) sub_PanCursor(1, 0); - else if (StringIsEqual(misc, _T("right"))) + else if (StringIsEqual(misc, "right")) sub_PanCursor(-1, 0); XCSoarInterface::SendMapSettings(true); diff --git a/src/Input/InputEventsPage.cpp b/src/Input/InputEventsPage.cpp index 040a220cd04..48aed4751a5 100644 --- a/src/Input/InputEventsPage.cpp +++ b/src/Input/InputEventsPage.cpp @@ -6,8 +6,8 @@ #include "util/StringAPI.hxx" void -InputEvents::eventPage(const TCHAR *misc) +InputEvents::eventPage(const char *misc) { - if (StringIsEqual(misc, _T("restore"))) + if (StringIsEqual(misc, "restore")) PageActions::Restore(); } diff --git a/src/Input/InputEventsSettings.cpp b/src/Input/InputEventsSettings.cpp index b20394622c8..c1c45b4e71a 100644 --- a/src/Input/InputEventsSettings.cpp +++ b/src/Input/InputEventsSettings.cpp @@ -24,19 +24,32 @@ #include "BackendComponents.hpp" void -InputEvents::eventSounds(const TCHAR *misc) +InputEvents::eventSounds(const char *misc) { SoundSettings &settings = CommonInterface::SetUISettings().sound; // bool OldEnableSoundVario = EnableSoundVario; - - if (StringIsEqual(misc, _T("toggle"))) - settings.vario.enabled = !settings.vario.enabled; - else if (StringIsEqual(misc, _T("on"))) + bool enabled = settings.vario.enabled; + if (StringIsEqual(misc, "toggle")) + settings.vario.enabled = !enabled; + else if (StringIsEqual(misc, "on")) settings.vario.enabled = true; - else if (StringIsEqual(misc, _T("off"))) + else if (StringIsEqual(misc, "off")) settings.vario.enabled = false; - else if (StringIsEqual(misc, _T("show"))) { - if (settings.vario.enabled) + else if (StringIsEqual(misc, "quieter")) { + settings.vario.volume = settings.vario.volume / 2; + if (settings.vario.volume < 1) // settings.vario.max_volume) + settings.vario.volume = 1; // don't switch to off! + // settings.vario.enabled = false; + } else if (StringIsEqual(misc, "louder")) { + if (settings.vario.volume > 0) + settings.vario.volume *= 2; + else + settings.vario.volume = 2; + if (settings.vario.volume > 100) // settings.vario.max_volume) + settings.vario.volume = 100; + // settings.vario.enabled = false; + } else if (StringIsEqual(misc, "show")) { + if (enabled) Message::AddMessage(_("Vario sounds on")); else Message::AddMessage(_("Vario sounds off")); @@ -44,27 +57,28 @@ InputEvents::eventSounds(const TCHAR *misc) } AudioVarioGlue::Configure(settings.vario); - Profile::Set(ProfileKeys::SoundAudioVario, settings.vario.enabled); + if (settings.vario.enabled != enabled) + Profile::Set(ProfileKeys::SoundAudioVario, settings.vario.enabled); } void -InputEvents::eventSnailTrail(const TCHAR *misc) +InputEvents::eventSnailTrail(const char *misc) { MapSettings &settings_map = CommonInterface::SetMapSettings(); - if (StringIsEqual(misc, _T("toggle"))) { + if (StringIsEqual(misc, "toggle")) { unsigned trail_length = (int)settings_map.trail.length; trail_length = (trail_length + 1u) % 4u; settings_map.trail.length = (TrailSettings::Length)trail_length; - } else if (StringIsEqual(misc, _T("off"))) + } else if (StringIsEqual(misc, "off")) settings_map.trail.length = TrailSettings::Length::OFF; - else if (StringIsEqual(misc, _T("long"))) + else if (StringIsEqual(misc, "long")) settings_map.trail.length = TrailSettings::Length::LONG; - else if (StringIsEqual(misc, _T("short"))) + else if (StringIsEqual(misc, "short")) settings_map.trail.length = TrailSettings::Length::SHORT; - else if (StringIsEqual(misc, _T("full"))) + else if (StringIsEqual(misc, "full")) settings_map.trail.length = TrailSettings::Length::FULL; - else if (StringIsEqual(misc, _T("show"))) { + else if (StringIsEqual(misc, "show")) { switch (settings_map.trail.length) { case TrailSettings::Length::OFF: Message::AddMessage(_("Snail trail off")); @@ -88,36 +102,36 @@ InputEvents::eventSnailTrail(const TCHAR *misc) } void -InputEvents::eventTerrainTopology(const TCHAR *misc) +InputEvents::eventTerrainTopology(const char *misc) { eventTerrainTopography(misc); } // Do JUST Terrain/Topography (toggle any, on/off any, show) void -InputEvents::eventTerrainTopography(const TCHAR *misc) +InputEvents::eventTerrainTopography(const char *misc) { - if (StringIsEqual(misc, _T("terrain toggle"))) + if (StringIsEqual(misc, "terrain toggle")) sub_TerrainTopography(-2); - else if (StringIsEqual(misc, _T("topography toggle"))) + else if (StringIsEqual(misc, "topography toggle")) sub_TerrainTopography(-3); - else if (StringIsEqual(misc, _T("topology toggle"))) + else if (StringIsEqual(misc, "topology toggle")) sub_TerrainTopography(-3); - else if (StringIsEqual(misc, _T("terrain on"))) + else if (StringIsEqual(misc, "terrain on")) sub_TerrainTopography(3); - else if (StringIsEqual(misc, _T("terrain off"))) + else if (StringIsEqual(misc, "terrain off")) sub_TerrainTopography(4); - else if (StringIsEqual(misc, _T("topography on"))) + else if (StringIsEqual(misc, "topography on")) sub_TerrainTopography(1); - else if (StringIsEqual(misc, _T("topography off"))) + else if (StringIsEqual(misc, "topography off")) sub_TerrainTopography(2); - else if (StringIsEqual(misc, _T("topology on"))) + else if (StringIsEqual(misc, "topology on")) sub_TerrainTopography(1); - else if (StringIsEqual(misc, _T("topology off"))) + else if (StringIsEqual(misc, "topology off")) sub_TerrainTopography(2); - else if (StringIsEqual(misc, _T("show"))) + else if (StringIsEqual(misc, "show")) sub_TerrainTopography(0); - else if (StringIsEqual(misc, _T("toggle"))) + else if (StringIsEqual(misc, "toggle")) sub_TerrainTopography(-1); XCSoarInterface::SendMapSettings(true); @@ -127,17 +141,17 @@ InputEvents::eventTerrainTopography(const TCHAR *misc) // +: increases deadband // -: decreases deadband void -InputEvents::eventAudioDeadband(const TCHAR *misc) +InputEvents::eventAudioDeadband(const char *misc) { SoundSettings &settings = CommonInterface::SetUISettings().sound; - if (StringIsEqual(misc, _T("+"))) { + if (StringIsEqual(misc, "+")) { if (settings.sound_deadband >= 40) return; ++settings.sound_deadband; } - if (StringIsEqual(misc, _T("-"))) { + if (StringIsEqual(misc, "-")) { if (settings.sound_deadband <= 0) return; @@ -157,7 +171,7 @@ InputEvents::eventAudioDeadband(const TCHAR *misc) // min: selects the worst performance (50%) // show: shows the current bug degradation void -InputEvents::eventBugs(const TCHAR *misc) +InputEvents::eventBugs(const char *misc) { if (!backend_components->protected_task_manager) return; @@ -166,21 +180,21 @@ InputEvents::eventBugs(const TCHAR *misc) auto BUGS = settings.bugs; auto oldBugs = BUGS; - if (StringIsEqual(misc, _T("up"))) { + if (StringIsEqual(misc, "up")) { BUGS += 1 / 10.; if (BUGS > 1) BUGS = 1; - } else if (StringIsEqual(misc, _T("down"))) { + } else if (StringIsEqual(misc, "down")) { BUGS -= 1 / 10.; if (BUGS < 0.5) BUGS = 0.5; - } else if (StringIsEqual(misc, _T("max"))) + } else if (StringIsEqual(misc, "max")) BUGS = 1; - else if (StringIsEqual(misc, _T("min"))) + else if (StringIsEqual(misc, "min")) BUGS = 0.5; - else if (StringIsEqual(misc, _T("show"))) { - TCHAR Temp[100]; - _stprintf(Temp, _T("%d"), (int)(BUGS * 100)); + else if (StringIsEqual(misc, "show")) { + char Temp[100]; + _stprintf(Temp, "%d", (int)(BUGS * 100)); Message::AddMessage(_("Bugs performance"), Temp); } @@ -198,7 +212,7 @@ InputEvents::eventBugs(const TCHAR *misc) // min: selects 0% ballast // show: displays a status message indicating the ballast percentage void -InputEvents::eventBallast(const TCHAR *misc) +InputEvents::eventBallast(const char *misc) { if (!backend_components->protected_task_manager) return; @@ -208,21 +222,21 @@ InputEvents::eventBallast(const TCHAR *misc) auto BALLAST = polar.GetBallast(); auto oldBallast = BALLAST; - if (StringIsEqual(misc, _T("up"))) { + if (StringIsEqual(misc, "up")) { BALLAST += 1 / 10.; if (BALLAST >= 1) BALLAST = 1; - } else if (StringIsEqual(misc, _T("down"))) { + } else if (StringIsEqual(misc, "down")) { BALLAST -= 1 / 10.; if (BALLAST < 0) BALLAST = 0; - } else if (StringIsEqual(misc, _T("max"))) + } else if (StringIsEqual(misc, "max")) BALLAST = 1; - else if (StringIsEqual(misc, _T("min"))) + else if (StringIsEqual(misc, "min")) BALLAST = 0; - else if (StringIsEqual(misc, _T("show"))) { - TCHAR Temp[100]; - _stprintf(Temp, _T("%d"), (int)(BALLAST * 100)); + else if (StringIsEqual(misc, "show")) { + char Temp[100]; + _stprintf(Temp, "%d", (int)(BALLAST * 100)); /* xgettext:no-c-format */ Message::AddMessage(_("Ballast %"), Temp); } @@ -236,7 +250,7 @@ InputEvents::eventBallast(const TCHAR *misc) // ProfileLoad // Loads the profile of the specified filename void -InputEvents::eventProfileLoad(const TCHAR *misc) +InputEvents::eventProfileLoad(const char *misc) { if (!StringIsEmpty(misc)) { Profile::LoadFile(Path(misc)); @@ -254,7 +268,7 @@ InputEvents::eventProfileLoad(const TCHAR *misc) // ProfileSave // Saves the profile to the specified filename void -InputEvents::eventProfileSave(const TCHAR *misc) +InputEvents::eventProfileSave(const char *misc) { if (!StringIsEmpty(misc)) { try { @@ -272,25 +286,25 @@ InputEvents::eventProfileSave(const TCHAR *misc) // -: decreases temperature by one degree celsius // show: Shows a status message with the current forecast temperature void -InputEvents::eventAdjustForecastTemperature(const TCHAR *misc) +InputEvents::eventAdjustForecastTemperature(const char *misc) { - if (StringIsEqual(misc, _T("+"))) + if (StringIsEqual(misc, "+")) CommonInterface::SetComputerSettings().forecast_temperature += Temperature::FromKelvin(1); - else if (StringIsEqual(misc, _T("-"))) + else if (StringIsEqual(misc, "-")) CommonInterface::SetComputerSettings().forecast_temperature -= Temperature::FromKelvin(1); - else if (StringIsEqual(misc, _T("show"))) { + else if (StringIsEqual(misc, "show")) { auto temperature = CommonInterface::GetComputerSettings().forecast_temperature; - TCHAR Temp[100]; - _stprintf(Temp, _T("%f"), temperature.ToUser()); + char Temp[100]; + _stprintf(Temp, "%f", temperature.ToUser()); Message::AddMessage(_("Forecast temperature"), Temp); } } void -InputEvents::eventDeclutterLabels(const TCHAR *misc) +InputEvents::eventDeclutterLabels(const char *misc) { - static const TCHAR *const msg[] = { + static const char *const msg[] = { N_("All"), N_("Task & Landables"), N_("Task"), @@ -299,22 +313,22 @@ InputEvents::eventDeclutterLabels(const TCHAR *misc) }; static constexpr unsigned int n = ARRAY_SIZE(msg); - static const TCHAR *const actions[n] = { - _T("all"), - _T("task+landables"), - _T("task"), - _T("none") - _T("task+airfields"), + static const char *const actions[n] = { + "all", + "task+landables", + "task", + "none", + "task+airfields", }; WaypointRendererSettings::LabelSelection &wls = CommonInterface::SetMapSettings().waypoint.label_selection; - if (StringIsEqual(misc, _T("toggle"))) { + if (StringIsEqual(misc, "toggle")) { wls = WaypointRendererSettings::LabelSelection(((unsigned)wls + 1) % n); Profile::Set(ProfileKeys::WaypointLabelSelection, (int)wls); - } else if (StringIsEqual(misc, _T("show"))) { - TCHAR tbuf[64]; - _stprintf(tbuf, _T("%s: %s"), _("Waypoint labels"), + } else if (StringIsEqual(misc, "show")) { + char tbuf[64]; + _stprintf(tbuf, "%s: %s", _("Waypoint labels"), gettext(msg[(unsigned)wls])); Message::AddMessage(tbuf); } @@ -332,46 +346,46 @@ InputEvents::eventDeclutterLabels(const TCHAR *misc) } void -InputEvents::eventAirspaceDisplayMode(const TCHAR *misc) +InputEvents::eventAirspaceDisplayMode(const char *misc) { AirspaceRendererSettings &settings = CommonInterface::SetMapSettings().airspace; - if (StringIsEqual(misc, _T("all"))) + if (StringIsEqual(misc, "all")) settings.altitude_mode = AirspaceDisplayMode::ALLON; - else if (StringIsEqual(misc, _T("clip"))) + else if (StringIsEqual(misc, "clip")) settings.altitude_mode = AirspaceDisplayMode::CLIP; - else if (StringIsEqual(misc, _T("auto"))) + else if (StringIsEqual(misc, "auto")) settings.altitude_mode = AirspaceDisplayMode::AUTO; - else if (StringIsEqual(misc, _T("below"))) + else if (StringIsEqual(misc, "below")) settings.altitude_mode = AirspaceDisplayMode::ALLBELOW; - else if (StringIsEqual(misc, _T("off"))) + else if (StringIsEqual(misc, "off")) settings.altitude_mode = AirspaceDisplayMode::ALLOFF; TriggerMapUpdate(); } void -InputEvents::eventOrientation(const TCHAR *misc) +InputEvents::eventOrientation(const char *misc) { MapSettings &settings_map = CommonInterface::SetMapSettings(); - if (StringIsEqual(misc, _T("northup"))) { + if (StringIsEqual(misc, "northup")) { settings_map.cruise_orientation = MapOrientation::NORTH_UP; settings_map.circling_orientation = MapOrientation::NORTH_UP; - } else if (StringIsEqual(misc, _T("northcircle"))) { + } else if (StringIsEqual(misc, "northcircle")) { settings_map.cruise_orientation = MapOrientation::TRACK_UP; settings_map.circling_orientation = MapOrientation::NORTH_UP; - } else if (StringIsEqual(misc, _T("trackcircle"))) { + } else if (StringIsEqual(misc, "trackcircle")) { settings_map.cruise_orientation = MapOrientation::NORTH_UP; settings_map.circling_orientation = MapOrientation::TRACK_UP; - } else if (StringIsEqual(misc, _T("trackup"))) { + } else if (StringIsEqual(misc, "trackup")) { settings_map.cruise_orientation = MapOrientation::TRACK_UP; settings_map.circling_orientation = MapOrientation::TRACK_UP; - } else if (StringIsEqual(misc, _T("northtrack"))) { + } else if (StringIsEqual(misc, "northtrack")) { settings_map.cruise_orientation = MapOrientation::TRACK_UP; settings_map.circling_orientation = MapOrientation::TARGET_UP; - } else if (StringIsEqual(misc, _T("targetup"))) { + } else if (StringIsEqual(misc, "targetup")) { settings_map.cruise_orientation = MapOrientation::TARGET_UP; settings_map.circling_orientation = MapOrientation::TARGET_UP; } @@ -431,14 +445,14 @@ InputEvents::sub_TerrainTopography(int vswitch) else if (vswitch == 0) { // Show terrain/topography // ARH Let user know what's happening - TCHAR buf[128]; + char buf[128]; if (settings_map.topography_enabled) - _stprintf(buf, _T("\r\n%s / "), _("On")); + _stprintf(buf, "\r\n%s / ", _("On")); else - _stprintf(buf, _T("\r\n%s / "), _("Off")); + _stprintf(buf, "\r\n%s / ", _("Off")); - _tcscat(buf, settings_map.terrain.enable + strcat(buf, settings_map.terrain.enable ? _("On") : _("Off")); Message::AddMessage(_("Topography/Terrain"), buf); diff --git a/src/Input/InputEventsTask.cpp b/src/Input/InputEventsTask.cpp index 288db13f7f6..7cafd62f448 100644 --- a/src/Input/InputEventsTask.cpp +++ b/src/Input/InputEventsTask.cpp @@ -42,7 +42,7 @@ trigger_redraw() // toggle: Toggles between armed and disarmed. // show: Shows current armed state void -InputEvents::eventArmAdvance(const TCHAR *misc) +InputEvents::eventArmAdvance(const char *misc) { if (!backend_components->protected_task_manager) return; @@ -50,13 +50,13 @@ InputEvents::eventArmAdvance(const TCHAR *misc) ProtectedTaskManager::ExclusiveLease task_manager{*backend_components->protected_task_manager}; TaskAdvance &advance = task_manager->SetTaskAdvance(); - if (StringIsEqual(misc, _T("on"))) { + if (StringIsEqual(misc, "on")) { advance.SetArmed(true); - } else if (StringIsEqual(misc, _T("off"))) { + } else if (StringIsEqual(misc, "off")) { advance.SetArmed(false); - } else if (StringIsEqual(misc, _T("toggle"))) { + } else if (StringIsEqual(misc, "toggle")) { advance.ToggleArmed(); - } else if (StringIsEqual(misc, _T("show"))) { + } else if (StringIsEqual(misc, "show")) { switch (advance.GetState()) { case TaskAdvance::MANUAL: Message::AddMessage(_("Advance manually")); @@ -86,7 +86,7 @@ InputEvents::eventArmAdvance(const TCHAR *misc) } void -InputEvents::eventCalculator([[maybe_unused]] const TCHAR *misc) +InputEvents::eventCalculator([[maybe_unused]] const char *misc) { dlgTaskManagerShowModal(); @@ -94,7 +94,7 @@ InputEvents::eventCalculator([[maybe_unused]] const TCHAR *misc) } void -InputEvents::eventGotoLookup([[maybe_unused]] const TCHAR *misc) +InputEvents::eventGotoLookup([[maybe_unused]] const char *misc) { const NMEAInfo &basic = CommonInterface::Basic(); @@ -112,7 +112,7 @@ InputEvents::eventGotoLookup([[maybe_unused]] const TCHAR *misc) // Adjusts MacCready settings // up, down, auto on, auto off, auto toggle, auto show void -InputEvents::eventMacCready(const TCHAR *misc) +InputEvents::eventMacCready(const char *misc) { if (!backend_components->protected_task_manager) return; @@ -123,28 +123,28 @@ InputEvents::eventMacCready(const TCHAR *misc) TaskBehaviour &task_behaviour = CommonInterface::SetComputerSettings().task; - if (StringIsEqual(misc, _T("up"))) { + if (StringIsEqual(misc, "up")) { const auto step = Units::ToSysVSpeed(GetUserVerticalSpeedStep()); ActionInterface::OffsetManualMacCready(step); - } else if (StringIsEqual(misc, _T("down"))) { + } else if (StringIsEqual(misc, "down")) { const auto step = Units::ToSysVSpeed(GetUserVerticalSpeedStep()); ActionInterface::OffsetManualMacCready(-step); - } else if (StringIsEqual(misc, _T("auto toggle"))) { + } else if (StringIsEqual(misc, "auto toggle")) { task_behaviour.auto_mc = !task_behaviour.auto_mc; Profile::Set(ProfileKeys::AutoMc, task_behaviour.auto_mc); - } else if (StringIsEqual(misc, _T("auto on"))) { + } else if (StringIsEqual(misc, "auto on")) { task_behaviour.auto_mc = true; Profile::Set(ProfileKeys::AutoMc, true); - } else if (StringIsEqual(misc, _T("auto off"))) { + } else if (StringIsEqual(misc, "auto off")) { task_behaviour.auto_mc = false; Profile::Set(ProfileKeys::AutoMc, false); - } else if (StringIsEqual(misc, _T("auto show"))) { + } else if (StringIsEqual(misc, "auto show")) { if (task_behaviour.auto_mc) { Message::AddMessage(_("Auto. MacCready on")); } else { Message::AddMessage(_("Auto. MacCready off")); } - } else if (StringIsEqual(misc, _T("show"))) { + } else if (StringIsEqual(misc, "show")) { Message::AddMessage(_("MacCready "), FormatUserVerticalSpeed(mc, false)); } } @@ -156,23 +156,23 @@ InputEvents::eventMacCready(const TCHAR *misc) // nextwrap: selects the next waypoint, wrapping back to start after final // previouswrap: selects the previous waypoint, wrapping to final after start void -InputEvents::eventAdjustWaypoint(const TCHAR *misc) +InputEvents::eventAdjustWaypoint(const char *misc) { auto *protected_task_manager = backend_components->protected_task_manager.get(); if (protected_task_manager == NULL) return; - if (StringIsEqual(misc, _T("next"))) + if (StringIsEqual(misc, "next")) protected_task_manager->IncrementActiveTaskPoint(1); // next - else if (StringIsEqual(misc, _T("nextwrap"))) + else if (StringIsEqual(misc, "nextwrap")) protected_task_manager->IncrementActiveTaskPoint(1); // next - with wrap - else if (StringIsEqual(misc, _T("previous"))) + else if (StringIsEqual(misc, "previous")) protected_task_manager->IncrementActiveTaskPoint(-1); // previous - else if (StringIsEqual(misc, _T("previouswrap"))) + else if (StringIsEqual(misc, "previouswrap")) protected_task_manager->IncrementActiveTaskPoint(-1); // previous with wrap - else if (StringIsEqual(misc, _T("nextarm"))) + else if (StringIsEqual(misc, "nextarm")) protected_task_manager->IncrementActiveTaskPointArm(1); // arm sensitive next - else if (StringIsEqual(misc, _T("previousarm"))) + else if (StringIsEqual(misc, "previousarm")) protected_task_manager->IncrementActiveTaskPointArm(-1); // arm sensitive previous { @@ -193,18 +193,18 @@ InputEvents::eventAdjustWaypoint(const TCHAR *misc) // toggle: toggles between abort and resume // show: displays a status message showing the task abort status void -InputEvents::eventAbortTask(const TCHAR *misc) +InputEvents::eventAbortTask(const char *misc) { if (!backend_components->protected_task_manager) return; ProtectedTaskManager::ExclusiveLease task_manager{*backend_components->protected_task_manager}; - if (StringIsEqual(misc, _T("abort"))) + if (StringIsEqual(misc, "abort")) task_manager->Abort(); - else if (StringIsEqual(misc, _T("resume"))) + else if (StringIsEqual(misc, "resume")) task_manager->Resume(); - else if (StringIsEqual(misc, _T("show"))) { + else if (StringIsEqual(misc, "show")) { switch (task_manager->GetMode()) { case TaskType::ABORT: Message::AddMessage(_("Task aborted")); @@ -249,7 +249,7 @@ InputEvents::eventAbortTask(const TCHAR *misc) // TaskLoad // Loads the task of the specified filename void -InputEvents::eventTaskLoad(const TCHAR *misc) +InputEvents::eventTaskLoad(const char *misc) { if (!backend_components->protected_task_manager) return; @@ -277,7 +277,7 @@ InputEvents::eventTaskLoad(const TCHAR *misc) // TaskSave // Saves the task to the specified filename void -InputEvents::eventTaskSave(const TCHAR *misc) +InputEvents::eventTaskSave(const char *misc) { if (!backend_components->protected_task_manager) return; @@ -288,19 +288,19 @@ InputEvents::eventTaskSave(const TCHAR *misc) } void -InputEvents::eventTaskTransition(const TCHAR *misc) +InputEvents::eventTaskTransition(const char *misc) { if (!backend_components->protected_task_manager) return; - if (StringIsEqual(misc, _T("start"))) { + if (StringIsEqual(misc, "start")) { const StartStats &start_stats = CommonInterface::Calculated().ordered_task_stats.start; if (!start_stats.HasStarted()) return; - TCHAR TempAll[120]; - _stprintf(TempAll, _T("\r\n%s: %s\r\n%s:%s\r\n%s: %s"), + char TempAll[120]; + _stprintf(TempAll, "\r\n%s: %s\r\n%s:%s\r\n%s: %s", _("Altitude"), FormatUserAltitude(start_stats.altitude).c_str(), _("Speed"), @@ -309,15 +309,15 @@ InputEvents::eventTaskTransition(const TCHAR *misc) FormatLocalTimeHHMM(start_stats.time, CommonInterface::GetComputerSettings().utc_offset).c_str()); Message::AddMessage(_("Task start"), TempAll); - } else if (StringIsEqual(misc, _T("next"))) { + } else if (StringIsEqual(misc, "next")) { Message::AddMessage(_("Next turnpoint")); - } else if (StringIsEqual(misc, _T("finish"))) { + } else if (StringIsEqual(misc, "finish")) { Message::AddMessage(_("Task finished")); } } void -InputEvents::eventResetTask([[maybe_unused]] const TCHAR *misc) +InputEvents::eventResetTask([[maybe_unused]] const char *misc) { if (backend_components->protected_task_manager) backend_components->protected_task_manager->ResetTask(); diff --git a/src/Input/InputEventsThermalAssistant.cpp b/src/Input/InputEventsThermalAssistant.cpp index 31fdc001837..af19779923d 100644 --- a/src/Input/InputEventsThermalAssistant.cpp +++ b/src/Input/InputEventsThermalAssistant.cpp @@ -5,7 +5,7 @@ #include "PageActions.hpp" void -InputEvents::eventThermalAssistant([[maybe_unused]] const TCHAR *misc) +InputEvents::eventThermalAssistant([[maybe_unused]] const char *misc) { PageActions::ShowThermalAssistant(); } diff --git a/src/Input/InputEventsTraffic.cpp b/src/Input/InputEventsTraffic.cpp index c318363a375..8f02ac54b35 100644 --- a/src/Input/InputEventsTraffic.cpp +++ b/src/Input/InputEventsTraffic.cpp @@ -10,9 +10,9 @@ #include "Dialogs/Traffic/TrafficDialogs.hpp" void -InputEvents::eventFLARMRadar([[maybe_unused]] const TCHAR *misc) +InputEvents::eventFLARMRadar([[maybe_unused]] const char *misc) { - if (StringIsEqual(misc, _T("ForceToggle"))) { + if (StringIsEqual(misc, "ForceToggle")) { CommonInterface::main_window->ToggleForceFLARMRadar(); } else CommonInterface::main_window->ToggleSuppressFLARMRadar(); @@ -21,43 +21,43 @@ InputEvents::eventFLARMRadar([[maybe_unused]] const TCHAR *misc) // FLARM Traffic // Displays the FLARM traffic dialog void -InputEvents::eventFlarmTraffic([[maybe_unused]] const TCHAR *misc) +InputEvents::eventFlarmTraffic([[maybe_unused]] const char *misc) { PageActions::ShowTrafficRadar(); } void -InputEvents::eventTraffic(const TCHAR *misc) +InputEvents::eventTraffic(const char *misc) { LoadFlarmDatabases(); - if (StringIsEqual(misc, _T("show"))) { + if (StringIsEqual(misc, "show")) { PageActions::ShowTrafficRadar(); return; } TrafficWidget *traffic_widget = (TrafficWidget *) - CommonInterface::main_window->GetFlavourWidget(_T("Traffic")); + CommonInterface::main_window->GetFlavourWidget("Traffic"); if (traffic_widget == nullptr) return; - if (StringIsEqual(misc, _T("zoom auto toggle"))) { + if (StringIsEqual(misc, "zoom auto toggle")) { traffic_widget->ToggleAutoZoom(); - } else if (StringIsEqual(misc, _T("zoom in"))) { + } else if (StringIsEqual(misc, "zoom in")) { traffic_widget->ZoomIn(); - } else if (StringIsEqual(misc, _T("zoom out"))) { + } else if (StringIsEqual(misc, "zoom out")) { traffic_widget->ZoomOut(); - } else if (StringIsEqual(misc, _T("northup toggle"))) { + } else if (StringIsEqual(misc, "northup toggle")) { traffic_widget->ToggleNorthUp(); - } else if (StringIsEqual(misc, _T("details"))) { + } else if (StringIsEqual(misc, "details")) { traffic_widget->OpenDetails(); - } else if (StringIsEqual(misc, _T("label toggle"))) { + } else if (StringIsEqual(misc, "label toggle")) { traffic_widget->SwitchData(); } } void -InputEvents::eventFlarmDetails([[maybe_unused]] const TCHAR *misc) +InputEvents::eventFlarmDetails([[maybe_unused]] const char *misc) { LoadFlarmDatabases(); TrafficListDialog(); diff --git a/src/Input/InputEventsVega.cpp b/src/Input/InputEventsVega.cpp index d5b96dbf4ec..fbf9763d2e4 100644 --- a/src/Input/InputEventsVega.cpp +++ b/src/Input/InputEventsVega.cpp @@ -61,30 +61,30 @@ AllVegasRequestSetting(const char *name) // zero: Zero's the airspeed indicator's offset // void -InputEvents::eventAdjustVarioFilter(const TCHAR *misc) +InputEvents::eventAdjustVarioFilter(const char *misc) { static int naccel = 0; - if (StringIsEqual(misc, _T("slow"))) + if (StringIsEqual(misc, "slow")) AllVegasSendSetting("VarioTimeConstant", 3); - else if (StringIsEqual(misc, _T("medium"))) + else if (StringIsEqual(misc, "medium")) AllVegasSendSetting("VarioTimeConstant", 2); - else if (StringIsEqual(misc, _T("fast"))) + else if (StringIsEqual(misc, "fast")) AllVegasSendSetting("VarioTimeConstant", 1); - else if (StringIsEqual(misc, _T("statistics"))) + else if (StringIsEqual(misc, "statistics")) AllVegasSendSetting("Diagnostics", 1); - else if (StringIsEqual(misc, _T("diagnostics"))) + else if (StringIsEqual(misc, "diagnostics")) AllVegasSendSetting("Diagnostics", 2); - else if (StringIsEqual(misc, _T("psraw"))) + else if (StringIsEqual(misc, "psraw")) AllVegasSendSetting("Diagnostics", 3); - else if (StringIsEqual(misc, _T("switch"))) + else if (StringIsEqual(misc, "switch")) AllVegasSendSetting("Diagnostics", 4); - else if (StringIsEqual(misc, _T("democlimb"))) { + else if (StringIsEqual(misc, "democlimb")) { AllVegasSendSetting("DemoMode", 0); AllVegasSendSetting("DemoMode", 2); - } else if (StringIsEqual(misc, _T("demostf"))) { + } else if (StringIsEqual(misc, "demostf")) { AllVegasSendSetting("DemoMode", 0); AllVegasSendSetting("DemoMode", 1); - } else if (StringIsEqual(misc, _T("accel"))) { + } else if (StringIsEqual(misc, "accel")) { switch (naccel) { case 0: AllVegasRequestSetting("AccelerometerSlopeX"); @@ -106,27 +106,27 @@ InputEvents::eventAdjustVarioFilter(const TCHAR *misc) if (naccel > 3) naccel = 0; - } else if (StringIsEqual(misc, _T("xdemo"))) { + } else if (StringIsEqual(misc, "xdemo")) { dlgVegaDemoShowModal(); - } else if (StringIsEqual(misc, _T("zero"))) { + } else if (StringIsEqual(misc, "zero")) { // zero, no mixing if (!CommonInterface::Calculated().flight.flying) { AllVegasSendSetting("ZeroASI", 1); } - } else if (StringIsEqual(misc, _T("save"))) { + } else if (StringIsEqual(misc, "save")) { AllVegasSendSetting("StoreToEeprom", 2); // accel calibration } else if (!CommonInterface::Calculated().flight.flying) { - if (StringIsEqual(misc, _T("X1"))) + if (StringIsEqual(misc, "X1")) AllVegasSendSetting("CalibrateAccel", 1); - else if (StringIsEqual(misc, _T("X2"))) + else if (StringIsEqual(misc, "X2")) AllVegasSendSetting("CalibrateAccel", 2); - else if (StringIsEqual(misc, _T("X3"))) + else if (StringIsEqual(misc, "X3")) AllVegasSendSetting("CalibrateAccel", 3); - else if (StringIsEqual(misc, _T("X4"))) + else if (StringIsEqual(misc, "X4")) AllVegasSendSetting("CalibrateAccel", 4); - else if (StringIsEqual(misc, _T("X5"))) + else if (StringIsEqual(misc, "X5")) AllVegasSendSetting("CalibrateAccel", 5); } } diff --git a/src/Input/InputKeys.cpp b/src/Input/InputKeys.cpp index ecfbfbd59ad..f11a2cd8c6d 100644 --- a/src/Input/InputKeys.cpp +++ b/src/Input/InputKeys.cpp @@ -7,74 +7,74 @@ #include "util/StringAPI.hxx" struct string_to_key { - const TCHAR *name; + const char *name; unsigned key; }; static constexpr struct string_to_key string_to_key[] = { - { _T("APP1"), KEY_APP1 }, - { _T("APP2"), KEY_APP2 }, - { _T("APP3"), KEY_APP3 }, - { _T("APP4"), KEY_APP4 }, - { _T("APP5"), KEY_APP5 }, - { _T("APP6"), KEY_APP6 }, - { _T("F1"), KEY_F1 }, - { _T("F2"), KEY_F2 }, - { _T("F3"), KEY_F3 }, - { _T("F4"), KEY_F4 }, - { _T("F5"), KEY_F5 }, - { _T("F6"), KEY_F6 }, - { _T("F7"), KEY_F7 }, - { _T("F8"), KEY_F8 }, - { _T("F9"), KEY_F9 }, - { _T("F10"), KEY_F10 }, - { _T("F11"), KEY_F11 }, - { _T("F12"), KEY_F12 }, + { "APP1", KEY_APP1 }, + { "APP2", KEY_APP2 }, + { "APP3", KEY_APP3 }, + { "APP4", KEY_APP4 }, + { "APP5", KEY_APP5 }, + { "APP6", KEY_APP6 }, + { "F1", KEY_F1 }, + { "F2", KEY_F2 }, + { "F3", KEY_F3 }, + { "F4", KEY_F4 }, + { "F5", KEY_F5 }, + { "F6", KEY_F6 }, + { "F7", KEY_F7 }, + { "F8", KEY_F8 }, + { "F9", KEY_F9 }, + { "F10", KEY_F10 }, + { "F11", KEY_F11 }, + { "F12", KEY_F12 }, #ifdef ANDROID /* These keys are used by BlueTooth keypads and available in Android*/ - { _T("BUTTON_R1"), KEYCODE_BUTTON_R1}, - { _T("BUTTON_R2"), KEYCODE_BUTTON_R2}, - { _T("BUTTON_L1"), KEYCODE_BUTTON_L1}, - { _T("BUTTON_L2"), KEYCODE_BUTTON_L2}, - { _T("BUTTON_A"), KEYCODE_BUTTON_A}, - { _T("BUTTON_B"), KEYCODE_BUTTON_B}, - { _T("BUTTON_C"), KEYCODE_BUTTON_C}, - { _T("BUTTON_X"), KEYCODE_BUTTON_X}, - { _T("BUTTON_Y"), KEYCODE_BUTTON_Y}, - { _T("BUTTON_Z"), KEYCODE_BUTTON_Z}, - { _T("MEDIA_NEXT"), KEYCODE_MEDIA_NEXT}, - { _T("MEDIA_PREVIOUS"), KEYCODE_MEDIA_PREVIOUS}, - { _T("MEDIA_PLAY_PAUSE"), KEYCODE_MEDIA_PLAY_PAUSE}, - { _T("VOLUME_UP"), KEY_VOLUME_UP }, - { _T("VOLUME_DOWN"), KEY_VOLUME_DOWN }, + { "BUTTON_R1", KEYCODE_BUTTON_R1}, + { "BUTTON_R2", KEYCODE_BUTTON_R2}, + { "BUTTON_L1", KEYCODE_BUTTON_L1}, + { "BUTTON_L2", KEYCODE_BUTTON_L2}, + { "BUTTON_A", KEYCODE_BUTTON_A}, + { "BUTTON_B", KEYCODE_BUTTON_B}, + { "BUTTON_C", KEYCODE_BUTTON_C}, + { "BUTTON_X", KEYCODE_BUTTON_X}, + { "BUTTON_Y", KEYCODE_BUTTON_Y}, + { "BUTTON_Z", KEYCODE_BUTTON_Z}, + { "MEDIA_NEXT", KEYCODE_MEDIA_NEXT}, + { "MEDIA_PREVIOUS", KEYCODE_MEDIA_PREVIOUS}, + { "MEDIA_PLAY_PAUSE", KEYCODE_MEDIA_PLAY_PAUSE}, + { "VOLUME_UP", KEY_VOLUME_UP }, + { "VOLUME_DOWN", KEY_VOLUME_DOWN }, #endif #ifdef USE_WINUSER /* These Keys are used for the Triadis-RemoteStick, as well as for expanded Keyboard-Events */ - { _T("F13"), KEY_F13 }, - { _T("F14"), KEY_F14 }, - { _T("F15"), KEY_F15 }, - { _T("F16"), KEY_F16 }, - { _T("F17"), KEY_F17 }, - { _T("F18"), KEY_F18 }, - { _T("F19"), KEY_F19 }, - { _T("F20"), KEY_F20 }, + { "F13", KEY_F13 }, + { "F14", KEY_F14 }, + { "F15", KEY_F15 }, + { "F16", KEY_F16 }, + { "F17", KEY_F17 }, + { "F18", KEY_F18 }, + { "F19", KEY_F19 }, + { "F20", KEY_F20 }, #endif - { _T("LEFT"), KEY_LEFT }, - { _T("RIGHT"), KEY_RIGHT }, - { _T("UP"), KEY_UP }, - { _T("DOWN"), KEY_DOWN }, - { _T("RETURN"), KEY_RETURN }, - { _T("ESCAPE"), KEY_ESCAPE }, - { _T("MENU"), KEY_MENU }, - { _T("TAB"), KEY_TAB }, + { "LEFT", KEY_LEFT }, + { "RIGHT", KEY_RIGHT }, + { "UP", KEY_UP }, + { "DOWN", KEY_DOWN }, + { "RETURN", KEY_RETURN }, + { "ESCAPE", KEY_ESCAPE }, + { "MENU", KEY_MENU }, + { "TAB", KEY_TAB }, { NULL } }; unsigned -ParseKeyCode(const TCHAR *data) +ParseKeyCode(const char *data) { for (const struct string_to_key *p = &string_to_key[0]; p->name != NULL; ++p) if (StringIsEqual(data, p->name)) diff --git a/src/Input/InputKeys.hpp b/src/Input/InputKeys.hpp index 74e3484f4ae..789986dca3c 100644 --- a/src/Input/InputKeys.hpp +++ b/src/Input/InputKeys.hpp @@ -7,4 +7,4 @@ [[gnu::pure]] unsigned -ParseKeyCode(const TCHAR *data); +ParseKeyCode(const char *data); diff --git a/src/Input/InputLookup.cpp b/src/Input/InputLookup.cpp index 755e8bfb60b..1a51f7006ff 100644 --- a/src/Input/InputLookup.cpp +++ b/src/Input/InputLookup.cpp @@ -8,7 +8,7 @@ // Mapping text names of events to the real thing struct Text2EventSTRUCT { - const TCHAR *text; + const char *text; pt2Event event; }; @@ -18,19 +18,19 @@ static constexpr Text2EventSTRUCT Text2Event[] = { }; // Mapping text names of events to the real thing -static const TCHAR *const Text2GCE[] = { +static const char *const Text2GCE[] = { #include "InputEvents_Text2GCE.cpp" nullptr }; // Mapping text names of events to the real thing -static const TCHAR *const Text2NE[] = { +static const char *const Text2NE[] = { #include "InputEvents_Text2NE.cpp" nullptr }; pt2Event -InputEvents::findEvent(tstring_view name) noexcept +InputEvents::findEvent(std::string_view name) noexcept { for (unsigned i = 0; Text2Event[i].text != nullptr; ++i) if (name == Text2Event[i].text) @@ -40,7 +40,7 @@ InputEvents::findEvent(tstring_view name) noexcept } int -InputEvents::findGCE(const TCHAR *data) +InputEvents::findGCE(const char *data) { int i; for (i = 0; i < GCE_COUNT; i++) { @@ -52,7 +52,7 @@ InputEvents::findGCE(const TCHAR *data) } int -InputEvents::findNE(const TCHAR *data) +InputEvents::findNE(const char *data) { int i; for (i = 0; i < NE_COUNT; i++) { diff --git a/src/Input/InputLookup.hpp b/src/Input/InputLookup.hpp index 8eba86c7144..87b5dd98c1b 100644 --- a/src/Input/InputLookup.hpp +++ b/src/Input/InputLookup.hpp @@ -3,22 +3,22 @@ #pragma once -#include "util/tstring_view.hxx" +#include #include -typedef void (*pt2Event)(const TCHAR *); +typedef void (*pt2Event)(const char *); namespace InputEvents { [[gnu::pure]] -int findGCE(const TCHAR *data); +int findGCE(const char *data); [[gnu::pure]] -int findNE(const TCHAR *data); +int findNE(const char *data); [[gnu::pure]] pt2Event -findEvent(tstring_view name) noexcept; +findEvent(std::string_view name) noexcept; } // namespace InputEvents diff --git a/src/Input/InputParser.cpp b/src/Input/InputParser.cpp index a6205479135..118c7133b3e 100644 --- a/src/Input/InputParser.cpp +++ b/src/Input/InputParser.cpp @@ -26,7 +26,7 @@ parse_assignment(char *buffer, const char *&key, const char *&value) if (separator == NULL || separator == buffer) return false; - *separator = _T('\0'); + *separator = '\0'; key = buffer; value = separator + 1; @@ -59,7 +59,7 @@ struct EventBuilder { // General errors - these should be true assert(location < 1024); - const TCHAR *new_label = NULL; + const char *new_label = NULL; // For each mode for (const auto token : TIterableSplitString(mode.c_str(), ' ')) { @@ -69,7 +69,7 @@ struct EventBuilder { // All modes are valid at this point int mode_id = config.MakeMode(token); if (mode_id < 0) { - LogFormat(_T("Too many modes: %.*s at %u"), + LogFormat("Too many modes: %.*s at %u", int(token.size()), token.data(), line); continue; } @@ -87,34 +87,34 @@ struct EventBuilder { // Make key (Keyboard input) // key - Hardware key or keyboard - if (type.equals(_T("key"))) { + if (type.equals("key")) { // Get the int key (eg: APP1 vs 'a') unsigned key = ParseKeyCode(data); if (key > 0) config.SetKeyEvent(mode_id, key, event_id); else - LogFormat(_T("Invalid key data: %s at %u"), data.c_str(), line); + LogFormat("Invalid key data: %s at %u", data.c_str(), line); // Make gce (Glide Computer Event) // GCE - Glide Computer Event - } else if (type.equals(_T("gce"))) { + } else if (type.equals("gce")) { // Get the int key (eg: APP1 vs 'a') int key = InputEvents::findGCE(data); if (key >= 0) config.GC2Event[key] = event_id; else - LogFormat(_T("Invalid GCE data: %s at %u"), data.c_str(), line); + LogFormat("Invalid GCE data: %s at %u", data.c_str(), line); // Make gesture (Gesture Event) // Key - Key Event - } else if (type.equals(_T("gesture"))) { + } else if (type.equals("gesture")) { // Check data for invalid characters: bool valid = true; - for (const TCHAR* c = data; *c; c++) - if (*c != _T('U') && - *c != _T('D') && - *c != _T('R') && - *c != _T('L')) + for (const char* c = data; *c; c++) + if (*c != 'U' && + *c != 'D' && + *c != 'R' && + *c != 'L') valid = false; if (valid) { @@ -122,24 +122,24 @@ struct EventBuilder { config.Gesture2Event.Remove(data.c_str()); config.Gesture2Event.Add(data.c_str(), event_id); } else - LogFormat(_T("Invalid gesture data: %s at %u"), data.c_str(), line); + LogFormat("Invalid gesture data: %s at %u", data.c_str(), line); // Make ne (NMEA Event) // NE - NMEA Event - } else if (type.equals(_T("ne"))) { + } else if (type.equals("ne")) { // Get the int key (eg: APP1 vs 'a') int key = InputEvents::findNE(data); if (key >= 0) config.N2Event[key] = event_id; else - LogFormat(_T("Invalid GCE data: %s at %u"), data.c_str(), line); + LogFormat("Invalid GCE data: %s at %u", data.c_str(), line); // label only - no key associated (label can still be touch screen) - } else if (type.equals(_T("label"))) { + } else if (type.equals("label")) { // Nothing to do here... } else { - LogFormat(_T("Invalid type: %s at %u"), type.c_str(), line); + LogFormat("Invalid type: %s at %u", type.c_str(), line); } } } @@ -206,7 +206,7 @@ ParseInputFile(InputConfig &config, BufferedReader &reader) continue; } - TCHAR *allocated = UnescapeBackslash(string_converter.Convert(d_misc)); + char *allocated = UnescapeBackslash(string_converter.Convert(d_misc)); current.event_id = config.AppendEvent(event, allocated, current.event_id); diff --git a/src/Input/InputQueue.hpp b/src/Input/InputQueue.hpp index 9a15f306b88..8439de0216d 100644 --- a/src/Input/InputQueue.hpp +++ b/src/Input/InputQueue.hpp @@ -5,7 +5,7 @@ #include -typedef void (*pt2Event)(const TCHAR *); +typedef void (*pt2Event)(const char *); namespace InputEvents { diff --git a/src/Job/Async.cpp b/src/Job/Async.cpp index ddab9c4617e..7004c38d7a6 100644 --- a/src/Job/Async.cpp +++ b/src/Job/Async.cpp @@ -49,6 +49,7 @@ AsyncJobRunner::Wait() Thread::Join(); delete env; + env = nullptr; if (exception) /* rethrow the exception that was thrown by Job::Run() in the @@ -75,8 +76,7 @@ AsyncJobRunner::Run() noexcept the calling thread in Wait() */ exception = std::current_exception(); } - - if (notify != NULL && !env->IsCancelled()) + if (notify != nullptr && env != nullptr && !env->IsCancelled()) notify->SendNotification(); running.store(false, std::memory_order_relaxed); diff --git a/src/Job/CMakeLists.txt b/src/Job/CMakeLists.txt new file mode 100644 index 00000000000..3af8562c849 --- /dev/null +++ b/src/Job/CMakeLists.txt @@ -0,0 +1,51 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +target_link_libraries(${TARGET_NAME} PUBLIC Operation) + +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/Job/CMakeSource.cmake b/src/Job/CMakeSource.cmake new file mode 100644 index 00000000000..6a6752ebcde --- /dev/null +++ b/src/Job/CMakeSource.cmake @@ -0,0 +1,8 @@ +set(_SOURCES + Job/Async.cpp + Job/Thread.cpp +) +set(SCRIPT_FILES + CMakeSource.cmake +) + diff --git a/src/Kobo/CMakeLists.txt b/src/Kobo/CMakeLists.txt new file mode 100644 index 00000000000..12c12f37ec8 --- /dev/null +++ b/src/Kobo/CMakeLists.txt @@ -0,0 +1,55 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + set(TARGET_NAME ${TARGET_FOLDER}) + +include(CMakeSource.cmake) +# organize the files in subdirectories +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_FOLDER}/" "" source_file ${source_file}) + string(REPLACE "${PROJECTGROUP_SOURCE_DIR}/" "../../" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_compile_definitions("OPENVARIO_DEVICE") +add_compile_definitions("IS_OPENVARIO") + +add_executable(${TARGET_NAME} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) + # message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +target_link_libraries(${TARGET_NAME} PUBLIC ${OPENVARIOBASEMENU_LIBS}) +# add_dependencies(${TARGET_NAME} util Data) diff --git a/src/Kobo/CMakeSource.cmake b/src/Kobo/CMakeSource.cmake new file mode 100644 index 00000000000..efbd84e5443 --- /dev/null +++ b/src/Kobo/CMakeSource.cmake @@ -0,0 +1,52 @@ +set(TEST_SRC_DIR "${PROJECTGROUP_SOURCE_DIR}/test/src") + +set(_SOURCES + Kobo/WifiDialog.cpp + Kobo/WPASupplicant.cpp +) +set (KOBO_MENU_SOURCES + ${SRC}/Kobo/WPASupplicant.cpp + ${SRC}/Kobo/System.cpp + ${SRC}/Kobo/Kernel.cpp + ${SRC}/Kobo/NetworkDialog.cpp + ${SRC}/Kobo/SystemDialog.cpp + ${SRC}/Kobo/ToolsDialog.cpp + ${SRC}/Kobo/WPASupplicant.cpp + ${SRC}/Kobo/WifiDialog.cpp + ${SRC}/Kobo/FakeSymbols.cpp + ${SRC}/Kobo/KoboMenu.cpp +) +list (APPEND KOBO_MENU_SOURCES + ${SRC}/Version.cpp + ${SRC}/Asset.cpp + ${SRC}/Formatter/HexColor.cpp + ${SRC}/Hardware/CPU.cpp + ${SRC}/Hardware/DisplayDPI.cpp + ${SRC}/Hardware/RotateDisplay.cpp + ${SRC}/Screen/Layout.cpp + ${SRC}/ui/control/TerminalWindow.cpp + ${SRC}/Look/TerminalLook.cpp + ${SRC}/Look/DialogLook.cpp + ${SRC}/Look/ButtonLook.cpp + ${SRC}/Look/CheckBoxLook.cpp + ${SRC}/Renderer/TwoTextRowsRenderer.cpp + ${SRC}/Gauge/LogoView.cpp + ${SRC}/Dialogs/DialogSettings.cpp + ${SRC}/Dialogs/WidgetDialog.cpp + ${SRC}/Dialogs/HelpDialog.cpp + ${SRC}/Dialogs/Message.cpp + ${SRC}/Dialogs/Error.cpp + ${SRC}/Dialogs/LockScreen.cpp + ${SRC}/Dialogs/TextEntry.cpp + ${SRC}/Dialogs/KnobTextEntry.cpp + ${SRC}/Dialogs/TouchTextEntry.cpp + ${SRC}/Dialogs/SimulatorPromptWindow.cpp + ${TEST_SRC_DIR}/Fonts.cpp + ${TEST_SRC_DIR}/FakeLanguage.cpp + ${TEST_SRC_DIR}/FakeLogFile.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake + ../../build/kobo.mk +) diff --git a/src/Kobo/FakeSymbols.cpp b/src/Kobo/FakeSymbols.cpp index 306bc7f9ac8..fb2b892af17 100644 --- a/src/Kobo/FakeSymbols.cpp +++ b/src/Kobo/FakeSymbols.cpp @@ -5,8 +5,8 @@ #include "Dialogs/DataField.hpp" bool -EditDataFieldDialog([[maybe_unused]] const TCHAR *caption, [[maybe_unused]] DataField &df, - [[maybe_unused]] const TCHAR *help_text) +EditDataFieldDialog([[maybe_unused]] const char *caption, [[maybe_unused]] DataField &df, + [[maybe_unused]] const char *help_text) { return false; } diff --git a/src/Kobo/KoboMenu.cpp b/src/Kobo/KoboMenu.cpp index 93f2ecfd730..abeedd1d5ae 100644 --- a/src/Kobo/KoboMenu.cpp +++ b/src/Kobo/KoboMenu.cpp @@ -140,7 +140,7 @@ Main() main_style.Resizable(); UI::SingleWindow main_window{screen_init.GetDisplay()}; - main_window.Create(_T("XCSoar/KoboMenu"), {600, 800}, main_style); + main_window.Create("XCSoar/KoboMenu", {600, 800}, main_style); main_window.Show(); global_dialog_look = &dialog_look; diff --git a/src/Kobo/NetworkDialog.cpp b/src/Kobo/NetworkDialog.cpp index 556787ab94d..44a5cd52d78 100644 --- a/src/Kobo/NetworkDialog.cpp +++ b/src/Kobo/NetworkDialog.cpp @@ -12,10 +12,10 @@ #include "System.hpp" [[gnu::pure]] -static const TCHAR * +static const char * GetWifiToggleCaption() { - return IsKoboWifiOn() ? _T("Wifi OFF") : _T("Wifi ON"); + return IsKoboWifiOn() ? "Wifi OFF" : "Wifi ON"; } class NetworkWidget final @@ -58,9 +58,9 @@ NetworkWidget::Prepare([[maybe_unused]] ContainerWindow &parent, [[maybe_unused] wifi_button = AddButton(_("Wifi"), [](){ ShowWifiDialog(); }); - AddButton(_T("Telnet server"), [](){ KoboRunTelnetd(); }); + AddButton("Telnet server", [](){ KoboRunTelnetd(); }); - AddButton(_T("Ftp server"), [](){ KoboRunFtpd(); }); + AddButton("Ftp server", [](){ KoboRunFtpd(); }); UpdateButtons(); } diff --git a/src/Kobo/PowerOff.cpp b/src/Kobo/PowerOff.cpp index 1cfbdc3326d..2fe0793b68c 100644 --- a/src/Kobo/PowerOff.cpp +++ b/src/Kobo/PowerOff.cpp @@ -54,26 +54,26 @@ DrawBanner(Canvas &canvas, PixelRect &rc) const int name_y = rc.top + (banner_height - large_font.GetHeight()) / 2; - const TCHAR *const name1 = _T("XC"); + const char *const name1 = "XC"; canvas.DrawText({x, name_y}, name1); x += canvas.CalcTextWidth(name1); - const TCHAR *const name2 = _T("Soar"); + const char *const name2 = "Soar"; canvas.SetTextColor(COLOR_GRAY); canvas.DrawText({x, name_y}, name2); canvas.SetTextColor(COLOR_BLACK); x += canvas.CalcTextWidth(name2) + 30; /* some more text */ - const TCHAR *const website = _T("www.xcsoar.org"); + const char *const website = "www.xcsoar.org"; canvas.Select(normal_font); canvas.DrawText({x, rc.top + int(banner_height - normal_font.GetHeight()) / 2}, website); - TCHAR comment[30] = _T("powered off"); + char comment[30] = "powered off"; const auto power_info = Power::GetInfo(); if (power_info.battery.remaining_percent) { - snprintf ( comment+strlen(comment), 30-strlen(comment), _T(" - battery %d%%"), *power_info.battery.remaining_percent); + snprintf ( comment+strlen(comment), 30-strlen(comment), " - battery %d%%", *power_info.battery.remaining_percent); } canvas.DrawText({rc.right - (int)canvas.CalcTextWidth(comment) - padding, rc.top + padding}, diff --git a/src/Kobo/SystemDialog.cpp b/src/Kobo/SystemDialog.cpp index a5719dfa92b..1b984c400fe 100644 --- a/src/Kobo/SystemDialog.cpp +++ b/src/Kobo/SystemDialog.cpp @@ -107,7 +107,7 @@ SystemWidget::SwitchOTGMode() switch_otg_mode->SetCaption("Enable USB-OTG"); usb_storage->SetEnabled(true); } else { - ShowMessageBox(_T("Failed to switch OTG mode."), _("Error"), MB_OK); + ShowMessageBox("Failed to switch OTG mode.", _("Error"), MB_OK); } } else { success = File::WriteExisting(Path("/sys/kernel/debug/ci_hdrc.0/role"), @@ -119,7 +119,7 @@ SystemWidget::SwitchOTGMode() switch_otg_mode->SetCaption("Disable USB-OTG"); usb_storage->SetEnabled(false); } else { - ShowMessageBox(_T("Failed to switch OTG mode."), _("Error"), MB_OK); + ShowMessageBox("Failed to switch OTG mode.", _("Error"), MB_OK); } } } else { @@ -138,8 +138,8 @@ SystemWidget::SwitchKernel() model != KoboModel::TOUCH2 && model != KoboModel::GLO_HD && model != KoboModel::AURA2 && - ShowMessageBox(_T("This feature was designed for the Kobo Mini, Touch 2.0, Glo HD and Aura 2, but this is not one. Use at your own risk. Continue?"), - _T("USB-OTG"), MB_YESNO) != IDYES) + ShowMessageBox("This feature was designed for the Kobo Mini, Touch 2.0, Glo HD and Aura 2, but this is not one. Use at your own risk. Continue?", + "USB-OTG", MB_YESNO) != IDYES) return; const char *otg_kernel_image, *kobo_kernel_image; @@ -166,7 +166,7 @@ SystemWidget::SwitchKernel() : otg_kernel_image; if (!KoboInstallKernel(kernel_image)) { - ShowMessageBox(_T("Failed to activate kernel."), _("Error"), MB_OK); + ShowMessageBox("Failed to activate kernel.", _("Error"), MB_OK); return; } @@ -178,20 +178,20 @@ inline void SystemWidget::ExportUSBStorage() { if (!KoboUmountData()) { - ShowMessageBox(_T("Failed to unmount data partition."), _("Error"), + ShowMessageBox("Failed to unmount data partition.", _("Error"), MB_OK); return; } if (!KoboExportUSBStorage()) { - ShowMessageBox(_T("Failed to export data partition."), _("Error"), + ShowMessageBox("Failed to export data partition.", _("Error"), MB_OK); KoboMountData(); return; } - ShowMessageBox(_T("Your PC has now access to the data partition until you close this dialog."), - _T("Export USB storage"), + ShowMessageBox("Your PC has now access to the data partition until you close this dialog.", + "Export USB storage", MB_OK); KoboUnexportUSBStorage(); diff --git a/src/Kobo/ToolsDialog.cpp b/src/Kobo/ToolsDialog.cpp index 9e12d2f1983..1861ac56351 100644 --- a/src/Kobo/ToolsDialog.cpp +++ b/src/Kobo/ToolsDialog.cpp @@ -18,7 +18,7 @@ struct ListItem StaticString<32> name; AllocatedPath path; - ListItem(const TCHAR *_name, Path _path) + ListItem(const char *_name, Path _path) :name(_name), path(_path) {} bool operator<(const ListItem &i2) const { @@ -59,7 +59,7 @@ void ToolsWidget::Prepare([[maybe_unused]] ContainerWindow &parent, [[maybe_unused]] const PixelRect &rc) noexcept { ScriptFileVisitor sfv(list); - Directory::VisitFiles(Path(_T("/mnt/onboard/XCSoarData/kobo/scripts")), sfv); + Directory::VisitFiles(Path("/mnt/onboard/XCSoarData/kobo/scripts"), sfv); unsigned len = list.size(); if (len > 0) diff --git a/src/Kobo/WifiDialog.cpp b/src/Kobo/WifiDialog.cpp index 04f1da20a1c..928b0c40bd0 100644 --- a/src/Kobo/WifiDialog.cpp +++ b/src/Kobo/WifiDialog.cpp @@ -175,7 +175,7 @@ WifiListWidget::OnPaintItem(Canvas &canvas, const PixelRect rc, row_renderer.DrawFirstRow(canvas, rc, info.ssid); row_renderer.DrawSecondRow(canvas, rc, info.bssid); - const TCHAR *state = nullptr; + const char *state = nullptr; StaticString<40> state_buffer; /* found the currently connected wifi network? */ @@ -187,7 +187,7 @@ WifiListWidget::OnPaintItem(Canvas &canvas, const PixelRect rc, if (addr.IsDefined()) { /* valid address? */ StaticString<40> addr_str; if (addr.ToString(addr_str.buffer(), addr_str.capacity()) != nullptr) { - state_buffer.Format(_T("%s (%s)"), state, addr_str.c_str()); + state_buffer.Format("%s (%s)", state, addr_str.c_str()); state = state_buffer; } } @@ -204,7 +204,7 @@ WifiListWidget::OnPaintItem(Canvas &canvas, const PixelRect rc, if (info.signal_detected) { StaticString<36> text; - text.UnsafeFormat(signal_level_in_dbm ? _T("%s %d dBm") : _T("%s %d"), + text.UnsafeFormat(signal_level_in_dbm ? "%s %d dBm" : "%s %d", wifi_security[info.security], info.signal_level); row_renderer.DrawRightSecondRow(canvas, rc, text); } diff --git a/src/Language/CMakeLists.txt b/src/Language/CMakeLists.txt new file mode 100644 index 00000000000..51bd6733971 --- /dev/null +++ b/src/Language/CMakeLists.txt @@ -0,0 +1,43 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories + +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if(MSVC) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +if(MSVC) + source_group("Script Files" FILES ${SCRIPT_FILES}) +endif() + + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} + # _Deprecated files... +) + +target_link_libraries(${TARGET_NAME} PUBLIC Task system po-Files) # _Deprecated) + +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util Data po-Files) diff --git a/src/Language/CMakeSource.cmake b/src/Language/CMakeSource.cmake new file mode 100644 index 00000000000..62406e2425f --- /dev/null +++ b/src/Language/CMakeSource.cmake @@ -0,0 +1,12 @@ +set(_SOURCES + Language/Language.cpp + Language/LanguageGlue.cpp + Language/Table.cpp + Language/MOFile.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake + + ../../build/main.mk # Language in main.mk! +) diff --git a/src/Language/Language.cpp b/src/Language/Language.cpp index be0fbbb2c71..69f1cb1ff71 100644 --- a/src/Language/Language.cpp +++ b/src/Language/Language.cpp @@ -14,22 +14,10 @@ #else -#ifdef _UNICODE -#include -#endif - #include "MOFile.hpp" const MOFile *mo_file; -#ifdef _UNICODE -#include "util/Macros.hpp" -#include "util/tstring.hpp" -#include -typedef std::map translation_map; -static translation_map translations; -#endif - #ifndef NDEBUG static bool language_allowed = false; @@ -64,8 +52,8 @@ DisallowLanguage() * @param text The text to search for * @return The translation if found, otherwise the text itself */ -const TCHAR* -gettext(const TCHAR* text) +const char* +gettext(const char* text) { assert(language_allowed); assert(text != NULL); @@ -74,56 +62,22 @@ gettext(const TCHAR* text) if (StringIsEmpty(text) || mo_file == NULL) return text; -#ifdef _UNICODE - // Try to lookup the english string in the map of cached TCHAR translations - const tstring text2(text); - translation_map::const_iterator it = translations.find(text2); - if (it != translations.end()) - // Return the looked up translation - return it->second.c_str(); - - // Convert the english TCHAR string to char - char original[4096]; - - // If the conversion failed -> use the english original string - if (::WideCharToMultiByte(CP_UTF8, 0, text, -1, - original, sizeof(original), NULL, NULL) <= 0) - return text; - - // Lookup the converted english char string in the MO file - const char *translation = mo_file->lookup(original); - // If the lookup failed -> use the english original string - if (translation == NULL || *translation == 0 || - strcmp(original, translation) == 0) - return text; - - // Convert the translated char string to TCHAR - TCHAR translation2[4096]; - if (::MultiByteToWideChar(CP_UTF8, 0, translation, -1, translation2, - ARRAY_SIZE(translation2)) <= 0) - return text; - - // Add the translated TCHAR string to the cache map for the next time - translations[text2] = translation2; - - // Return the translated TCHAR string - return translations[text2].c_str(); -#else // Search for the english original string in the MO file const char *translation = mo_file->lookup(text); // Return either the translated string if found or the original - return translation != NULL && *translation != 0 && ValidateUTF8(translation) - ? translation - : text; +#if defined(_WIN32) + return translation != nullptr && *translation != 0 ? + translation : text; +#else + return translation != nullptr && *translation != 0 && + ValidateUTF8(translation) ? translation : text; #endif } +// Unicode rudiment(?): void reset_gettext_cache() { -#ifdef _UNICODE - translations.clear(); -#endif } #endif /* !HAVE_POSIX */ diff --git a/src/Language/Language.hpp b/src/Language/Language.hpp index 62747265a74..fa81b919947 100644 --- a/src/Language/Language.hpp +++ b/src/Language/Language.hpp @@ -36,13 +36,13 @@ void DisallowLanguage(); #endif [[gnu::const]] -const TCHAR* gettext(const TCHAR* text); +const char* gettext(const char* text); /** * For source compatibility with GNU gettext. */ -#define _(x) gettext(_T(x)) -#define N_(x) _T(x) +#define _(x) gettext(x) +#define N_(x) x void reset_gettext_cache(); diff --git a/src/Language/LanguageGlue.cpp b/src/Language/LanguageGlue.cpp index 39f447e1717..99a3703df77 100644 --- a/src/Language/LanguageGlue.cpp +++ b/src/Language/LanguageGlue.cpp @@ -64,7 +64,7 @@ FindLanguage(WORD language) noexcept [[gnu::pure]] static const BuiltinLanguage * -FindLanguage(const TCHAR *resource) noexcept +FindLanguage(const char *resource) noexcept { assert(resource != nullptr); @@ -174,7 +174,8 @@ DetectLanguage() noexcept static void InitNativeGettext(const char *locale) noexcept { - const char *const domain = "xcsoar"; +// const char *const domain = "xcsoar"; + const char *const domain = "opensoar"; // TODO(August2111) /* we want to get UTF-8 strings from gettext() */ bind_textdomain_codeset(domain, "utf8"); @@ -192,20 +193,20 @@ InitNativeGettext(const char *locale) noexcept static bool ReadBuiltinLanguage(const BuiltinLanguage &language) noexcept { - LogFormat(_T("Language: loading resource '%s'"), language.resource); + LogFormat("Language: loading resource '%s'", language.resource); #ifdef HAVE_BUILTIN_LANGUAGES // Load MO file from resource delete mo_loader; mo_loader = new MOLoader({language.begin, (size_t)language.size}); if (mo_loader->error()) { - LogFormat(_T("Language: could not load resource '%s'"), language.resource); + LogFormat("Language: could not load resource '%s'", language.resource); delete mo_loader; mo_loader = nullptr; return false; } - LogFormat(_T("Loaded translations from resource '%s'"), language.resource); + LogFormat("Loaded translations from resource '%s'", language.resource); mo_file = &mo_loader->get(); #else @@ -216,7 +217,7 @@ ReadBuiltinLanguage(const BuiltinLanguage &language) noexcept } static bool -ReadResourceLanguageFile(const TCHAR *resource) noexcept +ReadResourceLanguageFile(const char *resource) noexcept { auto language = FindLanguage(resource); return language != nullptr && ReadBuiltinLanguage(*language); @@ -241,7 +242,7 @@ static bool LoadLanguageFile([[maybe_unused]] Path path) noexcept { #ifdef HAVE_BUILTIN_LANGUAGES - LogFormat(_T("Language: loading file '%s'"), path.c_str()); + LogFormat("Language: loading file '%s'", path.c_str()); delete mo_loader; mo_loader = nullptr; @@ -249,7 +250,7 @@ LoadLanguageFile([[maybe_unused]] Path path) noexcept try { mo_loader = new MOLoader(path); if (mo_loader->error()) { - LogFormat(_T("Language: could not load file '%s'"), path.c_str()); + LogFormat("Language: could not load file '%s'", path.c_str()); delete mo_loader; mo_loader = nullptr; return false; @@ -259,7 +260,7 @@ LoadLanguageFile([[maybe_unused]] Path path) noexcept return false; } - LogFormat(_T("Loaded translations from file '%s'"), path.c_str()); + LogFormat("Loaded translations from file '%s'", path.c_str()); mo_file = &mo_loader->get(); return true; @@ -292,12 +293,12 @@ ReadLanguageFile() noexcept auto value = Profile::GetPath(ProfileKeys::LanguageFile); - if (value == nullptr || value.empty() || value == Path(_T("auto"))) { + if (value == nullptr || value.empty() || value == Path("auto")) { AutoDetectLanguage(); return; } - if (value == Path(_T("none"))) + if (value == Path("none")) return; Path base = value.GetBase(); diff --git a/src/Language/Table.cpp b/src/Language/Table.cpp index 926ad14847a..6ac2632cf8b 100644 --- a/src/Language/Table.cpp +++ b/src/Language/Table.cpp @@ -78,15 +78,15 @@ extern "C" } #ifdef _WIN32 -#define L(number, locale, code_name, display_name) { number, code_name ## _mo, code_name ## _mo_size, _T( #code_name ".mo"), _T(display_name) } +#define L(number, locale, code_name, display_name) { number, code_name ## _mo, code_name ## _mo_size, #code_name ".mo", display_name } #else -#define L(number, locale, code_name, display_name) { code_name ## _mo, code_name ## _mo_size, _T( #code_name ".mo"), _T(display_name) } +#define L(number, locale, code_name, display_name) { code_name ## _mo, code_name ## _mo_size, #code_name ".mo", display_name } #endif #endif // HAVE_BUILTIN_LANGUAGES #ifdef USE_LIBINTL -#define L(number, locale, code_name, display_name) { #locale ".UTF-8", _T( #code_name ".mo"), _T(display_name) } +#define L(number, locale, code_name, display_name) { #locale ".UTF-8", #code_name ".mo", display_name } #endif // USE_LIBINTL #ifdef _WIN32 diff --git a/src/Language/Table.hpp b/src/Language/Table.hpp index 865758d9e0a..32814d4512e 100644 --- a/src/Language/Table.hpp +++ b/src/Language/Table.hpp @@ -24,8 +24,8 @@ struct BuiltinLanguage { const std::byte *begin; size_t size; #endif - const TCHAR *resource; - const TCHAR *name; + const char *resource; + const char *name; }; extern const BuiltinLanguage language_table[]; diff --git a/src/LocalPath.cpp b/src/LocalPath.cpp index a97575e943f..7e4910455f1 100644 --- a/src/LocalPath.cpp +++ b/src/LocalPath.cpp @@ -20,7 +20,7 @@ #ifdef _WIN32 #include "system/PathName.hpp" #else -#include "util/tstring.hpp" +#include #endif #include @@ -39,7 +39,7 @@ #include #endif -#define XCSDATADIR "XCSoarData" +#define OPENSOAR_DATADIR "OpenSoarData" /** * This is the partition that the Kobo software mounts on PCs @@ -47,7 +47,7 @@ #define KOBO_USER_DATA "/mnt/onboard" /** - * A list of XCSoarData directories. The first one is the primary + * A list of OpenSoarData directories. The first one is the primary * one, where "%LOCAL_PATH%\\" refers to. */ static std::list data_paths; @@ -75,7 +75,7 @@ SetPrimaryDataPath(Path path) noexcept data_paths.emplace_front(path); #ifndef ANDROID - cache_path = LocalPath(_T("cache")); + cache_path = LocalPath("cache"); #endif } @@ -89,7 +89,7 @@ SetSingleDataPath(Path path) noexcept data_paths.emplace_front(path); #ifndef ANDROID - cache_path = LocalPath(_T("cache")); + cache_path = LocalPath("cache"); #endif } @@ -102,13 +102,13 @@ LocalPath(Path file) noexcept } AllocatedPath -LocalPath(const TCHAR *file) noexcept +LocalPath(const char *file) noexcept { return LocalPath(Path(file)); } AllocatedPath -MakeLocalPath(const TCHAR *name) +MakeLocalPath(const char *name) { auto path = LocalPath(name); Directory::Create(path); @@ -121,17 +121,17 @@ RelativePath(Path path) noexcept return path.RelativeTo(GetPrimaryDataPath()); } -static constexpr TCHAR local_path_code[] = _T("%LOCAL_PATH%\\"); +static constexpr char local_path_code[] = "%LOCAL_PATH%\\"; [[gnu::pure]] -static const TCHAR * -AfterLocalPathCode(const TCHAR *p) noexcept +static const char * +AfterLocalPathCode(const char *p) noexcept { p = StringAfterPrefix(p, local_path_code); if (p == nullptr) return nullptr; - while (*p == _T('/') || *p == _T('\\')) + while (*p == '/' || *p == '\\') ++p; if (StringIsEmpty(p)) @@ -144,13 +144,13 @@ AllocatedPath ExpandLocalPath(Path src) noexcept { // Get the relative file name and location (ptr) - const TCHAR *ptr = AfterLocalPathCode(src.c_str()); + const char *ptr = AfterLocalPathCode(src.c_str()); if (ptr == nullptr) return src; #ifndef _WIN32 // Convert backslashes to slashes on platforms where it matters - tstring src2(ptr); + std::string src2(ptr); std::replace(src2.begin(), src2.end(), '\\', '/'); ptr = src2.c_str(); #endif @@ -174,17 +174,17 @@ ContractLocalPath(Path src) noexcept #ifdef _WIN32 /** - * Find a XCSoarData folder in the same location as the executable. + * Find a OpenSoarData folder in the same location as the executable. */ [[gnu::pure]] static AllocatedPath FindDataPathAtModule(HMODULE hModule) noexcept { - TCHAR buffer[MAX_PATH]; + char buffer[MAX_PATH]; if (GetModuleFileName(hModule, buffer, MAX_PATH) <= 0) return nullptr; - ReplaceBaseName(buffer, _T(XCSDATADIR)); + ReplaceBaseName(buffer, OPENSOAR_DATADIR); return Directory::Exists(Path(buffer)) ? AllocatedPath(buffer) : nullptr; @@ -197,9 +197,9 @@ FindDataPaths() noexcept { std::list result; - /* Kobo: hard-coded XCSoarData path */ + /* Kobo: hard-coded OpenSoarData path */ if constexpr (IsKobo()) { - result.emplace_back(_T(KOBO_USER_DATA DIR_SEPARATOR_S XCSDATADIR)); + result.emplace_back(KOBO_USER_DATA DIR_SEPARATOR_S OPENSOAR_DATADIR); return result; } @@ -209,18 +209,18 @@ FindDataPaths() noexcept const auto env = Java::GetEnv(); for (auto &path : context->GetExternalFilesDirs(env)) { - __android_log_print(ANDROID_LOG_DEBUG, "XCSoar", + __android_log_print(ANDROID_LOG_DEBUG, "OpenSoar", "Context.getExternalFilesDirs()='%s'", path.c_str()); result.emplace_back(std::move(path)); } if (auto path = Environment::GetExternalStoragePublicDirectory(env, - "XCSoarData"); + "OpenSoarData"); path != nullptr) { const bool writable = access(path.c_str(), W_OK) == 0; - __android_log_print(ANDROID_LOG_DEBUG, "XCSoar", + __android_log_print(ANDROID_LOG_DEBUG, "OpenSoar", "Environment.getExternalStoragePublicDirectory()='%s'%s", path.c_str(), writable ? "" : " (not accessible)"); @@ -238,22 +238,22 @@ FindDataPaths() noexcept } #ifdef _WIN32 - /* look for a XCSoarData directory in the same directory as - XCSoar.exe */ + /* look for a OpenSoarData directory in the same directory as + OpenSoar.exe */ if (auto path = FindDataPathAtModule(nullptr); path != nullptr) result.emplace_back(std::move(path)); - /* Windows: use "My Documents\XCSoarData" */ + /* Windows: use "My Documents\OpenSoarData" */ { - TCHAR buffer[MAX_PATH]; + char buffer[MAX_PATH]; if (SHGetSpecialFolderPath(nullptr, buffer, CSIDL_PERSONAL, result.empty())) - result.emplace_back(AllocatedPath::Build(buffer, _T(XCSDATADIR))); + result.emplace_back(AllocatedPath::Build(buffer, OPENSOAR_DATADIR)); } #endif // _WIN32 #ifdef HAVE_POSIX - /* on Unix, use ~/.xcsoar */ + /* on Unix, use ~/OpenSoarData too */ if (const char *home = getenv("HOME"); home != nullptr) { #ifdef __APPLE__ /* Mac OS X users are not used to dot-files in their home @@ -263,21 +263,21 @@ FindDataPaths() noexcept folder can also be accessed via iTunes, if UIFileSharingEnabled is set to YES in Info.plist */ #if (TARGET_OS_IPHONE) - constexpr const char *in_home = "Documents" XCSDATADIR; + constexpr const char *in_home = "Documents" OPENSOAR_DATADIR; #else - constexpr const char *in_home = XCSDATADIR; + constexpr const char *in_home = OPENSOAR_DATADIR; #endif #else // !APPLE - constexpr const char *in_home = ".xcsoar"; + constexpr const char *in_home = OPENSOAR_DATADIR; #endif result.emplace_back(AllocatedPath::Build(Path(home), in_home)); } #ifndef __APPLE__ - /* Linux (and others): allow global configuration in /etc/xcsoar */ - if (Directory::Exists(Path{"/etc/xcsoar"})) - result.emplace_back(Path{"/etc/xcsoar"}); + /* Linux (and others): allow global configuration in /etc/opensoar */ + if (Directory::Exists(Path{"/etc/opensoar"})) + result.emplace_back(Path{"/etc/opensoar"}); #endif // !APPLE #endif // HAVE_POSIX @@ -285,7 +285,7 @@ FindDataPaths() noexcept } void -VisitDataFiles(const TCHAR* filter, File::Visitor &visitor) +VisitDataFiles(const char* filter, File::Visitor &visitor) { for (const auto &i : data_paths) Directory::VisitSpecificFiles(i, filter, visitor, true); @@ -298,7 +298,7 @@ GetCachePath() noexcept } AllocatedPath -MakeCacheDirectory(const TCHAR *name) noexcept +MakeCacheDirectory(const char *name) noexcept { Directory::Create(cache_path); auto path = AllocatedPath::Build(cache_path, Path(name)); @@ -309,18 +309,19 @@ MakeCacheDirectory(const TCHAR *name) noexcept void InitialiseDataPath() { - data_paths = FindDataPaths(); - if (data_paths.empty()) - throw std::runtime_error("No data path found"); - + if (data_paths.empty()) { + data_paths = FindDataPaths(); + if (data_paths.empty()) + throw std::runtime_error("No data path found"); + } + // TODO: delete the old cache directory in OpenSoarData? #ifdef ANDROID cache_path = context->GetExternalCacheDir(Java::GetEnv()); if (cache_path == nullptr) throw std::runtime_error("No Android cache directory"); - // TODO: delete the old cache directory in XCSoarData? #else - cache_path = LocalPath(_T("cache")); + cache_path = LocalPath("cache"); #endif } diff --git a/src/LocalPath.hpp b/src/LocalPath.hpp index 1daf82c40c0..f97eca715b1 100644 --- a/src/LocalPath.hpp +++ b/src/LocalPath.hpp @@ -63,13 +63,13 @@ AllocatedPath LocalPath(Path file) noexcept; AllocatedPath -LocalPath(const TCHAR *file) noexcept; +LocalPath(const char *file) noexcept; /** * Create a subdirectory of XCSoarData and return its absolute path. */ AllocatedPath -MakeLocalPath(const TCHAR *name); +MakeLocalPath(const char *name); /** * Return the portion of the specified path that is relative to the @@ -99,7 +99,7 @@ ExpandLocalPath(Path src) noexcept; AllocatedPath ContractLocalPath(Path src) noexcept; -void VisitDataFiles(const TCHAR* filter, File::Visitor &visitor); +void VisitDataFiles(const char* filter, File::Visitor &visitor); [[gnu::pure]] Path @@ -107,4 +107,4 @@ GetCachePath() noexcept; [[gnu::pure]] AllocatedPath -MakeCacheDirectory(const TCHAR *name) noexcept; +MakeCacheDirectory(const char *name) noexcept; diff --git a/src/LogFile.cpp b/src/LogFile.cpp index f3efa5c3eff..6a1dfeb168d 100644 --- a/src/LogFile.cpp +++ b/src/LogFile.cpp @@ -12,10 +12,12 @@ #include "system/FileUtil.hpp" #include "io/UniqueFileDescriptor.hxx" #include "util/Exception.hxx" +#include "util/StaticString.hxx" #include -#include +#include +// #include // Unicode??? #include #include @@ -26,6 +28,10 @@ #include #endif +#ifdef IS_OPENVARIO +# include "OpenVario/System/OpenVarioDevice.hpp" +#endif + static FileOutputStream OpenLog() { @@ -34,13 +40,19 @@ OpenLog() if (!initialised) { initialised = true; + + /* Unfortunately on program start the LocalPath pointed to the 'standard' + * local path - and not to the user local path set with the caller argument + * '-datapath=' + * A handler for this is possible but make the management much complicated! + */ + path = LocalPath("OpenSoar"); /* delete the obsolete log file */ - File::Delete(LocalPath(_T("xcsoar-startup.log"))); - - path = LocalPath(_T("xcsoar.log")); - - File::Replace(path, LocalPath(_T("xcsoar-old.log"))); + File::Delete(path + "-startup.log"); + auto back_path = path + "-old.log"; + path = path + ".log"; + File::Replace(path, back_path); #ifdef ANDROID /* redirect stdout/stderr to xcsoar-startup.log on Android so we @@ -61,7 +73,7 @@ void LogString(std::string_view s) noexcept { #ifdef ANDROID - __android_log_print(ANDROID_LOG_INFO, "XCSoar", "%.*s", + __android_log_print(ANDROID_LOG_INFO, "OpenSoar", "%.*s", int(s.size()), s.data()); #elif defined(HAVE_POSIX) && !defined(NDEBUG) fprintf(stderr, "%.*s\n", @@ -115,48 +127,6 @@ LogFormat(const char *fmt, ...) noexcept LogString(buf); } -#ifdef _UNICODE - -static void -LogString(std::wstring_view s) noexcept -{ - try { - auto fos = OpenLog(); - BufferedOutputStream bos{fos}; - - bos.Write('['); - - { - char time_buffer[32]; - FormatISO8601(time_buffer, BrokenDateTime::NowUTC()); - bos.Write(time_buffer); - } - - bos.Write("] "); - bos.Write(s); - bos.NewLine(); - - bos.Flush(); - fos.Commit(); - } catch (...) { - } -} - -void -LogFormat(const wchar_t *Str, ...) noexcept -{ - wchar_t buf[MAX_PATH]; - va_list ap; - - va_start(ap, Str); - std::vswprintf(buf, std::size(buf), Str, ap); - va_end(ap); - - LogString(buf); -} - -#endif - void LogError(std::exception_ptr e) noexcept { diff --git a/src/LogFile.hpp b/src/LogFile.hpp index afc1422c2d9..38ff25991b4 100644 --- a/src/LogFile.hpp +++ b/src/LogFile.hpp @@ -13,10 +13,6 @@ #include #include -#ifdef _UNICODE -#include -#endif - void LogVFmt(fmt::string_view format_str, fmt::format_args args) noexcept; @@ -53,11 +49,6 @@ gcc_printf(1, 2) void LogFormat(const char *fmt, ...) noexcept; -#ifdef _UNICODE -void -LogFormat(const wchar_t *fmt, ...) noexcept; -#endif - #if !defined(NDEBUG) #define LogDebug(...) LogFmt(__VA_ARGS__) diff --git a/src/Logger/CMakeLists.txt b/src/Logger/CMakeLists.txt new file mode 100644 index 00000000000..5806b6215d4 --- /dev/null +++ b/src/Logger/CMakeLists.txt @@ -0,0 +1,52 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) + +target_link_libraries(${TARGET_NAME} PUBLIC IGC Formatter util io) + +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/Logger/CMakeSource.cmake b/src/Logger/CMakeSource.cmake new file mode 100644 index 00000000000..7f1c95ca233 --- /dev/null +++ b/src/Logger/CMakeSource.cmake @@ -0,0 +1,16 @@ +set(_SOURCES + Logger/ExternalLogger.cpp + Logger/FlightLogger.cpp + Logger/GlueFlightLogger.cpp + Logger/GRecord.cpp + Logger/Logger.cpp + Logger/LoggerEPE.cpp + Logger/LoggerFRecord.cpp + Logger/LoggerImpl.cpp + Logger/NMEALogger.cpp + Logger/Settings.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake +) diff --git a/src/Logger/ExternalLogger.cpp b/src/Logger/ExternalLogger.cpp index 415c5b5fbaa..cde81a08c85 100644 --- a/src/Logger/ExternalLogger.cpp +++ b/src/Logger/ExternalLogger.cpp @@ -52,7 +52,7 @@ DoDeviceDeclare(DeviceDescriptor &device, const Declaration &declaration, { TriStateJob job(device, declaration, home); JobDialog(UIGlobals::GetMainWindow(), UIGlobals::GetDialogLook(), - _T(""), job, true); + "", job, true); return job.GetResult(); } @@ -73,7 +73,7 @@ try { MessageOperationEnvironment env; const ScopeReturnDevice return_device{dev, env}; - const TCHAR *caption = dev.GetDisplayName(); + const char *caption = dev.GetDisplayName(); if (caption == nullptr) caption = _("Declare task"); @@ -142,7 +142,7 @@ DoReadFlightList(DeviceDescriptor &device, RecordedFlightList &flight_list) { TriStateJob job(device, flight_list); JobDialog(UIGlobals::GetMainWindow(), UIGlobals::GetDialogLook(), - _T(""), job, true); + "", job, true); return job.GetResult(); } @@ -167,7 +167,7 @@ DoDownloadFlight(DeviceDescriptor &device, { TriStateJob job(device, flight, path); JobDialog(UIGlobals::GetMainWindow(), UIGlobals::GetDialogLook(), - _T(""), job, true); + "", job, true); return job.GetResult(); } @@ -222,7 +222,7 @@ ShowFlightList(const RecordedFlightList &flight_list) const RecordedFlightInfo &flight = flight_list[i]; StaticString<64> buffer; - buffer.UnsafeFormat(_T("%04u/%02u/%02u %02u:%02u-%02u:%02u"), + buffer.UnsafeFormat("%04u/%02u/%02u %02u:%02u-%02u:%02u", flight.date.year, flight.date.month, flight.date.day, flight.start_time.hour, flight.start_time.minute, flight.end_time.hour, flight.end_time.minute); @@ -231,7 +231,7 @@ ShowFlightList(const RecordedFlightList &flight_list) } // Show list of the flights - int i = ComboPicker(_T("Choose a flight"), + int i = ComboPicker("Choose a flight", combo, nullptr, false); return i < 0 ? nullptr : &flight_list[i]; @@ -274,7 +274,7 @@ ExternalLogger::DownloadFlightFrom(DeviceDescriptor &device) return; } - const auto logs_path = MakeLocalPath(_T("logs")); + const auto logs_path = MakeLocalPath("logs"); while (true) { // Show list of the flights @@ -284,7 +284,7 @@ ExternalLogger::DownloadFlightFrom(DeviceDescriptor &device) // Download chosen IGC file into temporary file FileTransaction transaction(AllocatedPath::Build(logs_path, - _T("temp.igc"))); + "temp.igc")); try { switch (DoDownloadFlight(device, *flight, transaction.GetTemporaryPath())) { @@ -316,7 +316,7 @@ ExternalLogger::DownloadFlightFrom(DeviceDescriptor &device) if (header.flight == 0) header.flight = GetFlightNumber(flight_list, *flight); - TCHAR name[64]; + char name[64]; FormatIGCFilenameLong(name, date, header.manufacturer, header.id, header.flight); diff --git a/src/Logger/Logger.cpp b/src/Logger/Logger.cpp index 8bf8ac0f2b6..3a3f9fca1fc 100644 --- a/src/Logger/Logger.cpp +++ b/src/Logger/Logger.cpp @@ -68,16 +68,16 @@ Logger::GUIStartLogger(const NMEAInfo& gps_info, if (task) { if (!noAsk) { - TCHAR TaskMessage[1024]; - _tcscpy(TaskMessage, _T("Start Logger With Declaration\r\n")); + char TaskMessage[1024]; + strcpy(TaskMessage, "Start Logger With Declaration\r\n"); if (decl.Size()) { for (unsigned i = 0; i< decl.Size(); ++i) { - _tcscat(TaskMessage, decl.GetName(i)); - _tcscat(TaskMessage, _T("\r\n")); + strcat(TaskMessage, decl.GetName(i)); + strcat(TaskMessage, "\r\n"); } } else { - _tcscat(TaskMessage, _T("None")); + strcat(TaskMessage, "None"); } if (ShowMessageBox(TaskMessage, _("Start Logger"), @@ -87,7 +87,7 @@ Logger::GUIStartLogger(const NMEAInfo& gps_info, } const std::lock_guard protect{lock}; - logger.StartLogger(gps_info, settings.logger, _T(""), decl); + logger.StartLogger(gps_info, settings.logger, "", decl); } void @@ -117,7 +117,7 @@ Logger::GUIStopLogger(const NMEAInfo &gps_info, } void -Logger::LoggerNote(const TCHAR *text) +Logger::LoggerNote(const char *text) { const std::lock_guard protect{lock}; logger.LoggerNote(text); diff --git a/src/Logger/Logger.hpp b/src/Logger/Logger.hpp index c6268f651b4..95d84b8cf0b 100644 --- a/src/Logger/Logger.hpp +++ b/src/Logger/Logger.hpp @@ -38,6 +38,6 @@ class Logger { bool noAsk = false); void GUIStopLogger(const NMEAInfo &gps_info, bool noAsk = false); - void LoggerNote(const TCHAR *text); + void LoggerNote(const char *text); void ClearBuffer() noexcept; }; diff --git a/src/Logger/LoggerImpl.cpp b/src/Logger/LoggerImpl.cpp index 78133088da6..9ce2267f253 100644 --- a/src/Logger/LoggerImpl.cpp +++ b/src/Logger/LoggerImpl.cpp @@ -72,7 +72,7 @@ LoggerImpl::StopLogger([[maybe_unused]] const NMEAInfo &gps_info) writer->Flush(); - LogFormat(_T("Logger stopped: %s"), filename.c_str()); + LogFormat("Logger stopped: %s", filename.c_str()); // Logger off writer.reset(); @@ -202,7 +202,7 @@ LoggerImpl::StartLogger(const NMEAInfo &gps_info, assert(writer == nullptr); - const auto logs_path = MakeLocalPath(_T("logs")); + const auto logs_path = MakeLocalPath("logs"); const BrokenDate today = gps_info.date_time_utc.IsDatePlausible() ? gps_info.date_time_utc.GetDate() @@ -226,50 +226,50 @@ LoggerImpl::StartLogger(const NMEAInfo &gps_info, return false; } - LogFormat(_T("Logger Started: %s"), filename.c_str()); + LogFormat("Logger Started: %s", filename.c_str()); return true; } void -LoggerImpl::LoggerNote(const TCHAR *text) +LoggerImpl::LoggerNote(const char *text) { if (writer != nullptr) writer->LoggerNote(text); } [[gnu::pure]] -static const TCHAR * +static const char * GetGPSDeviceName() noexcept { if (is_simulator()) - return _T("Simulator"); + return "Simulator"; const DeviceConfig &device = CommonInterface::GetSystemSettings().devices[0]; if (device.UsesDriver()) return device.driver_name; if (device.IsAndroidInternalGPS()) - return _T("Internal GPS (Android)"); + return "Internal GPS (Android)"; - return _T("Unknown"); + return "Unknown"; } // TODO: fix scope so only gui things can start it void LoggerImpl::StartLogger(const NMEAInfo &gps_info, const LoggerSettings &settings, - const TCHAR *asset_number, const Declaration &decl) + const char *asset_number, const Declaration &decl) { if (!settings.logger_id.empty()) asset_number = settings.logger_id.c_str(); // chars must be legal in file names char logger_id[4]; - unsigned asset_length = _tcslen(asset_number); + unsigned asset_length = strlen(asset_number); for (unsigned i = 0; i < 3; i++) logger_id[i] = i < asset_length && IsAlphaNumericASCII(asset_number[i]) ? - asset_number[i] : _T('A'); - logger_id[3] = _T('\0'); + asset_number[i] : 'A'; + logger_id[3] = '\0'; if (!StartLogger(gps_info, settings, logger_id)) return; diff --git a/src/Logger/LoggerImpl.hpp b/src/Logger/LoggerImpl.hpp index 75bc2f01a47..67772f00811 100644 --- a/src/Logger/LoggerImpl.hpp +++ b/src/Logger/LoggerImpl.hpp @@ -100,14 +100,14 @@ class LoggerImpl } void StartLogger(const NMEAInfo &gps_info, const LoggerSettings &settings, - const TCHAR *asset_number, const Declaration &decl); + const char *asset_number, const Declaration &decl); /** * Stops the logger * @param gps_info NMEA_INFO struct holding the current date */ void StopLogger(const NMEAInfo &gps_info); - void LoggerNote(const TCHAR *text); + void LoggerNote(const char *text); void ClearBuffer() noexcept; private: diff --git a/src/Logger/NMEALogger.cpp b/src/Logger/NMEALogger.cpp index 6d44709fe5a..6bd458de8cb 100644 --- a/src/Logger/NMEALogger.cpp +++ b/src/Logger/NMEALogger.cpp @@ -22,11 +22,11 @@ NMEALogger::Start() assert(dt.IsPlausible()); StaticString<64> name; - name.Format(_T("%04u-%02u-%02u_%02u-%02u.nmea"), + name.Format("%04u-%02u-%02u_%02u-%02u.nmea", dt.year, dt.month, dt.day, dt.hour, dt.minute); - const auto logs_path = MakeLocalPath(_T("logs")); + const auto logs_path = MakeLocalPath("logs"); const auto path = AllocatedPath::Build(logs_path, name); file = std::make_unique(path, diff --git a/src/Look/AutoFont.cpp b/src/Look/AutoFont.cpp index 6f745cb7370..15c7c40153a 100644 --- a/src/Look/AutoFont.cpp +++ b/src/Look/AutoFont.cpp @@ -8,7 +8,7 @@ #include void -AutoSizeFont(FontDescription &d, unsigned width, const TCHAR *text) +AutoSizeFont(FontDescription &d, unsigned width, const char *text) { // JMW algorithm to auto-size info window font. // this is still required in case title font property doesn't exist. diff --git a/src/Look/AutoFont.hpp b/src/Look/AutoFont.hpp index 6173073214d..f76d50eb324 100644 --- a/src/Look/AutoFont.hpp +++ b/src/Look/AutoFont.hpp @@ -13,4 +13,4 @@ class FontDescription; * Throws on error. */ void -AutoSizeFont(FontDescription &d, unsigned width, const TCHAR *text); +AutoSizeFont(FontDescription &d, unsigned width, const char *text); diff --git a/src/Look/CMakeLists.txt b/src/Look/CMakeLists.txt new file mode 100644 index 00000000000..027b24aa4e5 --- /dev/null +++ b/src/Look/CMakeLists.txt @@ -0,0 +1,49 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER FrontEnd) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/Look/CMakeSource.cmake b/src/Look/CMakeSource.cmake new file mode 100644 index 00000000000..0d858439519 --- /dev/null +++ b/src/Look/CMakeSource.cmake @@ -0,0 +1,41 @@ +set(_SOURCES + Look/AircraftLook.cpp + Look/AirspaceLook.cpp + Look/AutoFont.cpp + Look/ButtonLook.cpp + Look/ChartLook.cpp + Look/CheckBoxLook.cpp + Look/ClimbPercentLook.cpp + Look/CrossSectionLook.cpp + Look/DefaultFonts.cpp + Look/DialogLook.cpp + Look/FinalGlideBarLook.cpp + Look/FlarmTrafficLook.cpp + Look/FontDescription.cpp + Look/GestureLook.cpp + Look/GlobalFonts.cpp + Look/HorizonLook.cpp + Look/IconLook.cpp + Look/InfoBoxLook.cpp + Look/Look.cpp + Look/MapLook.cpp + Look/NOAALook.cpp + Look/OverlayLook.cpp + Look/TaskLook.cpp + Look/TerminalLook.cpp + Look/ThermalAssistantLook.cpp + Look/ThermalBandLook.cpp + Look/TopographyLook.cpp + Look/TraceHistoryLook.cpp + Look/TrafficLook.cpp + Look/TrailLook.cpp + Look/VarioBarLook.cpp + Look/VarioLook.cpp + Look/WaveLook.cpp + Look/WaypointLook.cpp + Look/WindArrowLook.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake +) diff --git a/src/Look/FontDescription.cpp b/src/Look/FontDescription.cpp index 444b66ea1fb..76ed45762d2 100644 --- a/src/Look/FontDescription.cpp +++ b/src/Look/FontDescription.cpp @@ -16,7 +16,7 @@ FontDescription::FontDescription(unsigned height, } void -FontDescription::Init(const TCHAR *face, +FontDescription::Init(const char *face, int height, bool bold, bool italic, bool monospace) @@ -37,7 +37,7 @@ FontDescription::Init(const TCHAR *face, logfont.lfPitchAndFamily = (monospace ? FIXED_PITCH : VARIABLE_PITCH) | FF_DONTCARE; - _tcscpy(logfont.lfFaceName, face); + strcpy(logfont.lfFaceName, face); } #endif diff --git a/src/Look/FontDescription.hpp b/src/Look/FontDescription.hpp index 71bf4c87e8b..7423bfd1c28 100644 --- a/src/Look/FontDescription.hpp +++ b/src/Look/FontDescription.hpp @@ -50,7 +50,7 @@ class FontDescription { } private: - void Init(const TCHAR *face, + void Init(const char *face, int height, bool bold, bool italic, bool monospace); diff --git a/src/Look/InfoBoxLook.cpp b/src/Look/InfoBoxLook.cpp index e14ced6c7b0..0107be9cbb8 100644 --- a/src/Look/InfoBoxLook.cpp +++ b/src/Look/InfoBoxLook.cpp @@ -65,18 +65,18 @@ InfoBoxLook::ReinitialiseLayout(unsigned width) const unsigned max_font_height = Layout::FontScale(12); FontDescription title_font_d(8); - AutoSizeFont(title_font_d, width, _T("0123456789")); + AutoSizeFont(title_font_d, width, "0123456789"); if (title_font_d.GetHeight() > max_font_height) title_font_d.SetHeight(max_font_height); title_font.Load(title_font_d); FontDescription value_font_d(10, true); - AutoSizeFont(value_font_d, width, _T("1234m")); + AutoSizeFont(value_font_d, width, "1234m"); value_font.Load(value_font_d); FontDescription small_value_font_d(10); - AutoSizeFont(small_value_font_d, width, _T("12345m")); + AutoSizeFont(small_value_font_d, width, "12345m"); small_value_font.Load(small_value_font_d); unsigned unit_font_height = std::max(value_font_d.GetHeight() * 2u / 5u, 7u); diff --git a/src/Look/Look.hpp b/src/Look/Look.hpp index e1452b750d5..7e8b116adb3 100644 --- a/src/Look/Look.hpp +++ b/src/Look/Look.hpp @@ -16,6 +16,7 @@ #include "TrafficLook.hpp" #include "FlarmTrafficLook.hpp" #include "InfoBoxLook.hpp" +#include "WindArrowLook.hpp" #include "FinalGlideBarLook.hpp" #include "VarioBarLook.hpp" #include "IconLook.hpp" diff --git a/src/Look/StandardFonts.hpp b/src/Look/StandardFonts.hpp index bcc025ca765..5f0fff66c22 100644 --- a/src/Look/StandardFonts.hpp +++ b/src/Look/StandardFonts.hpp @@ -6,15 +6,15 @@ #include [[gnu::const]] -static inline const TCHAR * +static inline const char * GetStandardMonospaceFontFace() noexcept { - return _T("Consolas"); + return "Consolas"; } [[gnu::const]] -static inline const TCHAR * +static inline const char * GetStandardFontFace() noexcept { - return _T("Segeo UI"); + return "Segeo UI"; } diff --git a/src/Look/TerminalLook.cpp b/src/Look/TerminalLook.cpp index 012ba59a9e7..e2d57e5899f 100644 --- a/src/Look/TerminalLook.cpp +++ b/src/Look/TerminalLook.cpp @@ -8,5 +8,9 @@ void TerminalLook::Initialise() { - font.Load(FontDescription(Layout::FontScale(11), false, false, true)); +#ifdef IS_OPENVARIO_CB2 + font.Load(FontDescription(Layout::FontScale(6), false, false, true)); +#else + font.Load(FontDescription(Layout::FontScale(8), false, false, true)); +#endif } diff --git a/src/Look/WindArrowLook.cpp b/src/Look/WindArrowLook.cpp index c03d5120bd7..d1333eb00d1 100644 --- a/src/Look/WindArrowLook.cpp +++ b/src/Look/WindArrowLook.cpp @@ -15,6 +15,12 @@ WindArrowLook::Initialise(const Font &_font, bool inverse) : (HasColors() ? DarkColor(COLOR_GRAY) : COLOR_BLACK)); shaft_pen.Create(Pen::DASH2, Layout::ScalePenWidth(1), inverse ? COLOR_WHITE : COLOR_BLACK); arrow_brush.Create(IsDithered() ? COLOR_DARK_GRAY : ColorWithAlpha(COLOR_GRAY, ALPHA_OVERLAY)); + Color color_extern(0x80, 0x80, 0xff); // a light blue + arrow_brush_extern.Create( + IsDithered() ? color_extern : ColorWithAlpha(color_extern, ALPHA_OVERLAY)); + Color color_instantaneous(0x80, 0xff, 0x80); // a light green + arrow_brush_instantaneous.Create( + IsDithered() ? color_instantaneous : ColorWithAlpha(color_instantaneous, ALPHA_OVERLAY)); font = &_font; } diff --git a/src/Look/WindArrowLook.hpp b/src/Look/WindArrowLook.hpp index bcf47295ec5..b07b4dfdc5e 100644 --- a/src/Look/WindArrowLook.hpp +++ b/src/Look/WindArrowLook.hpp @@ -12,6 +12,8 @@ struct WindArrowLook { Pen arrow_pen, shaft_pen; Brush arrow_brush; + Brush arrow_brush_extern; + Brush arrow_brush_instantaneous; const Font *font; diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 7b3a67e4835..4cfbdfedfcd 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -626,7 +626,7 @@ MainWindow::OnMouseUp(PixelPoint p) noexcept if (dragging) { StopDragging(); - const TCHAR *gesture = gestures.Finish(); + const char *gesture = gestures.Finish(); if (gesture && InputEvents::processGesture(gesture)) return true; } @@ -712,7 +712,7 @@ MainWindow::RunTimer() noexcept if (CommonInterface::GetUISettings().thermal_assistant_position == UISettings::ThermalAssistantPosition::OFF) { thermal_assistant.Clear(); } else if (!CommonInterface::Calculated().circling || - InputEvents::IsFlavour(_T("TA"))) { + InputEvents::IsFlavour("TA")) { thermal_assistant.Hide(); } else if (!HasDialog()) { if (!thermal_assistant.IsDefined()) @@ -774,6 +774,11 @@ MainWindow::OnClose() noexcept if (UIActions::CheckShutdown()) { PostQuit(); } +#ifdef IS_OPENVARIO + if (UI::TopWindow::GetExitValue() == 0) + // normal exit code on OpenVario (for Test purpose!) + UI::TopWindow::SetExitValue(EXIT_NORMAL); // unix has only Byte 10000); +#endif return true; } @@ -1051,7 +1056,7 @@ MainWindow::SetWidget(Widget *_widget) noexcept } Widget * -MainWindow::GetFlavourWidget(const TCHAR *flavour) noexcept +MainWindow::GetFlavourWidget(const char *flavour) noexcept { return InputEvents::IsFlavour(flavour) ? widget @@ -1102,7 +1107,7 @@ MainWindow::UpdateTrafficGaugeVisibility() noexcept !CommonInterface::GetUIState().screen_blanked && /* hide the traffic gauge while the traffic widget is visible, to avoid showing the same information twice */ - !InputEvents::IsFlavour(_T("Traffic")); + !InputEvents::IsFlavour("Traffic"); if (traffic_visible && suppress_traffic_gauge) { if (flarm.status.available && diff --git a/src/MainWindow.hpp b/src/MainWindow.hpp index ac6aadc96ac..db95369cd21 100644 --- a/src/MainWindow.hpp +++ b/src/MainWindow.hpp @@ -37,7 +37,7 @@ namespace InfoBoxLayout { struct Layout; } * The XCSoar main window. */ class MainWindow : public UI::SingleWindow { - static constexpr const TCHAR *title = _T("XCSoar"); + static constexpr const char *title = "OpenSoar"; Look *look = nullptr; @@ -357,7 +357,7 @@ class MainWindow : public UI::SingleWindow { * @see InputEvents::IsFlavour(), InputEvents::SetFlavour() */ [[gnu::pure]] - Widget *GetFlavourWidget(const TCHAR *flavour) noexcept; + Widget *GetFlavourWidget(const char *flavour) noexcept; void ShowMenu(const Menu &menu, const Menu *overlay=nullptr, bool full=true) noexcept; diff --git a/src/MapWindow/CMakeLists.txt b/src/MapWindow/CMakeLists.txt new file mode 100644 index 00000000000..44ed038014d --- /dev/null +++ b/src/MapWindow/CMakeLists.txt @@ -0,0 +1,53 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) + +target_link_libraries(${TARGET_NAME} PUBLIC Topography Weather) + +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) + diff --git a/src/MapWindow/CMakeSource.cmake b/src/MapWindow/CMakeSource.cmake new file mode 100644 index 00000000000..282e4ed023e --- /dev/null +++ b/src/MapWindow/CMakeSource.cmake @@ -0,0 +1,40 @@ +set(_SOURCES + MapWindow/GlueMapWindow.cpp + MapWindow/GlueMapWindowDisplayMode.cpp + MapWindow/GlueMapWindowEvents.cpp + MapWindow/GlueMapWindowItems.cpp + MapWindow/GlueMapWindowOverlays.cpp + MapWindow/Items/AirspaceBuilder.cpp + MapWindow/Items/Builder.cpp + MapWindow/Items/List.cpp + MapWindow/Items/MapItem.cpp + MapWindow/Items/OverlayMapItem.cpp + MapWindow/Items/TrafficBuilder.cpp + MapWindow/Items/WeatherBuilder.cpp + MapWindow/MapCanvas.cpp + MapWindow/MapWindow.cpp + MapWindow/MapWindowBlackboard.cpp + MapWindow/MapWindowContest.cpp + MapWindow/MapWindowEvents.cpp + MapWindow/MapWindowGlideRange.cpp + MapWindow/MapWindowRender.cpp + MapWindow/MapWindowSymbols.cpp + MapWindow/MapWindowTask.cpp + MapWindow/MapWindowThermal.cpp + MapWindow/MapWindowTraffic.cpp + MapWindow/MapWindowTrail.cpp + MapWindow/MapWindowWaypoints.cpp + MapWindow/StencilMapCanvas.cpp + MapWindow/TargetMapWindow.cpp + MapWindow/TargetMapWindowDrag.cpp + MapWindow/TargetMapWindowEvents.cpp +) +if(UNIX) + list(APPEND MapWindow_SOURCES + MapWindow/OverlayBitmap.cpp + ) +endif() + +set(SCRIPT_FILES + CMakeSource.cmake +) diff --git a/src/MapWindow/GlueMapWindow.hpp b/src/MapWindow/GlueMapWindow.hpp index 07e6a29facd..0612babc144 100644 --- a/src/MapWindow/GlueMapWindow.hpp +++ b/src/MapWindow/GlueMapWindow.hpp @@ -236,7 +236,7 @@ class GlueMapWindow : public MapWindow { * @return True if the gesture was handled by the * event handler, False otherwise */ - bool OnMouseGesture(const TCHAR* gesture) noexcept; + bool OnMouseGesture(const char* gesture) noexcept; private: void DrawGesture(Canvas &canvas) const noexcept; diff --git a/src/MapWindow/GlueMapWindowEvents.cpp b/src/MapWindow/GlueMapWindowEvents.cpp index 03f48d689e0..55a7808ea87 100644 --- a/src/MapWindow/GlueMapWindowEvents.cpp +++ b/src/MapWindow/GlueMapWindowEvents.cpp @@ -266,7 +266,7 @@ GlueMapWindow::OnMouseUp(PixelPoint p) noexcept break; case DRAG_GESTURE: - const TCHAR* gesture = gestures.Finish(); + const char* gesture = gestures.Finish(); if (gesture && OnMouseGesture(gesture)) return true; @@ -328,7 +328,7 @@ GlueMapWindow::OnMultiTouchDown() noexcept #endif /* HAVE_MULTI_TOUCH */ bool -GlueMapWindow::OnMouseGesture(const TCHAR *gesture) noexcept +GlueMapWindow::OnMouseGesture(const char *gesture) noexcept { return InputEvents::processGesture(gesture); } diff --git a/src/MapWindow/GlueMapWindowOverlays.cpp b/src/MapWindow/GlueMapWindowOverlays.cpp index 10f50f68ece..c41a22d66ec 100644 --- a/src/MapWindow/GlueMapWindowOverlays.cpp +++ b/src/MapWindow/GlueMapWindowOverlays.cpp @@ -30,7 +30,7 @@ GlueMapWindow::DrawGesture(Canvas &canvas) const noexcept if (!gestures.HasPoints()) return; - const TCHAR *gesture = gestures.GetGesture(); + const char *gesture = gestures.GetGesture(); if (gesture != nullptr && !InputEvents::IsGesture(gesture)) canvas.Select(gesture_look.invalid_pen); else @@ -120,14 +120,14 @@ GlueMapWindow::DrawPanInfo(Canvas &canvas) const noexcept } } - TCHAR buffer[256]; - FormatGeoPoint(location, buffer, ARRAY_SIZE(buffer), _T('\n')); + char buffer[256]; + FormatGeoPoint(location, buffer, ARRAY_SIZE(buffer), '\n'); - TCHAR *start = buffer; + char *start = buffer; while (true) { - auto *newline = StringFind(start, _T('\n')); + auto *newline = StringFind(start, '\n'); if (newline != nullptr) - *newline = _T('\0'); + *newline = '\0'; TextInBox(canvas, start, p, mode, render_projection.GetScreenSize()); @@ -144,7 +144,7 @@ void GlueMapWindow::DrawGPSStatus(Canvas &canvas, const PixelRect &rc, const NMEAInfo &info) const noexcept { - const TCHAR *txt; + const char *txt; const MaskedIcon *icon; if (!info.alive) { @@ -310,37 +310,37 @@ GlueMapWindow::DrawMapScale(Canvas &canvas, const PixelRect &rc, buffer.clear(); if (GetMapSettings().auto_zoom_enabled) - buffer = _T("AUTO "); + buffer = "AUTO "; switch (follow_mode) { case FOLLOW_SELF: break; case FOLLOW_PAN: - buffer += _T("PAN "); + buffer += "PAN "; break; } const UIState &ui_state = GetUIState(); if (ui_state.auxiliary_enabled) { buffer += ui_state.panel_name; - buffer += _T(" "); + buffer += " "; } if (Basic().gps.replay) - buffer += _T("REPLAY "); + buffer += "REPLAY "; else if (Basic().gps.simulator) { buffer += _("Simulator"); - buffer += _T(" "); + buffer += " "; } if (GetComputerSettings().polar.ballast_timer_active) buffer.AppendFormat( - _T("BALLAST %d LITERS "), + "BALLAST %d LITERS ", (int)GetComputerSettings().polar.glide_polar_task.GetBallastLitres()); if (rasp_renderer != nullptr) { - const TCHAR *label = rasp_renderer->GetLabel(); + const char *label = rasp_renderer->GetLabel(); if (label != nullptr) buffer += gettext(label); } diff --git a/src/MapWindow/Items/MapItem.hpp b/src/MapWindow/Items/MapItem.hpp index b644c3682e8..cba043758cc 100644 --- a/src/MapWindow/Items/MapItem.hpp +++ b/src/MapWindow/Items/MapItem.hpp @@ -198,7 +198,7 @@ struct SkyLinesTrafficMapItem : public MapItem SkyLinesTrafficMapItem(uint32_t _id, Time _time_of_day_ms, int _altitude, - const TCHAR *_name) + const char *_name) :MapItem(Type::SKYLINES_TRAFFIC), id(_id), time_of_day(_time_of_day_ms), altitude(_altitude), name(_name) {} diff --git a/src/MapWindow/Items/RaspMapItem.hpp b/src/MapWindow/Items/RaspMapItem.hpp index 4897cfad151..cac9a112593 100644 --- a/src/MapWindow/Items/RaspMapItem.hpp +++ b/src/MapWindow/Items/RaspMapItem.hpp @@ -14,6 +14,6 @@ struct RaspMapItem : public MapItem { const StaticString<64> label; - explicit RaspMapItem(const TCHAR *_label) + explicit RaspMapItem(const char *_label) :MapItem(Type::RASP), label(_label) {} }; diff --git a/src/MapWindow/Items/TrafficBuilder.cpp b/src/MapWindow/Items/TrafficBuilder.cpp index 9d939f64638..6dc670dafda 100644 --- a/src/MapWindow/Items/TrafficBuilder.cpp +++ b/src/MapWindow/Items/TrafficBuilder.cpp @@ -45,10 +45,10 @@ MapItemListBuilder::AddSkyLinesTraffic() location.DistanceS(i.second.location) < range) { const uint32_t id = i.first; auto name_i = data.user_names.find(id); - const TCHAR *name; + const char *name; if (name_i == data.user_names.end()) { /* no name found */ - buffer.UnsafeFormat(_T("SkyLines %u"), (unsigned)id); + buffer.UnsafeFormat("SkyLines %u", (unsigned)id); name = buffer; } else /* we know the name */ diff --git a/src/MapWindow/MapWindowBlackboard.cpp b/src/MapWindow/MapWindowBlackboard.cpp index d3b85687319..57a57a0e589 100644 --- a/src/MapWindow/MapWindowBlackboard.cpp +++ b/src/MapWindow/MapWindowBlackboard.cpp @@ -34,7 +34,11 @@ UpdateFadingTraffic(bool fade_traffic, return; } +#ifdef _DEBUG // TODO(August)... + if (new_list.modified.Modified(old_list.modified) && false) { // TODO(August)... +#else if (new_list.modified.Modified(old_list.modified)||true) { +#endif /* first add all items from the old list */ for (const auto &traffic : old_list.list) if (traffic.location_available) diff --git a/src/MapWindow/MapWindowSymbols.cpp b/src/MapWindow/MapWindowSymbols.cpp index 6f5d27d5ac5..5b68656cb42 100644 --- a/src/MapWindow/MapWindowSymbols.cpp +++ b/src/MapWindow/MapWindowSymbols.cpp @@ -17,7 +17,7 @@ MapWindow::DrawWind(Canvas &canvas, const PixelPoint &Start, WindArrowRenderer wind_arrow_renderer(look.wind); wind_arrow_renderer.Draw(canvas, render_projection.GetScreenAngle(), - Start, rc, Calculated(), GetMapSettings()); + Start, rc, Calculated(), Basic(), GetMapSettings()); } void diff --git a/src/MapWindow/MapWindowTask.cpp b/src/MapWindow/MapWindowTask.cpp index 845bd85fc9f..6777c4ef6da 100644 --- a/src/MapWindow/MapWindowTask.cpp +++ b/src/MapWindow/MapWindowTask.cpp @@ -129,8 +129,8 @@ MapWindow::DrawTaskOffTrackIndicator(Canvas &canvas) noexcept int idist = iround((distance - 1) * 100); if ((idist != ilast) && (idist > 0) && (idist < 1000)) { - TCHAR Buffer[5]; - _stprintf(Buffer, _T("%d"), idist); + char Buffer[5]; + _stprintf(Buffer, "%d", idist); auto sc = render_projection.GeoToScreen(dloc); PixelSize tsize = canvas.CalcTextSize(Buffer); canvas.DrawText(sc - tsize / 2u, Buffer); diff --git a/src/MapWindow/MapWindowTraffic.cpp b/src/MapWindow/MapWindowTraffic.cpp index 05393bf2c0d..09f26dedd0a 100644 --- a/src/MapWindow/MapWindowTraffic.cpp +++ b/src/MapWindow/MapWindowTraffic.cpp @@ -184,7 +184,7 @@ MapWindow::DrawGLinkTraffic([[maybe_unused]] Canvas &canvas) const noexcept if(basic.gps_altitude_available && traf.altitude_received && fabs(double(traf.altitude) - basic.gps_altitude) >= 100.0) { // If average climb data available draw it to the canvas - TCHAR label_alt[100]; + char label_alt[100]; double alt = (double(traf.altitude) - basic.gps_altitude) / 100.0; FormatRelativeUserAltitude(alt, label_alt, false); @@ -235,12 +235,12 @@ MapWindow::DrawSkyLinesTraffic(Canvas &canvas) const noexcept traffic_look.teammate_icon.Draw(canvas, *p); if (DisplaySkyLinesTrafficMapMode::SYMBOL_NAME == GetMapSettings().skylines_traffic_map_mode) { const auto name_i = skylines_data->user_names.find(i.first); - const TCHAR *name = name_i != skylines_data->user_names.end() + const char *name = name_i != skylines_data->user_names.end() ? name_i->second.c_str() - : _T(""); + : ""; StaticString<128> buffer; - buffer.Format(_T("%s [%um]"), name, i.second.altitude); + buffer.Format("%s [%um]", name, i.second.altitude); TextInBoxMode mode; mode.shape = LabelShape::OUTLINED; diff --git a/src/MapWindow/Overlay.hpp b/src/MapWindow/Overlay.hpp index d97004d92fa..fd97b54479c 100644 --- a/src/MapWindow/Overlay.hpp +++ b/src/MapWindow/Overlay.hpp @@ -24,7 +24,7 @@ class MapOverlay { * Returns a human-readable name for this overlay. */ [[gnu::pure]] - virtual const TCHAR *GetLabel() const noexcept = 0; + virtual const char *GetLabel() const noexcept = 0; /** * Check whether the given location is inside the overlay. diff --git a/src/MapWindow/OverlayBitmap.hpp b/src/MapWindow/OverlayBitmap.hpp index 4bebf0e48c8..fba5b5463f6 100644 --- a/src/MapWindow/OverlayBitmap.hpp +++ b/src/MapWindow/OverlayBitmap.hpp @@ -7,7 +7,7 @@ #include "ui/canvas/Bitmap.hpp" #include "Geo/Quadrilateral.hpp" #include "Geo/GeoBounds.hpp" -#include "util/tstring.hpp" +#include class Canvas; class WindowProjection; @@ -35,7 +35,7 @@ class MapOverlayBitmap final : public MapOverlay { float alpha = 1; - tstring label; + std::string label; public: /** @@ -49,7 +49,7 @@ class MapOverlayBitmap final : public MapOverlay { * Move an existing #Bitmap with a geo reference. */ MapOverlayBitmap(Bitmap &&_bitmap, GeoQuadrilateral _bounds, - tstring::const_pointer _label) noexcept + std::string::const_pointer _label) noexcept :bitmap(std::move(_bitmap)), bounds(_bounds), simple_bounds(bounds.GetBounds()), label(_label) {} @@ -75,7 +75,7 @@ class MapOverlayBitmap final : public MapOverlay { } /* virtual methods from class MapOverlay */ - const TCHAR *GetLabel() const noexcept override { + const char *GetLabel() const noexcept override { return label.c_str(); } diff --git a/src/Markers/CMakeLists.txt b/src/Markers/CMakeLists.txt new file mode 100644 index 00000000000..fb24335629a --- /dev/null +++ b/src/Markers/CMakeLists.txt @@ -0,0 +1,32 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/Markers/CMakeSource.cmake b/src/Markers/CMakeSource.cmake new file mode 100644 index 00000000000..13c4ec66b60 --- /dev/null +++ b/src/Markers/CMakeSource.cmake @@ -0,0 +1,6 @@ +set(_SOURCES + Markers.cpp +) + +set(SCRIPT_FILES CMakeSource.cmake +) diff --git a/src/Markers/Markers.cpp b/src/Markers/Markers.cpp index 0de4c262a4b..329c3b3382c 100644 --- a/src/Markers/Markers.cpp +++ b/src/Markers/Markers.cpp @@ -14,7 +14,7 @@ MarkLocation(const GeoPoint &loc, const BrokenDateTime &time) try { assert(time.IsPlausible()); - FileOutputStream file(LocalPath(_T("xcsoar-marks.txt")), + FileOutputStream file(LocalPath("xcsoar-marks.txt"), FileOutputStream::Mode::APPEND_OR_CREATE); BufferedOutputStream os(file); os.Fmt("{:02}.{:02}.{:04}\t{:02}:{:02}:{:02}\tLon:{:f}\tLat:{:f}\n", diff --git a/src/Math/CMakeLists.txt b/src/Math/CMakeLists.txt new file mode 100644 index 00000000000..62dca83c2a3 --- /dev/null +++ b/src/Math/CMakeLists.txt @@ -0,0 +1,83 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR} + ${OUTPUT_FOLDER}/include +) + +set(MATHTABLES_H ${OUTPUT_FOLDER}/include/MathTables.h) + +if(MSVC) # Multi-Config! + set(MATHTABLES_CMD ${PROJECTGROUP_BINARY_DIR}/tools/Debug/MathTables) +else() + set(MATHTABLES_CMD ${PROJECTGROUP_BINARY_DIR}/tools/MathTables) +endif() +add_custom_command( # TARGET ${TARGET_NAME} PRE_BUILD + OUTPUT ${MATHTABLES_H} + COMMENT "Create 'MathTables.h' with Sine tables" + COMMAND ${MATHTABLES_CMD} >${MATHTABLES_H} + WORKING_DIRECTORY ${PROJECTGROUP_SOURCE_DIR} + # DEPENDS GenerateSineTables.cpp + DEPENDS MathTables + # ${PROJECTGROUP_SOURCE_DIR}/tools/GenerateSineTables.cpp + ) +list(APPEND HEADER_FILES ${MATHTABLES_H}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +# Aug: mal kurz ausblenden 5.9.22, +# add_dependencies(${TARGET_NAME} util) + +## add_custom_command(TARGET ${TARGET_NAME} PRE_BUILD +## # OUTPUT MathTables.h +## COMMENT "Create 'MathTables.h' with Sine tables" +## echo tools/Debug/MathTables to MathTables.h +## COMMAND ${PROJECTGROUP_BINARY_DIR}/tools/Debug/MathTables > MathTables.h +## WORKING_DIRECTORY ${PROJECTGROUP_SOURCE_DIR}/${OUTPUT}/include +## DEPENDS GenerateSineTables.cpp +## ) + +# target_link_libraries(${TARGET_NAME} MathTables) +add_dependencies(${TARGET_NAME} MathTables Data) + diff --git a/src/Math/CMakeSource.cmake b/src/Math/CMakeSource.cmake new file mode 100644 index 00000000000..657911fe703 --- /dev/null +++ b/src/Math/CMakeSource.cmake @@ -0,0 +1,23 @@ +set(_SOURCES + Math/Angle.cpp + Math/ARange.cpp + Math/ConvexFilter.cpp + Math/DiffFilter.cpp + Math/FastMath.cpp + Math/FastRotation.cpp + Math/FastTrig.cpp + Math/Filter.cpp + Math/Histogram.cpp + Math/KalmanFilter1d.cpp + Math/LeastSquares.cpp + Math/Screen.cpp + Math/SelfTimingKalmanFilter1d.cpp + Math/SunEphemeris.cpp + Math/XYDataStore.cpp + Math/ZeroFinder.cpp +) + + +set(SCRIPT_FILES + CMakeSource.cmake +) diff --git a/src/Math/Classify.hpp b/src/Math/Classify.hpp index dacde78f4ce..ad83e0b81be 100644 --- a/src/Math/Classify.hpp +++ b/src/Math/Classify.hpp @@ -21,5 +21,9 @@ constexpr bool IsFinite(std::floating_point auto value) noexcept { +#if defined _MSC_VER + return std::isfinite(value); +#else return __builtin_isfinite(value); +#endif } diff --git a/src/Math/Constants.hpp b/src/Math/Constants.hpp index e8e18e07cbd..5da292c4fb3 100644 --- a/src/Math/Constants.hpp +++ b/src/Math/Constants.hpp @@ -2,6 +2,11 @@ // Copyright The XCSoar Project #pragma once + +#ifdef __MSVC__ +# include +#endif + #include #ifndef M_PI diff --git a/src/Math/Trig.hpp b/src/Math/Trig.hpp index 696da15f447..0ab7dcac4bd 100644 --- a/src/Math/Trig.hpp +++ b/src/Math/Trig.hpp @@ -9,12 +9,11 @@ [[gnu::const]] static inline std::pair -sin_cos(const double thetha) noexcept -{ +sin_cos(const double thetha) noexcept { double s, c; #ifdef __APPLE__ __sincos(thetha, &s, &c); -#elif defined(_MSC_VER) +#elif defined(__MSVC__) || defined(__clang__) // STL and MSVC have no sincos... s = sin(thetha); c = cos(thetha); diff --git a/src/Menu/ButtonLabel.cpp b/src/Menu/ButtonLabel.cpp index 033d992d15b..e6604fb033d 100644 --- a/src/Menu/ButtonLabel.cpp +++ b/src/Menu/ButtonLabel.cpp @@ -16,7 +16,7 @@ * @return false if there is at least one ASCII letter in the string */ static constexpr bool -LacksAlphaASCII(const TCHAR *s) noexcept +LacksAlphaASCII(const char *s) noexcept { for (; *s != 0; ++s) if (IsAlphaASCII(*s)) @@ -31,14 +31,14 @@ LacksAlphaASCII(const TCHAR *s) noexcept * @return the translated string or nullptr if the buffer is too small */ [[gnu::pure]] -static const TCHAR * -GetTextN(const TCHAR *src, const TCHAR *src_end, - TCHAR *buffer, size_t buffer_size) noexcept +static const char * +GetTextN(const char *src, const char *src_end, + char *buffer, size_t buffer_size) noexcept { if (src == src_end) /* gettext("") returns the PO header, and thus we need to exclude this special case */ - return _T(""); + return ""; const size_t src_length = src_end - src; if (src_length >= buffer_size) @@ -47,33 +47,33 @@ GetTextN(const TCHAR *src, const TCHAR *src_end, /* copy to buffer, because gettext() expects a null-terminated string */ - *std::copy(src, src_end, buffer) = _T('\0'); + *std::copy(src, src_end, buffer) = '\0'; return gettext(buffer); } ButtonLabel::Expanded -ButtonLabel::Expand(const TCHAR *text, std::span buffer) noexcept +ButtonLabel::Expand(const char *text, std::span buffer) noexcept { Expanded expanded; - const TCHAR *dollar; + const char *dollar; - if (text == nullptr || *text == _T('\0') || *text == _T(' ')) { + if (text == nullptr || *text == '\0' || *text == ' ') { expanded.visible = false; return expanded; } else if ((dollar = StringFind(text, '$')) == nullptr) { /* no macro, we can just translate the text */ expanded.visible = true; expanded.enabled = true; - const TCHAR *nl = StringFind(text, '\n'); + const char *nl = StringFind(text, '\n'); if (nl != nullptr && LacksAlphaASCII(nl + 1)) { /* Quick hack for skipping the translation for second line of a two line label with only digits and punctuation in the second line, e.g. for menu labels like "Config\n2/3" */ /* copy the text up to the '\n' to a new buffer and translate it */ - TCHAR translatable[256]; - const TCHAR *translated = GetTextN(text, nl, translatable, + char translatable[256]; + const char *translated = GetTextN(text, nl, translatable, ARRAY_SIZE(translatable)); if (translated == nullptr) { /* buffer too small: keep it untranslated */ @@ -84,30 +84,30 @@ ButtonLabel::Expand(const TCHAR *text, std::span buffer) noexcept /* concatenate the translated text and the part starting with '\n' */ try { expanded.text = BuildString(buffer, translated, nl); - } catch (BasicStringBuilder::Overflow) { + } catch (BasicStringBuilder::Overflow) { expanded.text = gettext(text); } } else expanded.text = gettext(text); return expanded; } else { - const TCHAR *macros = dollar; + const char *macros = dollar; /* backtrack until the first non-whitespace character, because we don't want to translate whitespace between the text and the macro */ macros = StripRight(text, macros); - TCHAR s[100]; + char s[100]; expanded.enabled = !ExpandMacros(text, std::span{s}); - if (s[0] == _T('\0') || s[0] == _T(' ')) { + if (s[0] == '\0' || s[0] == ' ') { expanded.visible = false; return expanded; } /* copy the text (without trailing whitespace) to a new buffer and translate it */ - TCHAR translatable[256]; - const TCHAR *translated = GetTextN(text, macros, translatable, + char translatable[256]; + const char *translated = GetTextN(text, macros, translatable, ARRAY_SIZE(translatable)); if (translated == nullptr) { /* buffer too small: fail */ diff --git a/src/Menu/ButtonLabel.hpp b/src/Menu/ButtonLabel.hpp index 9b300c17044..e1b1871486f 100644 --- a/src/Menu/ButtonLabel.hpp +++ b/src/Menu/ButtonLabel.hpp @@ -15,14 +15,14 @@ namespace ButtonLabel { struct Expanded { bool visible, enabled; - const TCHAR *text; + const char *text; }; [[gnu::pure]] Expanded -Expand(const TCHAR *text, std::span buffer) noexcept; +Expand(const char *text, std::span buffer) noexcept; bool -ExpandMacros(const TCHAR *In, std::span dest) noexcept; +ExpandMacros(const char *In, std::span dest) noexcept; } // namespace ButtonLabel diff --git a/src/Menu/CMakeLists.txt b/src/Menu/CMakeLists.txt new file mode 100644 index 00000000000..ed0747dafde --- /dev/null +++ b/src/Menu/CMakeLists.txt @@ -0,0 +1,60 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") + +target_link_libraries(${TARGET_NAME} PUBLIC + Form + libOpenSoar + Blackboard + UIUtil + Dialogs +# ${LIBPNG_LIB} + ${ZZIP_LIB} # internal or external... +) + +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER FrontEnd) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/Menu/CMakeSource.cmake b/src/Menu/CMakeSource.cmake new file mode 100644 index 00000000000..deabae54bac --- /dev/null +++ b/src/Menu/CMakeSource.cmake @@ -0,0 +1,14 @@ +set(_SOURCES + Menu/ButtonLabel.cpp + Menu/ExpandMacros.cpp + Menu/MenuBar.cpp + Menu/MenuData.cpp + Menu/ShowMenuButton.cpp + Menu/Glue.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake + + ../../build/main.mk # menu sorces in main.mk! +) diff --git a/src/Menu/ExpandMacros.cpp b/src/Menu/ExpandMacros.cpp index ffbc0e2e833..62dc2ccec56 100644 --- a/src/Menu/ExpandMacros.cpp +++ b/src/Menu/ExpandMacros.cpp @@ -28,8 +28,8 @@ #include -static const TCHAR * -ExpandTaskMacros(tstring_view name, +static const char * +ExpandTaskMacros(std::string_view name, bool &invalid, const DerivedInfo &calculated, const ComputerSettings &settings_computer) noexcept @@ -38,14 +38,14 @@ ExpandTaskMacros(tstring_view name, const TaskStats &ordered_task_stats = calculated.ordered_task_stats; const CommonStats &common_stats = calculated.common_stats; - if (name == _T("CheckTaskResumed")) { + if (name == "CheckTaskResumed") { // TODO code: check, does this need to be set with temporary task? invalid |= common_stats.task_type == TaskType::ABORT || common_stats.task_type == TaskType::GOTO; - return _T(""); - } else if (name == _T("CheckTask")) { + return ""; + } else if (name == "CheckTask") { invalid |= !task_stats.task_valid; - return _T(""); + return ""; } if (!backend_components->protected_task_manager) { @@ -59,24 +59,24 @@ ExpandTaskMacros(tstring_view name, if (task == nullptr || !task_stats.task_valid || common_stats.task_type == TaskType::GOTO) { - if (name == _T("WaypointNext") || - name == _T("WaypointNextArm")) { + if (name == "WaypointNext" || + name == "WaypointNextArm") { invalid = true; return _("Next Turnpoint"); - } else if (name == _T("WaypointPrevious") || - name == _T("WaypointPreviousArm")) { + } else if (name == "WaypointPrevious" || + name == "WaypointPreviousArm") { invalid = true; return _("Previous Turnpoint"); } } else if (common_stats.task_type == TaskType::ABORT) { - if (name == _T("WaypointNext") || - name == _T("WaypointNextArm")) { + if (name == "WaypointNext" || + name == "WaypointNextArm") { invalid |= !common_stats.active_has_next; return common_stats.next_is_last ? _("Furthest Landpoint") : _("Next Landpoint"); - } else if (name == _T("WaypointPrevious") || - name == _T("WaypointPreviousArm")) { + } else if (name == "WaypointPrevious" || + name == "WaypointPreviousArm") { invalid |= !common_stats.active_has_previous; return common_stats.previous_is_first @@ -90,13 +90,13 @@ ExpandTaskMacros(tstring_view name, const bool previous_is_start = common_stats.previous_is_first; const bool has_optional_starts = ordered_task_stats.has_optional_starts; - if (name == _T("WaypointNext")) { + if (name == "WaypointNext") { // Waypoint\nNext invalid |= !common_stats.active_has_next; return next_is_final ? _("Finish Turnpoint") : _("Next Turnpoint"); - } else if (name == _T("WaypointPrevious")) { + } else if (name == "WaypointPrevious") { if (has_optional_starts && !common_stats.active_has_previous) { return _("Next Startpoint"); } else { @@ -106,7 +106,7 @@ ExpandTaskMacros(tstring_view name, : _("Previous Turnpoint"); } - } else if (name == _T("WaypointNextArm")) { + } else if (name == "WaypointNextArm") { // Waypoint\nNext switch (task_manager->GetOrderedTask().GetTaskAdvance().GetState()) { @@ -126,7 +126,7 @@ ExpandTaskMacros(tstring_view name, return _("Arm turn"); } - } else if (name == _T("WaypointPreviousArm")) { + } else if (name == "WaypointPreviousArm") { switch (task_manager->GetOrderedTask().GetTaskAdvance().GetState()) { case TaskAdvance::MANUAL: @@ -152,7 +152,7 @@ ExpandTaskMacros(tstring_view name, } } - if (name == _T("AdvanceArmed")) { + if (name == "AdvanceArmed") { switch (task_manager->GetOrderedTask().GetTaskAdvance().GetState()) { case TaskAdvance::MANUAL: invalid = true; @@ -174,11 +174,11 @@ ExpandTaskMacros(tstring_view name, case TaskAdvance::TURN_DISARMED: return _("Arm\nTurn"); } - } else if (name == _T("CheckAutoMc")) { + } else if (name == "CheckAutoMc") { invalid |= !task_stats.task_valid && settings_computer.task.IsAutoMCFinalGlideEnabled(); - return _T(""); - } else if (name == _T("TaskAbortToggleActionName")) { + return ""; + } else if (name == "TaskAbortToggleActionName") { if (common_stats.task_type == TaskType::GOTO) return ordered_task_stats.task_valid ? _("Resume") @@ -187,27 +187,27 @@ ExpandTaskMacros(tstring_view name, return common_stats.task_type == TaskType::ABORT ? _("Resume") : _("Abort"); - } else if (name == _T("CheckTaskRestart")) { + } else if (name == "CheckTaskRestart") { invalid |= !(common_stats.task_type == TaskType::ORDERED && task_stats.start.HasStarted()); - return _T(""); + return ""; } return nullptr; } [[gnu::pure]] -static const TCHAR * -ExpandTrafficMacros(tstring_view name) noexcept +static const char * +ExpandTrafficMacros(std::string_view name) noexcept { TrafficWidget *widget = (TrafficWidget *) - CommonInterface::main_window->GetFlavourWidget(_T("Traffic")); + CommonInterface::main_window->GetFlavourWidget("Traffic"); if (widget == nullptr) return nullptr; - if (name == _T("TrafficZoomAutoToggleActionName")) + if (name == "TrafficZoomAutoToggleActionName") return widget->GetAutoZoom() ? _("Manual") : _("Auto"); - else if (name == _T("TrafficNorthUpToggleActionName")) + else if (name == "TrafficNorthUpToggleActionName") return widget->GetNorthUp() ? _("Track up") : _("North up"); else return nullptr; @@ -243,15 +243,15 @@ GetUIState() noexcept return CommonInterface::GetUIState(); } -static const TCHAR * -LookupMacro(tstring_view name, bool &invalid) noexcept +static const char * +LookupMacro(std::string_view name, bool &invalid) noexcept { - if (name ==_T("CheckAirspace")) { + if (name =="CheckAirspace") { invalid |= data_components->airspaces->IsEmpty(); return nullptr; } - const TCHAR *value = ExpandTaskMacros(name, invalid, + const char *value = ExpandTaskMacros(name, invalid, Calculated(), GetComputerSettings()); if (value != nullptr) return value; @@ -260,43 +260,56 @@ LookupMacro(tstring_view name, bool &invalid) noexcept if (value != nullptr) return value; - if (name ==_T("CheckFLARM")) { + auto vario_sound = CommonInterface::SetUISettings().sound.vario; + + if (name =="CheckFLARM") { invalid |= !Basic().flarm.status.available; return nullptr; - } else if (name == _T("CheckWeather")) { + } else if (name == "CheckWeather") { const auto rasp = DataGlobals::GetRasp(); invalid |= rasp == nullptr || rasp->GetItemCount() == 0; return nullptr; - } else if (name == _T("CheckCircling")) { + } else if (name == "CheckCircling") { invalid |= !Calculated().circling; return nullptr; - } else if (name == _T("CheckVega")) { + } else if (name == "CheckVega") { invalid |= backend_components->devices == nullptr || !backend_components->devices->HasVega(); return nullptr; - } else if (name == _T("CheckReplay")) { + } else if (name == "CheckReplay") { invalid |= CommonInterface::MovementDetected(); return nullptr; - } else if (name == _T("CheckWaypointFile")) { + } else if (name == "CheckWaypointFile") { invalid |= data_components->waypoints->IsEmpty(); return nullptr; - } else if (name == _T("CheckLogger")) { + } else if (name == "CheckLogger") { invalid |= Basic().gps.replay; return nullptr; - } else if (name == _T("CheckNet")) { + } else if (name == "CheckNet") { #ifndef HAVE_HTTP invalid = true; #endif return nullptr; - } else if (name == _T("CheckTerrain")) { + } else if (name == "CheckTerrain") { invalid |= !Calculated().terrain_valid; return nullptr; - } else if (name == _T("LoggerActive")) { + } else if (name == "AudioOnOff") { + StaticString<10> s; + s.Format("(%u/7)", + vario_sound.volume > 0 ? 1 + (unsigned)log2(vario_sound.volume) : 0); + return vario_sound.enabled ? s.c_str() : "-"; + } else if (name == "CheckAudioQuiet") { + invalid |= !vario_sound.enabled || vario_sound.volume <= 1; + return nullptr; + } else if (name == "CheckAudioLoud") { + invalid |= !vario_sound.enabled || vario_sound.volume >= 100; + return nullptr; + } else if (name == "LoggerActive") { return backend_components->igc_logger != nullptr && backend_components->igc_logger->IsLoggerActive() ? _("Stop") : _("Start"); - } else if (name == _T("SnailTrailToggleName")) { + } else if (name == "SnailTrailToggleName") { switch (GetMapSettings().trail.length) { case TrailSettings::Length::OFF: return _("Long"); @@ -312,10 +325,10 @@ LookupMacro(tstring_view name, bool &invalid) noexcept } return nullptr; - } else if (name == _T("AirSpaceToggleName")) { + } else if (name == "AirSpaceToggleName") { return GetMapSettings().airspace.enable ? _("Off") : _("On"); - } else if (name == _T("TerrainTopologyToggleName") || - name == _T("TerrainTopographyToggleName")) { + } else if (name == "TerrainTopologyToggleName" || + name == "TerrainTopographyToggleName") { char val = 0; if (GetMapSettings().topography_enabled) val++; @@ -337,19 +350,19 @@ LookupMacro(tstring_view name, bool &invalid) noexcept } return nullptr; - } else if (name == _T("FullScreenToggleActionName")) { + } else if (name == "FullScreenToggleActionName") { return CommonInterface::main_window->GetFullScreen() ? _("Off") : _("On"); - } else if (name == _T("ZoomAutoToggleActionName")) { + } else if (name == "ZoomAutoToggleActionName") { return GetMapSettings().auto_zoom_enabled ? _("Manual") : _("Auto"); - } else if (name == _T("TopologyToggleActionName") || - name == _T("TopographyToggleActionName")) { + } else if (name == "TopologyToggleActionName" || + name == "TopographyToggleActionName") { return GetMapSettings().topography_enabled ? _("Hide") : _("Show"); - } else if (name == _T("TerrainToggleActionName")) { + } else if (name == "TerrainToggleActionName") { return GetMapSettings().terrain.enable ? _("Hide") : _("Show"); - } else if (name == _T("AirspaceToggleActionName")) { + } else if (name == "AirspaceToggleActionName") { return GetMapSettings().airspace.enable ? _("Hide") : _("Show"); - } else if (name == _T("MapLabelsToggleActionName")) { - static const TCHAR *const labels[] = { + } else if (name == "MapLabelsToggleActionName") { + static const char *const labels[] = { N_("All"), N_("Task & Landables"), N_("Task"), @@ -360,60 +373,60 @@ LookupMacro(tstring_view name, bool &invalid) noexcept static constexpr unsigned int n = ARRAY_SIZE(labels); unsigned int i = (unsigned)GetMapSettings().waypoint.label_selection; return gettext(labels[(i + 1) % n]); - } else if (name == _T("MacCreadyToggleActionName")) { + } else if (name == "MacCreadyToggleActionName") { return GetComputerSettings().task.auto_mc ? _("Manual") : _("Auto"); - } else if (name == _T("AuxInfoToggleActionName")) { + } else if (name == "AuxInfoToggleActionName") { return GetUIState().auxiliary_enabled ? _("Off") : _("On"); - } else if (name == _T("DispModeClimbShortIndicator")) { + } else if (name == "DispModeClimbShortIndicator") { return GetUIState().force_display_mode == DisplayMode::CIRCLING - ? _T("*") : _T(""); - } else if (name == _T("DispModeCruiseShortIndicator")) { + ? "*" : ""; + } else if (name == "DispModeCruiseShortIndicator") { return GetUIState().force_display_mode == DisplayMode::CRUISE - ? _T("*") : _T(""); - } else if (name == _T("DispModeAutoShortIndicator")) { + ? "*" : ""; + } else if (name == "DispModeAutoShortIndicator") { return GetUIState().force_display_mode == DisplayMode::NONE - ? _T("*") : _T(""); - } else if (name == _T("DispModeFinalShortIndicator")) { + ? "*" : ""; + } else if (name == "DispModeFinalShortIndicator") { return GetUIState().force_display_mode == DisplayMode::FINAL_GLIDE - ? _T("*") : _T(""); - } else if (name == _T("AirspaceModeAllShortIndicator")) { + ? "*" : ""; + } else if (name == "AirspaceModeAllShortIndicator") { return GetMapSettings().airspace.altitude_mode == AirspaceDisplayMode::ALLON - ? _T("*") : _T(""); - } else if (name == _T("AirspaceModeClipShortIndicator")) { + ? "*" : ""; + } else if (name == "AirspaceModeClipShortIndicator") { return GetMapSettings().airspace.altitude_mode == AirspaceDisplayMode::CLIP - ? _T("*") : _T(""); - } else if (name == _T("AirspaceModeAutoShortIndicator")) { + ? "*" : ""; + } else if (name == "AirspaceModeAutoShortIndicator") { return GetMapSettings().airspace.altitude_mode == AirspaceDisplayMode::AUTO - ? _T("*") : _T(""); - } else if (name == _T("AirspaceModeBelowShortIndicator")) { + ? "*" : ""; + } else if (name == "AirspaceModeBelowShortIndicator") { return GetMapSettings().airspace.altitude_mode == AirspaceDisplayMode::ALLBELOW - ? _T("*") : _T(""); - } else if (name == _T("AirspaceModeAllOffIndicator")) { + ? "*" : ""; + } else if (name == "AirspaceModeAllOffIndicator") { return GetMapSettings().airspace.altitude_mode == AirspaceDisplayMode::ALLOFF - ? _T("*") : _T(""); - } else if (name == _T("SnailTrailOffShortIndicator")) { + ? "*" : ""; + } else if (name == "SnailTrailOffShortIndicator") { return GetMapSettings().trail.length == TrailSettings::Length::OFF - ? _T("*") : _T(""); - } else if (name == _T("SnailTrailShortShortIndicator")) { + ? "*" : ""; + } else if (name == "SnailTrailShortShortIndicator") { return GetMapSettings().trail.length == TrailSettings::Length::SHORT - ? _T("*") : _T(""); - } else if (name == _T("SnailTrailLongShortIndicator")) { + ? "*" : ""; + } else if (name == "SnailTrailLongShortIndicator") { return GetMapSettings().trail.length == TrailSettings::Length::LONG - ? _T("*") : _T(""); - } else if (name == _T("SnailTrailFullShortIndicator")) { + ? "*" : ""; + } else if (name == "SnailTrailFullShortIndicator") { return GetMapSettings().trail.length == TrailSettings::Length::FULL - ? _T("*") : _T(""); - } else if (name == _T("AirSpaceOffShortIndicator")) { - return !GetMapSettings().airspace.enable ? _T("*") : _T(""); - } else if (name == _T("AirSpaceOnShortIndicator")) { - return GetMapSettings().airspace.enable ? _T("*") : _T(""); - } else if (name == _T("FlarmDispToggleActionName")) { + ? "*" : ""; + } else if (name == "AirSpaceOffShortIndicator") { + return !GetMapSettings().airspace.enable ? "*" : ""; + } else if (name == "AirSpaceOnShortIndicator") { + return GetMapSettings().airspace.enable ? "*" : ""; + } else if (name == "FlarmDispToggleActionName") { return CommonInterface::GetUISettings().traffic.enable_gauge ? _("Off") : _("On"); - } else if (name == _T("ZoomAutoToggleActionName")) { + } else if (name == "ZoomAutoToggleActionName") { return GetMapSettings().auto_zoom_enabled ? _("Manual") : _("Auto"); - } else if (name == _T("NextPageName")) { - static TCHAR label[64]; // TODO: oh no, a static string buffer! + } else if (name == "NextPageName") { + static char label[64]; // TODO: oh no, a static string buffer! const PageLayout &page = CommonInterface::GetUISettings().pages.pages[PageActions::NextIndex()]; return page.MakeTitle(CommonInterface::GetUISettings().info_boxes, @@ -423,12 +436,12 @@ LookupMacro(tstring_view name, bool &invalid) noexcept } bool -ButtonLabel::ExpandMacros(const TCHAR *In, std::span dest) noexcept +ButtonLabel::ExpandMacros(const char *In, std::span dest) noexcept { bool invalid = false; DollarExpand(In, dest, - [&invalid](tstring_view name){ + [&invalid](std::string_view name){ return LookupMacro(name, invalid); }); diff --git a/src/Menu/Glue.cpp b/src/Menu/Glue.cpp index b0de665c3fc..4d0f9d7bb3d 100644 --- a/src/Menu/Glue.cpp +++ b/src/Menu/Glue.cpp @@ -10,9 +10,9 @@ namespace MenuGlue { void SetLabelText(MenuBar &bar, unsigned index, - const TCHAR *text, unsigned event) noexcept + const char *text, unsigned event) noexcept { - TCHAR buffer[100]; + char buffer[100]; const auto expanded = ButtonLabel::Expand(text, std::span{buffer}); if (expanded.visible) bar.ShowButton(index, expanded.enabled, expanded.text, event); diff --git a/src/Menu/Glue.hpp b/src/Menu/Glue.hpp index 4a0cf48dc62..cd9d5ae2bb0 100644 --- a/src/Menu/Glue.hpp +++ b/src/Menu/Glue.hpp @@ -12,7 +12,7 @@ namespace MenuGlue { void SetLabelText(MenuBar &bar, unsigned i, - const TCHAR *text, unsigned event) noexcept; + const char *text, unsigned event) noexcept; /** * Show the specified menu. diff --git a/src/Menu/MenuBar.cpp b/src/Menu/MenuBar.cpp index 7a2cf200168..f716638cd32 100644 --- a/src/Menu/MenuBar.cpp +++ b/src/Menu/MenuBar.cpp @@ -76,12 +76,12 @@ MenuBar::MenuBar(ContainerWindow &parent, const ButtonLook &look) for (unsigned i = 0; i < MAX_BUTTONS; ++i) { PixelRect button_rc = GetButtonPosition(i, rc); - buttons[i].Create(parent, look, _T(""), button_rc, style); + buttons[i].Create(parent, look, "", button_rc, style); } } void -MenuBar::ShowButton(unsigned i, bool enabled, const TCHAR *text, +MenuBar::ShowButton(unsigned i, bool enabled, const char *text, unsigned event) { assert(i < MAX_BUTTONS); diff --git a/src/Menu/MenuBar.hpp b/src/Menu/MenuBar.hpp index 9639bfcd4b2..3b91124dff0 100644 --- a/src/Menu/MenuBar.hpp +++ b/src/Menu/MenuBar.hpp @@ -39,7 +39,7 @@ class MenuBar { MenuBar(ContainerWindow &parent, const ButtonLook &look); public: - void ShowButton(unsigned i, bool enabled, const TCHAR *text, + void ShowButton(unsigned i, bool enabled, const char *text, unsigned event); void HideButton(unsigned i); diff --git a/src/Menu/MenuData.cpp b/src/Menu/MenuData.cpp index f30b9fd2263..490a553a7ff 100644 --- a/src/Menu/MenuData.cpp +++ b/src/Menu/MenuData.cpp @@ -11,7 +11,7 @@ Menu::Clear() noexcept } void -Menu::Add(const TCHAR *label, unsigned location, unsigned event_id) noexcept +Menu::Add(const char *label, unsigned location, unsigned event_id) noexcept { if (location >= items.size()) return; diff --git a/src/Menu/MenuData.hpp b/src/Menu/MenuData.hpp index 3fa83a48cac..ae8426112f2 100644 --- a/src/Menu/MenuData.hpp +++ b/src/Menu/MenuData.hpp @@ -13,7 +13,7 @@ */ class MenuItem { public: - const TCHAR *label; + const char *label; unsigned event; void Clear() noexcept { @@ -32,7 +32,7 @@ class MenuItem { */ [[gnu::pure]] bool IsDynamic() const noexcept { - return label != nullptr && _tcsstr(label, _T("$(")) != nullptr; + return label != nullptr && strstr(label, "$(") != nullptr; } }; @@ -53,7 +53,7 @@ class Menu { return items[i]; } - void Add(const TCHAR *label, unsigned location, unsigned event_id) noexcept; + void Add(const char *label, unsigned location, unsigned event_id) noexcept; [[gnu::pure]] int FindByEvent(unsigned event) const noexcept; diff --git a/src/Message.cpp b/src/Message.cpp index 4d398af1509..b04f843c0f0 100644 --- a/src/Message.cpp +++ b/src/Message.cpp @@ -7,7 +7,7 @@ #include "Interface.hpp" void -Message::AddMessage(const TCHAR *text, const TCHAR *data) noexcept +Message::AddMessage(const char *text, const char *data) noexcept { if (CommonInterface::main_window->popup != nullptr) CommonInterface::main_window->popup->AddMessage(text, data); diff --git a/src/Message.hpp b/src/Message.hpp index d642ee57232..81e440e0e48 100644 --- a/src/Message.hpp +++ b/src/Message.hpp @@ -8,6 +8,6 @@ namespace Message { void -AddMessage(const TCHAR *text, const TCHAR *data=nullptr) noexcept; +AddMessage(const char *text, const char *data=nullptr) noexcept; } // namespace Message diff --git a/src/Monitor/AirspaceWarningMonitor.cpp b/src/Monitor/AirspaceWarningMonitor.cpp index cc75465698c..0bede527256 100644 --- a/src/Monitor/AirspaceWarningMonitor.cpp +++ b/src/Monitor/AirspaceWarningMonitor.cpp @@ -30,13 +30,13 @@ class AirspaceWarningWidget final StaticString<256> buffer; [[gnu::pure]] - const TCHAR *MakeMessage(const AbstractAirspace &airspace, + const char *MakeMessage(const AbstractAirspace &airspace, AirspaceWarning::State state, const AirspaceInterceptSolution &solution) noexcept { if (state == AirspaceWarning::WARNING_INSIDE) - buffer.Format(_T("%s: %s"), _("Inside airspace"), airspace.GetName()); + buffer.Format("%s: %s", _("Inside airspace"), airspace.GetName()); else - buffer.Format(_T("%s: %s (%s)"), _("Near airspace"), airspace.GetName(), + buffer.Format("%s: %s (%s)", _("Near airspace"), airspace.GetName(), FormatTimespanSmart(solution.elapsed_time, 2).c_str()); @@ -132,7 +132,7 @@ AirspaceWarningMonitor::Check() noexcept // un-blank the display, play a sound ResetUserIdle(); - PlayResource(_T("IDR_WAV_BEEPBWEEP")); + PlayResource("IDR_WAV_BEEPBWEEP"); // show airspace warnings dialog if (CommonInterface::GetUISettings().enable_airspace_warning_dialog) @@ -166,5 +166,5 @@ AirspaceWarningMonitor::Check() noexcept // un-blank the display, play a sound ResetUserIdle(); - PlayResource(_T("IDR_WAV_BEEPBWEEP")); + PlayResource("IDR_WAV_BEEPBWEEP"); } diff --git a/src/Monitor/CMakeLists.txt b/src/Monitor/CMakeLists.txt new file mode 100644 index 00000000000..c79a42de2ee --- /dev/null +++ b/src/Monitor/CMakeLists.txt @@ -0,0 +1,51 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories + + +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/Monitor/CMakeSource.cmake b/src/Monitor/CMakeSource.cmake new file mode 100644 index 00000000000..05e4fafdf79 --- /dev/null +++ b/src/Monitor/CMakeSource.cmake @@ -0,0 +1,13 @@ +set(_SOURCES + Monitor/AirspaceWarningMonitor.cpp + Monitor/AllMonitors.cpp + Monitor/MatTaskMonitor.cpp + Monitor/TaskAdvanceMonitor.cpp + Monitor/TaskConstraintsMonitor.cpp + Monitor/WindMonitor.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake +) + diff --git a/src/Monitor/MatTaskMonitor.cpp b/src/Monitor/MatTaskMonitor.cpp index ade12963a38..8adae698e21 100644 --- a/src/Monitor/MatTaskMonitor.cpp +++ b/src/Monitor/MatTaskMonitor.cpp @@ -28,8 +28,8 @@ class MatTaskAddWidget final StaticString<256> buffer; [[gnu::pure]] - const TCHAR *MakeMessage(const Waypoint &wp) { - buffer.Format(_T("%s\n%s"), wp.name.c_str(), _("Add this turn point?")); + const char *MakeMessage(const Waypoint &wp) { + buffer.Format("%s\n%s", wp.name.c_str(), _("Add this turn point?")); return buffer; } diff --git a/src/Monitor/TaskConstraintsMonitor.cpp b/src/Monitor/TaskConstraintsMonitor.cpp index 6f565cc1e44..0916bd95a78 100644 --- a/src/Monitor/TaskConstraintsMonitor.cpp +++ b/src/Monitor/TaskConstraintsMonitor.cpp @@ -35,7 +35,7 @@ TaskConstraintsMonitor::Check() !settings.start_constraints.CheckSpeed(basic.ground_speed) && max_start_speed_clock.CheckUpdate(std::chrono::seconds(30))) { StaticString<256> msg; - msg.Format(_T("%s (%s > %s)"), _("Maximum start speed exceeded"), + msg.Format("%s (%s > %s)", _("Maximum start speed exceeded"), FormatUserSpeed(basic.ground_speed).c_str(), FormatUserSpeed(settings.start_constraints.max_speed).c_str()); Message::AddMessage(msg); diff --git a/src/NMEA/CMakeLists.txt b/src/NMEA/CMakeLists.txt new file mode 100644 index 00000000000..c79a42de2ee --- /dev/null +++ b/src/NMEA/CMakeLists.txt @@ -0,0 +1,51 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories + + +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/NMEA/CMakeSource.cmake b/src/NMEA/CMakeSource.cmake new file mode 100644 index 00000000000..0f43ef5d11e --- /dev/null +++ b/src/NMEA/CMakeSource.cmake @@ -0,0 +1,23 @@ +set(_SOURCES + NMEA/Acceleration.cpp + NMEA/Aircraft.cpp + NMEA/Attitude.cpp + NMEA/Checksum.cpp + NMEA/CirclingInfo.cpp + NMEA/ClimbHistory.cpp + NMEA/ClimbInfo.cpp + NMEA/Derived.cpp + NMEA/ExternalSettings.cpp + NMEA/FlyingState.cpp + NMEA/GPSState.cpp + NMEA/Info.cpp + NMEA/InputLine.cpp + NMEA/MoreData.cpp + NMEA/SwitchState.cpp + NMEA/ThermalLocator.cpp + NMEA/VarioInfo.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake +) diff --git a/src/NMEA/Checksum.cpp b/src/NMEA/Checksum.cpp index 2737f55b57c..70dd3174020 100644 --- a/src/NMEA/Checksum.cpp +++ b/src/NMEA/Checksum.cpp @@ -25,7 +25,12 @@ VerifyNMEAChecksum(const char *p) noexcept return false; uint8_t ReadCheckSum = (unsigned char)ReadCheckSum2; +#if defined(__APPLE__) && (!defined(TARGET_OS_IPHONE) || !TARGET_OS_IPHONE) + // MacOS workaround + uint8_t CalcCheckSum = NMEAChecksum(p); +#else // MacOS uint8_t CalcCheckSum = NMEAChecksum({p, asterisk}); +#endif // MacOS return CalcCheckSum == ReadCheckSum; } @@ -37,5 +42,10 @@ AppendNMEAChecksum(char *p) noexcept const std::size_t length = strlen(p); +#if defined(__APPLE__) && (!defined(TARGET_OS_IPHONE) || !TARGET_OS_IPHONE) + // MacOS workaround + sprintf(p + length, "*%02X", NMEAChecksum(p)); +#else // MacOS sprintf(p + length, "*%02X", NMEAChecksum({p, length})); +#endif // MacOS } diff --git a/src/NMEA/Checksum.hpp b/src/NMEA/Checksum.hpp index cb0e8577958..c5806e83fdc 100644 --- a/src/NMEA/Checksum.hpp +++ b/src/NMEA/Checksum.hpp @@ -25,7 +25,12 @@ NMEAChecksum(std::convertible_to auto &&_src) noexcept if (*p == '$' || *p == '!') ++p; +#if defined(__APPLE__) && (!defined(TARGET_OS_IPHONE) || !TARGET_OS_IPHONE) + // MacOS workaround + while (*p != 0 && *p != '*') +#else // MACOS while (*p != 0) +#endif // MACOS checksum ^= static_cast(*p++); return checksum; diff --git a/src/NMEA/DeviceInfo.hpp b/src/NMEA/DeviceInfo.hpp index 0acb4f9a58b..f62714d635c 100644 --- a/src/NMEA/DeviceInfo.hpp +++ b/src/NMEA/DeviceInfo.hpp @@ -23,23 +23,23 @@ struct DeviceInfo { /** * The name of the product. */ - NarrowString<16> product; + StaticString<16> product; /** * The serial number. This is a string because we're not sure if a * device sends non-numeric data here. */ - NarrowString<16> serial; + StaticString<16> serial; /** * The hardware version number. */ - NarrowString<16> hardware_version; + StaticString<16> hardware_version; /** * The software (or firmware) version number. */ - NarrowString<16> software_version; + StaticString<16> software_version; void Clear() { product.clear(); diff --git a/src/NMEA/Info.cpp b/src/NMEA/Info.cpp index 23d79602a8e..c2feece106b 100644 --- a/src/NMEA/Info.cpp +++ b/src/NMEA/Info.cpp @@ -134,6 +134,7 @@ NMEAInfo::Reset() noexcept settings.Clear(); external_wind_available.Clear(); + external_instantaneous_wind_available.Clear(); temperature_available = false; humidity_available = false; @@ -310,6 +311,10 @@ NMEAInfo::Complement(const NMEAInfo &add) noexcept if (external_wind_available.Complement(add.external_wind_available)) external_wind = add.external_wind; + if (external_instantaneous_wind_available.Complement( + add.external_instantaneous_wind_available)) + external_instantaneous_wind = add.external_instantaneous_wind; + if (!temperature_available && add.temperature_available) { temperature = add.temperature; temperature_available = add.temperature_available; diff --git a/src/NMEA/Info.hpp b/src/NMEA/Info.hpp index 26227795ade..d0526be1c71 100644 --- a/src/NMEA/Info.hpp +++ b/src/NMEA/Info.hpp @@ -258,18 +258,31 @@ struct NMEAInfo { //################ /** - * Is external wind information available? + * Is external average wind information available? * @see ExternalWindSpeed * @see ExternalWindDirection */ Validity external_wind_available; /** - * The wind read from the device. If ExternalWindAvailable is + * The average wind read from the device. If ExternalWindAvailable is * false, then this value is undefined. */ SpeedVector external_wind; + /** + * Is external instantaneous wind information available? + * @see ExternalWindSpeed + * @see ExternalWindDirection + */ + Validity external_instantaneous_wind_available; + + /** + * The instantaneous wind read from the device. If ExternalWindAvailable is + * false, then this value is undefined. + */ + SpeedVector external_instantaneous_wind; + /** * Is temperature information available? * @see OutsideAirTemperature @@ -587,13 +600,22 @@ struct NMEAInfo { } /** - * Set the external wind value. + * Set the external average wind value. */ constexpr void ProvideExternalWind(const SpeedVector &value) noexcept { external_wind = value; external_wind_available.Update(clock); } + /** + * Set the external instantaneous wind value. + */ + void ProvideExternalInstantaneousWind(const SpeedVector &value) { + external_instantaneous_wind = value; + external_instantaneous_wind_available.Update(clock); + } + + /** * Clears all information, start with tabula rasa. */ diff --git a/src/OV/OpenVarioMenu.cpp b/src/OV/OpenVarioMenu.cpp deleted file mode 100644 index 53c1402d74d..00000000000 --- a/src/OV/OpenVarioMenu.cpp +++ /dev/null @@ -1,490 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -// Copyright The XCSoar Project - -#include "Dialogs/DialogSettings.hpp" -#include "Dialogs/Message.hpp" -#include "Dialogs/WidgetDialog.hpp" -#include "Dialogs/ProcessDialog.hpp" -#include "Dialogs/Error.hpp" -#include "Widget/DrawWidget.hpp" -#include "Widget/RowFormWidget.hpp" -#include "Renderer/FlightListRenderer.hpp" -#include "UIGlobals.hpp" -#include "Look/DialogLook.hpp" -#include "Screen/Layout.hpp" -#include "../test/src/Fonts.hpp" -#include "ui/canvas/Canvas.hpp" -#include "ui/window/Init.hpp" -#include "ui/window/SingleWindow.hpp" -#include "ui/event/Queue.hpp" -#include "ui/event/Timer.hpp" -#include "Logger/FlightParser.hpp" -#include "Language/Language.hpp" -#include "lib/dbus/Connection.hxx" -#include "lib/dbus/ScopeMatch.hxx" -#include "lib/dbus/Systemd.hxx" -#include "system/Process.hpp" -#include "io/FileLineReader.hpp" -#include "util/PrintException.hxx" -#include "util/ScopeExit.hxx" -#include "LocalPath.hpp" - -#include -#include - -enum Buttons { - LAUNCH_SHELL = 100, -}; - -static bool have_data_path = false; - -static DialogSettings dialog_settings; -static UI::SingleWindow *global_main_window; -static DialogLook *global_dialog_look; - -const DialogSettings & -UIGlobals::GetDialogSettings() -{ - return dialog_settings; -} - -const DialogLook & -UIGlobals::GetDialogLook() -{ - assert(global_dialog_look != nullptr); - - return *global_dialog_look; -} - -UI::SingleWindow & -UIGlobals::GetMainWindow() -{ - assert(global_main_window != nullptr); - - return *global_main_window; -} - -class FileMenuWidget final - : public RowFormWidget -{ - UI::Display &display; - UI::EventQueue &event_queue; - -public: - FileMenuWidget(UI::Display &_display, UI::EventQueue &_event_queue, - const DialogLook &look) noexcept - :RowFormWidget(look), - display(_display), event_queue(_event_queue) {} - -private: - /* virtual methods from class Widget */ - void Prepare(ContainerWindow &parent, - const PixelRect &rc) noexcept override; -}; - -void -FileMenuWidget::Prepare([[maybe_unused]] ContainerWindow &parent, - [[maybe_unused]] const PixelRect &rc) noexcept -{ - AddButton("Download XCSoar IGC files to USB", [this](){ - const UI::ScopeDropMaster drop_master{display}; - const UI::ScopeSuspendEventQueue suspend_event_queue{event_queue}; - Run("/usr/bin/download-igc.sh"); - }); - - AddButton("Download XCSoar to USB", [](){ - static constexpr const char *argv[] = { - "/usr/bin/download-all.sh", nullptr - }; - - RunProcessDialog(UIGlobals::GetMainWindow(), - UIGlobals::GetDialogLook(), - "Downloading files", argv); - }); - - AddButton("Upload files from USB to XCSoar", [](){ - static constexpr const char *argv[] = { - "/usr/bin/upload-xcsoar.sh", nullptr - }; - - RunProcessDialog(UIGlobals::GetMainWindow(), - UIGlobals::GetDialogLook(), - "Uploading files", argv); - }); -} - -class SystemMenuWidget final - : public RowFormWidget -{ - UI::Display &display; - UI::EventQueue &event_queue; - -public: - SystemMenuWidget(UI::Display &_display, UI::EventQueue &_event_queue, - const DialogLook &look) noexcept - :RowFormWidget(look), - display(_display), event_queue(_event_queue) {} - -private: - /* virtual methods from class Widget */ - void Prepare(ContainerWindow &parent, - const PixelRect &rc) noexcept override; -}; - -static void -CalibrateSensors() noexcept -try { - /* make sure sensord is stopped while calibrating sensors */ - auto connection = ODBus::Connection::GetSystem(); - const ODBus::ScopeMatch job_removed_match{connection, Systemd::job_removed_match}; - - bool has_sensord = false; - - if (Systemd::IsUnitActive(connection, "sensord.socket")) { - has_sensord = true; - - try { - Systemd::StopUnit(connection, "sensord.socket"); - } catch (...) { - std::throw_with_nested(std::runtime_error{"Failed to stop sensord"}); - } - } - - AtScopeExit(&connection, has_sensord){ - if (has_sensord) - Systemd::StartUnit(connection, "sensord.socket"); - }; - - /* calibrate the sensors */ - static constexpr const char *calibrate_sensors[] = { - "/opt/bin/sensorcal", "-c", nullptr - }; - - static constexpr int STATUS_BOARD_NOT_INITIALISED = 2; - static constexpr int RESULT_BOARD_NOT_INITIALISED = 100; - int result = RunProcessDialog(UIGlobals::GetMainWindow(), - UIGlobals::GetDialogLook(), - "Calibrate Sensors", calibrate_sensors, - [](int status){ - return status == STATUS_BOARD_NOT_INITIALISED - ? RESULT_BOARD_NOT_INITIALISED - : 0; - }); - if (result != RESULT_BOARD_NOT_INITIALISED) - return; - - /* initialise the sensors? */ - if (ShowMessageBox("Sensorboard is virgin. Do you want to initialise it?", - "Calibrate Sensors", MB_YESNO) != IDYES) - return; - - static constexpr const char *init_sensors[] = { - "/opt/bin/sensorcal", "-i", nullptr - }; - - result = RunProcessDialog(UIGlobals::GetMainWindow(), - UIGlobals::GetDialogLook(), - "Calibrate Sensors", init_sensors, - [](int status){ - return status == EXIT_SUCCESS - ? mrOK - : 0; - }); - if (result != mrOK) - return; - - /* calibrate again */ - RunProcessDialog(UIGlobals::GetMainWindow(), - UIGlobals::GetDialogLook(), - "Calibrate Sensors", calibrate_sensors, - [](int status){ - return status == STATUS_BOARD_NOT_INITIALISED - ? RESULT_BOARD_NOT_INITIALISED - : 0; - }); -} catch (...) { - ShowError(std::current_exception(), "Calibrate Sensors"); -} - -void -SystemMenuWidget::Prepare([[maybe_unused]] ContainerWindow &parent, - [[maybe_unused]] const PixelRect &rc) noexcept -{ - AddButton("Update System", [](){ - static constexpr const char *argv[] = { - "/usr/bin/update-system.sh", nullptr - }; - - RunProcessDialog(UIGlobals::GetMainWindow(), - UIGlobals::GetDialogLook(), - "Update System", argv); - }); - - AddButton("Update Maps", [](){ - static constexpr const char *argv[] = { - "/usr/bin/update-maps.sh", nullptr - }; - - RunProcessDialog(UIGlobals::GetMainWindow(), - UIGlobals::GetDialogLook(), - "Update Maps", argv); - }); - - AddButton("Calibrate Sensors", CalibrateSensors); - AddButton("Calibrate Touch", [this](){ - const UI::ScopeDropMaster drop_master{display}; - const UI::ScopeSuspendEventQueue suspend_event_queue{event_queue}; - Run("/usr/bin/ov-calibrate-ts.sh"); - }); - - AddButton("System Settings", [this](){ - const UI::ScopeDropMaster drop_master{display}; - const UI::ScopeSuspendEventQueue suspend_event_queue{event_queue}; - Run("/usr/lib/openvario/libexec/system_settings.sh"); - }); - - AddButton("System Info", [this](){ - const UI::ScopeDropMaster drop_master{display}; - const UI::ScopeSuspendEventQueue suspend_event_queue{event_queue}; - Run("/usr/lib/openvario/libexec/system_info.sh"); - }); -} - -class MainMenuWidget final - : public RowFormWidget -{ - enum Controls { - XCSOAR, - LOGBOOK, - FILE, - SYSTEM, - SHELL, - REBOOT, - SHUTDOWN, - TIMER, - }; - - UI::Display &display; - UI::EventQueue &event_queue; - - WndForm &dialog; - - UI::Timer timer{[this](){ - if (--remaining_seconds == 0) { - HideRow(Controls::TIMER); - StartXCSoar(); - } else { - ScheduleTimer(); - } - }}; - - unsigned remaining_seconds = 3; - -public: - MainMenuWidget(UI::Display &_display, UI::EventQueue &_event_queue, - WndForm &_dialog) noexcept - :RowFormWidget(_dialog.GetLook()), - display(_display), event_queue(_event_queue), - dialog(_dialog) {} - -private: - void StartXCSoar() noexcept { - const UI::ScopeDropMaster drop_master{display}; - const UI::ScopeSuspendEventQueue suspend_event_queue{event_queue}; - Run("/usr/bin/xcsoar", "-fly"); - } - - void ScheduleTimer() noexcept { - assert(remaining_seconds > 0); - - timer.Schedule(std::chrono::seconds{1}); - - char buffer[256]; - snprintf(buffer, sizeof(buffer), "Starting XCSoar in %u seconds (press any key to cancel)", - remaining_seconds); - SetText(Controls::TIMER, buffer); - } - - void CancelTimer() noexcept { - timer.Cancel(); - remaining_seconds = 0; - HideRow(Controls::TIMER); - } - - /* virtual methods from class Widget */ - void Prepare(ContainerWindow &parent, - const PixelRect &rc) noexcept override; - - void Show(const PixelRect &rc) noexcept override { - RowFormWidget::Show(rc); - - if (remaining_seconds > 0) - ScheduleTimer(); - } - - void Hide() noexcept override { - CancelTimer(); - RowFormWidget::Hide(); - } - - bool KeyPress(unsigned key_code) noexcept override { - CancelTimer(); - return RowFormWidget::KeyPress(key_code); - } -}; - -static void -ShowLogbook() noexcept -{ - const auto &look = UIGlobals::GetDialogLook(); - FlightListRenderer renderer{look.text_font, look.bold_font}; - - try { - FileLineReaderA file(LocalPath("flights.log")); - - FlightParser parser{file}; - FlightInfo flight; - while (parser.Read(flight)) - renderer.AddFlight(flight); - } catch (...) { - ShowError(std::current_exception(), "Logbook"); - return; - } - - TWidgetDialog - sub_dialog(WidgetDialog::Full{}, UIGlobals::GetMainWindow(), - look, "Logbook"); - - sub_dialog.SetWidget([&renderer](Canvas &canvas, const PixelRect &rc){ - renderer.Draw(canvas, rc); - }); - - sub_dialog.AddButton(_("Close"), mrOK); - sub_dialog.ShowModal(); -} - -void -MainMenuWidget::Prepare([[maybe_unused]] ContainerWindow &parent, - [[maybe_unused]] const PixelRect &rc) noexcept -{ - AddButton("Start XCSoar", [this](){ - CancelTimer(); - StartXCSoar(); - }); - - if (have_data_path) - AddButton("Logbook", [this](){ - CancelTimer(); - ShowLogbook(); - }); - else - AddDummy(); - - AddButton("Files", [this](){ - CancelTimer(); - - TWidgetDialog - sub_dialog(WidgetDialog::Full{}, dialog.GetMainWindow(), - GetLook(), "OpenVario Files"); - sub_dialog.SetWidget(display, event_queue, GetLook()); - sub_dialog.AddButton(_("Close"), mrOK); - return sub_dialog.ShowModal(); - }); - - AddButton("System", [this](){ - CancelTimer(); - - TWidgetDialog - sub_dialog(WidgetDialog::Full{}, dialog.GetMainWindow(), - GetLook(), "OpenVario System"); - sub_dialog.SetWidget(display, event_queue, GetLook()); - sub_dialog.AddButton(_("Close"), mrOK); - return sub_dialog.ShowModal(); - }); - - AddButton("Shell", [this](){ - dialog.SetModalResult(LAUNCH_SHELL); - }); - - AddButton("Reboot", [](){ - Run("/sbin/reboot"); - }); - - AddButton("Power off", [](){ - Run("/sbin/poweroff"); - }); - - AddReadOnly(""); -} - -static int -Main(UI::EventQueue &event_queue, UI::SingleWindow &main_window, - const DialogLook &dialog_look) -{ - TWidgetDialog - dialog(WidgetDialog::Full{}, main_window, - dialog_look, "OpenVario"); - dialog.SetWidget(main_window.GetDisplay(), event_queue, dialog); - - return dialog.ShowModal(); -} - -static int -Main() -{ - dialog_settings.SetDefaults(); - - ScreenGlobalInit screen_init; - Layout::Initialise(screen_init.GetDisplay(), {600, 800}); - InitialiseFonts(); - - DialogLook dialog_look; - dialog_look.Initialise(); - - UI::TopWindowStyle main_style; - main_style.Resizable(); - - UI::SingleWindow main_window{screen_init.GetDisplay()}; - main_window.Create(_T("XCSoar/OpenVarioMenu"), {600, 800}, main_style); - main_window.Show(); - - global_dialog_look = &dialog_look; - global_main_window = &main_window; - - int action = Main(screen_init.GetEventQueue(), main_window, dialog_look); - - main_window.Destroy(); - - DeinitialiseFonts(); - - return action; -} - -int main() -{ - try { - InitialiseDataPath(); - have_data_path = true; - } catch (...) { - fprintf(stderr, "Failed to locate data path: "); - PrintException(std::current_exception()); - } - - AtScopeExit() { - if (have_data_path) - DeinitialiseDataPath(); - }; - - int action = Main(); - - switch (action) { - case LAUNCH_SHELL: - execl("/bin/bash", "bash", "--login", nullptr); - execl("/bin/ash", "-ash", nullptr); - execl("/bin/ash", "-sh", nullptr); - perror("Failed to launch shell"); - return EXIT_FAILURE; - } - - return action; -} diff --git a/src/OV/System.cpp b/src/OV/System.cpp deleted file mode 100644 index 4e9268cfb57..00000000000 --- a/src/OV/System.cpp +++ /dev/null @@ -1,153 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -// Copyright The XCSoar Project - -#include "System.hpp" -#include "lib/dbus/Connection.hxx" -#include "lib/dbus/ScopeMatch.hxx" -#include "lib/dbus/Systemd.hxx" -#include "system/FileUtil.hpp" -#include "system/Path.hpp" -#include "io/KeyValueFileReader.hpp" -#include "io/FileOutputStream.hxx" -#include "io/BufferedOutputStream.hxx" -#include "io/FileLineReader.hpp" -#include "Dialogs/Error.hpp" -#include "DisplayOrientation.hpp" -#include "Hardware/RotateDisplay.hpp" - -#include -#include -#include - -#include - -void -LoadConfigFile(std::map> &map, Path path) -{ - FileLineReaderA reader(path); - KeyValueFileReader kvreader(reader); - KeyValuePair pair; - while (kvreader.Read(pair)) - map.emplace(pair.key, pair.value); -} - -void -WriteConfigFile(std::map> &map, Path path) -{ - FileOutputStream file(path); - BufferedOutputStream buffered(file); - - for (const auto &i : map) - buffered.Fmt("{}={}\n", i.first, i.second); - - buffered.Flush(); - file.Commit(); -} - -uint_least8_t -OpenvarioGetBrightness() noexcept -{ - char line[4]; - int result = 10; - - if (File::ReadString(Path("/sys/class/backlight/lcd/brightness"), line, sizeof(line))) { - result = atoi(line); - } - - return result; -} - -void -OpenvarioSetBrightness(uint_least8_t value) noexcept -{ - if (value < 1) { value = 1; } - if (value > 10) { value = 10; } - - File::WriteExisting(Path("/sys/class/backlight/lcd/brightness"), fmt::format_int{value}.c_str()); -} - -DisplayOrientation -OpenvarioGetRotation() -{ - std::map> map; - LoadConfigFile(map, Path("/boot/config.uEnv")); - - uint_least8_t result; - result = map.contains("rotation") ? std::stoi(map.find("rotation")->second) : 0; - - switch (result) { - case 0: return DisplayOrientation::LANDSCAPE; - case 1: return DisplayOrientation::PORTRAIT; - case 2: return DisplayOrientation::REVERSE_LANDSCAPE; - case 3: return DisplayOrientation::REVERSE_PORTRAIT; - default: return DisplayOrientation::DEFAULT; - } -} - -void -OpenvarioSetRotation(DisplayOrientation orientation) -{ - std::map> map; - - Display::Rotate(orientation); - - int rotation = 0; - switch (orientation) { - case DisplayOrientation::DEFAULT: - case DisplayOrientation::LANDSCAPE: - break; - case DisplayOrientation::PORTRAIT: - rotation = 1; - break; - case DisplayOrientation::REVERSE_LANDSCAPE: - rotation = 2; - break; - case DisplayOrientation::REVERSE_PORTRAIT: - rotation = 3; - break; - }; - - File::WriteExisting(Path("/sys/class/graphics/fbcon/rotate"), fmt::format_int{rotation}.c_str()); - - LoadConfigFile(map, Path("/boot/config.uEnv")); - map.insert_or_assign("rotation", fmt::format_int{rotation}.c_str()); - WriteConfigFile(map, Path("/boot/config.uEnv")); -} - -SSHStatus -OpenvarioGetSSHStatus() -{ - auto connection = ODBus::Connection::GetSystem(); - - if (Systemd::IsUnitEnabled(connection, "dropbear.socket")) { - return SSHStatus::ENABLED; - } else if (Systemd::IsUnitActive(connection, "dropbear.socket")) { - return SSHStatus::TEMPORARY; - } else { - return SSHStatus::DISABLED; - } -} - -void -OpenvarioEnableSSH(bool temporary) -{ - auto connection = ODBus::Connection::GetSystem(); - const ODBus::ScopeMatch job_removed_match{connection, Systemd::job_removed_match}; - - if (temporary) - Systemd::DisableUnitFile(connection, "dropbear.socket"); - else - Systemd::EnableUnitFile(connection, "dropbear.socket"); - - Systemd::StartUnit(connection, "dropbear.socket"); -} - -void -OpenvarioDisableSSH() -{ - auto connection = ODBus::Connection::GetSystem(); - const ODBus::ScopeMatch job_removed_match{connection, Systemd::job_removed_match}; - - Systemd::DisableUnitFile(connection, "dropbear.socket"); - Systemd::StopUnit(connection, "dropbear.socket"); -} diff --git a/src/OV/System.hpp b/src/OV/System.hpp deleted file mode 100644 index 070fcb800e4..00000000000 --- a/src/OV/System.hpp +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -// Copyright The XCSoar Project - -#pragma once - -#include "DisplayOrientation.hpp" - -#include -#include - -class Path; - -enum class SSHStatus { - ENABLED, - DISABLED, - TEMPORARY, -}; -/** - * Load a system config file and put its variables into a map -*/ -void -LoadConfigFile(std::map> &map, Path path); -/** - * Save a map of config variables to a system config file -*/ -void -WriteConfigFile(std::map> &map, Path path); - -uint_least8_t -OpenvarioGetBrightness() noexcept; - -void -OpenvarioSetBrightness(uint_least8_t value) noexcept; - -DisplayOrientation -OpenvarioGetRotation(); - -void -OpenvarioSetRotation(DisplayOrientation orientation); - -SSHStatus -OpenvarioGetSSHStatus(); - -void -OpenvarioEnableSSH(bool temporary); - -void -OpenvarioDisableSSH(); diff --git a/src/OpenSoar.cpp b/src/OpenSoar.cpp new file mode 100644 index 00000000000..cb99472cdca --- /dev/null +++ b/src/OpenSoar.cpp @@ -0,0 +1,226 @@ +/* +Copyright_License { + + XCSoar Glide Computer - http://www.xcsoar.org/ + Copyright (C) 2000-2022 The XCSoar Project + A detailed list of copyright holders can be found in the file "AUTHORS". + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +} +*/ + +/** + * This is the main entry point for the application + * @file OpenSoar.cpp + */ + +#include "Startup.hpp" +#include "LocalPath.hpp" +#include "Version.hpp" +#include "LogFile.hpp" +#include "CommandLine.hpp" +#include "MainWindow.hpp" +#include "Interface.hpp" +#include "Look/GlobalFonts.hpp" +#include "ui/window/Init.hpp" +#include "net/http/Init.hpp" +#include "ResourceLoader.hpp" +#include "Language/Language.hpp" +#include "Language/LanguageGlue.hpp" +#include "Simulator.hpp" +#include "Audio/GlobalPCMMixer.hpp" +#include "Audio/GlobalPCMResourcePlayer.hpp" +#include "Audio/GlobalVolumeController.hpp" +#include "system/Args.hpp" +#include "io/async/GlobalAsioThread.hpp" +#include "io/async/AsioThread.hpp" +#include "util/PrintException.hxx" + +#include "UIGlobals.hpp" +#include "system/Process.hpp" + +#ifdef ENABLE_SDL +/* this is necessary on Mac OS X, to let libSDL bootstrap Quartz + before entering our main() */ +#include +#endif + +#ifdef __APPLE__ +#include +#if !TARGET_OS_IPHONE +#import +#endif +#endif + +#include + +static const char *const Usage = "\n" + " -datapath= path to XCSoar/OpenSoar data can be defined\n" +#ifdef SIMULATOR_AVAILABLE + " -simulator bypass startup-screen, use simulator mode directly\n" + " -fly bypass startup-screen, use fly mode directly\n" +#endif + " -profile=fname load profile from file fname\n" + " -WIDTHxHEIGHT use screen resolution WIDTH x HEIGHT\n" + " -portrait use a 480x640 screen resolution\n" + " -square use a 480x480 screen resolution\n" + " -small use a 320x240 screen resolution\n" +#if !defined(ANDROID) + " -dpi=DPI force usage of DPI for pixel density\n" + " -dpi=XDPIxYDPI force usage of XDPI and YDPI for pixel density\n" +#endif +#ifdef HAVE_CMDLINE_FULLSCREEN + " -fullscreen full-screen mode\n" +#endif +#ifdef HAVE_CMDLINE_RESIZABLE + " -resizable resizable window\n" +#endif +#ifdef _WIN32 + " -console open debug output console\n" +#endif + ; + +static int Main() { + ScreenGlobalInit screen_init; + +#if defined(__APPLE__) && !TARGET_OS_IPHONE + // We do not want the ugly non-localized main menu which SDL creates + [NSApp setMainMenu: [[NSMenu alloc] init]]; +#endif + +#ifdef _WIN32 + /* try to make the UI most responsive */ + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL); +#endif + + AllowLanguage(); + InitLanguage(); + + ScopeGlobalAsioThread global_asio_thread; + const Net::ScopeInit net_init(asio_thread->GetEventLoop()); + +#ifdef EXTERNAL_AUDIO_INIT + InitAudio(&asio_thread->GetEventLoop()); + // How I get this variables to live up to the end? +#else + ScopeGlobalPCMMixer global_pcm_mixer(asio_thread->GetEventLoop()); + ScopeGlobalPCMResourcePlayer global_pcm_resouce_player; + ScopeGlobalVolumeController global_volume_controller; +#endif + + // Perform application initialization and run loop + int ret = EXIT_FAILURE; + if (Startup(screen_init.GetDisplay())) + ret = CommonInterface::main_window->RunEventLoop(); + + Shutdown(); + +#ifdef EXTERNAL_AUDIO_INIT + ShutdownAudio(); +#endif + + DisallowLanguage(); + + Fonts::Deinitialize(); + + DeinitialiseDataPath(); + + return ret; +} + +static int +Finishing(int ret) { + LogString("Finishing"); + switch (ret) { + case EXIT_REBOOT: +#ifdef IS_OPENVARIO + Run("/sbin/reboot"); + break; +#endif + return ret; + case EXIT_SHUTDOWN: +#ifdef IS_OPENVARIO + Run("/sbin/poweroff"); + break; +#endif + return ret; + case EXIT_SYSTEM: + default: + break; + } + return ret; +} + +/** + * Main entry point for the whole OpenSoar application + */ +#ifndef _WIN32 +int main(int argc, char **argv) +#else +int WINAPI +WinMain(HINSTANCE hInstance, [[maybe_unused]] HINSTANCE hPrevInstance, + [[maybe_unused]] LPSTR lpCmdLine2, + [[maybe_unused]] int nCmdShow) +#endif +try { + // Read options from the command line + int ret = -1; + bool rerun = false; + do { + { + rerun = false; + // UI::TopWindow::SetExitValue(0); + +#ifdef _WIN32 + if (UIGlobals::CommandLine == nullptr) + UIGlobals::CommandLine = GetCommandLine(); + Args args(UIGlobals::CommandLine, Usage); +#else + Args args(argc, argv, Usage); +#endif + CommandLine::Parse(args); + } + + InitialiseDataPath(); + +#ifdef USE_WIN32_RESOURCES + if (!ResourceLoader::Initialized()) + ResourceLoader::Init(hInstance); +#endif + // Write startup note + version to logfile + LogFormat("Starting OpenSoar %s", OpenSoar_ProductToken); + + // int + ret = Main(); + +#if defined(__APPLE__) && TARGET_OS_IPHONE + /* For some reason, the app process does not exit on iOS, but a black + * screen remains, if the process is not explicitly terminated */ + exit(ret); +#endif + +#ifdef IS_OPENVARIO + if (ret == 0) + ret = UI::TopWindow::GetExitValue(); +#endif + rerun = (ret == EXIT_RESTART); + if (rerun) + UI::TopWindow::SetExitValue(0); + } while (rerun); + return Finishing(ret); +} catch (...) { + PrintException(std::current_exception()); + return EXIT_FAILURE; +} diff --git a/src/OpenVario/CMakeLists.txt b/src/OpenVario/CMakeLists.txt new file mode 100644 index 00000000000..42b1f6b2de1 --- /dev/null +++ b/src/OpenVario/CMakeLists.txt @@ -0,0 +1,66 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + set(TARGET_NAME OpenVarioBaseMenu) + +include(CMakeSource.cmake) +# organize the files in subdirectories +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_FOLDER}/" "" source_file ${source_file}) + string(REPLACE "${PROJECTGROUP_SOURCE_DIR}/" "../../" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_compile_definitions("OPENVARIO_DEVICE") +add_compile_definitions("IS_OPENVARIO") + +# add_compile_definitions("USE_LIBINPUT") +# remove this definition after ??? + +add_compile_definitions("OPENVARIO_BASEMENU") + +if(MSVC) + SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECTGROUP_BINARY_DIR}") +endif() + +add_executable(${TARGET_NAME} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +## target_link_libraries(${TARGET_NAME} PUBLIC Logger) + + # message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER OpenVarioBaseMenu) + +target_link_libraries(${TARGET_NAME} PUBLIC ${OPENVARIOBASEMENU_LIBS}) +add_dependencies(${TARGET_NAME} util Data) diff --git a/src/OpenVario/CMakeSource.cmake b/src/OpenVario/CMakeSource.cmake new file mode 100644 index 00000000000..32a196fd55d --- /dev/null +++ b/src/OpenVario/CMakeSource.cmake @@ -0,0 +1,116 @@ +set(TEST_SRC_DIR "${PROJECTGROUP_SOURCE_DIR}/test/src") + +set(_SOURCES + OpenVario/OpenVarioBaseMenu.cpp + OpenVario/FileMenuWidget.cpp + OpenVario/DisplaySettingsWidget.cpp + OpenVario/SystemSettingsWidget.cpp + OpenVario/ExtraWidget.cpp + + OpenVario/System/OpenVarioDevice.cpp + OpenVario/System/OpenVarioTools.cpp + + OpenVario/System/SystemMenuWidget.cpp + OpenVario/System/Setting/RotationWidget.cpp + OpenVario/System/Setting/WifiWidget.cpp + + OpenVario/System/WifiDialogOV.cpp + OpenVario/System/WifiSupplicantOV.cpp + OpenVario/System/WifiDBus.cpp + OpenVario/System/NMConnector.cpp + + ${SRC}/Version.cpp + ${SRC}/Asset.cpp + ${SRC}/Formatter/HexColor.cpp + ${SRC}/Formatter/TimeFormatter.cpp + ${SRC}/Hardware/CPU.cpp + ${SRC}/Hardware/DisplayDPI.cpp + ${SRC}/Hardware/RotateDisplay.cpp + ${SRC}/Hardware/DisplayGlue.cpp + ${SRC}/Screen/Layout.cpp + ${SRC}/ui/control/TerminalWindow.cpp + ${SRC}/Look/TerminalLook.cpp + ${SRC}/Look/DialogLook.cpp + ${SRC}/Look/ButtonLook.cpp + ${SRC}/Look/CheckBoxLook.cpp + ${SRC}/Renderer/TwoTextRowsRenderer.cpp + ${SRC}/Gauge/LogoView.cpp + ${SRC}/Dialogs/DialogSettings.cpp + ${SRC}/Dialogs/WidgetDialog.cpp + ${SRC}/Dialogs/HelpDialog.cpp + ${SRC}/Dialogs/Message.cpp + ${SRC}/Dialogs/LockScreen.cpp + ${SRC}/Dialogs/TextEntry.cpp + ${SRC}/Dialogs/KnobTextEntry.cpp + ${SRC}/Dialogs/TouchTextEntry.cpp + ${SRC}/Dialogs/ProcessDialog.cpp + ${SRC}/Profile/Map.cpp + ${SRC}/Profile/File.cpp + ${SRC}/Profile/NumericValue.cpp + ${SRC}/LocalPath.cpp + # ${TEST_SRC_DIR}/Fonts.cpp + # ${SRC}/Language/Language.cpp # ${TEST_SRC_DIR}/FakeLanguage.cpp + ${SRC}/LogFile.cpp # ${TEST_SRC_DIR}/FakeLogFile.cpp + # ${SRC}/Kobo/FakeSymbols.cpp + ${SRC}/Dialogs/DataField.cpp +) + +set(OPENVARIOBASEMENU_LIBS +# ov.mk: OV_MENU_DEPENDS = WIDGET FORM DATA_FIELD SCREEN EVENT RESOURCE ASYNC LIBNET OS IO THREAD TIME MATH UTIL +# ov.mk: OV_MENU_STRIP = y + Profile Widget Form Renderer ui event net system io thread time Math util + co Blackboard Language + Dialogs Look MapWindow + + ${FMT_LIB} ${CURL_TARGET} ${CARES_TARGET} ${ZLIB_TARGET} + ${SODIUM_TARGET} # new at 06/2020 + ${SSL_LIB} # new at 03/2021 + ${CRYPTO_LIB} # new at 03/2021 +) + +# Win32! +if(WIN32) + list(APPEND _SOURCES + ${SRC}/ui/canvas/gdi/Canvas.cpp + ${SRC}/ui/canvas/gdi/Bitmap.cpp + ${SRC}/ui/canvas/gdi/GdiPlusBitmap.cpp + ${SRC}/ui/canvas/gdi/ResourceBitmap.cpp + ) + list(APPEND OPENVARIOBASEMENU_LIBS + msimg32 + winmm + ws2_32 + gdiplus + ) +endif() +list(APPEND _SOURCES +# FakeLogFile ${SRC}/LogFile.cpp + + ${SRC}/ProgressGlue.cpp + ${SRC}/ProgressWindow.cpp + + ${SRC}/Form/DigitEntry.cpp + + ${SRC}/io/FileOutputStream.cxx + + ${SRC}/lib/fmt/SystemError.cxx + ${SRC}/Units/Descriptor.cpp + + ${SRC}/ResourceLoader.cpp + +### ${SRC}/Dialogs/ProcessDialog.cpp +### ${SRC}/Kobo/FakeSymbols.cpp +### ${SRC}/ui/control/TerminalWindow.cpp + + ${SRC}/Interface.cpp + ${SRC}/Blackboard/InterfaceBlackboard.cpp + + # ${SRC}/Operation/ConsoleOperationEnvironment.cpp + ${SRC}/Operation/Operation.cpp + +## ${SRC}/MainWindow.cpp +) +set(SCRIPT_FILES + CMakeSource.cmake + ../../build/ov.mk +) diff --git a/src/OpenVario/DisplaySettingsWidget.cpp b/src/OpenVario/DisplaySettingsWidget.cpp new file mode 100644 index 00000000000..138cbd3d939 --- /dev/null +++ b/src/OpenVario/DisplaySettingsWidget.cpp @@ -0,0 +1,182 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright The XCSoar Project + +#include "Dialogs/DialogSettings.hpp" +#include "Dialogs/Message.hpp" +#include "Dialogs/ProcessDialog.hpp" +#include "Dialogs/WidgetDialog.hpp" +#include "DisplayOrientation.hpp" +#include "Form/DataField/Listener.hpp" +#include "Form/DataField/Enum.hpp" +#include "Form/DataField/Integer.hpp" +#include "Form/DataField/Boolean.hpp" +#include "Hardware/DisplayDPI.hpp" +#include "Hardware/DisplayGlue.hpp" +#include "Hardware/RotateDisplay.hpp" +#include "Look/DialogLook.hpp" +#include "Profile/File.hpp" +#include "Profile/Map.hpp" +#include "Profile/Profile.hpp" +#include "Screen/Layout.hpp" +#include "UIGlobals.hpp" +#include "UIActions.hpp" +#include "system/FileUtil.hpp" +#include "system/Process.hpp" +#include "ui/event/KeyCode.hpp" +#include "ui/event/Timer.hpp" +#include "ui/window/Init.hpp" +#include "UtilsSettings.hpp" +#include "LogFile.hpp" + +#include "Language/Language.hpp" + +#include "io/KeyValueFileReader.hpp" +#include "io/FileOutputStream.hxx" +#include "io/BufferedOutputStream.hxx" +#include "io/FileLineReader.hpp" + +#include "OpenVario/System/OpenVarioDevice.hpp" +#include "OpenVario/DisplaySettingsWidget.hpp" +#include "OpenVario/System/Setting/RotationWidget.hpp" +#include "OpenVario/System/Setting/WifiWidget.hpp" +#include "OpenVario/System/OpenVarioTools.hpp" + +#ifndef _WIN32 +#include +#include +#endif +#include + +#include +#include + +enum ControlIndex { + ROTATION, + BRIGHTNESS, + TOUCH_SCREEN, + + TOUCH_CALIBRATION, + +}; + + static constexpr StaticEnumChoice rotation_list[] = { + // { DisplayOrientation::DEFAULT, "default" }, + {DisplayOrientation::LANDSCAPE, "Landscape (0°)"}, + {DisplayOrientation::PORTRAIT, "Portrait (90°)"}, + {DisplayOrientation::REVERSE_LANDSCAPE, "Rev. Landscape (180°)"}, + {DisplayOrientation::REVERSE_PORTRAIT, "rev. Portrait (270°)"}, + nullptr}; + +class DisplaySettingsWidget final : public RowFormWidget, DataFieldListener { +public: + DisplaySettingsWidget() noexcept + : RowFormWidget(UIGlobals::GetDialogLook()) {} + + /* virtual methods from class Widget */ + void Prepare(ContainerWindow &parent, const PixelRect &rc) noexcept override; + bool Save(bool &changed) noexcept override; + // bool CheckChanged(bool &changed) noexcept; + +private: + /* methods from DataFieldListener */ + void OnModified(DataField &df) noexcept override; + void RotateDisplay(DisplayOrientation orientation) noexcept; + void SetEnabled(bool enabled) noexcept; + + unsigned brightness = 0; + unsigned rotation = 0; + + ContainerWindow* parent; + +}; + +void DisplaySettingsWidget::RotateDisplay( + DisplayOrientation orientation) noexcept { + ovdevice.SetRotation(orientation, 1); // internal rotation only +} + +void DisplaySettingsWidget::SetEnabled([[maybe_unused]] bool enabled) noexcept { + SetRowEnabled(TOUCH_CALIBRATION, enabled); +} + +void DisplaySettingsWidget::OnModified([[maybe_unused]] DataField &df) noexcept +{ + if (IsDataField(ROTATION, df)) { + RotateDisplay((DisplayOrientation)((const DataFieldEnum &)df).GetValue()); + } else if (IsDataField(BRIGHTNESS, df)) { + auto new_brightness = ((const DataFieldInteger &)df).GetValue(); + if (new_brightness != brightness) + ovdevice.SetBrightness(new_brightness / 10); + } else if (IsDataField(TOUCH_SCREEN, df)) { + SetEnabled(((const DataFieldBoolean &)df).GetValue()); + } +} + + +void +DisplaySettingsWidget::Prepare([[maybe_unused]] ContainerWindow &_parent, + [[maybe_unused]] const PixelRect &rc) noexcept +{ + parent = &_parent; + brightness = ovdevice.brightness * 10; + ovdevice.rotation = ovdevice.GetRotation(); + rotation = (unsigned)ovdevice.rotation; + + LogFmt("Rotation-Init {}", rotation); + + AddEnum(_("Rotation"), _("Rotation Display OpenVario"), rotation_list, + (unsigned)ovdevice.rotation, this); + + AddInteger(_("Brightness"), _("Brightness Display OpenVario"), "%d%%", + "%d%%", 10, 100, 10, brightness, this); + + AddBoolean(_("Touch enabled"), _("Enabling the tTouch Screen"), ovdevice.touch, this); + + auto touchBtn = AddButton(_("Calibrate Touch"), [this]() { + ContainerWindow::SetExitValue(LAUNCH_TOUCH_CALIBRATE); + UIActions::SignalShutdown(true); + return mrOK; + }); + touchBtn->SetEnabled(ovdevice.touch); +} + +bool +DisplaySettingsWidget::Save([[maybe_unused]] bool &_changed) noexcept { + bool changed = false; + if (SaveValueEnum(ROTATION, ovdevice.rotation)) { + /* On OpenVario never use another orientation as DEFAULT, because we set + * the correct value directly in the config.uEnv */ + Profile::Set(ProfileKeys::MapOrientation, + (unsigned)DisplayOrientation::DEFAULT); + ovdevice.SetRotation(ovdevice.rotation, 6); // fbcon and config.uEnv + // Now no restart necessary! + // UI::TopWindow::SetExitValue(EXIT_NEWSTART); + // require_restart = + changed = true; + } + + if (SaveValueInteger(BRIGHTNESS, "Brightness", brightness)) { + ovdevice.SetBrightness(brightness / 10); + changed = true; + } + + changed |= SaveValue(TOUCH_SCREEN, "TouchScreen", ovdevice.touch, false); + _changed = changed; + return true; +} + +bool +ShowDisplaySettingsWidget(ContainerWindow &parent, + const DialogLook &look) noexcept { + TWidgetDialog sub_dialog( + WidgetDialog::Full{}, (UI::SingleWindow &)parent, look, + "OpenVario Display Settings"); + sub_dialog.SetWidget(); + sub_dialog.AddButton(_("Close"), mrOK); + return sub_dialog.ShowModal(); +} + +std::unique_ptr +CreateDisplaySettingsWidget() noexcept { + return std::make_unique(); +} diff --git a/src/OpenVario/DisplaySettingsWidget.hpp b/src/OpenVario/DisplaySettingsWidget.hpp new file mode 100644 index 00000000000..cf763ee1366 --- /dev/null +++ b/src/OpenVario/DisplaySettingsWidget.hpp @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright The XCSoar Project + +#pragma once + +#ifdef IS_OPENVARIO + +#include + +class Widget; +class ContainerWindow; +class DialogLook; + +bool ShowDisplaySettingsWidget(ContainerWindow &parent, + const DialogLook &look) noexcept; + +std::unique_ptr +CreateDisplaySettingsWidget() noexcept; +#endif \ No newline at end of file diff --git a/src/OpenVario/ExtraWidget.cpp b/src/OpenVario/ExtraWidget.cpp new file mode 100644 index 00000000000..b43a2d76194 --- /dev/null +++ b/src/OpenVario/ExtraWidget.cpp @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright The XCSoar Project + +#ifdef IS_OPENVARIO + +#include "OpenVario/ExtraWidget.hpp" + +#include "Dialogs/ProcessDialog.hpp" +#include "Dialogs/WidgetDialog.hpp" +#include "Form/Form.hpp" +#include "Hardware/DisplayGlue.hpp" +#include "Hardware/RotateDisplay.hpp" +#include "Language/Language.hpp" +#include "Widget/RowFormWidget.hpp" + +#include "UIGlobals.hpp" + +#include "OpenVario/System/OpenVarioDevice.hpp" +#include "OpenVario/System/OpenVarioTools.hpp" + +#if 1 // Segmentation fault? def OPENVARIO_BASEMENU +# include "UIActions.hpp" +# include "ui/window/ContainerWindow.hpp" +#endif + +#include +#include + +constexpr const char *opensoar = "OpenSoar"; +constexpr const char *xcsoar = "XCSoar"; +constexpr const char *main_app = opensoar; +constexpr const char *_main_app = "OpenSoar"; // only temporarily + +class ExtraWidget final : public RowFormWidget { +public: + ExtraWidget() noexcept : RowFormWidget(UIGlobals::GetDialogLook()) {} + +private: + /* virtual methods from class Widget */ + void Prepare(ContainerWindow &parent, const PixelRect &rc) noexcept override; +}; + +void ExtraWidget::Prepare([[maybe_unused]] ContainerWindow &parent, + [[maybe_unused]] const PixelRect &rc) noexcept +{ +#if 0 + std::string ImageFile = ""; + AddFile(_("Upgrade Firmware"), + _("Upgrade Firmware (.img.gz) "), + ImageFile, "*.img.gz\0", FileType::IMAGE); + +#else + AddButton(_("Upgrade Firmware"), [this]() { +#if 0 // Segmentation fault? def OPENVARIO_BASEMENU + exit(START_UPGRADE); +#else // OPENVARIO_BASEMENU + ContainerWindow::SetExitValue(START_UPGRADE); + UIActions::SignalShutdown(false); + return mrOK; // START_UPGRADE; +#endif + }); +#endif + /* deprecated: */ AddButton(_("Calibrate Sensors"), CalibrateSensors); + + /* deprecated: */ AddButton(_("Calibrate Touch"), [this]() { +// the programm exit in OpenSoar looks complete different fro OpenVarioBaseMenu +#if 0 // Segmentation fault? def OPENVARIO_BASEMENU + exit(LAUNCH_TOUCH_CALIBRATE); +#else // OPENVARIO_BASEMENU + ContainerWindow::SetExitValue(LAUNCH_TOUCH_CALIBRATE); + UIActions::SignalShutdown(true); + return mrOK; +#endif // OPENVARIO_BASEMENU + }); +} + +bool +ShowExtraWidget(ContainerWindow &parent, + const DialogLook &look) noexcept +{ + TWidgetDialog sub_dialog( + WidgetDialog::Full{}, (UI::SingleWindow &)parent, look, + _("OpenVario File Transfers")); + sub_dialog.SetWidget(); + sub_dialog.AddButton(_("Close"), mrOK); + return sub_dialog.ShowModal(); +} + +std::unique_ptr +CreateExtraWidget() noexcept { + return std::make_unique(); +} +#endif diff --git a/src/OpenVario/ExtraWidget.hpp b/src/OpenVario/ExtraWidget.hpp new file mode 100644 index 00000000000..813418a8802 --- /dev/null +++ b/src/OpenVario/ExtraWidget.hpp @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright The XCSoar Project +#pragma once + +#ifdef IS_OPENVARIO + +#include + +class Widget; +class ContainerWindow; +struct DialogLook; + +bool +ShowExtraWidget(ContainerWindow &parent, + const DialogLook &look) noexcept; + +std::unique_ptr +CreateExtraWidget() noexcept; + +#endif \ No newline at end of file diff --git a/src/OpenVario/FileMenuWidget.cpp b/src/OpenVario/FileMenuWidget.cpp new file mode 100644 index 00000000000..177c53ef8cb --- /dev/null +++ b/src/OpenVario/FileMenuWidget.cpp @@ -0,0 +1,128 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright The XCSoar Project + +#ifdef IS_OPENVARIO + +#include "FileMenuWidget.hpp" +#include "Dialogs/ProcessDialog.hpp" +#include "Dialogs/WidgetDialog.hpp" +#include "Form/Form.hpp" +#include "Hardware/DisplayGlue.hpp" +#include "Hardware/RotateDisplay.hpp" +#include "Language/Language.hpp" +#include "Widget/RowFormWidget.hpp" + +#include "UIGlobals.hpp" + +// #include "ui/event/Globals.hpp" +// #include "ui/display/Display.hpp" + +#include +#include + +constexpr const char *opensoar = "OpenSoar"; +constexpr const char *xcsoar = "XCSoar"; +constexpr const char *main_app = opensoar; +constexpr const char *_main_app = "OpenSoar"; // only temporarily + +class FileMenuWidget final : public RowFormWidget { +public: + FileMenuWidget() noexcept : RowFormWidget(UIGlobals::GetDialogLook()) {} + +private: + /* virtual methods from class Widget */ + void Prepare(ContainerWindow &parent, const PixelRect &rc) noexcept override; +}; + +void FileMenuWidget::Prepare([[maybe_unused]] ContainerWindow &parent, + [[maybe_unused]] const PixelRect &rc) noexcept +{ + StaticString<60> title; + + AddButton(_("Upload IGC Files to USB (WIP)"), []() { + static constexpr const char *argv[] = { + "/usr/bin/download-igc.sh", nullptr + }; + RunProcessDialog(UIGlobals::GetMainWindow(), + UIGlobals::GetDialogLook(), + _("Download IGC Files"), argv); + }); + + //----------------------------------------------------- + title.Format(_(" - File Transfers %s Data"), main_app); + AddLabel(title); + + AddButton(_("Save: OpenVario -> USB"), []() { + static constexpr const char *argv[] = { + "/usr/bin/transfers.sh", "download-data", _main_app, nullptr + }; + + RunProcessDialog(UIGlobals::GetMainWindow(), + UIGlobals::GetDialogLook(), + _("Download files"), argv); + }); + + AddButton(_("Restore: OpenVario <- USB"), []() { + static constexpr const char *argv[] = {"/usr/bin/transfers.sh", + "upload-data", _main_app, nullptr}; + + StaticString<32> dialog_title; + dialog_title.Format(_("Restore %s"), main_app); + RunProcessDialog(UIGlobals::GetMainWindow(), UIGlobals::GetDialogLook(), + dialog_title, argv); + }); + + //----------------------------------------------------- + title.Format(_("- Complete System Data Transfers"), main_app); + AddLabel(title); // "---OpenSoar Data Files---"); + + AddButton(_("Backup: OpenVario System to USB"), []() { + static constexpr const char *argv[] = {"/usr/bin/transfer-system.sh", + "backup", _main_app, nullptr + }; + + RunProcessDialog(UIGlobals::GetMainWindow(), + UIGlobals::GetDialogLook(), + _("Backup System"), argv); + }); + + AddButton(_("Restore: OpenVario System from USB"), []() { + static constexpr const char *argv[] = {"/usr/bin/transfer-system.sh", + "restore", _main_app, nullptr + }; + RunProcessDialog(UIGlobals::GetMainWindow(), + UIGlobals::GetDialogLook(), + _("Restore System"), argv); + Display::Rotate(Display::DetectInitialOrientation()); + }); + + auto btn = AddButton(_("Image Backup to USB (WIP)"), []() { + static constexpr const char *argv[] = {"/usr/bin/transfer-system.sh", + "restore", _main_app, nullptr + }; + RunProcessDialog(UIGlobals::GetMainWindow(), + UIGlobals::GetDialogLook(), + _("Backup Image"), argv); + Display::Rotate(Display::DetectInitialOrientation()); + }); + btn->SetEnabled(false); +} + +bool +ShowFileMenuWidget(ContainerWindow &parent, + const DialogLook &look) noexcept +{ + TWidgetDialog sub_dialog( + WidgetDialog::Full{}, (UI::SingleWindow &)parent, look, + _("OpenVario File Transfers")); + sub_dialog.SetWidget(); + sub_dialog.AddButton(_("Close"), mrOK); + return sub_dialog.ShowModal(); +} + +std::unique_ptr +CreateFileMenuWidget() noexcept { + return std::make_unique(); +} + +#endif // IS_OPENVARIO \ No newline at end of file diff --git a/src/OpenVario/FileMenuWidget.hpp b/src/OpenVario/FileMenuWidget.hpp new file mode 100644 index 00000000000..cc68a5243bd --- /dev/null +++ b/src/OpenVario/FileMenuWidget.hpp @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright The XCSoar Project +#pragma once + +#ifdef IS_OPENVARIO + +#include + +class Widget; +class ContainerWindow; +struct DialogLook; + +bool +ShowFileMenuWidget(ContainerWindow &parent, + const DialogLook &look) noexcept; + +std::unique_ptr +CreateFileMenuWidget() noexcept; + +#endif \ No newline at end of file diff --git a/src/OpenVario/OpenVarioBaseMenu.cpp b/src/OpenVario/OpenVarioBaseMenu.cpp new file mode 100644 index 00000000000..a8b04cfa0e5 --- /dev/null +++ b/src/OpenVario/OpenVarioBaseMenu.cpp @@ -0,0 +1,435 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright The XCSoar Project + +#include "Dialogs/DialogSettings.hpp" +#include "Dialogs/WidgetDialog.hpp" +#include "Widget/RowFormWidget.hpp" +#include "UIGlobals.hpp" +#include "Look/DialogLook.hpp" +#include "Screen/Layout.hpp" + +#include "ui/window/Init.hpp" +#include "ui/window/SingleWindow.hpp" +#include "ui/event/Timer.hpp" +#include "ui/event/KeyCode.hpp" + +#include "Language/Language.hpp" +#include "system/Process.hpp" +#include "system/FileUtil.hpp" +#include "Profile/Profile.hpp" +#include "Profile/File.hpp" +#include "Profile/Map.hpp" +#include "DisplayOrientation.hpp" +#include "Hardware/DisplayGlue.hpp" +#include "Hardware/DisplayDPI.hpp" +#include "Hardware/RotateDisplay.hpp" +#include "util/StaticString.hxx" + +#include "OpenVario/FileMenuWidget.hpp" +#include "OpenVario/ExtraWidget.hpp" +#include "OpenVario/DisplaySettingsWidget.hpp" +#include "OpenVario/SystemSettingsWidget.hpp" + +#include "OpenVario/System/OpenVarioDevice.hpp" +#include "OpenVario/System/SystemMenuWidget.hpp" + +#include "LocalPath.hpp" +#include "LogFile.hpp" +#include "Dialogs/Message.hpp" + +#include +#include +#include +#include +#include + +static DialogSettings dialog_settings; +static UI::SingleWindow *global_main_window; +static DialogLook *global_dialog_look; +static unsigned StartTimeout = 1; + +const DialogSettings & +UIGlobals::GetDialogSettings() +{ + return dialog_settings; +} + +const DialogLook & +UIGlobals::GetDialogLook() +{ + assert(global_dialog_look != nullptr); + + return *global_dialog_look; +} + +UI::SingleWindow & +UIGlobals::GetMainWindow() +{ + assert(global_main_window != nullptr); + + return *global_main_window; +} + +class MainMenuWidget final + : public RowFormWidget +{ + unsigned remaining_seconds = 3; + + UI::Display &display; + UI::EventQueue &event_queue; + + WndForm &dialog; + + UI::Timer timer{[this](){ + if (remaining_seconds == (unsigned)-1) + CancelTimer(); + else if (--remaining_seconds == 0) { + progress_timer->Hide(); + StartOpenSoar(); // StartXCSoar(); + } else { + ScheduleTimer(); + } + }}; + +public: + MainMenuWidget(UI::Display &_display, UI::EventQueue &_event_queue, + WndForm &_dialog) noexcept + :RowFormWidget(_dialog.GetLook()), + display(_display), event_queue(_event_queue), + dialog(_dialog) { + ovdevice.LoadSettings(); + remaining_seconds = StartTimeout == 0 ? 0 : ovdevice.timeout; + } + +private: + int StartSoarExe(std::string_view exe, + std::filesystem::path _datapath = "") noexcept; + + int StartOpenSoar() noexcept { + std::filesystem::path datapath = ""; + if (ovdevice.settings.find("OpenSoarData") != ovdevice.settings.end()) + datapath = ovdevice.settings.find("OpenSoarData")->second; + else + datapath = ovdevice.GetDataPath().ToUTF8() + "/OpenSoarData/"; + + int ret_value = StartSoarExe("OpenSoar", datapath); + + // after OpenSoar the settings can be changed + ovdevice.LoadSettings(); + switch (ret_value) { + case 200: // simple exit from OpenSoar, go in menu + break; + case 201: + Run("/sbin/reboot"); + break; + case 202: + Run("/sbin/poweroff"); + break; + case LAUNCH_SHELL: // "Exit to shell' + exit(100); + case START_UPGRADE: + case LAUNCH_TOUCH_CALIBRATE: + exit(ret_value); + default: + break; + } + return ret_value; + } + + int StartXCSoar() noexcept { + std::filesystem::path datapath = ""; + if (ovdevice.settings.find("XCSoarData") != ovdevice.settings.end()) + datapath = ovdevice.settings.find("XCSoarData")->second; + else + datapath = ovdevice.GetDataPath().ToUTF8() + "/XCSoarData/"; + return StartSoarExe("xcsoar", datapath); + } + + void ScheduleTimer() noexcept { + assert(remaining_seconds > 0); + + timer.Schedule(std::chrono::seconds{1}); + + StaticString<256> buffer; + buffer.Format("Starting XCSoar in %u seconds (press any key to cancel)", + remaining_seconds); + progress_timer->SetText(buffer); + } + + void CancelTimer() noexcept { + timer.Cancel(); + remaining_seconds = 0; + progress_timer->Hide(); + } + + /* virtual methods from class Widget */ + void Prepare(ContainerWindow &parent, + const PixelRect &rc) noexcept override; + + void Show(const PixelRect &rc) noexcept override { + RowFormWidget::Show(rc); + + switch (remaining_seconds) { + case (unsigned)-1: + progress_timer->Hide(); + break; // Do Nothing ! + case 0: + progress_timer->Hide(); + StartOpenSoar(); // StartXCSoar(); + break; + default: + ScheduleTimer(); + break; + } + } + + void Hide() noexcept override { + CancelTimer(); + RowFormWidget::Hide(); + } + + bool KeyPress(unsigned key_code) noexcept override { + CancelTimer(); + + /* ignore escape key at first menu page */ + if (key_code != KEY_ESCAPE) { + return RowFormWidget::KeyPress(key_code); + } + else { + return true; + } + } + + WndProperty *progress_timer = nullptr; +}; + +int +MainMenuWidget::StartSoarExe(std::string_view _exe, + std::filesystem::path _datapath) noexcept { + int ret_value = 0; + const UI::ScopeDropMaster drop_master{display}; + const UI::ScopeSuspendEventQueue suspend_event_queue{event_queue}; + + std::filesystem::path ExePath = ovdevice.GetBinPath().append(_exe); +#ifdef _WIN32 + ExePath += ".exe"; +#endif + // std::string for memory storage reasons + std::string exe = ExePath.string().c_str(); + LogFormat("ExePath = %s", exe.c_str()); + printf("ExePath = %s\n", exe.c_str()); + if (File::Exists(Path(ExePath.c_str()))) { + std::vector ArgList; + ArgList.reserve(10); + ArgList = {exe.c_str(), "-fly"}; + + //=============== Datapath ======================= + StaticString<0x200> datapath("-datapath="); + if (_datapath.empty()) { + _datapath = GetPrimaryDataPath().c_str(); + } else { + datapath.append(_datapath.generic_string()); + datapath.append("/"); // last delimiter + } + if (!datapath.empty()) + ArgList.push_back(datapath.c_str()); + + //=============== Profile ======================= + if (ovdevice.settings.find("MainProfile") != ovdevice.settings.end()) { + StaticString<0x80> profile(""); + profile = "-profile="; + std::string str = ovdevice.settings.find("MainProfile")->second; + profile += ovdevice.settings.find("MainProfile")->second; + ArgList.push_back(profile.c_str()); + } + + //=============== Profile ======================= +#ifdef _WIN32 // OpenVario needs no format field! + if (ovdevice.settings.find("Format") != ovdevice.settings.end()) { + StaticString<0x10> format(""); + format = "-"; + format += ovdevice.settings.find("Format")->second; + ArgList.push_back(format.c_str()); + // LogFormat("format = %s", format.c_str()); + } else { + ArgList.push_back("-1400x700"); + } +#endif + //=============== End of Parameter ======================= + ArgList.push_back(nullptr); + //======================================================== + ret_value = Run(&ArgList[0]); + } else { // ExePath doesnt exist! + LogFormat("Program file '%s' doesnt exist!", ExePath.c_str()); +#ifdef _WIN32 + // with Linux ShowMessageBox -> crash! + ShowMessageBox(_("Program file doesnt exist!"), "Run", + MB_OK | MB_ICONEXCLAMATION); +#endif + } + return ret_value; +} + +void MainMenuWidget::Prepare([[maybe_unused]] ContainerWindow &parent, + [[maybe_unused]] const PixelRect &rc) noexcept { + + [[maybe_unused]] auto Btn_Club = // unused + AddButton(_("Start OpenSoar (Club)"), [this]() { + CancelTimer(); + StartOpenSoar(); + }); + + AddButton(_("Start OpenSoar"), [this]() { + CancelTimer(); + StartOpenSoar(); + }); + + [[maybe_unused]] auto Btn_XCSoar = AddButton(_("Start XCSoar"), [this]() { + CancelTimer(); + StartXCSoar(); + }); + + //---------------------------------------------------------- + AddReadOnly(""); // split between start cmds and setting + //---------------------------------------------------------- + + AddButton(_("File Transfers"), [this]() { + CancelTimer(); + return ShowFileMenuWidget(UIGlobals::GetMainWindow(), GetLook()); + }); + + AddButton(_("Display Settings"), [this]() { + CancelTimer(); + return ShowDisplaySettingsWidget(UIGlobals::GetMainWindow(), GetLook()); + }); + + AddButton(_("System Settings"), [this]() { + CancelTimer(); + return ShowSystemSettingsWidget(UIGlobals::GetMainWindow(), GetLook()); + }); + + AddButton(_("OpenVario Extra menu "), [this]() { + CancelTimer(); + return ShowExtraWidget(UIGlobals::GetMainWindow(), GetLook()); + }); + + AddButton(_("OpenVario Placeholder"), [this]() { + CancelTimer(); + return ShowSystemMenuWidget(UIGlobals::GetMainWindow(), GetLook()); + +// TWidgetDialog sub_dialog( +// WidgetDialog::Full{}, UIGlobals::GetMainWindow(), GetLook(), +// "OpenVario Placeholder Settings"); +// sub_dialog.SetWidget(display, event_queue, sub_dialog); +// // sub_dialog.SetWidget(); +// sub_dialog.AddButton(_("Close"), mrOK); +// return sub_dialog.ShowModal(); + }); + + //---------------------------------------------------------- + AddReadOnly(""); // split setting and switch off cmds + //---------------------------------------------------------- + + auto Btn_Shell = AddButton("Exit to Shell", + [this]() { dialog.SetModalResult(LAUNCH_SHELL); }); + +#ifndef RELEASE_VERSION + AddButton("Exit to Shell (with Wait)", + [this]() { dialog.SetModalResult(LAUNCH_SHELL_STOP); }); +#endif + + auto Btn_Reboot = + AddButton("Reboot", []() { Run("/sbin/reboot"); }); + // auto Btn_Reboot = AddButton("Reboot", []() { Run("/sbin/reboot"); }); + + auto Btn_Shutdown = + AddButton("Power off", []() { Run("/sbin/poweroff"); }); + // AddButton("Power off", []() { "/sbin/poweroff"); }); + + //---------------------------------------------------------- + progress_timer = RowFormWidget::Add("", "", true); + // AddReadOnly(""); // Timer-Progress + //---------------------------------------------------------- + + if (!ovdevice.IsReal()) { + Btn_Shell->SetCaption("Exit"); + Btn_Reboot->SetEnabled(false); + Btn_Shutdown->SetEnabled(false); + } + // Btn_XCSoar->SetEnabled(File::Exists); + + progress_timer->Hide(); +} + +static int +Main(UI::EventQueue &event_queue, UI::SingleWindow &main_window, + const DialogLook &dialog_look) +{ + TWidgetDialog + dialog(WidgetDialog::Full{}, main_window, + dialog_look, "OpenVario Base Menu"); + dialog.SetWidget(main_window.GetDisplay(), event_queue, dialog); + + return dialog.ShowModal(); +} + +static int +Main() +{ + InitialiseDataPath(); + ovdevice.Initialise(); + + dialog_settings.SetDefaults(); + + ScreenGlobalInit screen_init; + Layout::Initialise(screen_init.GetDisplay(), {600, 800}); + // InitialiseFonts(); + + // AllowLanguage is not in FalkLanguage + AllowLanguage(); + + DialogLook dialog_look; + dialog_look.Initialise(); + + UI::TopWindowStyle main_style; + main_style.Resizable(); +#ifndef _WIN32 + main_style.InitialOrientation(Display::DetectInitialOrientation()); +#endif + + UI::SingleWindow main_window{screen_init.GetDisplay()}; + main_window.Create("OpenSoar/OpenVarioBaseMenu", {600, 800}, main_style); + main_window.Show(); + + global_dialog_look = &dialog_look; + global_main_window = &main_window; + + if (!ovdevice.IsReal()) { + assert(File::Exists(ovdevice.GetSettingsConfig())); + } + + int action = Main(screen_init.GetEventQueue(), main_window, dialog_look); + + main_window.Destroy(); + + // DeinitialiseFonts(); + DeinitialiseDataPath(); + + return action; +} + +int +main(int argc, char *argv[]) +{ + if (argc > 0) + ovdevice.SetBinPath(argv[0]); + if (argc > 1) + StartTimeout = std::strtoul(argv[1], nullptr, 10); + /* the OpenVarioBaseMenu is waiting a second to solve timing problem with + display rotation */ + std::this_thread::sleep_for(std::chrono::seconds(1)); + + int action = Main(); + // save in LogFormat? + return action; +} diff --git a/src/OpenVario/System/NMConnector.cpp b/src/OpenVario/System/NMConnector.cpp new file mode 100644 index 00000000000..a4258873cfa --- /dev/null +++ b/src/OpenVario/System/NMConnector.cpp @@ -0,0 +1,110 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2011 Red Hat, Inc. + */ + +#if 0 // __MSVC__ + +// #ifndef __MSVC__ +/* + * The example shows how to add a new connection using libnm. Contrast this + * example with add-connection-gdbus.c, which is a bit lower level and talks + * directly to NM using GDBus. This example is simpler because libnm handles + * much of the low-level stuff for you. + * + * Compile with: + * gcc -Wall add-connection-libnm.c -o add-connection-libnm `pkg-config --libs + * --cflags libnm` + */ + +#include +#include + +static void added_cb(GObject *client, GAsyncResult *result, + gpointer user_data) { + GMainLoop *loop = user_data; + NMRemoteConnection *remote; + GError *error = NULL; + + /* NM responded to our request; either handle the resulting error or + * print out the object path of the connection we just added. + */ + remote = nm_client_add_connection_finish(NM_CLIENT(client), result, &error); + + if (error) { + g_print("Error adding connection: %s", error->message); + g_error_free(error); + } else { + g_print("Added: %s\n", nm_connection_get_path(NM_CONNECTION(remote))); + g_object_unref(remote); + } + + /* Tell the mainloop we're done and we can quit now */ + g_main_loop_quit(loop); +} + +static void add_connection(NMClient *client, GMainLoop *loop, + const char *con_name) { + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + char *uuid; + + /* Create a new connection object */ + connection = nm_simple_connection_new(); + + /* Build up the 'connection' Setting */ + s_con = (NMSettingConnection *)nm_setting_connection_new(); + uuid = nm_utils_uuid_generate(); + g_object_set(G_OBJECT(s_con), NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_ID, con_name, NM_SETTING_CONNECTION_TYPE, + "802-3-ethernet", NULL); + g_free(uuid); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + /* Build up the 'wired' Setting */ + s_wired = (NMSettingWired *)nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); + + /* Build up the 'ipv4' Setting */ + s_ip4 = (NMSettingIP4Config *)nm_setting_ip4_config_new(); + g_object_set(G_OBJECT(s_ip4), NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + + /* Ask the settings service to add the new connection; we'll quit the + * mainloop and exit when the callback is called. + */ + nm_client_add_connection_async(client, connection, TRUE, NULL, added_cb, + loop); + g_object_unref(connection); +} + +int main(int argc, char *argv[]) { + NMClient *client; + GMainLoop *loop; + GError *error = NULL; + + loop = g_main_loop_new(NULL, FALSE); + + /* Connect to NetworkManager */ + client = nm_client_new(NULL, &error); + if (!client) { + g_message("Error: Could not connect to NetworkManager: %s.", + error->message); + g_error_free(error); + return 1; + } + + /* Ask NM to add the new connection */ + add_connection(client, loop, "__Test connection__"); + /* Wait for the connection to be added */ + g_main_loop_run(loop); + + /* Clean up */ + g_object_unref(client); + + return 0; +} +#endif // __MSVC__ diff --git a/src/OpenVario/System/OpenVarioDevice.cpp b/src/OpenVario/System/OpenVarioDevice.cpp new file mode 100644 index 00000000000..6d88c99dbb7 --- /dev/null +++ b/src/OpenVario/System/OpenVarioDevice.cpp @@ -0,0 +1,443 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright The XCSoar Project + +#include "OpenVario/System/OpenVarioDevice.hpp" +#ifdef DBUS_FUNCTIONS +# include "lib/dbus/Connection.hxx" +# include "lib/dbus/ScopeMatch.hxx" +# include "lib/dbus/Systemd.hxx" +#endif + +#include "system/Process.hpp" +#include "system/FileUtil.hpp" +#include "io/KeyValueFileReader.hpp" +#include "io/FileOutputStream.hxx" +#include "io/BufferedOutputStream.hxx" +#include "io/FileLineReader.hpp" +#include "Dialogs/Error.hpp" +#include "Hardware/RotateDisplay.hpp" + +#include "Profile/File.hpp" +#include "Profile/Map.hpp" + +#include "util/StaticString.hxx" +#include "util/StringCompare.hxx" + +#include "LogFile.hpp" +#include "LocalPath.hpp" + +#ifndef _WIN32 +#include +#include +#endif +#include + +#include + +#include +#include + +#ifndef __MSVC__ +#include +#include +#endif + +#include + +using std::string_view_literals::operator""sv; + +OpenVario_Device ovdevice; + + +void ReadBool(std::map> &map, + std::string_view name, bool &value) noexcept; +void ReadInteger(std::map> &map, + std::string_view name, unsigned &value) noexcept; +void ReadString(std::map> &map, + std::string_view name, std::string_view &value) noexcept; + + void +OpenVario_Device::Initialise() noexcept { + if (!initialised) { + InitialiseDataPath(); + StaticString<0x100> home; + home.SetUTF8(getenv("HOME")); + home_path = Path(home); +#ifdef _WIN32 + data_path = Path("D:/Data/OpenSoarData"); +#else + data_path = Path("data"); + + system_config = + AllocatedPath::Build(Path("/boot"), Path("config.uEnv")); + is_real = File::Exists(system_config); +#endif + if (!is_real) // a pseudo 'config' file in home_path + system_config = AllocatedPath::Build(home_path, Path("config.uEnv")); + + if (Directory::Exists(data_path)) { + // auto config = AllocatedPath::Build(data_path, + // Path("openvario.cfg")); + settings_config = + AllocatedPath::Build(data_path, Path("openvario.cfg")); + upgrade_config = AllocatedPath::Build(data_path, Path("upgrade.cfg")); + } else { + settings_config = + AllocatedPath::Build(home_path, Path("openvario.cfg")); + upgrade_config = AllocatedPath::Build(home_path, Path("upgrade.cfg")); + } + if (!File::Exists(settings_config)) + File::CreateExclusive(settings_config); + + assert(File::Exists(settings_config)); + +#ifndef DBUS_FUNCTIONS + // This path is only for Debug purposes on Non-OpenVario systems + internal_config = + AllocatedPath::Build(home_path, Path("ov-internal.cfg")); +#endif + //---------------------------- + LogFormat("data_path (base) = %s", data_path.ToUTF8().c_str()); +#ifdef DEBUG_OPENVARIO + LogFormat("home_path = %s", home_path.ToUTF8().c_str()); + LogFormat("settings_config = %s", settings_config.ToUTF8().c_str()); + LogFormat("system_config = %s", system_config.ToUTF8().c_str()); + LogFormat("upgrade_config = %s", upgrade_config.ToUTF8().c_str()); + // the same...: LogFormat("upgrade_config = %s", upgrade_config.c_str()); + LogFormat("is_real = %s", is_real ? "True" : "False"); + + LogFormat("exe_path = %s", exe_path.c_str()); + LogFormat("bin_path = %s", bin_path.c_str()); +#endif + //---------------------------- + run_output_file = AllocatedPath::Build(home_path, Path("tmp.txt")); + LoadSettings(); + initialised = true; + } +} +void OpenVario_Device::Deinitialise() noexcept {} +//---------------------------------------------------------- +void ReadBool(std::map> &map, + std::string_view name, bool &value) noexcept { + if (map.find(name) != map.end()) + value = map.find(name)->second != "False"; +} +//---------------------------------------------------------- +void +ReadInteger(std::map> &map, + std::string_view name, unsigned &value) noexcept try { + auto iter = map.find(name); + if (iter != map.end()) { + value = std::stoul(iter->second); + } +} catch (std::exception &e) { + LogFormat("ReadInteger-Exception: %s", e.what()); +} +//---------------------------------------------------------- +void ReadString(std::map> &map, + std::string_view name, std::string_view &value) noexcept { + if (map.find(name) != map.end()) + value = map.find(name)->second; +} +//---------------------------------------------------------- +void +OpenVario_Device::LoadSettings() noexcept { + LoadConfigFile(system_map, GetSystemConfig()); + LoadConfigFile(settings, GetSettingsConfig()); + LoadConfigFile(upgrade_map, GetUpgradeConfig()); +#ifndef DBUS_FUNCTIONS + LoadConfigFile(internal_map, GetInternalConfig()); +#endif + ReadSettings(); +} + +//---------------------------------------------------------- +void OpenVario_Device::ReadSettings() noexcept { + unsigned i_rot = 0; + ReadInteger(system_map, "rotation", i_rot); + rotation = (DisplayOrientation) i_rot; +#ifdef _DEBUG + std::string_view fdtfile; + ReadString(system_map, "fdtfile", fdtfile); +#endif + + ReadBool(settings, "Enabled", enabled); + ReadBool(settings, "TouchScreen", touch); +#ifdef _DEBUG + ReadInteger(settings, "iTest", iTest); +#endif + ReadInteger(settings, "Timeout", timeout); + + brightness = GetBrightness(); + ssh = (unsigned)GetSSHStatus(); + sensord = GetSystemStatus("sensord"); + variod = GetSystemStatus("variod"); + rotation = GetRotation(); + +} +//---------------------------------------------------------- +void +LoadConfigFile(std::map> &map, Path path) +{ + if (File::Exists(path)) { + FileLineReaderA reader(path); + KeyValueFileReader kvreader(reader); + KeyValuePair pair; + while (kvreader.Read(pair)) { + map.emplace(pair.key, pair.value); + } + } +} + +//---------------------------------------------------------- +void +WriteConfigFile(std::map> &map, Path path) +{ + FileOutputStream file(path); + BufferedOutputStream buffered(file); + + for (const auto &i : map) + buffered.Fmt("{}={}\n", i.first, i.second); + + buffered.Flush(); + file.Commit(); +} + +//---------------------------------------------------------- +uint_least8_t +OpenVario_Device::GetBrightness() noexcept +{ + char line[4]; + int result = 10; + + if (File::ReadString(Path("/sys/class/backlight/lcd/brightness"), line, sizeof(line))) { + result = atoi(line); + } + + return result; +} + +void +OpenVario_Device::SetBrightness(uint_least8_t value) noexcept +{ + if (value < 1) { value = 1; } + if (value > 10) { value = 10; } + + brightness = value; + settings.insert_or_assign("Brightness", + std::to_string(value)); + File::WriteExisting(Path("/sys/class/backlight/lcd/brightness"), fmt::format_int{value}.c_str()); +} + +DisplayOrientation +OpenVario_Device::GetRotation() +{ + std::map> map; + LoadConfigFile(map, system_config); // Path("/boot/config.uEnv")); + if (map.contains("Rotation")) // this is wrong!!! + map.erase("Rotation"); + + uint_least8_t result; + result = map.contains("rotation") ? std::stoi(map.find("rotation")->second) : 0; + + switch (result) { + case 0: return DisplayOrientation::LANDSCAPE; + case 1: return DisplayOrientation::REVERSE_PORTRAIT; + case 2: return DisplayOrientation::REVERSE_LANDSCAPE; + case 3: return DisplayOrientation::PORTRAIT; + default: return DisplayOrientation::DEFAULT; + } + +} + +void +OpenVario_Device::SetRotation(DisplayOrientation orientation, int mode) +{ + std::map> map; + + LoadConfigFile(map, system_config); // Path("/boot/config.uEnv")); + if (map.contains("Rotation")) // this is wrong!!! + map.erase("Rotation"); + + if (mode & 1) + Display::Rotate(orientation); + + int rotation = 0; + switch (orientation) { + case DisplayOrientation::DEFAULT: + case DisplayOrientation::LANDSCAPE: + break; + case DisplayOrientation::REVERSE_PORTRAIT: + rotation = 1; + break; + case DisplayOrientation::REVERSE_LANDSCAPE: + rotation = 2; + break; + case DisplayOrientation::PORTRAIT: + rotation = 3; + break; + }; + + std::string rot_string = fmt::format_int{rotation}.c_str(); + if (map["rotation"] != rot_string) { + LogFormat("Set Rotation '%s' vs. '%s' (%d)", map["rotation"].c_str(), + rot_string.c_str(), rotation); + } + + + if (map["rotation"] != rot_string) { + if (mode & 2) { + File::WriteExisting(Path("/sys/class/graphics/fbcon/rotate"), + rot_string.c_str()); + } + + if (mode & 4) { + map.insert_or_assign("rotation", rot_string); + WriteConfigFile(map, system_config); + } + } +} + +#ifdef DBUS_FUNCTIONS +SSHStatus +OpenVario_Device::GetSSHStatus() noexcept +{ + auto connection = ODBus::Connection::GetSystem(); + + if (Systemd::IsUnitEnabled(connection, "dropbear.socket")) { + return SSHStatus::ENABLED; + } else if (Systemd::IsUnitActive(connection, "dropbear.socket")) { + return SSHStatus::TEMPORARY; + } else { + return SSHStatus::DISABLED; + } +} + +void +OpenVario_Device::SetSSHStatus(SSHStatus state) noexcept +{ + auto connection = ODBus::Connection::GetSystem(); + const ODBus::ScopeMatch job_removed_match{connection, + Systemd::job_removed_match}; + switch (state) { + case SSHStatus::ENABLED: + Systemd::EnableUnitFile(connection, "dropbear.socket"); + Systemd::StartUnit(connection, "dropbear.socket"); + break; + case SSHStatus::TEMPORARY: + Systemd::DisableUnitFile(connection, "dropbear.socket"); + Systemd::StartUnit(connection, "dropbear.socket"); + break; + case SSHStatus::DISABLED: + Systemd::DisableUnitFile(connection, "dropbear.socket"); + Systemd::StopUnit(connection, "dropbear.socket"); + break; + } +} + +bool +OpenVario_Device::GetSystemStatus(std::string_view system) noexcept +{ +#ifdef WITH_NEW_DBUS + auto connection = ODBus::Connection::GetSystem(); + return Systemd::IsUnitEnabled(connection, system.data()); +#else + // StaticString + + StaticString<0x20> file; + + std::string_view _dirname("/home/august2111"); + //Path run_tmp_file("/home/august2111/test.txt"); + Path run_tmp_file(_dirname.data()); + + if (system == "sensord") + file = "SensorD.txt"; + else if (system == "variod") + file = "VarioD.txt"; + else if (system == "dropbear.socket") + file = "SSH.txt"; + AllocatedPath _tmp_file = AllocatedPath::Build(home_path, Path(file)); + + Path tmp_file = _tmp_file; + + if (File::Exists(tmp_file)) + File::Delete(tmp_file); // remove, if exists + auto run_value = Run(tmp_file, "/bin/systemctl", "is-enabled", system.data()); + char buffer[0x20]; + File::ReadString(tmp_file, buffer, sizeof(buffer)); + switch (run_value) { + case 0: + if (std::string_view(buffer).starts_with("enabled")) + std::strncpy(buffer, "enabled -> ok!", sizeof(buffer)); + else + std::strncpy(buffer, "enabled -> not ok???", sizeof(buffer)); + return true; + case 1: + if (std::string_view(buffer).starts_with("disabled")) + std::strncpy(buffer, "disabled -> ok!", sizeof(buffer)); + else + std::strncpy(buffer, "disabled -> not ok???", sizeof(buffer)); + return false; + default: + return false; + } +#endif +} +void +OpenVario_Device::SetSystemStatus(std::string_view system, bool value) noexcept +{ +#ifdef WITH_NEW_DBUS + auto connection = ODBus::Connection::GetSystem(); + if (value) + Systemd::EnableUnitFile(connection, system.data()); + else + Systemd::DisableUnitFile(connection, system.data()); +#else + Run("/bin/systemctl", value ? "enable" : "disable", system.data()); +#endif +} + +#else // DBUS_FUNCTIONS +bool +OpenVario_Device::GetSystemStatus(std::string_view system) noexcept { + bool value; + ReadBool(internal_map, system.data(), value); + return value != 0; +} +void +OpenVario_Device::SetSystemStatus(std::string_view system, bool value) noexcept { + internal_map.insert_or_assign(system.data(), + value ? "True" : "False"); + WriteConfigFile(internal_map, GetInternalConfig()); +} + +SSHStatus +OpenVario_Device::GetSSHStatus() noexcept +{ + unsigned ssh; + ReadInteger(ovdevice.internal_map, "SSH", ssh); + + if (ssh == 0) { + return SSHStatus::ENABLED; + } else if (ssh == 1) { + return SSHStatus::DISABLED; + } else { + return SSHStatus::TEMPORARY; + } +} + +void +OpenVario_Device::SetSSHStatus(SSHStatus state) noexcept +{ + switch (state) { + case SSHStatus::DISABLED: + case SSHStatus::ENABLED: + case SSHStatus::TEMPORARY: + ovdevice.internal_map.insert_or_assign("SSH", + std::to_string((unsigned)state)); + WriteConfigFile(ovdevice.internal_map, ovdevice.GetInternalConfig()); + break; + } +} +#endif // DBUS_FUNCTIONS +//---------------------------------------------------------- diff --git a/src/OpenVario/System/OpenVarioDevice.hpp b/src/OpenVario/System/OpenVarioDevice.hpp new file mode 100644 index 00000000000..6088f3007a4 --- /dev/null +++ b/src/OpenVario/System/OpenVarioDevice.hpp @@ -0,0 +1,156 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright The XCSoar Project + +#pragma once + +#include "DisplayOrientation.hpp" +#include "Language/Language.hpp" +#include "system/Path.hpp" +// #include "LogFile.hpp" + +#include + +#include +#include +#include + + +#define DEBUG_TEST_VERSION 1 +#if !DEBUG_TEST_VERSION +#define RELEASE_VERSION +#endif + + +#define DEBUG_OPENVARIO 1 +#if defined(IS_OPENVARIO_CB2) + // && __has_include("dbus/dbus.h") +# define DBUS_FUNCTIONS 1 +# warning (Attention: DBUS is enabled) +#elif __GNUC__ +// # warning (Attention: No DBUS!) +#else +// #pragma message("Attention: No DBUS!") +#endif + +enum class SSHStatus { + ENABLED, + DISABLED, + TEMPORARY, +}; + +class OpenVario_Device { +public: + OpenVario_Device() { + Initialise(); + } + + void Initialise() noexcept; + void Deinitialise() noexcept; + void LoadSettings() noexcept; + void ReadSettings() noexcept; + Path GetSystemConfig() noexcept { return system_config; } + // void SetSystemConfig(Path configfile) noexcept { system_config = configfile; } + std::map> system_map; + + Path GetSettingsConfig() noexcept { return settings_config; } + // void SetSettingsConfig(Path configfile) noexcept { + // settings_config = configfile; + // } + std::map> settings; + + Path GetUpgradeConfig() noexcept { return upgrade_config; } + // void SetUpgradeConfig(Path configfile) noexcept { + // upgrade_config = configfile; + // } + std::map> upgrade_map; +#ifndef DBUS_FUNCTIONS + // This map is only for Debug purposes on Non-OpenVario systems + std::map> internal_map; + Path GetInternalConfig() noexcept { return internal_config; } +#endif + bool + IsReal() noexcept + { + return is_real; + } + Path GetDataPath() noexcept { return data_path; } + Path GetHomePath() noexcept { return home_path; } + std::filesystem::path GetBinPath() noexcept { return bin_path; } + std::filesystem::path GetExePath() noexcept { return exe_path; } + std::filesystem::path GetExeName() noexcept { + return exe_path.filename().replace_extension(); + } + void SetBinPath(const char *path) noexcept { + exe_path = path; + // std::filesystem::path::path + bin_path = exe_path.parent_path(); + } + Path GetRunTempFile() noexcept { return run_output_file; } + + struct { + bool enabled = true; + bool touch = false; + unsigned brightness = 100; + unsigned timeout = 5; + DisplayOrientation rotation = DisplayOrientation::DEFAULT; + + unsigned iTest = 0; + }; + + struct { // internal data + bool sensord = false; + bool variod = false; + unsigned ssh = (unsigned) SSHStatus::DISABLED; + }; + + + uint_least8_t GetBrightness() noexcept; + void SetBrightness(uint_least8_t value) noexcept; + DisplayOrientation GetRotation(); + void SetRotation(DisplayOrientation orientation, int mode=0); + + bool GetSystemStatus(std::string_view system) noexcept; + void SetSystemStatus(std::string_view system, bool value) noexcept; + SSHStatus GetSSHStatus() noexcept; + void SetSSHStatus(SSHStatus state) noexcept; + + private: + AllocatedPath system_config; // system config file, in the OV the + // /boot/config.uEnf + AllocatedPath upgrade_config; // the config file for upgrading OV + AllocatedPath settings_config; // the config file for settings inside + // the OpenVarioBaseMenu + AllocatedPath run_output_file; // the temp file in Run() processes +// AllocatedPath run_output_file; // the temp file in Run() processes +#ifndef DBUS_FUNCTIONS + // This path is only for Debug purposes on Non-OpenVario systems + AllocatedPath internal_config; +#endif + + AllocatedPath home_path; + AllocatedPath data_path; + + bool is_real = false; + bool initialised = false; +#if 1 // test with filesystem + std::filesystem::path exe_path; + std::filesystem::path bin_path; +#else + AllocatedPath exe_path; + AllocatedPath bin_path; +#endif +}; +extern OpenVario_Device ovdevice; + +class Path; + +/** + * Load a system config file and put its variables into a map +*/ +void +LoadConfigFile(std::map> &map, Path path); +/** + * Save a map of config variables to a system config file +*/ +void +WriteConfigFile(std::map> &map, Path path); diff --git a/src/OpenVario/System/OpenVarioTools.cpp b/src/OpenVario/System/OpenVarioTools.cpp new file mode 100644 index 00000000000..660ebfff186 --- /dev/null +++ b/src/OpenVario/System/OpenVarioTools.cpp @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright The XCSoar Project + +#include "OpenVario/System/OpenVarioTools.hpp" + +#include "Dialogs/ProcessDialog.hpp" +#include "Dialogs/Message.hpp" +#include "Form/Form.hpp" + +#include "UIGlobals.hpp" +#include "system/FileUtil.hpp" + +#include "Widget/RowFormWidget.hpp" + +#include "system/Process.hpp" +#include "ui/event/KeyCode.hpp" +#include "ui/event/Timer.hpp" +#include "ui/window/Init.hpp" +#include "util/ScopeExit.hxx" + + +//---------------------------------------------------------- + +void +CalibrateSensors() noexcept +{ + /* make sure sensord is stopped while calibrating sensors */ + static constexpr const char *start_sensord[] = {"/bin/systemctl", "start", + "sensord.service", nullptr}; + static constexpr const char *stop_sensord[] = {"/bin/systemctl", "stop", + "sensord.service", nullptr}; + + RunProcessDialog(UIGlobals::GetMainWindow(), UIGlobals::GetDialogLook(), + "Calibrate Sensors", stop_sensord, [](int status) { + return status == EXIT_SUCCESS ? mrOK : 0; + }); + + AtScopeExit() { + RunProcessDialog(UIGlobals::GetMainWindow(), UIGlobals::GetDialogLook(), + "Calibrate Sensors", start_sensord, [](int status) { + return status == EXIT_SUCCESS ? mrOK : 0; + }); + }; + + /* calibrate the sensors */ + static constexpr const char *calibrate_sensors[] = {"/opt/bin/sensorcal", + "-c", nullptr}; + + static constexpr int STATUS_BOARD_NOT_INITIALISED = 2; + static constexpr int RESULT_BOARD_NOT_INITIALISED = 100; + int result = RunProcessDialog( + UIGlobals::GetMainWindow(), UIGlobals::GetDialogLook(), + "Calibrate Sensors", calibrate_sensors, [](int status) { + return status == STATUS_BOARD_NOT_INITIALISED + ? RESULT_BOARD_NOT_INITIALISED + : 0; + }); + if (result != RESULT_BOARD_NOT_INITIALISED) + return; + + /* initialise the sensors? */ + if (ShowMessageBox("Sensorboard is virgin. Do you want to initialise it?", + "Calibrate Sensors", MB_YESNO) != IDYES) + return; + + static constexpr const char *init_sensors[] = {"/opt/bin/sensorcal", "-i", + nullptr}; + + result = + RunProcessDialog(UIGlobals::GetMainWindow(), UIGlobals::GetDialogLook(), + "Calibrate Sensors", init_sensors, [](int status) { + return status == EXIT_SUCCESS ? mrOK : 0; + }); + if (result != mrOK) + return; + + /* calibrate again */ + RunProcessDialog(UIGlobals::GetMainWindow(), UIGlobals::GetDialogLook(), + "Calibrate Sensors", calibrate_sensors, [](int status) { + return status == STATUS_BOARD_NOT_INITIALISED + ? RESULT_BOARD_NOT_INITIALISED + : 0; + }); +} diff --git a/src/OpenVario/System/OpenVarioTools.hpp b/src/OpenVario/System/OpenVarioTools.hpp new file mode 100644 index 00000000000..ac67bd37e26 --- /dev/null +++ b/src/OpenVario/System/OpenVarioTools.hpp @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright The XCSoar Project + +#pragma once + +void CalibrateSensors() noexcept; diff --git a/src/OpenVario/System/Setting/RotationWidget.cpp b/src/OpenVario/System/Setting/RotationWidget.cpp new file mode 100644 index 00000000000..6052c12bd2e --- /dev/null +++ b/src/OpenVario/System/Setting/RotationWidget.cpp @@ -0,0 +1,115 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright The XCSoar Project + +#include "Dialogs/DialogSettings.hpp" +#include "Dialogs/Message.hpp" +#include "Dialogs/ProcessDialog.hpp" +#include "Dialogs/WidgetDialog.hpp" +#include "DisplayOrientation.hpp" +#include "Hardware/DisplayDPI.hpp" +#include "Hardware/DisplayGlue.hpp" +#include "Hardware/RotateDisplay.hpp" +#include "Look/DialogLook.hpp" +#include "Profile/File.hpp" +#include "Profile/Map.hpp" +#include "Screen/Layout.hpp" +#include "UIGlobals.hpp" +#include "system/FileUtil.hpp" +#include "system/Process.hpp" +#include "ui/event/KeyCode.hpp" +#include "ui/event/Timer.hpp" +#include "ui/window/Init.hpp" + +#include "Language/Language.hpp" + +#include "io/KeyValueFileReader.hpp" +#include "io/FileOutputStream.hxx" +#include "io/BufferedOutputStream.hxx" +#include "io/FileLineReader.hpp" + +#include "Widget/RowFormWidget.hpp" + + +#include "OpenVario/System/OpenVarioDevice.hpp" +#include "OpenVario/System/Setting/RotationWidget.hpp" + +#ifndef __MSVC__ +#include +#include +#endif +#include + +#include +#include + +//---------------------------------------------------------- +//---------------------------------------------------------- +//---------------------------------------------------------- + +/* x-menu writes the value for the display rotation to /sys because the value is also required for the console in the OpenVario. +In addition, the display rotation is saved in /boot/config.uEnv so that the Openvario sets the correct rotation again when it is restarted.*/ + +class SettingRotationWidget final : public RowFormWidget { + +public: + SettingRotationWidget() noexcept + : RowFormWidget(UIGlobals::GetDialogLook()) {} + +private: + /* virtual methods from class Widget */ + void Prepare(ContainerWindow &parent, const PixelRect &rc) noexcept override; + void SaveRotation(const std::string &rotationvalue); +}; + +/*/ +void +SettingRotationWidget::SaveRotation(const int rotationInt) +{ + + File::WriteExisting(Path("/sys/class/graphics/fbcon/rotate"), (rotationString).c_str()); +// int rotationInt = stoi(rotationString); + // ChangeConfigInt("rotation", rotationInt, ovdevice.GetSettingsConfig()); + // TODO(August2111): move the from ovdevice.settings to ovdevice.sysetm + LoadConfigFile(ovdevice.system_map, ovdevice.GetSystemConfig()); // -> OpenVarioBaseMenu->StartUp! + ovdevice.rotation = (DisplayOrientation) stoi(rotationString); + ovdevice.system_map.insert_or_assign("rotation", std::to_string((unsigned) ovdevice.rotation)); + WriteConfigFile(ovdevice.system_map, ovdevice.GetSystemConfig()); +} +*/ + +void +SettingRotationWidget::Prepare([[maybe_unused]] ContainerWindow &parent, + [[maybe_unused]] const PixelRect &rc) noexcept +{ + AddButton("Landscape", [this](){ + // SaveRotation("2"); + // Display::Rotate(DisplayOrientation::LANDSCAPE); + ovdevice.SetRotation(DisplayOrientation::LANDSCAPE); + }); + + AddButton("Portrait (90°)", [this](){ + //SaveRotation("1"); + ovdevice.SetRotation(DisplayOrientation::REVERSE_PORTRAIT); + }); + + AddButton("Landscape (180°)", [this](){ + // SaveRotation("4"); + ovdevice.SetRotation(DisplayOrientation::REVERSE_LANDSCAPE); + }); + + AddButton("Portrait (270°)", [this](){ + // SaveRotation("3"); + ovdevice.SetRotation(DisplayOrientation::PORTRAIT); + }); +} + +bool +ShowRotationSettingsWidget(ContainerWindow &parent, + const DialogLook &look) noexcept { + TWidgetDialog sub_dialog( + WidgetDialog::Full{}, (UI::SingleWindow &)parent, look, + "OpenVario Rotation Settings"); + sub_dialog.SetWidget(); + sub_dialog.AddButton(_("Close"), mrOK); + return sub_dialog.ShowModal(); +} diff --git a/src/OpenVario/System/Setting/RotationWidget.hpp b/src/OpenVario/System/Setting/RotationWidget.hpp new file mode 100644 index 00000000000..11631f9c982 --- /dev/null +++ b/src/OpenVario/System/Setting/RotationWidget.hpp @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright The XCSoar Project + +#pragma once + +#include + +// class Widget; +class ContainerWindow; +class DialogLook; + +bool +ShowRotationSettingsWidget(ContainerWindow &parent, + const DialogLook &look) noexcept; + + +// std::unique_ptr CreateSettingRotationWidget() noexcept; diff --git a/src/OpenVario/System/Setting/WifiWidget.cpp b/src/OpenVario/System/Setting/WifiWidget.cpp new file mode 100644 index 00000000000..ee18ad01a92 --- /dev/null +++ b/src/OpenVario/System/Setting/WifiWidget.cpp @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright The XCSoar Project + +#include "Dialogs/DialogSettings.hpp" +#include "Dialogs/Message.hpp" +#include "Dialogs/ProcessDialog.hpp" +#include "Dialogs/WidgetDialog.hpp" +#include "DisplayOrientation.hpp" +#include "Hardware/DisplayDPI.hpp" +#include "Hardware/DisplayGlue.hpp" +#include "Hardware/RotateDisplay.hpp" +#include "Look/DialogLook.hpp" +#include "Profile/File.hpp" +#include "Profile/Map.hpp" +#include "Screen/Layout.hpp" +#include "UIGlobals.hpp" +#include "system/FileUtil.hpp" +#include "system/Process.hpp" +#include "ui/event/KeyCode.hpp" +#include "ui/event/Timer.hpp" +#include "ui/window/Init.hpp" + +#include "Language/Language.hpp" + +#include "io/KeyValueFileReader.hpp" +#include "io/FileOutputStream.hxx" +#include "io/BufferedOutputStream.hxx" +#include "io/FileLineReader.hpp" + +#include "OpenVario/System/OpenVarioDevice.hpp" +#include "OpenVario/System/Setting/WifiWidget.hpp" + +#ifndef __MSVC__ +#include +#include +#endif +#include + +#include +#include + +//---------------------------------------------------------- +//---------------------------------------------------------- +//---------------------------------------------------------- diff --git a/src/OpenVario/System/Setting/WifiWidget.hpp b/src/OpenVario/System/Setting/WifiWidget.hpp new file mode 100644 index 00000000000..d4dbe691280 --- /dev/null +++ b/src/OpenVario/System/Setting/WifiWidget.hpp @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright The XCSoar Project + +#pragma once + +#include "Widget/RowFormWidget.hpp" +#include "ui/event/Queue.hpp" +#include "ui/window/SingleWindow.hpp" + diff --git a/src/OpenVario/System/SystemMenuWidget.cpp b/src/OpenVario/System/SystemMenuWidget.cpp new file mode 100644 index 00000000000..d6213455a52 --- /dev/null +++ b/src/OpenVario/System/SystemMenuWidget.cpp @@ -0,0 +1,263 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright The XCSoar Project + +#ifdef IS_OPENVARIO +// don't use (and compile) this code outside an OpenVario project! + +#include "Dialogs/DialogSettings.hpp" +#include "Dialogs/Message.hpp" +#include "Dialogs/ProcessDialog.hpp" +#include "Dialogs/WidgetDialog.hpp" +#include "DisplayOrientation.hpp" +#include "Hardware/DisplayDPI.hpp" +#include "Hardware/DisplayGlue.hpp" +#include "Hardware/RotateDisplay.hpp" +#include "Look/DialogLook.hpp" +#include "Profile/File.hpp" +#include "Profile/Map.hpp" +#include "Screen/Layout.hpp" +#include "UIGlobals.hpp" +#include "system/FileUtil.hpp" + +#include "Widget/RowFormWidget.hpp" + +# include "system/Process.hpp" +#include "ui/event/KeyCode.hpp" +#include "ui/event/Timer.hpp" +#include "ui/window/Init.hpp" +#include "util/ScopeExit.hxx" + +#include "OpenVario/SystemSettingsWidget.hpp" + +#include "OpenVario/System/OpenVarioDevice.hpp" +#include "OpenVario/System/OpenVarioTools.hpp" + +#include "OpenVario/System/SystemMenuWidget.hpp" + +#include "system/Process.hpp" + +#include // for std::cout << ... +#include +#include + +#if 1 // Segmentation fault? def OPENVARIO_BASEMENU +# include "ui/window/ContainerWindow.hpp" +# include "UIActions.hpp" +#endif + +class SystemMenuWidget final : public RowFormWidget { +public: + SystemMenuWidget() noexcept : RowFormWidget(UIGlobals::GetDialogLook()) {} + + void SetEnabled([[maybe_unused]]bool enabled) noexcept {} + + /* virtual methods from class Widget */ + void Prepare(ContainerWindow &parent, const PixelRect &rc) noexcept override; + bool Save(bool &changed) noexcept override { return true; } + +private: + +}; + +//----------------------------------------------------------------------------- +class ScreenSSHWidget final : public RowFormWidget { + +public: + ScreenSSHWidget() noexcept : RowFormWidget(UIGlobals::GetDialogLook()) {} + +private: + /* virtual methods from class Widget */ + void Prepare(ContainerWindow &parent, const PixelRect &rc) noexcept override; +}; + +void ScreenSSHWidget::Prepare([[maybe_unused]] ContainerWindow &parent, + [[maybe_unused]] const PixelRect &rc) noexcept { + AddButton("Enable", []() { + static constexpr const char *argv[] = { + "/bin/sh", "-c", + "systemctl enable --now dropbear.socket && printf '\nSSH has been enabled'", + + nullptr}; + + RunProcessDialog(UIGlobals::GetMainWindow(), UIGlobals::GetDialogLook(), + "Enable", argv); + }); + + AddButton("Disable", []() { + static constexpr const char *argv[] = { + "/bin/sh", "-c", + "systemctl disable --now dropbear.socket && printf '\nSSH has been disabled'", + nullptr}; + + RunProcessDialog(UIGlobals::GetMainWindow(), UIGlobals::GetDialogLook(), + "Disable", argv); + }); + + AddButton("IsEnabled", []() { + static constexpr const char *argv[] = { + "/bin/sh", "-c", + "systemctl is-enabled dropbear.socket", + nullptr}; + + RunProcessDialog(UIGlobals::GetMainWindow(), UIGlobals::GetDialogLook(), + "IsEnabled", argv); + }); + AddButton("IsActive", []() { + static constexpr const char *argv[] = { + "/bin/sh", "-c", + "systemctl is-active dropbear.socket", + nullptr}; + + RunProcessDialog(UIGlobals::GetMainWindow(), UIGlobals::GetDialogLook(), + "IsActive", argv); + }); + + AddButton("GetStatus", []() { + static constexpr const char *argv[] = { + "/bin/sh", "-c", + "systemctl is-enabled dropbear.socket", + "systemctl is-active dropbear.socket", nullptr}; + + RunProcessDialog(UIGlobals::GetMainWindow(), UIGlobals::GetDialogLook(), + "GetStatus", argv); + }); + AddButton("GetStatus2", []() { + static constexpr const char *argv[] = { + "/bin/sh", "-c", + "/bin/systemctl is-enabled dropbear.socket", + "echo '\n ===== \n'", + "/bin/systemctl is-active dropbear.socket", nullptr}; + + RunProcessDialog(UIGlobals::GetMainWindow(), UIGlobals::GetDialogLook(), + "GetStatus2", argv); + }); +} + +//----------------------------------------------------------------------------- +void +SystemMenuWidget::Prepare([[maybe_unused]] ContainerWindow &parent, + [[maybe_unused]] const PixelRect &rc) noexcept +{ + AddButton(_("Upgrade Firmware"), [this]() { +#if 0 // Segmentation fault? def OPENVARIO_BASEMENU + exit(START_UPGRADE); +#else // OPENVARIO_BASEMENU + ContainerWindow::SetExitValue(START_UPGRADE); + UIActions::SignalShutdown(true); + return START_UPGRADE; +#endif + }); + +#if 1 + // the variant with command line... + // UI::SingleWindow main_window = + AddButton("SSH", [this]() { + TWidgetDialog sub_dialog(WidgetDialog::Full{}, + // dialog.GetMainWindow(), GetLook(), + UIGlobals::GetMainWindow(), GetLook(), + "Enable or Disable SSH"); + sub_dialog.SetWidget(); + sub_dialog.AddButton(_("Close"), mrOK); + return sub_dialog.ShowModal(); + }); +#endif + + AddButton(_("Update System"), [](){ + static constexpr const char *argv[] = { + "/usr/bin/update-system.sh", nullptr + }; + + RunProcessDialog(UIGlobals::GetMainWindow(), + UIGlobals::GetDialogLook(), + "Update System", argv); + }); + + AddButton(_("Calibrate Sensors"), CalibrateSensors); + + AddButton(_("Calibrate Touch"), [this]() { +// the programm exit in OpenSoar looks complete different fro OpenVarioBaseMenu +#if 0 // Segmentation fault? def OPENVARIO_BASEMENU + exit(LAUNCH_TOUCH_CALIBRATE); +#else // OPENVARIO_BASEMENU + ContainerWindow::SetExitValue(LAUNCH_TOUCH_CALIBRATE); + UIActions::SignalShutdown(true); + return mrOK; + // InputEvents::eventShutdown("reboot"); + // dialog.SetModalResult(LAUNCH_TOUCH_CALIBRATE); + // dialog.SetModalResult(LAUNCH_TOUCH_CALIBRATE); + +#if 0 +#if defined(_WIN32) + static constexpr const char *argv[] = { "/usr/bin/ov-calibrate-ts.sh", + nullptr}; + + RunProcessDialog(UIGlobals::GetMainWindow(), UIGlobals::GetDialogLook(), + "Calibrate Touch", argv); +#else +// const UI::ScopeDropMaster drop_master{display}; +// const UI::ScopeSuspendEventQueue + // suspend_event_queue{event_queue}; + // RunProcessDialog(UIGlobals::GetMainWindow(), + // UIGlobals::GetDialogLook(), + // "System Info", "/usr/bin/ov-calibrate-ts.sh"); +// Run("/usr/bin/ov-calibrate-ts.sh"); +#endif +#endif +#endif // OPENVARIO_BASEMENU + }); + + AddButton(_("System Info"), []() { + static constexpr const char *argv[] = { + "/usr/bin/system-info.sh", nullptr + }; + + RunProcessDialog(UIGlobals::GetMainWindow(), + UIGlobals::GetDialogLook(), + "System Info", argv); + }); + + AddButton(_("List Dir"), []() { + static constexpr const char *argv[] = {"/bin/ls", "-l", nullptr}; + + RunProcessDialog(UIGlobals::GetMainWindow(), + UIGlobals::GetDialogLook(), + "List Dir", argv); + }); + + AddButton(_("Test-Process 2"), [this]() { + StaticString<0x200> str; + str.Format("%s/%s", ovdevice.GetHomePath().c_str(), "process.txt"); + Path output = Path(str); + + auto ret_value = Run( + output, + "/home/august2111/TestProcess.sh"); + + char buffer[0x100]; + File::ReadString(output, buffer, sizeof(buffer)); + std::string xx = buffer; + xx += "\nreturn value: " + std::to_string(ret_value); + File::WriteExisting(output, xx.c_str()); + return ret_value; + }); +} + +bool +ShowSystemMenuWidget(ContainerWindow &parent, + const DialogLook &look) noexcept +{ + TWidgetDialog sub_dialog( + WidgetDialog::Full{}, (UI::SingleWindow &) parent, look, + "OpenVario System Menu"); + sub_dialog.SetWidget(); + sub_dialog.AddButton(_("Close"), mrOK); + return sub_dialog.ShowModal(); +} + +std::unique_ptr +CreateSystemMenuWidget() noexcept +{ + return std::make_unique(); +} + +#endif diff --git a/src/OpenVario/System/SystemMenuWidget.hpp b/src/OpenVario/System/SystemMenuWidget.hpp new file mode 100644 index 00000000000..ac7ac378692 --- /dev/null +++ b/src/OpenVario/System/SystemMenuWidget.hpp @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright The XCSoar Project + +#pragma once + +#define OV_SETTINGS 0 + +#ifdef IS_OPENVARIO + +#include + +class Widget; +class ContainerWindow; +struct DialogLook; + +bool +ShowSystemMenuWidget(ContainerWindow &parent, + const DialogLook &look) noexcept; + +std::unique_ptr +CreateSystemMenuWidget() noexcept; +#endif \ No newline at end of file diff --git a/src/OpenVario/System/WifiDBus.cpp b/src/OpenVario/System/WifiDBus.cpp new file mode 100644 index 00000000000..e185bf49614 --- /dev/null +++ b/src/OpenVario/System/WifiDBus.cpp @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright The XCSoar Project + + +// #ifdef __GNUC__ +#if 1 +#ifdef DBUS_FUNCTIONS +#include "lib/dbus/Conn ection.hxx" +#include "lib/dbus/ScopeMatch.hxx" +#include "lib/dbus/Systemd.hxx" +#endif + +#if 0 + +WiFiAgent::WiFiAgent(GDBusConnection *inputConnection, Poco::JSON::Object::Ptr credentials) +: connection(inputConnection), parameters(std::move(credentials)) { + static const GDBusInterfaceVTable vtable = { + .method_call = handleMethodCall, + .get_property = nullptr, + .set_property = nullptr, + }; + static GError* error = nullptr; + + objectId = g_dbus_connection_register_object( + connection, + WiFiAgent::ourAgentPath, + WiFiAgent::introspectionWrapper->interfaces[0], + &vtable, + parameters.get(), + nullptr, + &error + ); + if(objectId == 0 || error != nullptr) + throw GlibException("Register WiFi agent", error); + + GVariant* agentPathVariant = g_variant_new("(o)", WiFiAgent::ourAgentPath); + if(agentPathVariant == nullptr) + throw std::runtime_error("Register WiFi agent: g_variant_new failed."); + + GVariant* result = g_dbus_connection_call_sync(connection, "net.connman", "/", "net.connman.Manager", +"RegisterAgent", agentPathVariant, nullptr, G_DBUS_CALL_FLAGS_NONE, -1, nullptr, &error); + if(result == nullptr || error != nullptr) + throw GlibException("Register WiFi agent", error); +} + + +//----------------------------------------------------------------------------- +void WiFiAgent::handleMethodCall(GDBusConnection *, const gchar *, + const gchar *, const gchar *, const gchar *method, + GVariant *methodParameters, GDBusMethodInvocation *invocation, gpointer userdata) { + std::cout << "Method got called." << std::endl; +} +//----------------------------------------------------------------------------- +static inline class IntrospectionWrapper final { + GDBusNodeInfo* introspection = nullptr; + static constexpr auto introspectionXML = + "" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + ""; + +public: + IntrospectionWrapper() { + GError* error = nullptr; + introspection = g_dbus_node_info_new_for_xml(introspectionXML, &error); + if(introspection == nullptr || error != nullptr) + std::cerr << GlibException("Agent introspection construction", error) << std::endl; + } + GDBusNodeInfo* operator->() { return introspection; }; + GDBusNodeInfo* get() { return introspection; } +} introspectionWrapper; +//----------------------------------------------------------------------------- +void DBusManipulator::connectToTheNetwork(GDBusProxy *network) { + GError* error = nullptr; + g_dbus_proxy_call_sync(network, "Connect", nullptr, G_DBUS_CALL_FLAGS_NONE, -1, nullptr, &error); + if(error != nullptr) + throw GlibException("Connect to the network", error); + + const auto state = variantGetValue(getNetworkProperty(network, "State")); + if(state != "online" && state != "ready") + throw std::runtime_error("Connect to the WiFi network: connection failed"); + + std::cout << "Connected to the network successfully." << std::endl; +} +//----------------------------------------------------------------------------- +void TestDBus() { + // GDBusProxy *network = g_dbus_proxy_new_for_bus_sync( + ODBus::Proxy *network = g_dbus_proxy_new_for_bus_sync( + G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, nullptr, + "net.connman", servicePath, "net.connman.Service", nullptr, &error); + if (network == nullptr || error != nullptr) + throw GlibException("Get network by name", error); +} + +#endif 0 +//----------------------------------------------------------------------------- +#endif // __GNUC__ diff --git a/src/OpenVario/System/WifiDialogOV.cpp b/src/OpenVario/System/WifiDialogOV.cpp new file mode 100644 index 00000000000..444be088f00 --- /dev/null +++ b/src/OpenVario/System/WifiDialogOV.cpp @@ -0,0 +1,868 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright The XCSoar Project + +#include "OpenVario/System/WifiDialogOV.hpp" +#include "OpenVario/System/WifiSupplicantOV.hpp" +#include "Dialogs/WidgetDialog.hpp" +#include "Dialogs/Message.hpp" +#include "Dialogs/Error.hpp" +#include "Dialogs/TextEntry.hpp" +#include "UIGlobals.hpp" +#include "Look/DialogLook.hpp" +#include "ui/canvas/Canvas.hpp" +#include "Screen/Layout.hpp" +#include "Renderer/TwoTextRowsRenderer.hpp" +#include "Language/Language.hpp" +#include "Widget/ListWidget.hpp" +#include "net/IPv4Address.hxx" +#include "ui/event/PeriodicTimer.hpp" +#include "util/HexFormat.hxx" +#include "util/StaticString.hxx" + +#include "LocalPath.hpp" +#include "LogFile.hpp" +#include "system/Process.hpp" +#include "OpenVario/System/OpenVarioDevice.hpp" +#include "system/FileUtil.hpp" +#include "io/FileReader.hxx" +#include "io/ProgressReader.hpp" +#include "io/BufferedReader.hxx" +#include "io/StringConverter.hpp" +#include "io/ProgressReader.hpp" +#include "util/StringStrip.hxx" +#include "util/StringCompare.hxx" +#include "util/StringAPI.hxx" +// #include "Operation/ConsoleOperationEnvironment.hpp" +#include "Operation/Operation.hpp" +#include "Operation/ProgressListener.hpp" +// #include "lib/fmt/RuntimeError.hxx" + +#include +#include +#if DEBUG_TEST_VERSION +# include +#endif + +using std::string_view_literals::operator""sv; + +const char *const connmanctl = "/usr/bin/connmanctl"; + +#ifdef KOBO +#include "Model.hpp" +#else +static const char * +GetKoboWifiInterface() noexcept +{ + /* dummy implementation for builds on (regular) Linux so KoboMenu + can be debugged there */ + return "dummy"; +} +#endif + +#ifdef WithWPA +/* workaround because OpenSSL has a typedef called "UI", which clashes + with our "UI" namespace */ +#define UI OPENSSL_UI +#include // for PKCS5_PBKDF2_HMAC_SHA1() +#undef UI +#endif // WithWPA + +class WifiListWidget final + : public ListWidget { + + struct NetworkInfo { + StaticString<64> mac_id; + StaticString<64> bssid; + StaticString<256> ssid; + StaticString<256> base_id; + int signal_level; + int id; + + enum WifiSecurity security; + + bool old_visible, old_configured; + bool enabled = false; // '*' - 1st char + bool coupled = false; // 'A' - 2nd char + bool connected = false; // 'R' - 3rd char; + }; + + Button *scan_button; + Button *reconnect_button; + Button *connect_button; + + WifiStatus status; + + TrivialArray networks; + + TwoTextRowsRenderer row_renderer; + +// WPASupplicant wpa_supplicant; + + UI::PeriodicTimer update_timer{[this]{ UpdateList(); }}; + +public: + void CreateButtons(WidgetDialog &dialog) { + scan_button = dialog.AddButton(_("Scan"), [this](){ + try { + EnsureConnected(); + // wpa_supplicant.Scan(); + ScanWifi(); + UpdateList(); + } catch (...) { + ShowError(std::current_exception(), _("Error")); + } + }); + + reconnect_button = dialog.AddButton(_("Re-Connect"), [this]() { + try { + ReConnect(); + } catch (...) { + ShowError(std::current_exception(), _("Error")); + } + }); + + connect_button = dialog.AddButton(_("Connect"), [this]() { + try { + Connect(); + } catch (...) { + ShowError(std::current_exception(), _("Error")); + } + }); + } + + void UpdateButtons(); + void ScanWifi(); + + /* virtual methods from class Widget */ + void Prepare(ContainerWindow &parent, + const PixelRect &rc) noexcept override { + const DialogLook &look = UIGlobals::GetDialogLook(); + + CreateList(parent, look, rc, + row_renderer.CalculateLayout(look.text_font, + look.small_font)); + // insert from August2111 + ScanWifi(); + + UpdateList(); + update_timer.Schedule(std::chrono::seconds(1)); + } + + /* virtual methods from class ListItemRenderer */ + void OnPaintItem(Canvas &canvas, const PixelRect rc, + unsigned idx) noexcept override; + + /* virtual methods from class ListCursorHandler */ + void OnCursorMoved([[maybe_unused]] unsigned index) noexcept override { + UpdateButtons(); + } + + // add August2111: + void WifiConnect(enum WifiSecurity security, + // WPASupplicant &wpa_supplicant, + const char *ssid, const char *psk); + void WifiDisconnect(const char *ssid); + + private: + /** + * Ensure that we're connected to wpa_supplicant. + * + * Throws on error. + */ + void EnsureConnected(); + + [[gnu::pure]] + NetworkInfo *FindByID(int id) noexcept; + + [[gnu::pure]] + NetworkInfo *FindByBSSID(const char *bssid) noexcept; + + [[gnu::pure]] + NetworkInfo *FindVisibleBySSID(const char *ssid) noexcept; + + [[gnu::pure]] + NetworkInfo *Find(const WifiConfiguredNetworkInfo &c) noexcept; + + void MergeList(const WifiVisibleNetwork *p, unsigned n); + void Append(const WifiConfiguredNetworkInfo &src); + void Merge(const WifiConfiguredNetworkInfo &c); + void MergeList(const WifiConfiguredNetworkInfo *p, unsigned n); + void UpdateScanResults(); + void UpdateConfigured(); + void SweepList(); + void UpdateList(); + + void Connect(); + void ReConnect(); +}; + +void +WifiListWidget::ScanWifi() +{ +#ifdef __MSVC__ + char buffer[0x1000]; + auto file = Path("connman-scan-results.txt"); + File::ReadString(Path("/Data/connman-services.txt"), buffer, sizeof(buffer)); + File::CreateExclusive(file); + File::WriteExisting(file, buffer); +#else + Run(Path("connman-technologies.txt"), connmanctl, "technologies"); + Run(Path("connman-enable.txt"), connmanctl, "enable", "wifi"); + Run(Path("connman-scan.txt"), connmanctl, "scan", "wifi"); + Run(Path("connman-scan-results.txt"), connmanctl, "services"); +#endif +} + +void +WifiListWidget::UpdateButtons() +{ + const unsigned cursor = GetList().GetCursorIndex(); + + if (cursor < networks.size()) { + const auto &info = networks[cursor]; + +// if (info.id >= 0) { + if (info.connected) { + // connect_button->SetCaption(_("Remove")); + connect_button->SetCaption(_("Disconnect")); + connect_button->SetEnabled(true); + } else if (info.signal_level >= 0) { + connect_button->SetCaption(_("Connect")); + connect_button->SetEnabled(true); + } + } else { + connect_button->SetEnabled(false); + } +} + +void +WifiListWidget::OnPaintItem(Canvas &canvas, const PixelRect rc, + unsigned idx) noexcept +{ + const auto &info = networks[idx]; + + static char wifi_security[][20] = { + "WPA", + "WEP", + "Open", + }; + + row_renderer.DrawFirstRow(canvas, rc, info.ssid); + row_renderer.DrawSecondRow(canvas, rc,info.bssid); + + const char *state = nullptr; + StaticString<40> state_buffer; + + /* found the currently connected wifi network? */ + if (StringIsEqual(info.bssid.c_str(), status.bssid.c_str())) { + state = _("Connected"); + + /* look up ip address for wlan0 or eth0 */ +#ifdef _WIN32 + const auto addr = IPv4Address(192, 168, 0, 1, 0); + if (addr.IsDefined()) { /* valid address? */ + // StaticString<40> addr_str; + StaticString<40> addr_str; + addr_str = "192.186.0.1"; + state_buffer.Format("%s (%s)", state, addr_str.c_str()); + state = state_buffer; + } +#else + // const auto addr = IPv4Address::GetDeviceAddress(GetKoboWifiInterface()); + const auto addr = IPv4Address::GetDeviceAddress("wlan0"); + if (addr.IsDefined()) { /* valid address? */ + // StaticString<40> addr_str; + StaticString<40> addr_str; + if (addr.ToString(addr_str.buffer(), addr_str.capacity()) != nullptr) { + state_buffer.Format("%s (%s)", state, addr_str.c_str()); + state = state_buffer; + } + } +#endif + } +#if 0 + else if (info.id >= 0) + state = info.signal_level >= 0 + ? _("Saved and visible") + : _("Saved, but not visible"); + else if (info.signal_level >= 0) + state = _("Visible"); +#else + else if (info.connected) + state = _("Connected"); + else if (info.coupled) + state = _("Saved and visible"); + else if (info.enabled) + state = _("Saved, but not visible"); // ? + else + state = _("Visible"); +#endif + + if (state != nullptr) + row_renderer.DrawRightFirstRow(canvas, rc, state); + + if (info.signal_level >= 0) { + StaticString<32> text; + text.UnsafeFormat("%s %u", wifi_security[info.security], + info.signal_level); + row_renderer.DrawRightSecondRow(canvas, rc, text); + } +} + +// TODO August2111: coming fro WPA-Sup..?? +// static +void WifiListWidget::WifiDisconnect( const char *ssid) { + auto network = FindVisibleBySSID(ssid); +// StaticString<0x100> base_id; +// base_id.Format("wifi_%s_%s_managed_", network->mac_id.c_str()), +// network->bssid.c_str())); +#if defined(IS_OPENVARIO_CB2) + // disconnect port + Run(Path("wifi-disconnect.txt"), connmanctl, "disconnect", network->base_id.c_str()); +#endif + ShowMessageBox(network->base_id.c_str(), "Disconnected", MB_OK); +} + +void WifiListWidget::WifiConnect(enum WifiSecurity security, + // WPASupplicant &wpa_supplicant, + const char *ssid, const char *psk) +{ + { +// ShowMessageBox(psk, "Wifi-Passphrase", MB_OK); + + auto network = FindVisibleBySSID(ssid); + std::cout << "Test: " << 1 << std::endl; +// StaticString<0x100> base_id; +// base_id.Format("wifi_%s_%s_managed_", network->mac_id.c_str()), +// network->bssid.c_str()); + +// std::cout << "Test: " << 2 << std::endl; +// switch (network->security) { +// case WPA_SECURITY: +// base_id.append("psk"); +// break; +// case WEP_SECURITY: +// base_id.append("wep"); +// break; +// case OPEN_SECURITY: +// default: +// base_id.append("none"); +// break; +// } + +#if 0 // content of 'settings' file: + [wifi_8c883b0078ce_537573616e6e65204361626c652047617374_managed_psk] + Name=Susanne Cable Gast + SSID=537573616e6e65204361626c652047617374 + Frequency=2412 + Favorite=true + AutoConnect=true + Modified=2024-01-31T13:55:30Z + Passphrase=LibeLLe7B + IPv4.method=dhcp + IPv4.DHCP.LastAddress=192.168.179.2 + IPv6.method=off + IPv6.privacy=disabled +#endif // WithWPA + StaticString<0x1000> buffer; + buffer.Format("[%s]\n", network->base_id.c_str()); + buffer.AppendFormat("Type=%s\n", "wifi"); + buffer.AppendFormat("Name=%s\n", ssid); + buffer.AppendFormat("SSID=%s\n", + network->bssid.c_str()); // network->bssid; + buffer.AppendFormat("Frequency=%d\n", 2412); + // buffer.AppendFormat("Favorite=true\n"); + buffer.append("Favorite=true\n"); + buffer.append("AutoConnect=true\n"); + buffer.AppendFormat("Passphrase=%s\n", psk); + // buffer.AppendFormat("Modified=2024-02-01T12:38:31Z\n"); + buffer.AppendFormat("IPv4.method=%s\n", "dhcp"); + // buffer.AppendFormat("IPv4.DHCP.LastAddress=192.168.178.32\n"); + buffer.append("IPv6.method=off\n"); + buffer.append("IPv6.privacy=disabled\n"); + std::cout << "Test: " << 6 << std::endl; + std::cout << buffer << std::endl; + ShowMessageBox(buffer.c_str(), "WifiConnect", MB_OK); + std::cout << "Test: " << 7 << std::endl; + + Path base_id(network->base_id.c_str()); + +#if defined(IS_OPENVARIO_CB2) + // save on the connman setting location: + auto ssid_path = + AllocatedPath::Build(Path("/var/lib/connman"), base_id); +#else + auto ssid_path = AllocatedPath::Build(ovdevice.GetDataPath(), + base_id); + ssid_path = AllocatedPath::Build(ssid_path, base_id); +#endif + auto setting_file = AllocatedPath::Build(ssid_path, Path("settings")); + if (File::Exists(setting_file)) + File::Delete(setting_file); + else + Directory::Create(ssid_path); + File::CreateExclusive(setting_file); + File::WriteExisting(setting_file, buffer); + +#if defined(IS_OPENVARIO_CB2) + // disable wifi + Run(Path("wifi-disable.txt"), connmanctl, "disable", "wifi"); + // wait a second + std::this_thread::sleep_for(std::chrono::seconds(1)); + // enable wifi again for AutoConnect + Run(Path("wifi-enable.txt"), connmanctl, "enable", "wifi"); + // wait a second after wifi enabling (?) + std::this_thread::sleep_for(std::chrono::seconds(1)); + // ask state of the wifi connection + Run(Path("wifi-connect.txt"), connmanctl, "services", + network->base_id.c_str()); +#endif + } +#ifdef WithWPA + const unsigned id = wpa_supplicant.AddNetwork(); + char *endPsk_ptr; + + wpa_supplicant.SetNetworkSSID(id, ssid); + + if (security == WPA_SECURITY) { + std::array pmk; + PKCS5_PBKDF2_HMAC_SHA1(psk, strlen(psk), + (const unsigned char *)ssid, strlen(ssid), + 4096, + pmk.size(), (unsigned char *)pmk.data()); + + std::array hex; + *HexFormat(hex.data(), pmk) = 0; + + wpa_supplicant.SetNetworkPSK(id, hex.data()); + } else if (security == WEP_SECURITY) { + wpa_supplicant.SetNetworkID(id, "key_mgmt", "NONE"); + + /* + * If psk is all hexidecimal should SetNetworkID, assuming user provided key in hex. + * Use strtoll to confirm the psk is entirely in hex. + * Also to need to check that it does not begin with 0x which WPA supplicant does not like. + */ + + (void) strtoll(psk, &endPsk_ptr, 16); + + if ((*endPsk_ptr == '\0') && // confirm strtoll processed all of psk + (strlen(psk) >= 2) && (psk[0] != '0') && (psk[1] != 'x')) // and the first two characters were no "0x" + wpa_supplicant.SetNetworkID(id, "wep_key0", psk); + else + wpa_supplicant.SetNetworkString(id, "wep_key0", psk); + + wpa_supplicant.SetNetworkID(id, "auth_alg", "OPEN\tSHARED"); + } else if (security == OPEN_SECURITY){ + wpa_supplicant.SetNetworkID(id, "key_mgmt", "NONE"); + } else + throw std::runtime_error{"Unsupported Wifi security type"}; + + wpa_supplicant.EnableNetwork(id); + wpa_supplicant.SaveConfig(); +#endif // WithWPA +} + +inline void +WifiListWidget::ReConnect() +{ + EnsureConnected(); + + const unsigned i = GetList().GetCursorIndex(); + if (i >= networks.size()) + return; + +#if defined(IS_OPENVARIO_CB2) + // disable wifi + Run(Path("wifi-disable.txt"), connmanctl, "disable", "wifi"); + // wait a second + std::this_thread::sleep_for(std::chrono::seconds(1)); + // enable wifi again for AutoConnect + Run(Path("wifi-enable.txt"), connmanctl, "enable", "wifi"); + // wait a second after wifi enabling (?) + std::this_thread::sleep_for(std::chrono::seconds(1)); +// // ask state of the wifi connection +// Run(Path("wifi-connect.txt"), connmanctl, "services", +// network->base_id.c_str()); +#endif + + UpdateList(); +} + +inline void +WifiListWidget::Connect() +{ + EnsureConnected(); + + const unsigned i = GetList().GetCursorIndex(); + if (i >= networks.size()) + return; + + const auto &info = networks[i]; +// if (info.id < 0) { + if (info.connected) { + WifiDisconnect(info.ssid); + } else { + const auto ssid = info.ssid; + + StaticString<256> caption; + caption.Format(_("Passphrase of network '%s'"), ssid.c_str()); + + StaticString<32> passphrase; + passphrase.clear(); + if (info.security == OPEN_SECURITY) + passphrase.clear(); + else if (!TextEntryDialog(passphrase, caption, false)) + return; + + WifiConnect(info.security, /* wpa_supplicant, */ info.ssid, + passphrase); +// } else { +// wpa_supplicant.RemoveNetwork(info.id); +// wpa_supplicant.SaveConfig(); + } + + UpdateList(); +} + +void +WifiListWidget::EnsureConnected() +{ + char path[64]; + sprintf(path, "/var/run/wpa_supplicant/%s", GetKoboWifiInterface()); +// wpa_supplicant.EnsureConnected(path); +} + +inline WifiListWidget::NetworkInfo * +WifiListWidget::FindByID(int id) noexcept +{ + auto f = std::find_if(networks.begin(), networks.end(), + [id](const NetworkInfo &info) { + return info.id == id; + }); + if (f == networks.end()) + return nullptr; + +#ifdef __MSVC__ + return &(*f); +#else + return f; +#endif +} + +WifiListWidget::NetworkInfo * +WifiListWidget::FindByBSSID(const char *bssid) noexcept +{ + auto f = std::find_if(networks.begin(), networks.end(), + [bssid](const NetworkInfo &info) { + return info.bssid == bssid; + }); + if (f == networks.end()) + return nullptr; +#ifdef __MSVC__ + return &(*f); +#else + return f; +#endif +} + +WifiListWidget::NetworkInfo * +WifiListWidget::FindVisibleBySSID(const char *ssid) noexcept +{ + auto f = std::find_if(networks.begin(), networks.end(), + [ssid](const NetworkInfo &info) { + return info.signal_level >= 0 && info.ssid == ssid; + }); + if (f == networks.end()) + return nullptr; + +#ifdef __MSVC__ + return &(*f); +#else + return f; +#endif +} + +inline void +WifiListWidget::MergeList(const WifiVisibleNetwork *p, unsigned n) +{ + for (unsigned i = 0; i < unsigned(n); ++i) { + const auto &found = p[i]; + + auto info = FindByBSSID(found.bssid); + if (info == nullptr) { + info = &networks.append(); + info->bssid = found.bssid; + info->id = -1; + } + + info->mac_id = found.mac_id; + info->ssid = found.ssid; + info->signal_level = found.signal_level; + info->base_id = found.base_id; + info->security = found.security; + info->enabled = found.enabled; + info->coupled = found.coupled; + info->connected = found.connected; + info->old_visible = false; + } + +#ifndef WithWPA + +#endif + + +} + +size_t +ParseConnmanScan(WifiVisibleNetwork *dest, BufferedReader &reader, + [[maybe_unused]] OperationEnvironment &env, size_t max) { + StringConverter string_converter; + + bool ignore = false; + const char *line; + size_t n = 0; + + // Iterate through the lines + while ((line = reader.ReadLine()) != nullptr) { + StripRight(line); + + // Skip empty line + if (StringIsEmpty(line)) + continue; + if (StringLength(line) < 4) + continue; + + auto info = &dest[n]; + std::string_view state{line, 4}; + line += 4; + auto pos = StringFind(line, " wifi_"); + if (pos == nullptr) + continue; + //------------------------------------- + std::string_view base_id{pos + 1}; + info->base_id = StripRight(base_id); + + info->enabled = state[0] == '*'; // '*' - 1st char + info->coupled = state[1] == 'A'; // 'A' - 2nd char + info->connected = state[2] == 'R'; // 'R' - 3rd char; + // SSID + if (pos - line > 2) { + std::string_view ssid{line, (size_t)(pos - line)}; + info->ssid = StripRight(ssid); + } + line = pos + StringLength(" wifi_"); + + pos = StringFind(line, "_"); + if (pos - line > 2) { + std::string_view bssid{line, (size_t)(pos - line)}; + info->bssid = StripRight(bssid); + std::string_view mac_id{line, (size_t)(pos - line)}; + info->mac_id = StripRight(mac_id); + } + line = pos +1; + + pos = StringFind(line, "_managed"); + if (pos - line > 2) { + std::string_view bssid{line, (size_t)(pos - line)}; + info->bssid = StripRight(bssid); + } + line = pos + StringLength("_managed") +1; + + info->signal_level = 1; // signal level not supported up to now ?-1; + + + if (line == "psk"sv) + info->security = WPA_SECURITY; + // info->security = OPEN_SECURITY; + else if (line == "wep"sv) + info->security = WEP_SECURITY; + else if (line == "open"sv) + info->security = OPEN_SECURITY; + + if (++n >= max) + break; + } + return n; +} + +static size_t +ParseConnmanScan(WifiVisibleNetwork *dest, Path path, + OperationEnvironment &env, size_t max) noexcept +try { + FileReader file_reader{path}; + ProgressReader progress_reader{file_reader, file_reader.GetSize(), env }; + BufferedReader buffered_reader{progress_reader}; + size_t n = 0; + try { + n = ParseConnmanScan(dest, buffered_reader, env, max); + } catch (...) { +// std::throw_with_nested(FmtRuntimeError("Error in file {}", path)); + } + + return n; +} catch (...) { + LogError(std::current_exception()); + // operation.SetError(std::current_exception()); + return 0; +} + +#ifndef WithWPA +unsigned +ScanResults(WifiVisibleNetwork *dest, unsigned max) +{ + const Path file = Path("connman-scan-results.txt"); + if (File::Exists(file)) { + // ConsoleOperationEnvironment env; + NullOperationEnvironment env; + auto n = ParseConnmanScan(dest, file, env, max); + + auto file2 = Path("connman-services.txt"); + if (File::Exists(file2)) + File::Delete(file2); + File::Rename(file, file2); + // File::Delete(file); + return n; + } else { + return 0; + } +} +#endif + +inline void +WifiListWidget::UpdateScanResults() +{ + WifiVisibleNetwork *buffer = new WifiVisibleNetwork[networks.capacity()]; + +#ifdef WithWPA + int n = wpa_supplicant.ScanResults(buffer, networks.capacity()); +#else + auto n = ScanResults(buffer, networks.capacity()); +#endif + // int n = networks.capacity(); + if (n >= 0) + MergeList(buffer, n); + + delete[] buffer; +} + +inline WifiListWidget::NetworkInfo * +WifiListWidget::Find(const WifiConfiguredNetworkInfo &c) noexcept +{ + auto found = FindByID(c.id); + if (found != nullptr) + return found; + + return c.bssid == "any" + ? FindVisibleBySSID(c.ssid) + : FindByBSSID(c.bssid); +} + +inline void +WifiListWidget::Append(const WifiConfiguredNetworkInfo &src) +{ + auto &dest = networks.append(); + dest.bssid = src.bssid; + dest.ssid = src.ssid; + dest.id = src.id; + dest.signal_level = -1; + dest.old_configured = false; +} + +inline void +WifiListWidget::Merge(const WifiConfiguredNetworkInfo &c) +{ + auto found = Find(c); + if (found != nullptr) { + found->id = c.id; + found->old_configured = false; + } else + Append(c); +} + +inline void +WifiListWidget::MergeList(const WifiConfiguredNetworkInfo *p, unsigned n) +{ + for (unsigned i = 0; i < unsigned(n); ++i) + Merge(p[i]); +} + +inline void +WifiListWidget::UpdateConfigured() +{ + WifiConfiguredNetworkInfo *buffer = + new WifiConfiguredNetworkInfo[networks.capacity()]; + int n = 0; + //wpa_supplicant.ListNetworks(buffer, networks.capacity()); + if (n >= 0) + MergeList(buffer, n); + + delete[] buffer; +} + +inline void +WifiListWidget::SweepList() +{ + unsigned cursor = GetList().GetCursorIndex(); + + for (int i = networks.size() - 1; i >= 0; --i) { + NetworkInfo &info = networks[i]; + + if (info.old_visible && info.old_configured) { + networks.remove(i); + if (cursor > unsigned(i)) + --cursor; + } else { + if (info.old_visible) + info.signal_level = -1; + + if (info.old_configured) + info.id = -1; + } + } + + GetList().SetCursorIndex(cursor); +} + +void +WifiListWidget::UpdateList() +{ + // std::cout << "UpdateList!" << std::endl; + status.Clear(); + + try { +// WPA? EnsureConnected(); +// WPA? wpa_supplicant.Status(status); + + for (auto &i : networks) + i.old_visible = i.old_configured = true; + +// WPA? + UpdateScanResults(); +// WPA? UpdateConfigured(); + /* remove items that are still marked as "old" */ + // but not without WPA SweepList(); + // std::cout << "After SweepList!" << std::endl; + } catch (...) { + networks.clear(); + } + + GetList().SetLength(networks.size()); + // std::cout << "After GetList.SetLength!" << std::endl; + + UpdateButtons(); + // std::cout << "After UpdateButton!" << std::endl; +} + +void +ShowWifiDialog() +{ + const DialogLook &look = UIGlobals::GetDialogLook(); + TWidgetDialog + dialog(WidgetDialog::Full{}, UIGlobals::GetMainWindow(), + look, _("Wifi")); + dialog.AddButton(_("Close"), mrOK); + dialog.SetWidget(); + dialog.GetWidget().CreateButtons(dialog); + dialog.ShowModal(); +} diff --git a/src/OpenVario/System/WifiDialogOV.hpp b/src/OpenVario/System/WifiDialogOV.hpp new file mode 100644 index 00000000000..bb4ba8ae355 --- /dev/null +++ b/src/OpenVario/System/WifiDialogOV.hpp @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright The XCSoar Project + +#pragma once + +class SingleWindow; +struct DialogLook; + +void +ShowWifiDialog(); diff --git a/src/OpenVario/System/WifiSupplicantOV.cpp b/src/OpenVario/System/WifiSupplicantOV.cpp new file mode 100644 index 00000000000..73862dd8fd4 --- /dev/null +++ b/src/OpenVario/System/WifiSupplicantOV.cpp @@ -0,0 +1,384 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright The XCSoar Project + +#if 0 +#include "OpenVario/System/WifiSupplicantOV.hpp" +#include "lib/fmt/ToBuffer.hxx" +#include "lib/fmt/SystemError.hxx" +#include "net/AllocatedSocketAddress.hxx" +#include "util/IterableSplitString.hxx" +#include "util/NumberParser.hxx" +#include "util/SpanCast.hxx" +#include "util/StringSplit.hxx" + +#include +#include +#include + +using std::string_view_literals::operator""sv; + +void +WPASupplicant::Connect(const char *path) +{ + Close(); + + AllocatedSocketAddress peer_address; +#ifdef WithWPA + peer_address.SetLocal(path); + + if (!fd.Create(AF_LOCAL, SOCK_DGRAM, 0)) + throw MakeErrno("Failed to create socket"); + + if (!fd.AutoBind()) + throw MakeErrno("Failed to bind socket"); + + if (!fd.Connect(peer_address)) + throw FmtErrno("Failed to connect to {}", path); +#endif +} + +void +WPASupplicant::Close() noexcept +{ + if (fd.IsDefined()) + fd.Close(); +} + +void +WPASupplicant::SendCommand(std::string_view cmd) +{ + /* discard any previous responses that may be left in the socket's + receive queue, maybe because the last command failed */ + ReadDiscard(); + + const ssize_t nbytes = fd.Write(AsBytes(cmd)); + if (nbytes < 0) + throw MakeErrno("Failed to send command to wpa_supplicant"); + + if (std::size_t(nbytes) != cmd.size()) + throw std::runtime_error("Short send to wpa_supplicant"); +} + +void +WPASupplicant::ExpectResponse(std::string_view expected) +{ + char buffer[4096]; + assert(expected.size() <= sizeof(buffer)); + + if (ReadStringTimeout(buffer) != expected) + throw std::runtime_error{"Unexpected wpa_supplicant response"}; +} + +static bool +ParseStatusLine(WifiStatus &status, std::string_view src) noexcept +{ + const auto [name, value] = Split(src, '='); + if (value.data() == nullptr) + return false; + + if (name == "bssid"sv) + status.bssid = value; + else if (name == "ssid"sv) + status.ssid = value; + return true; +} + +static bool +ParseStatus(WifiStatus &status, std::string_view src) noexcept +{ + status.Clear(); + + for (const auto line : IterableSplitString(src, '\n')) + ParseStatusLine(status, line); + + return true; +} + +bool +WPASupplicant::Status(WifiStatus &status) +{ + SendCommand("STATUS"); + + char buffer[4096]; + const auto src = ReadStringTimeout(buffer); + if (src.empty()) + throw std::runtime_error{"wpa_supplicant closed the socket"}; + + return ParseStatus(status, src); +} + +/* + * Scan Results look like: + * bssid frequency signal_level flags ssid + * bc:14:01:e1:d6:78 2412 178 [WPA-PSK-TKIP+CCMP][WPA2-PSK-TKIP+CCMP][WPS][ESS] FunnyMaple + * 00:22:a4:b8:f3:31 2437 185 [WEP][ESS] BELL778 + * 98:fc:11:3e:58:ea 2462 169 [WPA-PSK-TKIP+CCMP][WPA2-PSK-TKIP+CCMP][WPS][ESS] Cisco54414 + * bc:14:01:e1:d6:79 2412 176 [WPA2-PSK-CCMP][ESS] + * 44:94:fc:36:22:48 2412 173 [WPA2-PSK-CCMP][WPS][ESS] NETGEAR14 + * + * Fields are delimited by single tabs. + * + * Items of interest which are: + * - bssid binary ssid + * - signal_level a number, bigger is better. + * - network type. A wireless router may support one or all of WEP, WPA, and WPA2. + * WPA and WPA2 are handled the same. WPA/WPA2 are preferred over WEP. + * - ssid ascii ssid. ssid could be empty if ssid broadcast is disabled. + */ +static bool +ParseScanResultsLine(WifiVisibleNetwork &dest, std::string_view line) noexcept +{ + const auto [bssid, rest1] = Split(line, '\t'); + const auto [frequency, rest2] = Split(rest1, '\t'); + const auto [signal_level, rest3] = Split(rest2, '\t'); + const auto [flags, rest4] = Split(rest3, '\t'); + const auto [ssid, _] = Split(rest4, '\t'); + + if (bssid.empty() || frequency.empty() || signal_level.empty() || ssid.empty()) + return false; + + dest.bssid = bssid; + + if (const auto value = ParseInteger(signal_level)) + dest.signal_level = *value; + else + return false; + + if (flags.find("WPA"sv) != flags.npos) + dest.security = WPA_SECURITY; + else if (flags.find("WEP"sv) != flags.npos) + dest.security = WEP_SECURITY; + else + dest.security = OPEN_SECURITY; + + dest.ssid = ssid; + return true; +} + +static std::size_t +ParseScanResults(WifiVisibleNetwork *dest, std::size_t max, std::string_view src) +{ + if (!src.starts_with("bssid"sv)) + throw std::runtime_error{"Malformed wpa_supplicant response"}; + + src = Split(src, '\n').second; + if (src.data() == nullptr) + throw std::runtime_error{"Malformed wpa_supplicant response"}; + + std::size_t n = 0; + for (const auto line : IterableSplitString(src, '\n')) { + if (line.empty()) + break; + + if (!ParseScanResultsLine(dest[n], line)) + break; + + // skip hidden ssid + if (!dest[n].ssid.empty()) { + ++n; + + if (n >= max) + break; + } + } + + return n; +} + +std::size_t +WPASupplicant::ScanResults(WifiVisibleNetwork *dest, unsigned max) +{ + assert(dest != nullptr); + assert(max > 0); + + SendCommand("SCAN_RESULTS"); + + char buffer[4096]; + const auto src = ReadStringTimeout(buffer); + if (src.empty()) + throw std::runtime_error{"wpa_supplicant closed the socket"}; + + return ParseScanResults(dest, max, src); +} + +unsigned +WPASupplicant::AddNetwork() +{ + SendCommand("ADD_NETWORK"); + + char buffer[4096]; + const auto line = ExpectLineTimeout(buffer); + + if (auto id = ParseInteger(line)) + return *id; + + throw std::runtime_error{"Malformed wpa_supplicant response"}; +} + +void +WPASupplicant::SetNetworkString(unsigned id, + const char *name, const char *value) +{ + SendCommand(FmtBuffer<512>("SET_NETWORK {} {} \"{}\"", id, name, value).c_str()); + ExpectOK(); +} + +void +WPASupplicant::SetNetworkID(unsigned id, + const char *name, const char *value) +{ + SendCommand(FmtBuffer<512>("SET_NETWORK {} {} {}", id, name, value).c_str()); + ExpectOK(); +} + +void +WPASupplicant::SelectNetwork(unsigned id) +{ + SendCommand(FmtBuffer<64>("SELECT_NETWORK {}", id).c_str()); + ExpectOK(); +} + +void +WPASupplicant::EnableNetwork(unsigned id) +{ + SendCommand(FmtBuffer<64>("ENABLE_NETWORK {}", id).c_str()); + ExpectOK(); +} + +void +WPASupplicant::DisableNetwork(unsigned id) +{ + SendCommand(FmtBuffer<64>("DISABLE_NETWORK {}", id).c_str()); + ExpectOK(); +} + +void +WPASupplicant::RemoveNetwork(unsigned id) +{ + SendCommand(FmtBuffer<64>("REMOVE_NETWORK {}", id).c_str()); + ExpectOK(); +} + +static bool +ParseListResultsLine(WifiConfiguredNetworkInfo &dest, std::string_view line) +{ + const auto [id, rest1] = Split(line, '\t'); + const auto [ssid, rest2] = Split(rest1, '\t'); + const auto [bssid, _] = Split(rest2, '\t'); + + if (ssid.data() == nullptr || bssid.data() == nullptr) + return false; + + if (const auto value = ParseInteger(id)) + dest.id = *value; + else + return false; + + dest.ssid = ssid; + dest.bssid = bssid; + return true; +} + +static std::size_t +ParseListResults(WifiConfiguredNetworkInfo *dest, std::size_t max, std::string_view src) +{ + if (!src.starts_with("network id"sv)) + throw std::runtime_error{"Malformed wpa_supplicant response"}; + + src = Split(src, '\n').second; + if (src.data() == nullptr) + throw std::runtime_error{"Malformed wpa_supplicant response"}; + + std::size_t n = 0; + for (const auto line : IterableSplitString(src, '\n')) { + if (line.empty()) + break; + + if (!ParseListResultsLine(dest[n], line)) + break; + + ++n; + if (n >= max) + break; + } + + return n; +} + +std::size_t +WPASupplicant::ListNetworks(WifiConfiguredNetworkInfo *dest, std::size_t max) +{ + assert(dest != nullptr); + assert(max > 0); + + SendCommand("LIST_NETWORKS"); + + char buffer[4096]; + const auto src = ReadStringTimeout(buffer); + if (src.empty()) + throw std::runtime_error{"Malformed wpa_supplicant response"}; + + return ParseListResults(dest, max, src); +} + +void +WPASupplicant::ReadDiscard() noexcept +{ + std::byte buffer[4096]; + + while (fd.ReadNoWait(buffer) > 0) {} +} + +std::size_t +WPASupplicant::ReadTimeout(std::span dest, int timeout_ms) +{ + /* TODO: this is a kludge, because SocketDescriptor::Read() + hard-codes MSG_DONTWAIT; we would be better off moving all of + this into an IOLoop/IOThread */ + + ssize_t nbytes = fd.ReadNoWait(dest); + if (nbytes < 0) { + const int e = errno; + if (e != EAGAIN) + throw MakeErrno(e, "Failed to receive response from wpa_supplicant"); + + const int r = fd.WaitReadable(timeout_ms); + if (r < 0) + throw MakeErrno("Failed to receive response from wpa_supplicant"); + + if (r == 0) + throw std::runtime_error{"Timeout waiting for wpa_supplicant response"}; + + nbytes = fd.Read(dest); + } + + if (nbytes < 0) + throw MakeErrno("Failed to receive response from wpa_supplicant"); + + if (nbytes == 0) { + fd.Close(); + throw std::runtime_error{"Connection to wpa_supplicant closed"}; + } + + return nbytes; +} + +std::string_view +WPASupplicant::ReadStringTimeout(std::span buffer, int timeout_ms) +{ + std::size_t nbytes = ReadTimeout(std::as_writable_bytes(buffer), timeout_ms); + return ToStringView(buffer.first(nbytes)); +} + +std::string_view +WPASupplicant::ExpectLineTimeout(std::span buffer, int timeout_ms) +{ + std::string_view result = ReadStringTimeout(buffer, timeout_ms); + if (!result.ends_with('\n')) + throw std::runtime_error{"Unexpected wpa_supplicant response"}; + + result.remove_suffix(1); + return result; +} + +#endif \ No newline at end of file diff --git a/src/OpenVario/System/WifiSupplicantOV.hpp b/src/OpenVario/System/WifiSupplicantOV.hpp new file mode 100644 index 00000000000..8b1ebf64ea7 --- /dev/null +++ b/src/OpenVario/System/WifiSupplicantOV.hpp @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright The XCSoar Project + +#pragma once + +#include "util/StaticString.hxx" +#include "net/SocketDescriptor.hxx" + +#include +#include +#include + +enum WifiSecurity { + WPA_SECURITY, + WEP_SECURITY, + OPEN_SECURITY, +}; + +struct WifiStatus { + StaticString<64> bssid; + StaticString<256> ssid; + + void Clear() { + bssid.clear(); + ssid.clear(); + } +}; + +struct WifiVisibleNetwork { + StaticString<64> mac_id; + StaticString<64> bssid; + StaticString<256> ssid; + StaticString<256> base_id; + unsigned signal_level; + enum WifiSecurity security; + + bool enabled = false; // '*' - 1st char + bool coupled = false; // 'A' - 2nd char + bool connected = false; // 'R' - 3rd char; +}; + +struct WifiConfiguredNetworkInfo { + int id; + StaticString<64> bssid; + StaticString<256> ssid; +}; + +#if 0 +/** + * All methods that are not `noexcept` throw on error. + */ +class WPASupplicant { + SocketDescriptor fd; + +public: + WPASupplicant() noexcept:fd(SocketDescriptor::Undefined()) {} + + ~WPASupplicant() noexcept { + Close(); + } + + [[gnu::pure]] + bool IsConnected() const noexcept { + // TODO: what if the socket is broken? + return fd.IsDefined(); + } + + /** + * Throws on error. + */ + void Connect(const char *path); + + void EnsureConnected(const char *path) { + if (!IsConnected()) + Connect(path); + } + + void Close() noexcept; + + void SendCommand(std::string_view cmd); + + void ExpectResponse(std::string_view expected); + + void ExpectOK() { + ExpectResponse("OK\n"); + } + + void SaveConfig() { + SendCommand("SAVE_CONFIG"); + ExpectOK(); + } + + bool Status(WifiStatus &status); + + void Scan() { + SendCommand("SCAN"); + ExpectOK(); + } + + /** + * @return the number of networks + */ + std::size_t ScanResults(WifiVisibleNetwork *dest, unsigned max); + + /** + * @return the network id + */ + unsigned AddNetwork(); + + void SetNetworkString(unsigned id, const char *name, const char *value); + + void SetNetworkID(unsigned id, const char *name, const char *value); + + void SetNetworkSSID(unsigned id, const char *ssid) { + SetNetworkString(id, "ssid", ssid); + } + + void SetNetworkPSK(unsigned id, const char *psk) { + SetNetworkID(id, "psk", psk); + } + + void SelectNetwork(unsigned id); + void EnableNetwork(unsigned id); + void DisableNetwork(unsigned id); + void RemoveNetwork(unsigned id); + + /** + * Throws on error. + * + * @return the number of networks + */ + std::size_t ListNetworks(WifiConfiguredNetworkInfo *dest, std::size_t max); + +private: + void ReadDiscard() noexcept; + + std::size_t ReadTimeout(std::span dest, int timeout_ms=2000); + + std::string_view ReadStringTimeout(std::span buffer, int timeout_ms=2000); + + std::string_view ExpectLineTimeout(std::span buffer, int timeout_ms=2000); +}; + +#endif \ No newline at end of file diff --git a/src/OpenVario/SystemSettingsWidget.cpp b/src/OpenVario/SystemSettingsWidget.cpp new file mode 100644 index 00000000000..75d535e2461 --- /dev/null +++ b/src/OpenVario/SystemSettingsWidget.cpp @@ -0,0 +1,248 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright The XCSoar Project + +#ifdef IS_OPENVARIO +// don't use (and compile) this code outside an OpenVario project! + +#include "OpenVario/SystemSettingsWidget.hpp" +#include "Dialogs/WidgetDialog.hpp" +#include "Widget/RowFormWidget.hpp" +#include "Look/DialogLook.hpp" + +#include "Language/Language.hpp" +#include "Form/DataField/Boolean.hpp" +#include "Form/DataField/Listener.hpp" +#include "Form/DataField/Enum.hpp" +#include "Form/DataField/Integer.hpp" +#include "Interface.hpp" +#include "UIGlobals.hpp" +#include "ui/window/SingleWindow.hpp" + +#include "Dialogs/Message.hpp" +#include "./LogFile.hpp" +#include "UIActions.hpp" +#include "ProgramVersion.h" + +#include "OpenVario/System/OpenVarioDevice.hpp" +#include "OpenVario/System/OpenVarioTools.hpp" +#include "OpenVario/System/WifiDialogOV.hpp" + + +#include +#include + +enum ControlIndex { + FW_VERSION, + FIRMWARE, + ENABLED, + SENSORD, + VARIOD, + SSH, + TIMEOUT, + WIFI_BUTTON, + SENSOR_CAL, + +#ifdef _DEBUG + INTEGERTEST, +#endif +}; + + +#if 1 +#include "UIGlobals.hpp" +// ------------------------------------------- +class SystemSettingsWidget final : public RowFormWidget, DataFieldListener { +public: + SystemSettingsWidget() noexcept : RowFormWidget(UIGlobals::GetDialogLook()) {} + + void SetEnabled(bool enabled) noexcept; + + /* virtual methods from class Widget */ + void Prepare(ContainerWindow &parent, const PixelRect &rc) noexcept override; + bool Save(bool &changed) noexcept override; + bool CheckChanged(bool &changed) noexcept; + + +private: + /* methods from DataFieldListener */ + void OnModified(DataField &df) noexcept override; +}; +#endif + +#ifdef OPENVARIOBASEMENU + static constexpr StaticEnumChoice timeout_list[] = { + { 0, "immediately", }, + { 1, "1s", }, + { 3, "3s", }, + { 5, "5s", }, + { 10, "10s", }, + { 30, "30s", }, + { 60, "1min", }, + { -1, "never", }, + nullptr + }; +#endif + + static constexpr StaticEnumChoice enable_list[] = { + { SSHStatus::ENABLED, "enabled", }, + { SSHStatus::DISABLED, "disabled", }, + { SSHStatus::TEMPORARY, "temporary", }, + nullptr + }; + +void +SystemSettingsWidget::SetEnabled([[maybe_unused]] bool enabled) noexcept +{ + // this disabled itself: SetRowEnabled(ENABLED, enabled); + // SetRowEnabled(BRIGHTNESS, enabled); +#ifdef OPENVARIOBASEMENU + SetRowEnabled(TIMEOUT, enabled); +#endif +} + +void +SystemSettingsWidget::OnModified([[maybe_unused]] DataField &df) noexcept +{ + if (IsDataField(ENABLED, df)) { + // const DataFieldBoolean &dfb = ; + SetEnabled(((const DataFieldBoolean &)df).GetValue()); + } else if (IsDataField(FIRMWARE, df)) { + // (DataFieldInteger*)df) + ShowMessageBox("FirmWare-Selection", "??File??", MB_OKCANCEL); + } +} + +void +SystemSettingsWidget::Prepare(ContainerWindow &parent, + const PixelRect &rc) noexcept +{ + RowFormWidget::Prepare(parent, rc); + + AddReadOnly(_("Current OpenSoar"), _("Current firmware version of OpenVario"), +#if defined(PROGRAM_VERSION) + PROGRAM_VERSION); +#else + "7.42.21.3"); +#endif + AddFile(_("OV-Firmware"), _("Current firmware file version of OpenVario"), + "OVImage", "*.img.gz\0", FileType::IMAGE); // no callback... , this); + + AddBoolean( + _("Settings Enabled"), + _("Enable the Settings Page"), ovdevice.enabled, this); + + AddBoolean(_("SensorD"), _("Enable the SensorD"), ovdevice.sensord, this); + AddBoolean(_("VarioD"), _("Enable the VarioD"), ovdevice.variod, this); + AddEnum(_("SSH"), _("Enable the SSH Connection"), enable_list, + ovdevice.ssh); + +#ifdef OPENVARIOBASEMENU + AddEnum(_("Program Timeout"), _("Timeout for Program Start."), timeout_list, ovdevice.timeout); +#else + AddDummy(); // Placeholder for enum enumeration +#endif + + auto btnWifi = AddButton( + "Settings Wifi", [this]() { + ShowWifiDialog(); + }); + btnWifi->SetEnabled(true); // dependend on availability? Missing: + + AddButton(_("Calibrate Sensors"), CalibrateSensors); + + +#ifdef _DEBUG + AddInteger(_("IntegerTest"), + _("IntegerTest."), "%d", "%d", 0, + 99999, 1, ovdevice.iTest); +#endif + +#if 1 + AddButton(_("Upgrade Firmware (temp.)"), [this]() { + ContainerWindow::SetExitValue(START_UPGRADE); + UIActions::SignalShutdown(false); + return mrOK; // START_UPGRADE; + }); +#endif + + SetEnabled(ovdevice.enabled); +} + +bool +SystemSettingsWidget::CheckChanged([[maybe_unused]] bool &_changed) noexcept +{ + return false; +} + +bool +SystemSettingsWidget::Save([[maybe_unused]] bool &_changed) noexcept +{ + bool changed = false; + changed |= SaveValue(ENABLED, "Enabled", ovdevice.enabled, false); + + if (SaveValue(ENABLED, "Enabled", ovdevice.enabled, false)) { + ovdevice.settings.insert_or_assign("Enabled", + ovdevice.enabled ? "True" : "False"); + changed = true; + } + +#ifdef OPENVARIOBASEMENU + if (SaveValueEnum(TIMEOUT, "Timeout", ovdevice.timeout)) { + ovdevice.settings.insert_or_assign("Timeout", + std::to_string(ovdevice.timeout)); + changed = true; + } +#endif + +#ifdef _DEBUG + if (SaveValueInteger(INTEGERTEST, "iTest", ovdevice.iTest)) { + ovdevice.settings.insert_or_assign( + "iTest", std::to_string(ovdevice.iTest)); + changed = true; + } +#endif + +#if 0 // TOD(August2111) Only Test + ovdevice.settings.insert_or_assign("OpenSoarData", + "D:/Data/OpenSoarData"); +#endif + + if (changed) { + WriteConfigFile(ovdevice.settings, ovdevice.GetSettingsConfig()); + } + + if (SaveValueEnum(SSH, ovdevice.ssh)) + ovdevice.SetSSHStatus((SSHStatus)ovdevice.ssh); + + if (SaveValue(SENSORD, ovdevice.sensord)) + ovdevice.SetSystemStatus("sensord", ovdevice.sensord); + + if (SaveValue(VARIOD, ovdevice.variod)) + ovdevice.SetSystemStatus("variod", ovdevice.variod); + + _changed = changed; + return true; +} + +// this has only defined in OpenVarioBaseMenu... +bool +ShowSystemSettingsWidget(ContainerWindow &parent, + const DialogLook &look) noexcept +{ + TWidgetDialog sub_dialog( + WidgetDialog::Full{}, (UI::SingleWindow &) parent, look, + "OpenVario System Settings"); + sub_dialog.SetWidget(); + sub_dialog.AddButton(_("Save"), mrOK); + sub_dialog.AddButton(_("Close"), mrOK); + return sub_dialog.ShowModal(); +} +#endif + +std::unique_ptr +CreateSystemSettingsWidget() noexcept +{ + return std::make_unique(); +} + + diff --git a/src/OpenVario/SystemSettingsWidget.hpp b/src/OpenVario/SystemSettingsWidget.hpp new file mode 100644 index 00000000000..912e3148dd1 --- /dev/null +++ b/src/OpenVario/SystemSettingsWidget.hpp @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright The XCSoar Project + +#pragma once + +#ifdef IS_OPENVARIO + +#include + +class Widget; +class ContainerWindow; +struct DialogLook; + +bool +ShowSystemSettingsWidget(ContainerWindow &parent, + const DialogLook &look) noexcept; + +std::unique_ptr +CreateSystemSettingsWidget() noexcept; + +#endif \ No newline at end of file diff --git a/src/Operation/CMakeLists.txt b/src/Operation/CMakeLists.txt new file mode 100644 index 00000000000..c79a42de2ee --- /dev/null +++ b/src/Operation/CMakeLists.txt @@ -0,0 +1,51 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories + + +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/Operation/CMakeSource.cmake b/src/Operation/CMakeSource.cmake new file mode 100644 index 00000000000..430c273ec4c --- /dev/null +++ b/src/Operation/CMakeSource.cmake @@ -0,0 +1,16 @@ +set(_SOURCES + Operation/MessageOperationEnvironment.cpp + Operation/NoCancelOperationEnvironment.cpp + Operation/Operation.cpp + Operation/PopupOperationEnvironment.cpp + Operation/ProxyOperationEnvironment.cpp + Operation/ThreadedOperationEnvironment.cpp + Operation/VerboseOperationEnvironment.cpp + Operation/PluggableOperationEnvironment.cpp + Operation/SubOperationEnvironment.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake +) + diff --git a/src/Operation/ConsoleOperationEnvironment.cpp b/src/Operation/ConsoleOperationEnvironment.cpp index f130ad38bc7..8d0725bf4ba 100644 --- a/src/Operation/ConsoleOperationEnvironment.cpp +++ b/src/Operation/ConsoleOperationEnvironment.cpp @@ -6,15 +6,15 @@ #include void -ConsoleOperationEnvironment::SetErrorMessage(const TCHAR *text) noexcept +ConsoleOperationEnvironment::SetErrorMessage(const char *text) noexcept { - _ftprintf(stderr, _T("ERROR: %s\n"), text); + _ftprintf(stderr, "ERROR: %s\n", text); } void -ConsoleOperationEnvironment::SetText(const TCHAR *text) noexcept +ConsoleOperationEnvironment::SetText(const char *text) noexcept { - _tprintf(_T("%s\n"), text); + _tprintf("%s\n", text); } void diff --git a/src/Operation/ConsoleOperationEnvironment.hpp b/src/Operation/ConsoleOperationEnvironment.hpp index 77d22d72997..d8a66cfbef0 100644 --- a/src/Operation/ConsoleOperationEnvironment.hpp +++ b/src/Operation/ConsoleOperationEnvironment.hpp @@ -10,8 +10,8 @@ class ConsoleOperationEnvironment : public QuietOperationEnvironment { public: /* virtual methods from class OperationEnvironment */ - void SetErrorMessage(const TCHAR *text) noexcept override; - void SetText(const TCHAR *text) noexcept override; + void SetErrorMessage(const char *text) noexcept override; + void SetText(const char *text) noexcept override; void SetProgressRange(unsigned range) noexcept override; void SetProgressPosition(unsigned position) noexcept override; }; diff --git a/src/Operation/MessageOperationEnvironment.cpp b/src/Operation/MessageOperationEnvironment.cpp index be24766b708..a84ee849e5d 100644 --- a/src/Operation/MessageOperationEnvironment.cpp +++ b/src/Operation/MessageOperationEnvironment.cpp @@ -5,7 +5,7 @@ #include "Dialogs/Message.hpp" void -MessageOperationEnvironment::SetErrorMessage(const TCHAR *text) noexcept +MessageOperationEnvironment::SetErrorMessage(const char *text) noexcept { - ShowMessageBox(text, _T(""), MB_OK|MB_ICONERROR); + ShowMessageBox(text, "", MB_OK|MB_ICONERROR); } diff --git a/src/Operation/MessageOperationEnvironment.hpp b/src/Operation/MessageOperationEnvironment.hpp index 88de3576bce..43502934bc0 100644 --- a/src/Operation/MessageOperationEnvironment.hpp +++ b/src/Operation/MessageOperationEnvironment.hpp @@ -12,5 +12,5 @@ class MessageOperationEnvironment : public QuietOperationEnvironment { public: /* virtual methods from class OperationEnvironment */ - void SetErrorMessage(const TCHAR *text) noexcept override; + void SetErrorMessage(const char *text) noexcept override; }; diff --git a/src/Operation/Operation.cpp b/src/Operation/Operation.cpp index 37fecda0ee9..94e7751d354 100644 --- a/src/Operation/Operation.cpp +++ b/src/Operation/Operation.cpp @@ -3,13 +3,12 @@ #include "Operation/Operation.hpp" #include "system/Sleep.h" -#include "util/ConvertString.hpp" #include "util/Exception.hxx" void OperationEnvironment::SetError(std::exception_ptr e) noexcept { - SetErrorMessage(UTF8ToWideConverter(GetFullMessage(e).c_str())); + SetErrorMessage(GetFullMessage(e).c_str()); } bool @@ -30,12 +29,12 @@ NullOperationEnvironment::Sleep(std::chrono::steady_clock::duration) noexcept } void -NullOperationEnvironment::SetErrorMessage([[maybe_unused]] const TCHAR *text) noexcept +NullOperationEnvironment::SetErrorMessage([[maybe_unused]] const char *text) noexcept { } void -NullOperationEnvironment::SetText([[maybe_unused]] const TCHAR *text) noexcept +NullOperationEnvironment::SetText([[maybe_unused]] const char *text) noexcept { } diff --git a/src/Operation/Operation.hpp b/src/Operation/Operation.hpp index 337a54dd152..11e621fea9f 100644 --- a/src/Operation/Operation.hpp +++ b/src/Operation/Operation.hpp @@ -44,13 +44,13 @@ class OperationEnvironment : private NonCopyable, public ProgressListener { * Show a human-readable (localized) short text describing the * error condition. */ - virtual void SetErrorMessage(const TCHAR *text) noexcept = 0; + virtual void SetErrorMessage(const char *text) noexcept = 0; /** * Show a human-readable (localized) short text describing the * current state of the operation. */ - virtual void SetText(const TCHAR *text) noexcept = 0; + virtual void SetText(const char *text) noexcept = 0; }; class NullOperationEnvironment : public OperationEnvironment { @@ -59,8 +59,8 @@ class NullOperationEnvironment : public OperationEnvironment { bool IsCancelled() const noexcept override; void SetCancelHandler(std::function handler) noexcept override; void Sleep(std::chrono::steady_clock::duration duration) noexcept override; - void SetErrorMessage(const TCHAR *text) noexcept override; - void SetText(const TCHAR *text) noexcept override; + void SetErrorMessage(const char *text) noexcept override; + void SetText(const char *text) noexcept override; void SetProgressRange(unsigned range) noexcept override; void SetProgressPosition(unsigned position) noexcept override; }; diff --git a/src/Operation/PluggableOperationEnvironment.cpp b/src/Operation/PluggableOperationEnvironment.cpp index 8a639bbfbdd..579c3ecb6ff 100644 --- a/src/Operation/PluggableOperationEnvironment.cpp +++ b/src/Operation/PluggableOperationEnvironment.cpp @@ -27,14 +27,14 @@ PluggableOperationEnvironment::Sleep(std::chrono::steady_clock::duration duratio } void -PluggableOperationEnvironment::SetErrorMessage(const TCHAR *text) noexcept +PluggableOperationEnvironment::SetErrorMessage(const char *text) noexcept { if (other != nullptr) other->SetErrorMessage(text); } void -PluggableOperationEnvironment::SetText(const TCHAR *text) noexcept +PluggableOperationEnvironment::SetText(const char *text) noexcept { if (other != nullptr) other->SetText(text); diff --git a/src/Operation/PluggableOperationEnvironment.hpp b/src/Operation/PluggableOperationEnvironment.hpp index fdd1670cfe8..8e69529a29b 100644 --- a/src/Operation/PluggableOperationEnvironment.hpp +++ b/src/Operation/PluggableOperationEnvironment.hpp @@ -27,8 +27,8 @@ class PluggableOperationEnvironment final : public OperationEnvironment { bool IsCancelled() const noexcept override; void SetCancelHandler(std::function handler) noexcept override; void Sleep(std::chrono::steady_clock::duration duration) noexcept override; - void SetErrorMessage(const TCHAR *text) noexcept override; - void SetText(const TCHAR *text) noexcept override; + void SetErrorMessage(const char *text) noexcept override; + void SetText(const char *text) noexcept override; void SetProgressRange(unsigned range) noexcept override; void SetProgressPosition(unsigned position) noexcept override; }; diff --git a/src/Operation/PopupOperationEnvironment.cpp b/src/Operation/PopupOperationEnvironment.cpp index ab729bfcd9f..1f080ecb14d 100644 --- a/src/Operation/PopupOperationEnvironment.cpp +++ b/src/Operation/PopupOperationEnvironment.cpp @@ -5,7 +5,7 @@ #include "Message.hpp" void -PopupOperationEnvironment::SetErrorMessage(const TCHAR *text) noexcept +PopupOperationEnvironment::SetErrorMessage(const char *text) noexcept { Message::AddMessage(text); } diff --git a/src/Operation/PopupOperationEnvironment.hpp b/src/Operation/PopupOperationEnvironment.hpp index b3b4ec9c54d..fbfc6674823 100644 --- a/src/Operation/PopupOperationEnvironment.hpp +++ b/src/Operation/PopupOperationEnvironment.hpp @@ -11,5 +11,5 @@ class PopupOperationEnvironment : public QuietOperationEnvironment { public: /* virtual methods from class OperationEnvironment */ - void SetErrorMessage(const TCHAR *text) noexcept override; + void SetErrorMessage(const char *text) noexcept override; }; diff --git a/src/Operation/ProxyOperationEnvironment.cpp b/src/Operation/ProxyOperationEnvironment.cpp index ff589f0d88d..8f4f290a4c8 100644 --- a/src/Operation/ProxyOperationEnvironment.cpp +++ b/src/Operation/ProxyOperationEnvironment.cpp @@ -22,13 +22,13 @@ ProxyOperationEnvironment::Sleep(std::chrono::steady_clock::duration duration) n } void -ProxyOperationEnvironment::SetErrorMessage(const TCHAR *text) noexcept +ProxyOperationEnvironment::SetErrorMessage(const char *text) noexcept { other.SetErrorMessage(text); } void -ProxyOperationEnvironment::SetText(const TCHAR *text) noexcept +ProxyOperationEnvironment::SetText(const char *text) noexcept { other.SetText(text); } diff --git a/src/Operation/ProxyOperationEnvironment.hpp b/src/Operation/ProxyOperationEnvironment.hpp index 5847b2442cd..93c2cb50af7 100644 --- a/src/Operation/ProxyOperationEnvironment.hpp +++ b/src/Operation/ProxyOperationEnvironment.hpp @@ -21,8 +21,8 @@ class ProxyOperationEnvironment : public OperationEnvironment { bool IsCancelled() const noexcept override; void SetCancelHandler(std::function handler) noexcept override; void Sleep(std::chrono::steady_clock::duration duration) noexcept override; - void SetErrorMessage(const TCHAR *text) noexcept override; - void SetText(const TCHAR *text) noexcept override; + void SetErrorMessage(const char *text) noexcept override; + void SetText(const char *text) noexcept override; void SetProgressRange(unsigned range) noexcept override; void SetProgressPosition(unsigned position) noexcept override; }; diff --git a/src/Operation/ThreadedOperationEnvironment.cpp b/src/Operation/ThreadedOperationEnvironment.cpp index 61403d79dfa..852034e8ffd 100644 --- a/src/Operation/ThreadedOperationEnvironment.cpp +++ b/src/Operation/ThreadedOperationEnvironment.cpp @@ -48,7 +48,7 @@ ThreadedOperationEnvironment::Sleep(std::chrono::steady_clock::duration duration } void -ThreadedOperationEnvironment::SetErrorMessage(const TCHAR *_error) noexcept +ThreadedOperationEnvironment::SetErrorMessage(const char *_error) noexcept { { const std::lock_guard lock{mutex}; @@ -59,7 +59,7 @@ ThreadedOperationEnvironment::SetErrorMessage(const TCHAR *_error) noexcept } void -ThreadedOperationEnvironment::SetText(const TCHAR *_text) noexcept +ThreadedOperationEnvironment::SetText(const char *_text) noexcept { { const std::lock_guard lock{mutex}; diff --git a/src/Operation/ThreadedOperationEnvironment.hpp b/src/Operation/ThreadedOperationEnvironment.hpp index c2564d5c501..96bca187d3f 100644 --- a/src/Operation/ThreadedOperationEnvironment.hpp +++ b/src/Operation/ThreadedOperationEnvironment.hpp @@ -27,17 +27,17 @@ class ThreadedOperationEnvironment bool update_text, update_progress_range, update_progress_position; Data() noexcept - :text(_T("")), + :text(""), progress_range(0u), progress_position(0u), update_error(false), update_text(false), update_progress_range(false), update_progress_position(false) {} - void SetErrorMessage(const TCHAR *_error) noexcept { + void SetErrorMessage(const char *_error) noexcept { error = _error; update_error = true; } - void SetText(const TCHAR *_text) noexcept { + void SetText(const char *_text) noexcept { text = _text; update_text = true; } @@ -114,8 +114,8 @@ class ThreadedOperationEnvironment bool IsCancelled() const noexcept override; void SetCancelHandler(std::function handler) noexcept override; void Sleep(std::chrono::steady_clock::duration duration) noexcept override; - void SetErrorMessage(const TCHAR *error) noexcept override; - void SetText(const TCHAR *text) noexcept override; + void SetErrorMessage(const char *error) noexcept override; + void SetText(const char *text) noexcept override; void SetProgressRange(unsigned range) noexcept override; void SetProgressPosition(unsigned position) noexcept override; diff --git a/src/Operation/VerboseOperationEnvironment.cpp b/src/Operation/VerboseOperationEnvironment.cpp index 408129256cc..333cc1b1ac1 100644 --- a/src/Operation/VerboseOperationEnvironment.cpp +++ b/src/Operation/VerboseOperationEnvironment.cpp @@ -5,7 +5,7 @@ #include "ProgressGlue.hpp" void -VerboseOperationEnvironment::SetText(const TCHAR *text) noexcept +VerboseOperationEnvironment::SetText(const char *text) noexcept { ProgressGlue::Create(text); } diff --git a/src/Operation/VerboseOperationEnvironment.hpp b/src/Operation/VerboseOperationEnvironment.hpp index fc24e03d33a..7321dedd440 100644 --- a/src/Operation/VerboseOperationEnvironment.hpp +++ b/src/Operation/VerboseOperationEnvironment.hpp @@ -15,7 +15,7 @@ class VerboseOperationEnvironment : public MessageOperationEnvironment { void Hide() noexcept; /* virtual methods from class OperationEnvironment */ - void SetText(const TCHAR *text) noexcept override; + void SetText(const char *text) noexcept override; void SetProgressRange(unsigned range) noexcept override; void SetProgressPosition(unsigned position) noexcept override; }; diff --git a/src/PageSettings.cpp b/src/PageSettings.cpp index c538807a362..179d67c530f 100644 --- a/src/PageSettings.cpp +++ b/src/PageSettings.cpp @@ -8,13 +8,13 @@ #include -const TCHAR * +const char * PageLayout::MakeTitle(const InfoBoxSettings &info_box_settings, - std::span buffer, + std::span buffer, const bool concise) const noexcept { if (!valid) - return _T("---"); + return "---"; switch (main) { case PageLayout::Main::MAP: @@ -33,7 +33,7 @@ PageLayout::MakeTitle(const InfoBoxSettings &info_box_settings, gcc_unreachable(); } - BasicStringBuilder builder{buffer}; + BasicStringBuilder builder{buffer}; try { if (infobox_config.enabled) { @@ -49,7 +49,7 @@ PageLayout::MakeTitle(const InfoBoxSettings &info_box_settings, builder.Append(' '); builder.Append(_("Auto")); } else { - builder.Append(_T(" (")); + builder.Append(" ("); builder.Append(_("Auto")); builder.Append(')'); } @@ -68,13 +68,13 @@ PageLayout::MakeTitle(const InfoBoxSettings &info_box_settings, case Bottom::CROSS_SECTION: // TODO: better text and translate - builder.Append(_T(", XS")); + builder.Append(", XS"); break; case Bottom::MAX: gcc_unreachable(); } - } catch (BasicStringBuilder::Overflow) { + } catch (BasicStringBuilder::Overflow) { } return buffer.data(); diff --git a/src/PageSettings.hpp b/src/PageSettings.hpp index 3f5b3516655..c6a56bd6614 100644 --- a/src/PageSettings.hpp +++ b/src/PageSettings.hpp @@ -134,8 +134,8 @@ struct PageLayout } [[nodiscard]] - const TCHAR *MakeTitle(const InfoBoxSettings &info_box_settings, - std::span buffer, + const char *MakeTitle(const InfoBoxSettings &info_box_settings, + std::span buffer, const bool concise=false) const noexcept; constexpr bool operator==(const PageLayout &other) const noexcept = default; diff --git a/src/Plane/CMakeLists.txt b/src/Plane/CMakeLists.txt new file mode 100644 index 00000000000..c79a42de2ee --- /dev/null +++ b/src/Plane/CMakeLists.txt @@ -0,0 +1,51 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories + + +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/Plane/CMakeSource.cmake b/src/Plane/CMakeSource.cmake new file mode 100644 index 00000000000..c3b8bf7f056 --- /dev/null +++ b/src/Plane/CMakeSource.cmake @@ -0,0 +1,9 @@ +set(_SOURCES + Plane/PlaneFileGlue.cpp + Plane/PlaneGlue.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake +) + diff --git a/src/Plane/PlaneFileGlue.cpp b/src/Plane/PlaneFileGlue.cpp index 57d12707ec9..cd961ca36b8 100644 --- a/src/Plane/PlaneFileGlue.cpp +++ b/src/Plane/PlaneFileGlue.cpp @@ -145,7 +145,7 @@ try { void PlaneGlue::Write(const Plane &plane, KeyValueFileWriter &writer) { - NarrowString<255> tmp; + StaticString<255> tmp; writer.Write("Registration", plane.registration); writer.Write("CompetitionID", plane.competition_id); diff --git a/src/Polar/CMakeLists.txt b/src/Polar/CMakeLists.txt new file mode 100644 index 00000000000..c79a42de2ee --- /dev/null +++ b/src/Polar/CMakeLists.txt @@ -0,0 +1,51 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories + + +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/Polar/CMakeSource.cmake b/src/Polar/CMakeSource.cmake new file mode 100644 index 00000000000..95a017ad007 --- /dev/null +++ b/src/Polar/CMakeSource.cmake @@ -0,0 +1,12 @@ +set(_SOURCES + Polar/Parser.cpp + Polar/Polar.cpp + Polar/PolarFileGlue.cpp + Polar/PolarGlue.cpp + Polar/PolarStore.cpp + Polar/Shape.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake +) diff --git a/src/Polar/Parser.cpp b/src/Polar/Parser.cpp index 090e634d4b5..7baa70dcc25 100644 --- a/src/Polar/Parser.cpp +++ b/src/Polar/Parser.cpp @@ -14,23 +14,23 @@ ParsePolarShape(PolarShape &shape, const char *s) noexcept { char *p; auto v1 = Units::ToSysUnit(ParseDouble(s, &p), Unit::KILOMETER_PER_HOUR); - if (*p != _T(',')) + if (*p != ',') return false; auto w1 = ParseDouble(p + 1, &p); - if (*p != _T(',')) + if (*p != ',') return false; auto v2 = Units::ToSysUnit(ParseDouble(p + 1, &p), Unit::KILOMETER_PER_HOUR); - if (*p != _T(',')) + if (*p != ',') return false; auto w2 = ParseDouble(p + 1, &p); - if (*p != _T(',')) + if (*p != ',') return false; auto v3 = Units::ToSysUnit(ParseDouble(p + 1, &p), Unit::KILOMETER_PER_HOUR); - if (*p != _T(',')) + if (*p != ',') return false; auto w3 = ParseDouble(p + 1, &p); @@ -54,42 +54,42 @@ ParsePolar(PolarInfo &polar_r, const char *s) noexcept // *LS-3 WinPilot POLAR file: MassDryGross[kg], MaxWaterBallast[liters], Speed1[km/h], Sink1[m/s], Speed2, Sink2, Speed3, Sink3 // 403, 101, 115.03, -0.86, 174.04, -1.76, 212.72, -3.4 - if (s[0] == _T('*')) + if (s[0] == '*') /* a comment */ return false; char *p; polar.shape.reference_mass = ParseDouble(s, &p); - if (*p != _T(',')) + if (*p != ',') return false; polar.max_ballast = ParseDouble(p + 1, &p); - if (*p != _T(',')) + if (*p != ',') return false; polar.shape[0].v = Units::ToSysUnit(ParseDouble(p + 1, &p), Unit::KILOMETER_PER_HOUR); - if (*p != _T(',')) + if (*p != ',') return false; polar.shape[0].w = ParseDouble(p + 1, &p); - if (*p != _T(',')) + if (*p != ',') return false; polar.shape[1].v = Units::ToSysUnit(ParseDouble(p + 1, &p), Unit::KILOMETER_PER_HOUR); - if (*p != _T(',')) + if (*p != ',') return false; polar.shape[1].w = ParseDouble(p + 1, &p); - if (*p != _T(',')) + if (*p != ',') return false; polar.shape[2].v = Units::ToSysUnit(ParseDouble(p + 1, &p), Unit::KILOMETER_PER_HOUR); - if (*p != _T(',')) + if (*p != ',') return false; polar.shape[2].w = ParseDouble(p + 1, &p); - polar.wing_area = (*p != _T(',')) ? 0. : ParseDouble(p + 1, &p); - polar.v_no = (*p != _T(',')) ? 0. : ParseDouble(p + 1, &p); + polar.wing_area = (*p != ',') ? 0. : ParseDouble(p + 1, &p); + polar.v_no = (*p != ',') ? 0. : ParseDouble(p + 1, &p); polar_r = polar; return true; diff --git a/src/Polar/PolarStore.cpp b/src/Polar/PolarStore.cpp index 5c74c557021..405b071b501 100644 --- a/src/Polar/PolarStore.cpp +++ b/src/Polar/PolarStore.cpp @@ -39,7 +39,7 @@ Item::ToPolarInfo() const noexcept } static constexpr Item default_polar = { - _T("LS-8 (15m)"), 325, 185, 70, -0.51, 115, -0.85, 173, -2.00, 10.5, 0.0, 108, 240, + "LS-8 (15m)", 325, 185, 70, -0.51, 115, -0.85, 173, -2.00, 10.5, 0.0, 108, 240, }; /** @@ -49,206 +49,206 @@ static constexpr Item default_polar = { * for ever. */ static constexpr Item internal_polars[] = { - { _T("206 Hornet"), 318, 100, 80, -0.606, 120, -0.99, 160, -1.918, 9.8, 41.666, 100, 227 }, - { _T("303 Mosquito"), 450, 0, 100.0, -0.68, 120.0, -0.92, 150.0, -1.45, 9.85, 0.0, 107, 242 }, - { _T("304CZ"), 310, 115, 115.03, -0.86, 174.04, -1.76, 212.72, -3.4, 0, 0.0, 110, 235 }, - { _T("401 Kestrel (17m)"), 367, 33, 95, -0.62, 110, -0.76, 175, -2.01, 11.58 , 0.0, 110, 260 }, - { _T("604 Kestrel"), 570, 100, 112.97, -0.72, 150.64, -1.42, 207.13, -4.1, 16.26, 0.0, 114, 455 }, + { "206 Hornet", 318, 100, 80, -0.606, 120, -0.99, 160, -1.918, 9.8, 41.666, 100, 227 }, + { "303 Mosquito", 450, 0, 100.0, -0.68, 120.0, -0.92, 150.0, -1.45, 9.85, 0.0, 107, 242 }, + { "304CZ", 310, 115, 115.03, -0.86, 174.04, -1.76, 212.72, -3.4, 0, 0.0, 110, 235 }, + { "401 Kestrel (17m)", 367, 33, 95, -0.62, 110, -0.76, 175, -2.01, 11.58 , 0.0, 110, 260 }, + { "604 Kestrel", 570, 100, 112.97, -0.72, 150.64, -1.42, 207.13, -4.1, 16.26, 0.0, 114, 455 }, // from Akaflieg Karlsruhe, idaflieg measurement 2017 with new winglet design at Aalen Elchingen - { _T("AK-8"), 362 , 100, 84.1343, -0.6524, 130.0, -0.9474, 170.0, -1.8380, 9.75, 50.0, 107, 233 }, + { "AK-8", 362 , 100, 84.1343, -0.6524, 130.0, -0.9474, 170.0, -1.8380, 9.75, 50.0, 107, 233 }, // from LX8000/9000 simulator - { _T("Antares 18S"), 350, 250, 100, -0.54, 120, -0.63, 150, -1.07, 10.97, 0.0, 120, 295 }, - { _T("Antares 18T"), 395, 205, 100, -0.54, 120, -0.69, 150, -1.11, 10.97, 0.0, 120, 345 }, - { _T("Antares 20E"), 530, 130, 100, -0.52, 120, -0.61, 150, -0.91, 12.6, 0.0, 123, 475 }, + { "Antares 18S", 350, 250, 100, -0.54, 120, -0.63, 150, -1.07, 10.97, 0.0, 120, 295 }, + { "Antares 18T", 395, 205, 100, -0.54, 120, -0.69, 150, -1.11, 10.97, 0.0, 120, 345 }, + { "Antares 20E", 530, 130, 100, -0.52, 120, -0.61, 150, -0.91, 12.6, 0.0, 123, 475 }, - { _T("Apis (13m)"), 200, 45, 100, -0.74, 120, -1.01, 150, -1.66, 10.36, 0.0, 93, 137 }, - { _T("Apis 2 (15m)"), 310, 0, 80, -0.60, 100, -0.75, 140, -1.45, 12.40, 0.0, 98, 215 }, // from LK8000 + { "Apis (13m)", 200, 45, 100, -0.74, 120, -1.01, 150, -1.66, 10.36, 0.0, 93, 137 }, + { "Apis 2 (15m)", 310, 0, 80, -0.60, 100, -0.75, 140, -1.45, 12.40, 0.0, 98, 215 }, // from LK8000 // from Shempp Hirth - { _T("Arcus"), 700, 185, 110, -0.64, 140, -0.88, 180, -1.47, 15.59, 50.0, 120, 430 }, + { "Arcus", 700, 185, 110, -0.64, 140, -0.88, 180, -1.47, 15.59, 50.0, 120, 430 }, - { _T("ASG-29 (15m)"), 362, 165, 108.8, -0.635, 156.4, -1.182, 211.13, -2.540, 9.20, 0.0, 114, 270 }, - { _T("ASG-29 (18m)"), 355, 225, 85, -0.47, 90, -0.48, 185, -2.00, 10.5, 0.0, 121, 280 }, - { _T("ASG-29E (15m)"), 350, 200, 100, -0.64, 120, -0.75, 150, -1.13, 9.2, 0.0, 114, 315 }, - { _T("ASG-29E (18m)"), 400, 200, 90, -0.499, 95.5, -0.510, 196.4, -2.12, 10.5, 0.0, 121, 325 }, - { _T("ASH-25"), 750, 121, 130.01, -0.78, 169.96, -1.4, 219.94, -2.6, 16.31, 0.0, 122, 478 }, - { _T("ASH-26"), 340, 185, 100, -0.56, 120, -0.74, 150, -1.16, 11.7, 0.0, 119, 325 }, - { _T("ASH-26E"), 435, 90, 90, -0.51, 96, -0.53, 185, -2.00, 11.7, 0.0, 119, 360 }, - { _T("ASK-13"), 456, 0, 85, -0.84, 120, -1.5, 150, -2.8, 17.5, 44.444, 79, 296 }, - { _T("ASK-18"), 310, 0, 75, -0.613, 138, -1.773, 200, -4.234, 12.99, 0, 88, 215 }, - { _T("ASK-21"), 468, 0, 74.1, -0.67, 101.9, -0.90, 166.7, -2.68, 17.95, 50.0, 92, 360 }, - { _T("ASK-23"), 330, 0, 100, -0.85, 120, -1.19, 150, -2.02, 12.9, 0.0, 92, 240 }, - { _T("ASW-12"), 394, 189, 95, -0.57, 148, -1.48, 183.09, -2.6, 13.00, 0.0, 110, 324 }, - { _T("ASW-15"), 349, 91, 97.56, -0.77, 156.12, -1.9, 195.15, -3.4, 11.0, 0.0, 97, 210 }, - { _T("ASW-17"), 522, 151, 114.5, -0.7, 169.05, -1.68, 206.5, -2.9, 14.84, 0.0, 115, 405 }, - { _T("ASW-19"), 363, 125, 97.47, -0.74, 155.96, -1.64, 194.96, -3.1, 11.0, 47.222, 100, 240 }, - { _T("ASW-20"), 377, 159, 116.2, -0.77, 174.3, -1.89, 213.04, -3.3, 10.5, 0.0, 108, 255 }, - { _T("ASW-20BL"), 400, 126, 95, -0.628, 148, -1.338, 200, -2.774, 10.49, 0, 112, 275 }, - { _T("ASW-22B"), 597, 303, 80, -0.4015, 120, -0.66, 160, -1.3539, 16.31, 0.0, 123, 270 }, - { _T("ASW-22BLE"), 465, 285, 100, -0.47, 120, -0.63, 150, -1.04, 16.7, 0.0, 124, 275 }, - { _T("ASW-24"), 350, 159, 108.82, -0.73, 142.25, -1.21, 167.41, -1.8, 10.0, 0.0, 107, 230 }, - { _T("ASW-27"), 365, 165, 88.8335, -0.5939, 130.0, -0.8511, 170.0, -1.6104, 9.0, 0.0, 114, 235 }, // from idaflieg 1997 & 2018 - { _T("ASW-28 (15m)"), 310, 200, 92.6, -0.571, 120.38, -0.875, 148.16, -1.394, 10.5, 55.555, 108, 235 }, // from SeeYou - { _T("ASW-28 (18m)"), 345, 190, 65, -0.47, 107, -0.67, 165, -2.00, 10.5, 0.0, 114, 270 }, - { _T("Blanik L13"), 472, 0, 85.0, -0.84, 143.0, -3.32, 200.0, -9.61, 19.1, 0.0, 78, 292 }, + { "ASG-29 (15m)", 362, 165, 108.8, -0.635, 156.4, -1.182, 211.13, -2.540, 9.20, 0.0, 114, 270 }, + { "ASG-29 (18m)", 355, 225, 85, -0.47, 90, -0.48, 185, -2.00, 10.5, 0.0, 121, 280 }, + { "ASG-29E (15m)", 350, 200, 100, -0.64, 120, -0.75, 150, -1.13, 9.2, 0.0, 114, 315 }, + { "ASG-29E (18m)", 400, 200, 90, -0.499, 95.5, -0.510, 196.4, -2.12, 10.5, 0.0, 121, 325 }, + { "ASH-25", 750, 121, 130.01, -0.78, 169.96, -1.4, 219.94, -2.6, 16.31, 0.0, 122, 478 }, + { "ASH-26", 340, 185, 100, -0.56, 120, -0.74, 150, -1.16, 11.7, 0.0, 119, 325 }, + { "ASH-26E", 435, 90, 90, -0.51, 96, -0.53, 185, -2.00, 11.7, 0.0, 119, 360 }, + { "ASK-13", 456, 0, 85, -0.84, 120, -1.5, 150, -2.8, 17.5, 44.444, 79, 296 }, + { "ASK-18", 310, 0, 75, -0.613, 138, -1.773, 200, -4.234, 12.99, 0, 88, 215 }, + { "ASK-21", 468, 0, 74.1, -0.67, 101.9, -0.90, 166.7, -2.68, 17.95, 50.0, 92, 360 }, + { "ASK-23", 330, 0, 100, -0.85, 120, -1.19, 150, -2.02, 12.9, 0.0, 92, 240 }, + { "ASW-12", 394, 189, 95, -0.57, 148, -1.48, 183.09, -2.6, 13.00, 0.0, 110, 324 }, + { "ASW-15", 349, 91, 97.56, -0.77, 156.12, -1.9, 195.15, -3.4, 11.0, 0.0, 97, 210 }, + { "ASW-17", 522, 151, 114.5, -0.7, 169.05, -1.68, 206.5, -2.9, 14.84, 0.0, 115, 405 }, + { "ASW-19", 363, 125, 97.47, -0.74, 155.96, -1.64, 194.96, -3.1, 11.0, 47.222, 100, 240 }, + { "ASW-20", 377, 159, 116.2, -0.77, 174.3, -1.89, 213.04, -3.3, 10.5, 0.0, 108, 255 }, + { "ASW-20BL", 400, 126, 95, -0.628, 148, -1.338, 200, -2.774, 10.49, 0, 112, 275 }, + { "ASW-22B", 597, 303, 80, -0.4015, 120, -0.66, 160, -1.3539, 16.31, 0.0, 123, 270 }, + { "ASW-22BLE", 465, 285, 100, -0.47, 120, -0.63, 150, -1.04, 16.7, 0.0, 124, 275 }, + { "ASW-24", 350, 159, 108.82, -0.73, 142.25, -1.21, 167.41, -1.8, 10.0, 0.0, 107, 230 }, + { "ASW-27", 365, 165, 88.8335, -0.5939, 130.0, -0.8511, 170.0, -1.6104, 9.0, 0.0, 114, 235 }, // from idaflieg 1997 & 2018 + { "ASW-28 (15m)", 310, 200, 92.6, -0.571, 120.38, -0.875, 148.16, -1.394, 10.5, 55.555, 108, 235 }, // from SeeYou + { "ASW-28 (18m)", 345, 190, 65, -0.47, 107, -0.67, 165, -2.00, 10.5, 0.0, 114, 270 }, + { "Blanik L13", 472, 0, 85.0, -0.84, 143.0, -3.32, 200.0, -9.61, 19.1, 0.0, 78, 292 }, // from factory polar (flight manual) - { _T("Blanik L13-AC"), 500, 0, 70, -0.85, 110, -1.25, 160, -3.2, 17.44, 44.44, 78, 306 }, - { _T("Blanik L23"), 510, 0, 95.0, -0.94, 148.0, -2.60, 200.0, -6.37, 19.1, 0.0, 80, 310 }, - { _T("Carat"), 470, 0, 100, -0.83, 120, -1.04, 150, -1.69, 10.58, 0.0, 93, 341 }, - { _T("Cirrus (18m)"), 330, 100, 100, -0.74, 120, -1.06, 150, -1.88, 12.6, 0.0, 102, 260 }, + { "Blanik L13-AC", 500, 0, 70, -0.85, 110, -1.25, 160, -3.2, 17.44, 44.44, 78, 306 }, + { "Blanik L23", 510, 0, 95.0, -0.94, 148.0, -2.60, 200.0, -6.37, 19.1, 0.0, 80, 310 }, + { "Carat", 470, 0, 100, -0.83, 120, -1.04, 150, -1.69, 10.58, 0.0, 93, 341 }, + { "Cirrus (18m)", 330, 100, 100, -0.74, 120, -1.06, 150, -1.88, 12.6, 0.0, 102, 260 }, // Idaflieg measurement, 28.08.2015 at Aalen Elchingen - { _T("D-43 18m"), 668, 0, 100, -0.62, 130, -0.863, 170, -1.672, 15.93, 250, 99, }, + { "D-43 18m", 668, 0, 100, -0.62, 130, -0.863, 170, -1.672, 15.93, 250, 99, }, - { _T("Delta USHPA-2"), 100, 0, 30, -1.10, 44.3, -1.52, 58.0, -3.60, 0, 0.0, 0, 5 }, - { _T("Delta USHPA-3"), 100, 0, 37, -0.95, 48.1, -1.15, 73.0, -3.60, 0, 0.0, 0, 5 }, - { _T("Delta USHPA-4"), 100, 0, 37, -0.89, 48.3, -1.02, 76.5, -3.30, 0, 0.0, 0, 5 }, - { _T("DG-1000 (20m)"), 613, 160, 106.0, -0.62, 153.0, -1.53, 200.0, -3.2, 17.51, 0.0, 111, 415 }, - { _T("DG-100"), 300, 100, 100, -0.73, 120, -1.00, 150, -1.7, 11.0, 0.0, 100, 230 }, - { _T("DG-200"), 300, 120, 100, -0.68, 120, -0.86, 150, -1.3, 10.0, 0.0, 107, 230 }, - { _T("DG-300"), 310, 190, 95.0, -0.66, 140.0, -1.28, 160.0, -1.70, 10.27, 0.0, 104, 235 }, - { _T("DG-400 (15m)"), 440, 90, 115, -0.76, 160.53, -1.22, 210.22, -2.3, 10.0, 0.0, 107, 306 }, - { _T("DG-400 (17m)"), 444, 90, 118.28, -0.68, 163.77, -1.15, 198.35, -1.8, 10.57, 0.0, 109, 310 }, - { _T("DG-500 (20m)"), 659, 100, 115.4, -0.71, 152.01, -1.28, 190.02, -2.3, 18.29, 0.0, 104, 390 }, - { _T("DG-600 (15m)"), 327, 180, 100, -0.60, 120, -0.76, 150, -1.19, 10.95, 0.0, 110, 255 }, - { _T("DG-800B (15m)"), 468, 100, 103.610, -0.6535, 130.0, -0.8915, 170.0, -1.4807, 10.68, 52.8, 113, 340 }, - { _T("DG-800B (18m)"), 472, 100, 90.0086, -0.5496, 130.0, -0.7920, 170.0, -1.4248, 11.81, 52.8, 119, 344 }, + { "Delta USHPA-2", 100, 0, 30, -1.10, 44.3, -1.52, 58.0, -3.60, 0, 0.0, 0, 5 }, + { "Delta USHPA-3", 100, 0, 37, -0.95, 48.1, -1.15, 73.0, -3.60, 0, 0.0, 0, 5 }, + { "Delta USHPA-4", 100, 0, 37, -0.89, 48.3, -1.02, 76.5, -3.30, 0, 0.0, 0, 5 }, + { "DG-1000 (20m)", 613, 160, 106.0, -0.62, 153.0, -1.53, 200.0, -3.2, 17.51, 0.0, 111, 415 }, + { "DG-100", 300, 100, 100, -0.73, 120, -1.00, 150, -1.7, 11.0, 0.0, 100, 230 }, + { "DG-200", 300, 120, 100, -0.68, 120, -0.86, 150, -1.3, 10.0, 0.0, 107, 230 }, + { "DG-300", 310, 190, 95.0, -0.66, 140.0, -1.28, 160.0, -1.70, 10.27, 0.0, 104, 235 }, + { "DG-400 (15m)", 440, 90, 115, -0.76, 160.53, -1.22, 210.22, -2.3, 10.0, 0.0, 107, 306 }, + { "DG-400 (17m)", 444, 90, 118.28, -0.68, 163.77, -1.15, 198.35, -1.8, 10.57, 0.0, 109, 310 }, + { "DG-500 (20m)", 659, 100, 115.4, -0.71, 152.01, -1.28, 190.02, -2.3, 18.29, 0.0, 104, 390 }, + { "DG-600 (15m)", 327, 180, 100, -0.60, 120, -0.76, 150, -1.19, 10.95, 0.0, 110, 255 }, + { "DG-800B (15m)", 468, 100, 103.610, -0.6535, 130.0, -0.8915, 170.0, -1.4807, 10.68, 52.8, 113, 340 }, + { "DG-800B (18m)", 472, 100, 90.0086, -0.5496, 130.0, -0.7920, 170.0, -1.4248, 11.81, 52.8, 119, 344 }, // as taken from handbook of DG-800S the pure glider variant - { _T("DG-800S (15m)"), 370, 150, 92.1255, -0.5811, 130.0, -0.9754, 170.0, -1.6933, 10.68, 52.8, 113, 260 }, - { _T("DG-800S (18m)"), 350, 150, 77.5081, -0.4733, 130.0, -0.9257, 170.0, -1.7948, 11.81, 52.8, 119, 264 }, + { "DG-800S (15m)", 370, 150, 92.1255, -0.5811, 130.0, -0.9754, 170.0, -1.6933, 10.68, 52.8, 113, 260 }, + { "DG-800S (18m)", 350, 150, 77.5081, -0.4733, 130.0, -0.9257, 170.0, -1.7948, 11.81, 52.8, 119, 264 }, - { _T("Dimona"), 670, 100, 100, -1.29, 120, -1.61, 150, -2.45, 15.3, 0.0, 68, 470 }, - { _T("Discus 2b"), 312, 200, 105, -0.66, 150, -1.05, 200, -2.0, 10.6, 0.0, 108, 252 }, - { _T("Discus 2c (18m)"), 377, 188, 100, -0.57, 120, -0.76, 150, -1.33, 11.36, 55.555, 114, 280 }, - { _T("Discus"), 350, 182, 95, -0.63, 140, -1.23, 180, -2.29, 10.58, 55.555, 107, 233 }, - { _T("Duo Discus"), 615, 80, 103, -0.64, 152, -1.25, 200, -2.51, 16.4, 0.0, 112, 420 }, - { _T("Duo Discus T"), 615, 80, 103, -0.64, 152, -1.25, 200, -2.51, 16.4, 0.0, 112, 445 }, - { _T("Duo Discus xT"), 700, 50, 110, -0.664, 155, -1.206, 200, -2.287, 16.40, 50.0, 113, 445 }, - { _T("EB 28"), 670, 180, 100, -0.46, 120, -0.61, 150, -0.96, 16.8, 0.0, 125, 570 }, - { _T("EB 28 Edition"), 670, 180, 100, -0.47, 120, -0.63, 150, -0.97, 16.5, 0.0, 125, 570 }, - { _T("G 102 Astir CS"), 330, 90, 75.0, -0.7, 93.0, -0.74, 185.00, -3.1, 12.40, 0.0, 96, 255 }, + { "Dimona", 670, 100, 100, -1.29, 120, -1.61, 150, -2.45, 15.3, 0.0, 68, 470 }, + { "Discus 2b", 312, 200, 105, -0.66, 150, -1.05, 200, -2.0, 10.6, 0.0, 108, 252 }, + { "Discus 2c (18m)", 377, 188, 100, -0.57, 120, -0.76, 150, -1.33, 11.36, 55.555, 114, 280 }, + { "Discus", 350, 182, 95, -0.63, 140, -1.23, 180, -2.29, 10.58, 55.555, 107, 233 }, + { "Duo Discus", 615, 80, 103, -0.64, 152, -1.25, 200, -2.51, 16.4, 0.0, 112, 420 }, + { "Duo Discus T", 615, 80, 103, -0.64, 152, -1.25, 200, -2.51, 16.4, 0.0, 112, 445 }, + { "Duo Discus xT", 700, 50, 110, -0.664, 155, -1.206, 200, -2.287, 16.40, 50.0, 113, 445 }, + { "EB 28", 670, 180, 100, -0.46, 120, -0.61, 150, -0.96, 16.8, 0.0, 125, 570 }, + { "EB 28 Edition", 670, 180, 100, -0.47, 120, -0.63, 150, -0.97, 16.5, 0.0, 125, 570 }, + { "G 102 Astir CS", 330, 90, 75.0, -0.7, 93.0, -0.74, 185.00, -3.1, 12.40, 0.0, 96, 255 }, // from factory polar (flight manual) by Christopher Schenk - { _T("G 102 Club Astir IIIb"), 380, 0, 75.0, -0.6, 100.0, -0.70, 180.00, -3.1, 12.40, 0.0, 91, 255 }, - { _T("G 102 Standard Astir III"), 380, 70, 75.0, -0.6, 100.0, -0.70, 180.00, -2.8, 12.40, 0.0, 100, 260 }, + { "G 102 Club Astir IIIb", 380, 0, 75.0, -0.6, 100.0, -0.70, 180.00, -3.1, 12.40, 0.0, 91, 255 }, + { "G 102 Standard Astir III", 380, 70, 75.0, -0.6, 100.0, -0.70, 180.00, -2.8, 12.40, 0.0, 100, 260 }, - { _T("G 103 Twin 2"), 580, 0, 99, -0.8, 175.01, -1.95, 225.02, -3.8, 17.52, 0.0, 92, 390 }, - { _T("G 104 Speed Astir"), 351, 90, 90, -0.63, 105, -0.72, 157, -2.00, 11.5, 0.0, 105, 265 }, - { _T("Genesis II"), 374, 151, 94, -0.61, 141.05, -1.18, 172.4, -2.0, 11.24, 0.0, 107, 240 }, - { _T("Glasfluegel 304"), 305, 145, 100, -0.78, 120, -0.97, 150, -1.43, 9.9, 0.0, 110, 235 }, - { _T("H-201 Std Libelle"), 304, 50, 97, -0.79, 152.43, -1.91, 190.54, -3.3, 9.8, 41.666, 98, 185 }, - { _T("H-205 Club Libelle"), 295, 0, 100, -0.85, 120, -1.21, 150, -2.01, 9.8, 41.666, 96, 200 }, - { _T("H-301 Libelle"), 300, 50, 94, -0.68, 147.71, -2.03, 184.64, -4.1, 9.8, 41.666, 100, 180 }, - { _T("IS-28B2"), 590, 0, 100, -0.82, 160, -2.28, 200, -4.27, 18.24, 0.0, 84, 375 }, - { _T("IS-29D2 Lark"), 360, 0, 100, -0.82, 135.67, -1.55, 184.12, -3.3, 10.4, 0.0, 96, 240 }, - { _T("Janus (18m)"), 498, 240, 100, -0.71, 120, -0.92, 150, -1.46, 16.6, 0.0, 102, 405 }, - { _T("Janus C FG"), 603, 170, 115.5, -0.76, 171.79, -1.98, 209.96, -4.0, 17.4, 47.222, 106, 405 }, // obviously wrong - { _T("Janus C RG"), 519, 240, 90, -0.60, 120, -0.88, 160, -1.64, 17.3, 50, 108, 405 }, // from factory polar - { _T("JS-1B (18m)"), 405, 180, 108, -0.57, 152, -1.06, 180, -1.65, 11.25, 56.3, 121, 310 }, // from factory polar - { _T("JS-1C (21m)"), 441, 180, 108, -0.52, 156, -1.1, 180, -1.62, 12.25, 56.3, 126, 330 }, // from factory polar - { _T("JS-3 (15m)"), 350, 158, 100, -0.6, 130, -0.8, 160, -1.2, 8.75, 57.5, 116, 270 }, // from factory polar - { _T("JS-3 (18m)"), 398, 158, 100, -0.55, 130, -0.72, 160, -1.12, 9.95, 57.5, 122, 282 }, // from factory polar - { _T("Ka 2b"), 418, 0, 87, -0.9, 120, -1.5, 150, -2.6, 17.5, 0.0, 78, 278 }, - { _T("Ka 4 Rhoenlerche"), 360, 0, 65, -0.95, 120, -2.5, 140, -3.5, 16.34, 0.0, 54, 220 }, - { _T("Ka 6CR"), 310, 0, 64.83 , -0.67 , 130.0, -2.26 , 170.0, -4.69 , 12.5 , 0.0 , 82, 185 }, - { _T("Ka 6E"), 310, 0, 87.35, -0.81, 141.92, -2.03, 174.68, -3.5, 12.4, 0.0, 85, 185 }, // from idaflieg measured 1970 - { _T("Ka 7"), 445, 0, 87, -0.92, 120, -1.55, 150, -2.7, 17.5, 0.0, 78, 285 }, - { _T("Ka 8"), 290, 0, 74.1, -0.76, 101.9, -1.27, 166.7, -4.64, 14.15, 0.0, 76, 190 }, - { _T("L 33 Solo"), 330, 0, 87.2, -0.8, 135.64, -1.73, 174.4, -3.4, 11.0, 0.0, 86, 210 }, - { _T("LAK-12"), 430, 190, 75, -0.48, 125, -0.88, 175, -1.97, 14.63, 48.611, 114, 360 }, // from marius@sargevicius.com - { _T("LAK-17 (15m)"), 285, 215, 100, -0.60, 120, -0.72, 150, -1.09, 9.06, 0.0, 113, 220 }, - { _T("LAK-17 (18m)"), 295, 205, 100, -0.56, 120, -0.74, 150, -1.16, 9.8, 0.0, 119, 225 }, - { _T("LAK17a (15m)"), 285, 180, 95, -0.574, 148, -1.310, 200, -2.885, 9.06, 0.0, 113, 220 }, - { _T("LAK17a (18m)"), 298, 180, 115, -0.680, 158, -1.379, 200, -2.975, 9.80, 0.0, 119, 225 }, - { _T("LAK-19 (15m)"), 285, 195, 100, -0.64, 120, -0.85, 150, -1.41, 9.06, 0.0, 108, 220 }, - { _T("LAK-19 (18m)"), 295, 185, 100, -0.60, 120, -0.82, 150, -1.34, 9.8, 0.0, 114, 226 }, - { _T("LS-10s (15m)"), 370, 170, 100, -0.64, 120, -0.80, 150, -1.26, 10.27, 0.0, 113, 288 }, - { _T("LS-10s (18m)"), 380, 220, 100, -0.58, 120, -0.75, 150, -1.21, 11.45, 0.0, 119, 295 }, - { _T("LS-1c"), 350, 91, 115.87, -1.02, 154.49, -1.84, 193.12, -3.3, 9.74, 0.0, 98, 200 }, - { _T("LS-1f"), 345, 80, 100, -0.75, 120, -0.98, 150, -1.6, 9.74, 0.0, 100, 230 }, // from idaflieg - { _T("LS-3 (17m)"), 325, 0, 100, -0.61, 120, -0.84, 150, -1.53, 11.22, 0.0, 109, 255 }, - { _T("LS-3"), 383, 121, 93.0, -0.64, 127.0, -0.93, 148.2, -1.28, 10.5, 0.0, 107, 270 }, - { _T("LS-4"), 361, 121, 100, -0.69, 120, -0.87, 150, -1.44, 10.5, 0.0, 104, 235 }, + { "G 103 Twin 2", 580, 0, 99, -0.8, 175.01, -1.95, 225.02, -3.8, 17.52, 0.0, 92, 390 }, + { "G 104 Speed Astir", 351, 90, 90, -0.63, 105, -0.72, 157, -2.00, 11.5, 0.0, 105, 265 }, + { "Genesis II", 374, 151, 94, -0.61, 141.05, -1.18, 172.4, -2.0, 11.24, 0.0, 107, 240 }, + { "Glasfluegel 304", 305, 145, 100, -0.78, 120, -0.97, 150, -1.43, 9.9, 0.0, 110, 235 }, + { "H-201 Std Libelle", 304, 50, 97, -0.79, 152.43, -1.91, 190.54, -3.3, 9.8, 41.666, 98, 185 }, + { "H-205 Club Libelle", 295, 0, 100, -0.85, 120, -1.21, 150, -2.01, 9.8, 41.666, 96, 200 }, + { "H-301 Libelle", 300, 50, 94, -0.68, 147.71, -2.03, 184.64, -4.1, 9.8, 41.666, 100, 180 }, + { "IS-28B2", 590, 0, 100, -0.82, 160, -2.28, 200, -4.27, 18.24, 0.0, 84, 375 }, + { "IS-29D2 Lark", 360, 0, 100, -0.82, 135.67, -1.55, 184.12, -3.3, 10.4, 0.0, 96, 240 }, + { "Janus (18m)", 498, 240, 100, -0.71, 120, -0.92, 150, -1.46, 16.6, 0.0, 102, 405 }, + { "Janus C FG", 603, 170, 115.5, -0.76, 171.79, -1.98, 209.96, -4.0, 17.4, 47.222, 106, 405 }, // obviously wrong + { "Janus C RG", 519, 240, 90, -0.60, 120, -0.88, 160, -1.64, 17.3, 50, 108, 405 }, // from factory polar + { "JS-1B (18m)", 405, 180, 108, -0.57, 152, -1.06, 180, -1.65, 11.25, 56.3, 121, 310 }, // from factory polar + { "JS-1C (21m)", 441, 180, 108, -0.52, 156, -1.1, 180, -1.62, 12.25, 56.3, 126, 330 }, // from factory polar + { "JS-3 (15m)", 350, 158, 100, -0.6, 130, -0.8, 160, -1.2, 8.75, 57.5, 116, 270 }, // from factory polar + { "JS-3 (18m)", 398, 158, 100, -0.55, 130, -0.72, 160, -1.12, 9.95, 57.5, 122, 282 }, // from factory polar + { "Ka 2b", 418, 0, 87, -0.9, 120, -1.5, 150, -2.6, 17.5, 0.0, 78, 278 }, + { "Ka 4 Rhoenlerche", 360, 0, 65, -0.95, 120, -2.5, 140, -3.5, 16.34, 0.0, 54, 220 }, + { "Ka 6CR", 310, 0, 64.83 , -0.67 , 130.0, -2.26 , 170.0, -4.69 , 12.5 , 0.0 , 82, 185 }, + { "Ka 6E", 310, 0, 87.35, -0.81, 141.92, -2.03, 174.68, -3.5, 12.4, 0.0, 85, 185 }, // from idaflieg measured 1970 + { "Ka 7", 445, 0, 87, -0.92, 120, -1.55, 150, -2.7, 17.5, 0.0, 78, 285 }, + { "Ka 8", 290, 0, 74.1, -0.76, 101.9, -1.27, 166.7, -4.64, 14.15, 0.0, 76, 190 }, + { "L 33 Solo", 330, 0, 87.2, -0.8, 135.64, -1.73, 174.4, -3.4, 11.0, 0.0, 86, 210 }, + { "LAK-12", 430, 190, 75, -0.48, 125, -0.88, 175, -1.97, 14.63, 48.611, 114, 360 }, // from marius@sargevicius.com + { "LAK-17 (15m)", 285, 215, 100, -0.60, 120, -0.72, 150, -1.09, 9.06, 0.0, 113, 220 }, + { "LAK-17 (18m)", 295, 205, 100, -0.56, 120, -0.74, 150, -1.16, 9.8, 0.0, 119, 225 }, + { "LAK17a (15m)", 285, 180, 95, -0.574, 148, -1.310, 200, -2.885, 9.06, 0.0, 113, 220 }, + { "LAK17a (18m)", 298, 180, 115, -0.680, 158, -1.379, 200, -2.975, 9.80, 0.0, 119, 225 }, + { "LAK-19 (15m)", 285, 195, 100, -0.64, 120, -0.85, 150, -1.41, 9.06, 0.0, 108, 220 }, + { "LAK-19 (18m)", 295, 185, 100, -0.60, 120, -0.82, 150, -1.34, 9.8, 0.0, 114, 226 }, + { "LS-10s (15m)", 370, 170, 100, -0.64, 120, -0.80, 150, -1.26, 10.27, 0.0, 113, 288 }, + { "LS-10s (18m)", 380, 220, 100, -0.58, 120, -0.75, 150, -1.21, 11.45, 0.0, 119, 295 }, + { "LS-1c", 350, 91, 115.87, -1.02, 154.49, -1.84, 193.12, -3.3, 9.74, 0.0, 98, 200 }, + { "LS-1f", 345, 80, 100, -0.75, 120, -0.98, 150, -1.6, 9.74, 0.0, 100, 230 }, // from idaflieg + { "LS-3 (17m)", 325, 0, 100, -0.61, 120, -0.84, 150, -1.53, 11.22, 0.0, 109, 255 }, + { "LS-3", 383, 121, 93.0, -0.64, 127.0, -0.93, 148.2, -1.28, 10.5, 0.0, 107, 270 }, + { "LS-4", 361, 121, 100, -0.69, 120, -0.87, 150, -1.44, 10.5, 0.0, 104, 235 }, // Derived from Idaflieg measurements, D-7742, measured at 13-15/8/1991 in Aalen. Empty mass from comments by the owner here: https://www.youtube.com/watch?v=wSX3k-Lp7HA. - { _T("LS-5"), 461, 120, 75, -0.45, 135, -1.0, 172.5, -1.9, 13.9, 0.0, 118, 361 }, - { _T("LS-6 (15m)"), 327, 160, 90, -0.6, 100, -0.658, 183, -1.965, 10.53, 0.0, 111, 265 }, - { _T("LS-6 (18m)"), 330, 140, 90, -0.51, 100, -0.57, 183, -2.00, 11.4, 0.0, 117, 272 }, - { _T("LS-7wl"), 350, 150, 103.77, -0.73, 155.65, -1.47, 180.00, -2.66, 9.80, 0.0, 107, 235 }, - { _T("LS-8 (15m)"), 325, 185, 70, -0.51, 115, -0.85, 173, -2.00, 10.5, 0.0, 108, 240 }, - { _T("LS-8 (18m)"), 325, 185, 80, -0.51, 94, -0.56, 173, -2.00, 11.4, 0.0, 114, 250 }, - { _T("Mini Nimbus"), 345, 155, 100, -0.69, 120, -0.92, 150, -1.45, 9.86, 55.555, 107, 235 }, - { _T("Nimbus 2"), 493, 159, 119.83, -0.75, 179.75, -2.14, 219.69, -3.8, 14.41, 44.444, 114, 350 }, - { _T("Nimbus 3"), 527, 159, 116.18, -0.67, 174.28, -1.81, 232.37, -3.8, 16.70, 52.777, 122, 396 }, - { _T("Nimbus 3DM"), 820, 168, 114.97, -0.57, 157.42, -0.98, 222.24, -2.3, 16.70, 52.777, 121, 595 }, - { _T("Nimbus 3D"), 712, 168, 93.64, -0.46, 175.42, -1.48, 218.69, -2.5, 16.70, 52.777, 121, 485 }, - { _T("Nimbus 3T"), 577, 310, 141.7, -0.99, 182.35, -1.89, 243.13, -4.0, 16.70, 52.777, 121, 422 }, - { _T("Nimbus 4"), 597, 303, 85.1, -0.41, 127.98, -0.75, 162.74, -1.4, 17.8, 50.0, 124, 470 }, - { _T("Nimbus 4DM"), 820, 168, 100.01, -0.48, 150.01, -0.87, 190.76, -1.6, 17.8, 50.0, 123, 595 }, - { _T("Nimbus 4D"), 743, 303, 107.5, -0.5, 142.74, -0.83, 181.51, -1.6, 17.8, 50.0, 123, 515 }, - { _T("Para Competition"), 100, 0, 39.0, -1.0, 45.0, -1.1, 64.0, -2.30, 0, 0.0, 0 }, - { _T("Para EN A/DHV1"), 100, 0, 29.0, -1.1, 34.0, -1.3, 44.0, -2.30, 0, 0.0, 0 }, - { _T("Para EN B/DHV12"), 100, 0, 29.5, -1.1, 37.0, -1.2, 50.0, -2.30, 0, 0.0, 0 }, - { _T("Para EN C/DHV2"), 110, 4.19, 33.0, -1.0, 39.0, -1.2, 56.0, -2.30, 0, 0.0, 0 }, - { _T("Para EN D/DHV23"), 100, 0, 33.0, -1.1, 41.0, -1.2, 58.0, -2.30, 0, 0.0, 0 }, - { _T("Pegase 101A"), 344, 120, 85.0, -0.62, 105, -0.75, 175, -2.54, 10.5, 0.0, 102, 252 }, - { _T("Phoebus C"), 310, 150, 100, -0.70, 120, -0.98, 150, -1.58, 14.06, 0.0, 100, 225 }, - { _T("PIK-20B"), 354, 144, 102.5, -0.69, 157.76, -1.59, 216.91, -3.6, 10.0, 0.0, 102, 240 }, - { _T("PIK-20D"), 348, 144, 100, -0.69, 156.54, -1.78, 215.24, -4.2, 10.0, 0.0, 104, 227 }, - { _T("PIK-20E"), 437, 80, 109.61, -0.83, 166.68, -2, 241.15, -4.7, 10.0, 0.0, 104, 324 }, - { _T("PIK-30M"), 460, 0, 123.6, -0.78, 152.04, -1.12, 200.22, -2.2, 10.63, 0.0, 0, 347 }, + { "LS-5", 461, 120, 75, -0.45, 135, -1.0, 172.5, -1.9, 13.9, 0.0, 118, 361 }, + { "LS-6 (15m)", 327, 160, 90, -0.6, 100, -0.658, 183, -1.965, 10.53, 0.0, 111, 265 }, + { "LS-6 (18m)", 330, 140, 90, -0.51, 100, -0.57, 183, -2.00, 11.4, 0.0, 117, 272 }, + { "LS-7wl", 350, 150, 103.77, -0.73, 155.65, -1.47, 180.00, -2.66, 9.80, 0.0, 107, 235 }, + { "LS-8 (15m)", 325, 185, 70, -0.51, 115, -0.85, 173, -2.00, 10.5, 0.0, 108, 240 }, + { "LS-8 (18m)", 325, 185, 80, -0.51, 94, -0.56, 173, -2.00, 11.4, 0.0, 114, 250 }, + { "Mini Nimbus", 345, 155, 100, -0.69, 120, -0.92, 150, -1.45, 9.86, 55.555, 107, 235 }, + { "Nimbus 2", 493, 159, 119.83, -0.75, 179.75, -2.14, 219.69, -3.8, 14.41, 44.444, 114, 350 }, + { "Nimbus 3", 527, 159, 116.18, -0.67, 174.28, -1.81, 232.37, -3.8, 16.70, 52.777, 122, 396 }, + { "Nimbus 3DM", 820, 168, 114.97, -0.57, 157.42, -0.98, 222.24, -2.3, 16.70, 52.777, 121, 595 }, + { "Nimbus 3D", 712, 168, 93.64, -0.46, 175.42, -1.48, 218.69, -2.5, 16.70, 52.777, 121, 485 }, + { "Nimbus 3T", 577, 310, 141.7, -0.99, 182.35, -1.89, 243.13, -4.0, 16.70, 52.777, 121, 422 }, + { "Nimbus 4", 597, 303, 85.1, -0.41, 127.98, -0.75, 162.74, -1.4, 17.8, 50.0, 124, 470 }, + { "Nimbus 4DM", 820, 168, 100.01, -0.48, 150.01, -0.87, 190.76, -1.6, 17.8, 50.0, 123, 595 }, + { "Nimbus 4D", 743, 303, 107.5, -0.5, 142.74, -0.83, 181.51, -1.6, 17.8, 50.0, 123, 515 }, + { "Para Competition", 100, 0, 39.0, -1.0, 45.0, -1.1, 64.0, -2.30, 0, 0.0, 0 }, + { "Para EN A/DHV1", 100, 0, 29.0, -1.1, 34.0, -1.3, 44.0, -2.30, 0, 0.0, 0 }, + { "Para EN B/DHV12", 100, 0, 29.5, -1.1, 37.0, -1.2, 50.0, -2.30, 0, 0.0, 0 }, + { "Para EN C/DHV2", 110, 4.19, 33.0, -1.0, 39.0, -1.2, 56.0, -2.30, 0, 0.0, 0 }, + { "Para EN D/DHV23", 100, 0, 33.0, -1.1, 41.0, -1.2, 58.0, -2.30, 0, 0.0, 0 }, + { "Pegase 101A", 344, 120, 85.0, -0.62, 105, -0.75, 175, -2.54, 10.5, 0.0, 102, 252 }, + { "Phoebus C", 310, 150, 100, -0.70, 120, -0.98, 150, -1.58, 14.06, 0.0, 100, 225 }, + { "PIK-20B", 354, 144, 102.5, -0.69, 157.76, -1.59, 216.91, -3.6, 10.0, 0.0, 102, 240 }, + { "PIK-20D", 348, 144, 100, -0.69, 156.54, -1.78, 215.24, -4.2, 10.0, 0.0, 104, 227 }, + { "PIK-20E", 437, 80, 109.61, -0.83, 166.68, -2, 241.15, -4.7, 10.0, 0.0, 104, 324 }, + { "PIK-30M", 460, 0, 123.6, -0.78, 152.04, -1.12, 200.22, -2.2, 10.63, 0.0, 0, 347 }, // Derived from Pilatus B4 PH-448, fixed gear serial production, measured at Idaflieg-vergleichsfliegen at Aalen in the year 1973. - { _T("Pilatus B4 FG"), 306, 0, 90.0, -0.847, 126.0, -1.644, 198.0, -5.098, 14.0, 0.0, 86, 230 }, - { _T("PW-5 Smyk"), 300, 0, 99.5, -0.95, 158.48, -2.85, 198.1, -5.1, 10.16, 0.0, 85, 190 }, - { _T("PW-6"), 546, 0, 104, -0.847, 152, -1.994, 200, -4.648, 15.3, 0, 86, 360 }, - { _T("R-26S Gobe"), 420, 0, 60.0, -1.02, 80.0, -0.96, 120.0, -2.11, 18.00, 30.5, 0, 230 }, - { _T("Russia AC-4"), 250, 0, 99.3, -0.92, 140.01, -1.8, 170.01, -2.9, 7.70, 0.0, 84, 140 }, - { _T("SF-27B"), 300, 0, 100, -0.81, 120, -1.27, 150, -2.50, 13, 0.0, 88, 220 }, - { _T("SGS 1-26E"), 315, 0, 82.3, -1.04, 117.73, -1.88, 156.86, -3.8, 14.87, 0.0, 63, 202 }, - { _T("SGS 1-34"), 354, 0, 89.82, -0.8, 143.71, -2.1, 179.64, -3.8, 14.03, 0.0, 85, 259 }, - { _T("SGS 1-35A"), 381, 179, 98.68, -0.74, 151.82, -1.8, 202.87, -3.9, 9.64, 0.0, 0, 180 }, - { _T("SGS 1-36 Sprite"), 322, 0, 75.98, -0.68, 132.96, -2, 170.95, -4.1, 13.10, 0.0, 76, 215 }, - { _T("SGS 2-33"), 470, 0, 82.32, -0.96, 130.0, -1.74, 170.0, -3.44, 20.35, 33, 54, 272 }, + { "Pilatus B4 FG", 306, 0, 90.0, -0.847, 126.0, -1.644, 198.0, -5.098, 14.0, 0.0, 86, 230 }, + { "PW-5 Smyk", 300, 0, 99.5, -0.95, 158.48, -2.85, 198.1, -5.1, 10.16, 0.0, 85, 190 }, + { "PW-6", 546, 0, 104, -0.847, 152, -1.994, 200, -4.648, 15.3, 0, 86, 360 }, + { "R-26S Gobe", 420, 0, 60.0, -1.02, 80.0, -0.96, 120.0, -2.11, 18.00, 30.5, 0, 230 }, + { "Russia AC-4", 250, 0, 99.3, -0.92, 140.01, -1.8, 170.01, -2.9, 7.70, 0.0, 84, 140 }, + { "SF-27B", 300, 0, 100, -0.81, 120, -1.27, 150, -2.50, 13, 0.0, 88, 220 }, + { "SGS 1-26E", 315, 0, 82.3, -1.04, 117.73, -1.88, 156.86, -3.8, 14.87, 0.0, 63, 202 }, + { "SGS 1-34", 354, 0, 89.82, -0.8, 143.71, -2.1, 179.64, -3.8, 14.03, 0.0, 85, 259 }, + { "SGS 1-35A", 381, 179, 98.68, -0.74, 151.82, -1.8, 202.87, -3.9, 9.64, 0.0, 0, 180 }, + { "SGS 1-36 Sprite", 322, 0, 75.98, -0.68, 132.96, -2, 170.95, -4.1, 13.10, 0.0, 76, 215 }, + { "SGS 2-33", 470, 0, 82.32, -0.96, 130.0, -1.74, 170.0, -3.44, 20.35, 33, 54, 272 }, // From Silene E78/E78B manual, available on Issoire Aviation website - { _T("Silene E78"), 450, 0, 75, -0.548, 125, -1.267, 160, -2.439, 18, 47.222, 0, 365 }, - { _T("Skylark 4"), 395, 0, 78, -0.637, 139, -2, 200, -5.092, 16.1, 0, 84, 258 }, - { _T("Std Austria S"), 297, 0, 70.0, -0.70, 118.0, -1.0, 145.0, -1.5, 13.5 , 38.9, 90, 205}, // From Schempp-Hirth sales handout, potentially too good - { _T("Std Cirrus"), 337, 80, 93.23, -0.74, 149.17, -1.71, 205.1, -4.2, 10.04, 0.0, 99, 215 }, - { _T("Stemme S-10"), 850, 0, 133.47, -0.83, 167.75, -1.41, 205.03, -2.3, 18.70, 0.0, 110, 645 }, - { _T("SZD-30 Pirat"), 370, 0, 80, -0.72, 100, -0.98, 150, -2.46, 13.8, 0.0, 86, 260 }, - { _T("SZD-36 Cobra"), 350, 30, 70.8, -0.60, 94.5, -0.69, 148.1, -1.83, 11.6, 0.0, 98, 275 }, - { _T("SZD-42 Jantar II"), 482, 191, 109.5, -0.66, 157.14, -1.47, 196.42, -2.7, 14.27, 0.0, 113, 362 }, - { _T("SZD-48-2 Jantar Std 2"), 375, 150, 100, -0.73, 120, -0.95, 150, -1.60, 10.66, 0.0, 100, 274 }, - { _T("SZD-48-3 Jantar Std 3"), 326, 150, 95, -0.66, 180, -2.24, 220, -3.85, 10.66, 0.0, 100, 274 }, - { _T("SZD-50 Puchacz"), 435, 135, 100, -1.00, 120, -1.42, 150, -2.35, 18.16, 0.0, 84, 370 }, - { _T("SZD-51-1 Junior"), 333, 0, 70, -0.58, 130, -1.6, 180, -3.6, 12.51, 0.0, 90, 242 }, + { "Silene E78", 450, 0, 75, -0.548, 125, -1.267, 160, -2.439, 18, 47.222, 0, 365 }, + { "Skylark 4", 395, 0, 78, -0.637, 139, -2, 200, -5.092, 16.1, 0, 84, 258 }, + { "Std Austria S", 297, 0, 70.0, -0.70, 118.0, -1.0, 145.0, -1.5, 13.5 , 38.9, 90, 205}, // From Schempp-Hirth sales handout, potentially too good + { "Std Cirrus", 337, 80, 93.23, -0.74, 149.17, -1.71, 205.1, -4.2, 10.04, 0.0, 99, 215 }, + { "Stemme S-10", 850, 0, 133.47, -0.83, 167.75, -1.41, 205.03, -2.3, 18.70, 0.0, 110, 645 }, + { "SZD-30 Pirat", 370, 0, 80, -0.72, 100, -0.98, 150, -2.46, 13.8, 0.0, 86, 260 }, + { "SZD-36 Cobra", 350, 30, 70.8, -0.60, 94.5, -0.69, 148.1, -1.83, 11.6, 0.0, 98, 275 }, + { "SZD-42 Jantar II", 482, 191, 109.5, -0.66, 157.14, -1.47, 196.42, -2.7, 14.27, 0.0, 113, 362 }, + { "SZD-48-2 Jantar Std 2", 375, 150, 100, -0.73, 120, -0.95, 150, -1.60, 10.66, 0.0, 100, 274 }, + { "SZD-48-3 Jantar Std 3", 326, 150, 95, -0.66, 180, -2.24, 220, -3.85, 10.66, 0.0, 100, 274 }, + { "SZD-50 Puchacz", 435, 135, 100, -1.00, 120, -1.42, 150, -2.35, 18.16, 0.0, 84, 370 }, + { "SZD-51-1 Junior", 333, 0, 70, -0.58, 130, -1.6, 180, -3.6, 12.51, 0.0, 90, 242 }, // From Perkoz handbook - { _T("SZD-54-2 Perkoz (FT 17m)") /* flat tip */, 442, 0, 98, -0.92, 174, -4.35, 250, -13.22, 16.36, 47.05, 98, 375 }, - { _T("SZD-54-2 Perkoz (WL 17m)") /* winglet */, 442, 0, 99, -0.86, 175, -4.22, 250, -13.01, 16.36, 47.05, 98, 375 }, - { _T("SZD-54-2 Perkoz (WL 20m)") /* long winglet */, 442, 0, 91, -0.69, 170, -3.98, 250, -12.66, 17.30, 47.05, 102, 380 }, + { "SZD-54-2 Perkoz (FT 17m)" /* flat tip */, 442, 0, 98, -0.92, 174, -4.35, 250, -13.22, 16.36, 47.05, 98, 375 }, + { "SZD-54-2 Perkoz (WL 17m)" /* winglet */, 442, 0, 99, -0.86, 175, -4.22, 250, -13.01, 16.36, 47.05, 98, 375 }, + { "SZD-54-2 Perkoz (WL 20m)" /* long winglet */, 442, 0, 91, -0.69, 170, -3.98, 250, -12.66, 17.30, 47.05, 102, 380 }, - { _T("SZD-55-1 Promyk"), 350, 200, 100.0, -0.66, 120, -0.86, 150, -1.4, 9.60, 0.0, 106, 215 }, - { _T("SZD-9 bis 1E Bocian"), 540, 0, 70, -0.83, 90, -1.00, 140, -2.53, 20, 0.0, 76, 330 }, - { _T("Taurus"), 472, 0, 100, -0.71, 120, -0.83, 150, -1.35, 12.26, 0.0, 99, 306 }, - { _T("Ventus 2c (18m)"), 385, 180, 80.0, -0.5, 120.0, -0.73, 180.0, -2.0, 11.03, 55.555, 120, 260 }, - { _T("Ventus 2cT (18m)"), 410, 110, 100.0, -0.62, 150.0, -1.2, 200.0, -2.3, 11.03, 55.555, 120, 305 }, - { _T("Ventus 2cx (18m)"), 385, 215, 80.0, -0.5, 120.0, -0.73, 180.0, -2.0, 11.03, 55.555, 120, 265 }, - { _T("Ventus 2cxT (18m)"), 470, 130, 100.0, -0.56, 150.0, -1.13, 200.0, -2.28, 11.03, 55.555, 120, 310 }, - { _T("Ventus a/b (16.6m)"), 358, 151, 100.17, -0.64, 159.69, -1.47, 239.54, -4.3, 9.96, 55.555, 113, 250 }, - { _T("Ventus b (15m)"), 341, 151, 97.69, -0.68, 156.3, -1.46, 234.45, -3.9, 9.51, 55.555, 110, 240 }, - { _T("Ventus cM (17.6)"), 430, 0, 100.17, -0.6, 159.7, -1.32, 210.54, -2.5, 10.14, 55.555, 115, 360 }, + { "SZD-55-1 Promyk", 350, 200, 100.0, -0.66, 120, -0.86, 150, -1.4, 9.60, 0.0, 106, 215 }, + { "SZD-9 bis 1E Bocian", 540, 0, 70, -0.83, 90, -1.00, 140, -2.53, 20, 0.0, 76, 330 }, + { "Taurus", 472, 0, 100, -0.71, 120, -0.83, 150, -1.35, 12.26, 0.0, 99, 306 }, + { "Ventus 2c (18m)", 385, 180, 80.0, -0.5, 120.0, -0.73, 180.0, -2.0, 11.03, 55.555, 120, 260 }, + { "Ventus 2cT (18m)", 410, 110, 100.0, -0.62, 150.0, -1.2, 200.0, -2.3, 11.03, 55.555, 120, 305 }, + { "Ventus 2cx (18m)", 385, 215, 80.0, -0.5, 120.0, -0.73, 180.0, -2.0, 11.03, 55.555, 120, 265 }, + { "Ventus 2cxT (18m)", 470, 130, 100.0, -0.56, 150.0, -1.13, 200.0, -2.28, 11.03, 55.555, 120, 310 }, + { "Ventus a/b (16.6m)", 358, 151, 100.17, -0.64, 159.69, -1.47, 239.54, -4.3, 9.96, 55.555, 113, 250 }, + { "Ventus b (15m)", 341, 151, 97.69, -0.68, 156.3, -1.46, 234.45, -3.9, 9.51, 55.555, 110, 240 }, + { "Ventus cM (17.6)", 430, 0, 100.17, -0.6, 159.7, -1.32, 210.54, -2.5, 10.14, 55.555, 115, 360 }, // from LK8000 - { _T("VSO-10 Gradient"), 347, 0, 90, -0.78, 130, -1.41, 160, -2.44, 12.0, 44.444, 96, 250 }, - { _T("VT-116 Orlik II"), 335, 0, 80, -0.7, 100, -1.05, 120, -1.65, 12.8, 33.333, 86, 215 }, + { "VSO-10 Gradient", 347, 0, 90, -0.78, 130, -1.41, 160, -2.44, 12.0, 44.444, 96, 250 }, + { "VT-116 Orlik II", 335, 0, 80, -0.7, 100, -1.05, 120, -1.65, 12.8, 33.333, 86, 215 }, // from factory polar. // flight manual http://www.issoire-aviation.fr/doc_avia_gen/MdV_WA26P_R2.pdf // Contest handicap reference: http://docplayer.fr/79733029-Handicaps-planeurs-ffvv.html - { _T("WA 26 P Squale"), 330, 0, 80, -0.61, 152, -2, 174, -3.0, 12.6, 0.0, 86, 228 }, + { "WA 26 P Squale", 330, 0, 80, -0.61, 152, -2, 174, -3.0, 12.6, 0.0, 86, 228 }, - { _T("Zuni II"), 358, 182, 110, -0.88, 167, -2.21, 203.72, -3.6, 10.13, 0.0, 0, 238 }, + { "Zuni II", 358, 182, 110, -0.88, 167, -2.21, 203.72, -3.6, 10.13, 0.0, 0, 238 }, }; const Item & diff --git a/src/Polar/PolarStore.hpp b/src/Polar/PolarStore.hpp index 254daa44382..ea9e5fc4ec7 100644 --- a/src/Polar/PolarStore.hpp +++ b/src/Polar/PolarStore.hpp @@ -14,7 +14,7 @@ namespace PolarStore { struct Item { /**< Name of the glider type */ - const TCHAR *name; + const char *name; // Using doubles here to simplify the code in PolarStore.cpp diff --git a/src/PopupMessage.cpp b/src/PopupMessage.cpp index 65f5f9c4c7c..ef334c9412b 100644 --- a/src/PopupMessage.cpp +++ b/src/PopupMessage.cpp @@ -19,7 +19,7 @@ using std::max; void PopupMessage::Message::Set(Type _type, std::chrono::steady_clock::duration _tshow, - const TCHAR *_text, + const char *_text, std::chrono::steady_clock::time_point now) noexcept { type = _type; @@ -66,7 +66,7 @@ PopupMessage::Message::AppendTo(StaticString<2000> &buffer, } if (!buffer.empty()) - buffer.append(_T("\r\n")); + buffer.append("\r\n"); buffer.append(text); return true; } @@ -240,7 +240,7 @@ PopupMessage::GetEmptySlot() noexcept void PopupMessage::AddMessage(std::chrono::steady_clock::duration tshow, Type type, - const TCHAR *Text) noexcept + const char *Text) noexcept { const auto now = std::chrono::steady_clock::now(); @@ -306,7 +306,7 @@ PopupMessage::Acknowledge(Type type) noexcept // TODO code: (need to discuss) Consider moving almost all this functionality into AddMessage ? void -PopupMessage::AddMessage(const TCHAR* text, const TCHAR *data) noexcept +PopupMessage::AddMessage(const char* text, const char *data) noexcept { const std::lock_guard lock{mutex}; @@ -317,11 +317,11 @@ PopupMessage::AddMessage(const TCHAR* text, const TCHAR *data) noexcept // TODO code: consider what is a sensible size? if (msg.visible) { - TCHAR msgcache[1024]; - _tcscpy(msgcache, text); + char msgcache[1024]; + strcpy(msgcache, text); if (data != nullptr) { - _tcscat(msgcache, _T(" ")); - _tcscat(msgcache, data); + strcat(msgcache, " "); + strcat(msgcache, data); } AddMessage(msg.delay, MSG_USERINTERFACE, msgcache); diff --git a/src/PopupMessage.hpp b/src/PopupMessage.hpp index 9d8dd0305de..0a84945956e 100644 --- a/src/PopupMessage.hpp +++ b/src/PopupMessage.hpp @@ -71,7 +71,7 @@ class PopupMessage : public PaintWindow } void Set(Type type, std::chrono::steady_clock::duration tshow, - const TCHAR *text, + const char *text, std::chrono::steady_clock::time_point now) noexcept; /** @@ -117,10 +117,10 @@ class PopupMessage : public PaintWindow protected: /** Caller must hold the lock. */ void AddMessage(std::chrono::steady_clock::duration tshow, Type type, - const TCHAR *Text) noexcept; + const char *Text) noexcept; public: - void AddMessage(const TCHAR* text, const TCHAR *data=nullptr) noexcept; + void AddMessage(const char* text, const char *data=nullptr) noexcept; /** * Repeats last non-visible message of specified type diff --git a/src/Profile/CMakeLists.txt b/src/Profile/CMakeLists.txt new file mode 100644 index 00000000000..c79a42de2ee --- /dev/null +++ b/src/Profile/CMakeLists.txt @@ -0,0 +1,51 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories + + +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/Profile/CMakeSource.cmake b/src/Profile/CMakeSource.cmake new file mode 100644 index 00000000000..c3990f78fe6 --- /dev/null +++ b/src/Profile/CMakeSource.cmake @@ -0,0 +1,35 @@ +set(_SOURCES + Profile/AirspaceConfig.cpp + Profile/ComputerProfile.cpp + Profile/ContestProfile.cpp + Profile/Current.cpp + Profile/DeviceConfig.cpp + Profile/File.cpp + Profile/FlarmProfile.cpp + Profile/GeoValue.cpp + Profile/InfoBoxConfig.cpp + Profile/Map.cpp + Profile/MapProfile.cpp + Profile/NumericValue.cpp + Profile/PageProfile.cpp + Profile/PathValue.cpp + Profile/Profile.cpp + Profile/ProfileMap.cpp + Profile/RouteProfile.cpp + Profile/Screen.cpp + Profile/Settings.cpp + Profile/StringValue.cpp + Profile/SystemProfile.cpp + Profile/TaskProfile.cpp + Profile/TerrainConfig.cpp + Profile/TrackingProfile.cpp + Profile/UIProfile.cpp + Profile/UnitsConfig.cpp + Profile/WeatherProfile.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake +) + + diff --git a/src/Profile/DeviceConfig.cpp b/src/Profile/DeviceConfig.cpp index 2724dd2d169..680945f5d77 100644 --- a/src/Profile/DeviceConfig.cpp +++ b/src/Profile/DeviceConfig.cpp @@ -14,6 +14,8 @@ #include +using std::string_view_literals::operator""sv; + static const char *const port_type_strings[] = { "disabled", "serial", @@ -33,7 +35,8 @@ static const char *const port_type_strings[] = { "ble_sensor", "ble_hm10", "glider_link", - "android_usb_serial", +// "android_usb_serial", + "usb_serial", NULL }; @@ -54,6 +57,8 @@ MakeDeviceSettingName(char *buffer, const char *prefix, unsigned n, static bool StringToPortType(const char *value, DeviceConfig::PortType &type) { + if (value == "android_usb_serial"sv) + value = "usb_serial"; // avoid the old name for (auto i = port_type_strings; *i != NULL; ++i) { if (StringIsEqual(value, *i)) { type = (DeviceConfig::PortType)std::distance(port_type_strings, i); @@ -80,29 +85,30 @@ LoadPath(const ProfileMap &map, DeviceConfig &config, unsigned n) { char buffer[64]; MakeDeviceSettingName(buffer, "Port", n, "Path"); +#ifdef _WIN32 + bool retvalue = map.Get(buffer, config.path); + // the usual windows port names has no colon at the end + if (retvalue && !config.path.empty()) { + if ((config.path.back() == char(':')) && + /* In Windows the value itself should be only have the short */ + config.path.StartsWith("COM")) { + /* old-style raw names has a trailing colon (for backwards + compatibility with older XCSoar versions) */ + config.path.Truncate(config.path.length() - 1); + // write back this (short) value to the profile: + ((ProfileMap)map).Set(buffer, config.path); + } else if (config.path.StartsWith("\\\\.\\COM")) { + /* since 7.30 the raw names in the XCSoar config has the UNC style + (compatibility with this XCSoar versions config) */ + config.path = config.path + 4; + // write back this (short) value to the profile: + ((ProfileMap)map).Set(buffer, config.path); // write back to the profile + } + } + return retvalue; +#else return map.Get(buffer, config.path); -} - -static bool -LoadPortIndex(const ProfileMap &map, DeviceConfig &config, unsigned n) -{ - char buffer[64]; - MakeDeviceSettingName(buffer, "Port", n, "Index"); - - unsigned index; - if (!map.Get(buffer, index)) - return false; - - /* adjust the number, compatibility quirk for XCSoar 5 */ - if (index < 10) - ++index; - else if (index == 10) - index = 0; - - TCHAR path[64]; - _stprintf(path, _T("COM%u:"), index); - config.path = path; - return true; +#endif } void @@ -116,6 +122,9 @@ Profile::GetDeviceConfig(const ProfileMap &map, unsigned n, MakeDeviceSettingName(buffer, "Port", n, "BluetoothMAC"); map.Get(buffer, config.bluetooth_mac); + MakeDeviceSettingName(buffer, "Port", n, "PortName"); + map.Get(buffer, config.port_name); + MakeDeviceSettingName(buffer, "Port", n, "IOIOUartID"); map.Get(buffer, config.ioio_uart_id); @@ -129,32 +138,20 @@ Profile::GetDeviceConfig(const ProfileMap &map, unsigned n, config.path.clear(); if ((!have_port_type || - config.port_type == DeviceConfig::PortType::ANDROID_USB_SERIAL || + config.port_type == DeviceConfig::PortType::USB_SERIAL || +#ifdef _WIN32 + config.port_type == DeviceConfig::PortType::BLE_HM10 || + config.port_type == DeviceConfig::PortType::BLE_SENSOR || +#endif + config.port_type == DeviceConfig::PortType::RFCOMM || config.port_type == DeviceConfig::PortType::SERIAL) && - !LoadPath(map, config, n) && LoadPortIndex(map, config, n)) + !LoadPath(map, config, n)) config.port_type = DeviceConfig::PortType::SERIAL; + // config.port_type = DeviceConfig::PortType::BLE_HM10; MakeDeviceSettingName(buffer, "Port", n, "BaudRate"); if (!map.Get(buffer, config.baud_rate)) { - /* XCSoar before 6.2 used to store a "speed index", not the real - baud rate - try to import the old settings */ - - static constexpr unsigned speed_index_table[] = { - 1200, - 2400, - 4800, - 9600, - 19200, - 38400, - 57600, - 115200 - }; - - MakeDeviceSettingName(buffer, "Speed", n, "Index"); - unsigned speed_index; - if (map.Get(buffer, speed_index) && - speed_index < ARRAY_SIZE(speed_index_table)) - config.baud_rate = speed_index_table[speed_index]; + config.baud_rate = 0; } MakeDeviceSettingName(buffer, "Port", n, "BulkBaudRate"); @@ -233,6 +230,9 @@ Profile::SetDeviceConfig(ProfileMap &map, WritePortType(map, n, config.port_type); + MakeDeviceSettingName(buffer, "Port", n, "PortName"); + map.Set(buffer, config.port_name); + MakeDeviceSettingName(buffer, "Port", n, "BluetoothMAC"); map.Set(buffer, config.bluetooth_mac); diff --git a/src/Profile/GeoValue.cpp b/src/Profile/GeoValue.cpp index 4143c22821d..db38b1802f8 100644 --- a/src/Profile/GeoValue.cpp +++ b/src/Profile/GeoValue.cpp @@ -15,13 +15,13 @@ ProfileMap::GetGeoPoint(std::string_view key, GeoPoint &value) const noexcept char *endptr; double longitude = ParseDouble(p, &endptr); - if (endptr == p || *endptr != _T(' ') || + if (endptr == p || *endptr != ' ' || longitude < -180.0 || longitude > 180.0) return false; p = endptr + 1; double latitude = ParseDouble(p, &endptr); - if (endptr == p || *endptr != _T('\0') || + if (endptr == p || *endptr != '\0' || latitude < -90.0 || latitude > 90.0) return false; @@ -33,7 +33,7 @@ ProfileMap::GetGeoPoint(std::string_view key, GeoPoint &value) const noexcept void ProfileMap::SetGeoPoint(std::string_view key, const GeoPoint &value) noexcept { - NarrowString<128> buffer; + StaticString<128> buffer; buffer.UnsafeFormat("%f %f", (double)value.longitude.Degrees(), (double)value.latitude.Degrees()); diff --git a/src/Profile/InfoBoxConfig.cpp b/src/Profile/InfoBoxConfig.cpp index e442d318db9..26ed2b4bd7a 100644 --- a/src/Profile/InfoBoxConfig.cpp +++ b/src/Profile/InfoBoxConfig.cpp @@ -35,7 +35,7 @@ GetIBType(const ProfileMap &map, std::string_view key, unsigned _val = val; bool ret = map.Get(key, _val); - if (_val >= e_NUM_TYPES) + if (!TypeIsValid((InfoBoxFactory::Type)_val)) return false; val = (InfoBoxFactory::Type)_val; @@ -96,6 +96,10 @@ Profile::Load(const ProfileMap &map, InfoBoxSettings &settings) case InfoBoxSettings::Geometry::TOP_LEFT_4: case InfoBoxSettings::Geometry::BOTTOM_RIGHT_4: case InfoBoxSettings::Geometry::SPLIT_3X6: + case InfoBoxSettings::Geometry::TOP_8_VARIO_BOTTOM_5: + case InfoBoxSettings::Geometry::TOP_8_VARIO_BOTTOM_10: + case InfoBoxSettings::Geometry::TOP_12_VARIO: + case InfoBoxSettings::Geometry::TOP_16_VARIO: break; case InfoBoxSettings::Geometry::OBSOLETE_TOP_LEFT_4: @@ -123,7 +127,7 @@ Profile::Load(const ProfileMap &map, InfoBoxSettings &settings) sprintf(profileKey, "InfoBoxPanel%uName", i); map.Get(profileKey, panel.name); if (panel.name.empty()) - _stprintf(panel.name.buffer(), _T("AUX-%u"), i-2); + _stprintf(panel.name.buffer(), "AUX-%u", i-2); } for (unsigned j = 0; j < panel.MAX_CONTENTS; ++j) { diff --git a/src/Profile/Map.hpp b/src/Profile/Map.hpp index e92a7a9d7e8..b458bcf1e4d 100644 --- a/src/Profile/Map.hpp +++ b/src/Profile/Map.hpp @@ -87,7 +87,7 @@ class ProfileMap { void Set(std::string_view key, const char *value) noexcept; - // TCHAR string values + // char string values /** * Reads a value from the profile map @@ -95,18 +95,14 @@ class ProfileMap { * @param key name of the value that should be read * @param value Pointer to the output buffer */ - bool Get(std::string_view key, std::span value) const noexcept; + bool Get(std::string_view key, std::span value) const noexcept; template bool Get(std::string_view key, - BasicStringBuffer &value) const noexcept { + BasicStringBuffer &value) const noexcept { return Get(key, std::span{value.data(), value.capacity()}); } -#ifdef _UNICODE - void Set(std::string_view key, const TCHAR *value) noexcept; -#endif - // numeric values bool Get(std::string_view key, int &value) const noexcept; @@ -177,12 +173,8 @@ class ProfileMap { /** * Gets a path from the profile and return its base name only. */ -#ifdef _UNICODE - BasicAllocatedString GetPathBase(std::string_view key) const noexcept; -#else [[gnu::pure]] - StringPointer GetPathBase(std::string_view key) const noexcept; -#endif + StringPointer GetPathBase(std::string_view key) const noexcept; void SetPath(std::string_view key, Path value) noexcept; diff --git a/src/Profile/PathValue.cpp b/src/Profile/PathValue.cpp index d7e47675fc8..9a7e05879e4 100644 --- a/src/Profile/PathValue.cpp +++ b/src/Profile/PathValue.cpp @@ -9,16 +9,12 @@ #include "util/StringCompare.hxx" #include "util/StringPointer.hxx" -#ifdef _UNICODE -#include "util/AllocatedString.hxx" -#endif - #include /* for MAX_PATH */ AllocatedPath ProfileMap::GetPath(std::string_view key) const noexcept { - TCHAR buffer[MAX_PATH]; + char buffer[MAX_PATH]; if (!Get(key, std::span{buffer})) return nullptr; @@ -40,10 +36,10 @@ ProfileMap::GetPathIsEqual(std::string_view key, Path value) const noexcept [[gnu::pure]] static Path -BackslashBaseName(const TCHAR *p) noexcept +BackslashBaseName(const char *p) noexcept { if (DIR_SEPARATOR != '\\') { - const auto *backslash = StringFindLast(p, _T('\\')); + const auto *backslash = StringFindLast(p, '\\'); if (backslash != NULL) p = backslash + 1; } @@ -51,25 +47,7 @@ BackslashBaseName(const TCHAR *p) noexcept return Path(p).GetBase(); } -#ifdef _UNICODE - -BasicAllocatedString -ProfileMap::GetPathBase(std::string_view key) const noexcept -{ - TCHAR buffer[MAX_PATH]; - if (!Get(key, std::span{buffer})) - return nullptr; - - const TCHAR *base = BackslashBaseName(buffer).c_str(); - if (base == nullptr) - return nullptr; - - return BasicAllocatedString(base); -} - -#else - -StringPointer +StringPointer ProfileMap::GetPathBase(std::string_view key) const noexcept { const auto *path = Get(key); @@ -79,13 +57,11 @@ ProfileMap::GetPathBase(std::string_view key) const noexcept return path; } -#endif - void ProfileMap::SetPath(std::string_view key, Path value) noexcept { if (value == nullptr || StringIsEmpty(value.c_str())) - Set(key, _T("")); + Set(key, ""); else { const auto contracted = ContractLocalPath(value); if (contracted != nullptr) diff --git a/src/Profile/Profile.cpp b/src/Profile/Profile.cpp index 2d9dbdf6ad2..41f8b111d56 100644 --- a/src/Profile/Profile.cpp +++ b/src/Profile/Profile.cpp @@ -11,7 +11,7 @@ #include "util/StringUtil.hpp" #include "util/StringCompare.hxx" #include "util/StringAPI.hxx" -#include "util/tstring.hpp" +#include #include "system/FileUtil.hpp" #include "system/Path.hpp" @@ -32,6 +32,8 @@ Profile::GetPath() noexcept void Profile::Load() noexcept { + if (startProfileFile == nullptr) + SetFiles(nullptr); assert(startProfileFile != nullptr); LogString("Loading profiles"); @@ -44,7 +46,7 @@ Profile::LoadFile(Path path) noexcept { try { LoadFile(map, path); - LogFormat(_T("Loaded profile from %s"), path.c_str()); + LogFormat("Loaded profile from %s", path.c_str()); } catch (...) { LogError(std::current_exception(), "Failed to load profile"); } @@ -72,7 +74,7 @@ Profile::Save() noexcept void Profile::SaveFile(Path path) { - LogFormat(_T("Saving profile to %s"), path.c_str()); + LogFormat("Saving profile to %s", path.c_str()); SaveFile(map, path); } @@ -88,8 +90,8 @@ Profile::SetFiles(Path override_path) noexcept if (StringFind(override_path.c_str(), '.') != nullptr) startProfileFile = LocalPath(override_path); else { - tstring t(override_path.c_str()); - t += _T(".prf"); + std::string t(override_path.c_str()); + t += ".prf"; startProfileFile = LocalPath(t.c_str()); } } else @@ -98,7 +100,7 @@ Profile::SetFiles(Path override_path) noexcept } // Set the default profile file - startProfileFile = LocalPath(_T(XCSPROFILE)); + startProfileFile = LocalPath(XCSPROFILE); } AllocatedPath diff --git a/src/Profile/ProfileMap.cpp b/src/Profile/ProfileMap.cpp index d09da6adb15..e49f4077e99 100644 --- a/src/Profile/ProfileMap.cpp +++ b/src/Profile/ProfileMap.cpp @@ -24,7 +24,7 @@ Profile::Get(std::string_view key, const char *default_value) noexcept } bool -Profile::Get(std::string_view key, std::span value) noexcept +Profile::Get(std::string_view key, std::span value) noexcept { return map.Get(key, value); } @@ -77,16 +77,6 @@ Profile::Set(std::string_view key, const char *value) noexcept map.Set(key, value); } -#ifdef _UNICODE - -void -Profile::Set(std::string_view key, const TCHAR *value) noexcept -{ - map.Set(key, value); -} - -#endif - void Profile::Set(std::string_view key, int value) noexcept { diff --git a/src/Profile/ProfileMap.hpp b/src/Profile/ProfileMap.hpp index 0c1b962fad7..8d4d17cd092 100644 --- a/src/Profile/ProfileMap.hpp +++ b/src/Profile/ProfileMap.hpp @@ -49,7 +49,7 @@ Get(std::string_view key, const char *default_value=nullptr) noexcept; * @param max_size Maximum size of the output buffer */ bool -Get(std::string_view key, std::span value) noexcept; +Get(std::string_view key, std::span value) noexcept; /** * Writes a value to the profile map @@ -59,11 +59,6 @@ Get(std::string_view key, std::span value) noexcept; void Set(std::string_view key, const char *value) noexcept; -#ifdef _UNICODE -void -Set(std::string_view key, const TCHAR *value) noexcept; -#endif - bool Get(std::string_view key, int &value) noexcept; @@ -100,7 +95,7 @@ GetEnum(std::string_view key, T &value) noexcept static inline void Set(std::string_view key, bool value) noexcept { - Set(key, value ? _T("1") : _T("0")); + Set(key, value ? "1" : "0"); } void @@ -130,7 +125,7 @@ SetEnum(std::string_view key, T value) noexcept template static inline bool -Get(std::string_view key, BasicStringBuffer &value) noexcept +Get(std::string_view key, BasicStringBuffer &value) noexcept { return Get(key, std::span{value.data(), value.capacity()}); } diff --git a/src/Profile/StringValue.cpp b/src/Profile/StringValue.cpp index c96b2f6a6d0..4dd1586979c 100644 --- a/src/Profile/StringValue.cpp +++ b/src/Profile/StringValue.cpp @@ -6,47 +6,19 @@ #include "util/TruncateString.hpp" #include "util/Macros.hpp" -#ifdef _UNICODE -#include "util/Macros.hpp" - -#include -#endif - bool -ProfileMap::Get(std::string_view key, std::span value) const noexcept +ProfileMap::Get(std::string_view key, std::span value) const noexcept { const char *src = Get(key); if (src == nullptr) { - value[0] = _T('\0'); + value[0] = '\0'; return false; } -#ifdef _UNICODE - int result = MultiByteToWideChar(CP_UTF8, 0, src, -1, - value.data(), value.size()); - return result > 0; -#else if (!ValidateUTF8(src)) return false; CopyTruncateString(value.data(), value.size(), src); return true; -#endif -} - -#ifdef _UNICODE - -void -ProfileMap::Set(std::string_view key, const TCHAR *value) noexcept -{ - char buffer[MAX_PATH]; - int length = WideCharToMultiByte(CP_UTF8, 0, value, -1, - buffer, ARRAY_SIZE(buffer), - nullptr, nullptr); - if (length <= 0) - return; - - Set(key, buffer); } -#endif diff --git a/src/Profile/TrackingProfile.cpp b/src/Profile/TrackingProfile.cpp index 3cc0c00e45c..c8f26830637 100644 --- a/src/Profile/TrackingProfile.cpp +++ b/src/Profile/TrackingProfile.cpp @@ -44,10 +44,10 @@ static void Load(const ProfileMap &map, map.Get(ProfileKeys::LiveTrack24Enabled, settings.enabled); if (!map.Get(ProfileKeys::LiveTrack24Server, settings.server)) - settings.server = _T("www.livetrack24.com"); - else if (StringIsEqual(settings.server, _T("livexc.dhv1.de"))) { + settings.server = "www.livetrack24.com"; + else if (StringIsEqual(settings.server, "livexc.dhv1.de")) { // DHV tracking server moved to new host (#3208) - settings.server = _T("livexc.dhv.de"); + settings.server = "livexc.dhv.de"; } map.Get(ProfileKeys::LiveTrack24Username, settings.username); diff --git a/src/ProgressGlue.cpp b/src/ProgressGlue.cpp index c413e709da0..73216ef8b2b 100644 --- a/src/ProgressGlue.cpp +++ b/src/ProgressGlue.cpp @@ -15,7 +15,7 @@ static ProgressWindow *global_progress_window; static PeriodClock throttle_clock; void -ProgressGlue::Create(const TCHAR *text) noexcept +ProgressGlue::Create(const char *text) noexcept { UIGlobals::GetMainWindow().RefreshSize(); diff --git a/src/ProgressGlue.hpp b/src/ProgressGlue.hpp index debaf15953d..1c293e655dd 100644 --- a/src/ProgressGlue.hpp +++ b/src/ProgressGlue.hpp @@ -13,7 +13,7 @@ namespace ProgressGlue { * Creates or updates the ProgressWindow * @param text the text inside the progress bar */ -void Create(const TCHAR *text) noexcept; +void Create(const char *text) noexcept; void Move(const PixelRect &rc) noexcept; diff --git a/src/ProgressWindow.cpp b/src/ProgressWindow.cpp index e5bca666ff9..c4334bc0dea 100644 --- a/src/ProgressWindow.cpp +++ b/src/ProgressWindow.cpp @@ -76,12 +76,12 @@ ProgressWindow::UpdateLayout(PixelRect rc) noexcept } void -ProgressWindow::SetMessage(const TCHAR *text) noexcept +ProgressWindow::SetMessage(const char *text) noexcept { AssertThread(); if (text == nullptr) - text = _T(""); + text = ""; message = text; Invalidate(message_position); diff --git a/src/ProgressWindow.hpp b/src/ProgressWindow.hpp index 0588adccbd6..6fc30da1b5f 100644 --- a/src/ProgressWindow.hpp +++ b/src/ProgressWindow.hpp @@ -36,7 +36,7 @@ class ProgressWindow : public ContainerWindow { public: explicit ProgressWindow(ContainerWindow &parent) noexcept; - void SetMessage(const TCHAR *text) noexcept; + void SetMessage(const char *text) noexcept; void SetRange(unsigned min_value, unsigned max_value) noexcept; void SetStep(unsigned size) noexcept; diff --git a/src/Projection/CMakeLists.txt b/src/Projection/CMakeLists.txt new file mode 100644 index 00000000000..c79a42de2ee --- /dev/null +++ b/src/Projection/CMakeLists.txt @@ -0,0 +1,51 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories + + +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/Projection/CMakeSource.cmake b/src/Projection/CMakeSource.cmake new file mode 100644 index 00000000000..12e6e787587 --- /dev/null +++ b/src/Projection/CMakeSource.cmake @@ -0,0 +1,11 @@ +set(_SOURCES + Projection/ChartProjection.cpp + Projection/CompareProjection.cpp + Projection/MapWindowProjection.cpp + Projection/Projection.cpp + Projection/WindowProjection.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake +) diff --git a/src/RadioFrequency.cpp b/src/RadioFrequency.cpp index 26959125585..4e569c5e9ed 100644 --- a/src/RadioFrequency.cpp +++ b/src/RadioFrequency.cpp @@ -8,8 +8,10 @@ #include "util/StringFormat.hpp" #include "util/NumberParser.hpp" -TCHAR * -RadioFrequency::Format(TCHAR *buffer, size_t max_size) const noexcept +using std::string_view_literals::operator""sv; + +char * +RadioFrequency::Format(char *buffer, size_t max_size) const noexcept { if (!IsDefined()) return nullptr; @@ -18,7 +20,7 @@ RadioFrequency::Format(TCHAR *buffer, size_t max_size) const noexcept unsigned mhz = khz / 1000; khz %= 1000; - StringFormat(buffer, max_size, _T("%u.%03u"), mhz, khz); + StringFormat(buffer, max_size, "%u.%03u", mhz, khz); return buffer; } @@ -31,9 +33,24 @@ RadioFrequency::Parse(std::string_view src) noexcept mhz = *value; else return Null(); - + if (mhz < MIN_KHZ / 1000. && mhz > MAX_KHZ / 1000.) return Null(); - + return FromKiloHertz(uround(mhz * 1000)); } + +RadioFrequency +RadioFrequency::Parse(StringParser<> &src) noexcept +{ + auto mhz = src.ReadDouble(); + if (mhz.has_value()) { + if (src.SkipMatchIgnoreCase("MHz"sv)) + *mhz *= 1.0; + else if (src.SkipMatchIgnoreCase("kHz"sv)) + *mhz /= 1000.0; + return FromKiloHertz(uround(*mhz * 1000)); + } else { + return RadioFrequency(); + } +} diff --git a/src/RadioFrequency.hpp b/src/RadioFrequency.hpp index e58eacefe2d..8f7f470db63 100644 --- a/src/RadioFrequency.hpp +++ b/src/RadioFrequency.hpp @@ -3,6 +3,9 @@ #pragma once +#include "util/StringAPI.hxx" +#include "util/StringParser.hxx" + #include #include #include @@ -53,6 +56,12 @@ class RadioFrequency { return f; } + static constexpr RadioFrequency Convert(double mhz) noexcept { + RadioFrequency f; + f.SetKiloHertz(mhz * 1000.0 + 0.49); // for a correct truncation + return f; + } + friend constexpr auto operator<=>(RadioFrequency, RadioFrequency) noexcept = default; @@ -95,8 +104,11 @@ class RadioFrequency { SetKiloHertz(new_khz); } - TCHAR *Format(TCHAR *buffer, size_t max_size) const noexcept; + char *Format(char *buffer, size_t max_size) const noexcept; [[gnu::pure]] static RadioFrequency Parse(std::string_view src) noexcept; + + [[gnu::pure]] + static RadioFrequency Parse(StringParser<> &src) noexcept; }; diff --git a/src/Renderer/AirspaceLabelRenderer.cpp b/src/Renderer/AirspaceLabelRenderer.cpp index 8380a4d5c79..2b738bcf439 100644 --- a/src/Renderer/AirspaceLabelRenderer.cpp +++ b/src/Renderer/AirspaceLabelRenderer.cpp @@ -93,11 +93,11 @@ AirspaceLabelRenderer::DrawLabel(Canvas &canvas, const WindowProjection &projection, const AirspaceLabelList::Label &label) noexcept { - TCHAR topText[NAME_SIZE + 1]; + char topText[NAME_SIZE + 1]; AirspaceFormatter::FormatAltitudeShort(topText, label.top, false); const PixelSize topSize = canvas.CalcTextSize(topText); - TCHAR baseText[NAME_SIZE + 1]; + char baseText[NAME_SIZE + 1]; AirspaceFormatter::FormatAltitudeShort(baseText, label.base, false); const PixelSize baseSize = canvas.CalcTextSize(baseText); diff --git a/src/Renderer/AirspaceListRenderer.cpp b/src/Renderer/AirspaceListRenderer.cpp index 3a116d935a7..02ab81f0fb3 100644 --- a/src/Renderer/AirspaceListRenderer.cpp +++ b/src/Renderer/AirspaceListRenderer.cpp @@ -16,7 +16,7 @@ static void Draw(Canvas &canvas, PixelRect rc, const AbstractAirspace &airspace, - const TCHAR *comment, + const char *comment, const TwoTextRowsRenderer &row_renderer, const AirspaceLook &look, const AirspaceRendererSettings &renderer_settings) @@ -33,7 +33,7 @@ Draw(Canvas &canvas, PixelRect rc, rc.left += line_height + padding; // Draw upper airspace altitude limit - TCHAR buffer[40]; + char buffer[40]; AirspaceFormatter::FormatAltitudeShort(buffer, airspace.GetTop()); const int top_x = row_renderer.DrawRightFirstRow(canvas, rc, buffer); @@ -71,7 +71,7 @@ AirspaceListRenderer::Draw(Canvas &canvas, const PixelRect rc, { StaticString<256> comment(AirspaceFormatter::GetClass(airspace)); - comment.AppendFormat(_T(" - %s - %s"), + comment.AppendFormat(" - %s - %s", FormatUserDistanceSmart(vector.distance).c_str(), FormatBearing(vector.bearing).c_str()); diff --git a/src/Renderer/AirspacePreviewRenderer.cpp b/src/Renderer/AirspacePreviewRenderer.cpp index 114d2890cd8..7870a2e0ddc 100644 --- a/src/Renderer/AirspacePreviewRenderer.cpp +++ b/src/Renderer/AirspacePreviewRenderer.cpp @@ -84,6 +84,7 @@ AirspacePreviewRenderer::UnprepareFill([[maybe_unused]] Canvas &canvas) #ifdef ENABLE_OPENGL ::glDisable(GL_BLEND); #elif defined(USE_GDI) + canvas.SetTextColor(COLOR_BLACK); canvas.SetMixCopy(); #endif } diff --git a/src/Renderer/BarographRenderer.cpp b/src/Renderer/BarographRenderer.cpp index e8e0c52474b..1ee9fc7a183 100644 --- a/src/Renderer/BarographRenderer.cpp +++ b/src/Renderer/BarographRenderer.cpp @@ -17,19 +17,19 @@ #include "GradientRenderer.hpp" void -BarographCaption(TCHAR *sTmp, const FlightStatistics &fs) +BarographCaption(char *sTmp, const FlightStatistics &fs) { const std::lock_guard lock{fs.mutex}; if (!fs.altitude_ceiling.HasResult() || fs.altitude_base.IsEmpty()) { - sTmp[0] = _T('\0'); + sTmp[0] = '\0'; } else if (fs.altitude_ceiling.GetCount() < 4) { - StringFormatUnsafe(sTmp, _T("%s:\r\n %.0f-%.0f %s"), + StringFormatUnsafe(sTmp, "%s:\r\n %.0f-%.0f %s", _("Working band"), (double)Units::ToUserAltitude(fs.GetMinWorkingHeight()), (double)Units::ToUserAltitude(fs.GetMaxWorkingHeight()), Units::GetAltitudeName()); } else { - StringFormatUnsafe(sTmp, _T("%s:\r\n %.0f-%.0f %s\r\n\r\n%s:\r\n %.0f %s/hr"), + StringFormatUnsafe(sTmp, "%s:\r\n %.0f-%.0f %s\r\n\r\n%s:\r\n %.0f %s/hr", _("Working band"), (double)Units::ToUserAltitude(fs.GetMinWorkingHeight()), (double)Units::ToUserAltitude(fs.GetMaxWorkingHeight()), @@ -99,8 +99,8 @@ RenderBarograph(Canvas &canvas, const PixelRect rc, const ProtectedTaskManager *_task) { ChartRenderer chart(chart_look, canvas, rc); - chart.SetXLabel(_T("t"), _T("hr")); - chart.SetYLabel(_T("h"), Units::GetAltitudeName()); + chart.SetXLabel("t", "hr"); + chart.SetYLabel("h", Units::GetAltitudeName()); chart.Begin(); if (!fs.altitude.HasResult()) { diff --git a/src/Renderer/BarographRenderer.hpp b/src/Renderer/BarographRenderer.hpp index a2d85f1c06f..5deed9d7e48 100644 --- a/src/Renderer/BarographRenderer.hpp +++ b/src/Renderer/BarographRenderer.hpp @@ -16,7 +16,7 @@ class ProtectedTaskManager; class TaskManager; void -BarographCaption(TCHAR *buffer, const FlightStatistics &fs); +BarographCaption(char *buffer, const FlightStatistics &fs); void RenderBarographSpark(Canvas &canvas, const PixelRect rc, diff --git a/src/Renderer/CMakeLists.txt b/src/Renderer/CMakeLists.txt new file mode 100644 index 00000000000..397480aa3b1 --- /dev/null +++ b/src/Renderer/CMakeLists.txt @@ -0,0 +1,66 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories + + +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +# # # !!! # ATTENTION Terrain inside Renderer! +# # # !!! foreach(cpp_file ${Terrain_SOURCES}) +# # # !!! list(APPEND SOURCE_FILES ${PROJECTGROUP_SOURCE_DIR}/src/${cpp_file}) +# # # !!! endforeach() +# # # !!! +# # # !!! # ATTENTION Engine inside Renderer! +# # # !!! foreach(cpp_file ${Engine_SOURCES}) +# # # !!! list(APPEND SOURCE_FILES ${PROJECTGROUP_SOURCE_DIR}/src/${cpp_file}) +# # # !!! endforeach() + + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER FrontEnd) + +add_dependencies(${TARGET_NAME} util) +# add_dependencies(${TARGET_NAME} Terrain) + +target_link_libraries(${TARGET_NAME} PUBLIC Projection Engine Terrain MapWindow) +add_dependencies(${TARGET_NAME} Projection Engine Terrain) diff --git a/src/Renderer/CMakeSource.cmake b/src/Renderer/CMakeSource.cmake new file mode 100644 index 00000000000..20ad9da726e --- /dev/null +++ b/src/Renderer/CMakeSource.cmake @@ -0,0 +1,78 @@ +set(_SOURCES + Renderer/AircraftRenderer.cpp + Renderer/AirspaceLabelList.cpp + Renderer/AirspaceLabelRenderer.cpp + Renderer/AirspaceListRenderer.cpp + Renderer/AirspacePreviewRenderer.cpp + Renderer/AirspaceRenderer.cpp + Renderer/AirspaceRendererGL.cpp + Renderer/AirspaceRendererOther.cpp + Renderer/AirspaceRendererSettings.cpp + Renderer/BackgroundRenderer.cpp + Renderer/BarographRenderer.cpp + Renderer/BestCruiseArrowRenderer.cpp + Renderer/BitmapButtonRenderer.cpp + Renderer/ButtonRenderer.cpp + Renderer/ChartRenderer.cpp + Renderer/ClimbChartRenderer.cpp + Renderer/ClimbPercentRenderer.cpp + Renderer/ColorButtonRenderer.cpp + Renderer/CompassRenderer.cpp + Renderer/CuRenderer.cpp + Renderer/FAITriangleAreaRenderer.cpp + Renderer/FinalGlideBarRenderer.cpp + Renderer/FlightStatisticsRenderer.cpp + Renderer/GeoBitmapRenderer.cpp + Renderer/GlassRenderer.cpp + Renderer/GlidePolarInfoRenderer.cpp + Renderer/GlidePolarRenderer.cpp + Renderer/GradientRenderer.cpp + Renderer/HorizonRenderer.cpp + Renderer/LabelBlock.cpp + Renderer/MacCreadyRenderer.cpp + Renderer/MapItemListRenderer.cpp + Renderer/MapScaleRenderer.cpp + Renderer/NextArrowRenderer.cpp + Renderer/NOAAListRenderer.cpp + Renderer/OZPreviewRenderer.cpp + Renderer/OZRenderer.cpp + Renderer/SymbolButtonRenderer.cpp + Renderer/SymbolRenderer.cpp + Renderer/TabRenderer.cpp + Renderer/TaskLegRenderer.cpp + Renderer/TaskPointRenderer.cpp + Renderer/TaskProgressRenderer.cpp + Renderer/TaskRenderer.cpp + Renderer/TaskSpeedRenderer.cpp + Renderer/TextButtonRenderer.cpp + Renderer/TextInBox.cpp + Renderer/TextRenderer.cpp + Renderer/TextRowRenderer.cpp + Renderer/ThermalBandRenderer.cpp + Renderer/TraceHistoryRenderer.cpp + Renderer/TrackLineRenderer.cpp + Renderer/TrafficRenderer.cpp + Renderer/TrailRenderer.cpp + Renderer/TransparentRendererCache.cpp + Renderer/TwoTextRowsRenderer.cpp + Renderer/UnitSymbolRenderer.cpp + Renderer/VarioBarRenderer.cpp + Renderer/VarioHistogramRenderer.cpp + Renderer/WaveRenderer.cpp + Renderer/WaypointIconRenderer.cpp + Renderer/WaypointLabelList.cpp + Renderer/WaypointListRenderer.cpp + Renderer/WaypointRenderer.cpp + Renderer/WaypointRendererSettings.cpp + Renderer/WindArrowRenderer.cpp + Renderer/WindChartRenderer.cpp + + Renderer/ProgressBarRenderer.cpp + Renderer/RadarRenderer.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake + + ../../build/screen.mk +) diff --git a/src/Renderer/ChartRenderer.cpp b/src/Renderer/ChartRenderer.cpp index 3416b2378a0..ff23a3b1716 100644 --- a/src/Renderer/ChartRenderer.cpp +++ b/src/Renderer/ChartRenderer.cpp @@ -29,27 +29,27 @@ ChartRenderer::ChartRenderer(const ChartLook &_look, Canvas &the_canvas, } void -ChartRenderer::SetXLabel(const TCHAR *text) noexcept +ChartRenderer::SetXLabel(const char *text) noexcept { CopyTruncateString(x_label.data(), x_label.capacity(), text); } void -ChartRenderer::SetXLabel(const TCHAR *text, const TCHAR *unit) noexcept +ChartRenderer::SetXLabel(const char *text, const char *unit) noexcept { StringFormat(x_label.data(), x_label.capacity(), - _T("%s [%s]"), text, unit); + "%s [%s]", text, unit); } void -ChartRenderer::SetYLabel(const TCHAR *text, const TCHAR *unit) noexcept +ChartRenderer::SetYLabel(const char *text, const char *unit) noexcept { StringFormat(y_label.data(), y_label.capacity(), - _T("%s [%s]"), text, unit); + "%s [%s]", text, unit); } void -ChartRenderer::SetYLabel(const TCHAR *text) noexcept +ChartRenderer::SetYLabel(const char *text) noexcept { CopyTruncateString(y_label.data(), y_label.capacity(), text); } @@ -193,7 +193,7 @@ ChartRenderer::ScaleXFromValue(const double value) noexcept } void -ChartRenderer::DrawLabel(DoublePoint2D v, const TCHAR *text) noexcept +ChartRenderer::DrawLabel(DoublePoint2D v, const char *text) noexcept { canvas.Select(look.label_font); canvas.SetBackgroundTransparent(); @@ -214,7 +214,7 @@ ChartRenderer::DrawLabel(DoublePoint2D v, const TCHAR *text) noexcept } void -ChartRenderer::DrawNoData(const TCHAR *text) noexcept +ChartRenderer::DrawNoData(const char *text) noexcept { canvas.Select(look.label_font); canvas.SetBackgroundTransparent(); @@ -437,21 +437,21 @@ ChartRenderer::DrawLineGraph(const XYDataStore &lsdata, DrawLineGraph(lsdata, look.GetPen(style), swap); } -BasicStringBuffer +BasicStringBuffer ChartRenderer::FormatTicText(const double val, const double step, UnitFormat units) noexcept { - BasicStringBuffer buffer; + BasicStringBuffer buffer; if (units == UnitFormat::TIME) { const unsigned total_minutes(val * 60); - StringFormat(buffer.data(), buffer.capacity(), _T("%u:%02u"), + StringFormat(buffer.data(), buffer.capacity(), "%u:%02u", total_minutes / 60, total_minutes % 60); } else { if (step < 1) { - StringFormat(buffer.data(), buffer.capacity(), _T("%.1f"), val); + StringFormat(buffer.data(), buffer.capacity(), "%.1f", val); } else { - StringFormat(buffer.data(), buffer.capacity(), _T("%.0f"), val); + StringFormat(buffer.data(), buffer.capacity(), "%.0f", val); } } diff --git a/src/Renderer/ChartRenderer.hpp b/src/Renderer/ChartRenderer.hpp index 19a988566c6..614934b93f2 100644 --- a/src/Renderer/ChartRenderer.hpp +++ b/src/Renderer/ChartRenderer.hpp @@ -33,7 +33,7 @@ class ChartRenderer PixelRect rc; PixelRect rc_chart; - BasicStringBuffer x_label, y_label; + BasicStringBuffer x_label, y_label; ReusableArray point_buffer; @@ -62,11 +62,11 @@ class ChartRenderer const PixelRect &the_rc, const bool has_padding=true) noexcept; - void SetXLabel(const TCHAR *text) noexcept; - void SetXLabel(const TCHAR *text, const TCHAR *unit) noexcept; + void SetXLabel(const char *text) noexcept; + void SetXLabel(const char *text, const char *unit) noexcept; - void SetYLabel(const TCHAR *text) noexcept; - void SetYLabel(const TCHAR *text, const TCHAR *unit) noexcept; + void SetYLabel(const char *text) noexcept; + void SetYLabel(const char *text, const char *unit) noexcept; /** * Prepare for drawing; this method calculates the layout. Call @@ -117,7 +117,7 @@ class ChartRenderer void ScaleXFromValue(double val) noexcept; [[gnu::pure]] - static BasicStringBuffer FormatTicText(double val, double step, + static BasicStringBuffer FormatTicText(double val, double step, UnitFormat units) noexcept; void DrawXGrid(double tic_step, double unit_step, @@ -125,8 +125,8 @@ class ChartRenderer void DrawYGrid(double tic_step, double unit_step, UnitFormat units = UnitFormat::NONE) noexcept; - void DrawLabel(DoublePoint2D v, const TCHAR *text) noexcept; - void DrawNoData(const TCHAR *text) noexcept; + void DrawLabel(DoublePoint2D v, const char *text) noexcept; + void DrawNoData(const char *text) noexcept; void DrawNoData() noexcept; void DrawBlankRectangle(DoublePoint2D min, DoublePoint2D max) noexcept; diff --git a/src/Renderer/ClimbChartRenderer.cpp b/src/Renderer/ClimbChartRenderer.cpp index 666797d701c..27d5e5b0eef 100644 --- a/src/Renderer/ClimbChartRenderer.cpp +++ b/src/Renderer/ClimbChartRenderer.cpp @@ -16,19 +16,19 @@ #include "GradientRenderer.hpp" void -ClimbChartCaption(TCHAR *sTmp, +ClimbChartCaption(char *sTmp, const FlightStatistics &fs) { const std::lock_guard lock{fs.mutex}; if (fs.thermal_average.IsEmpty()) { - sTmp[0] = _T('\0'); + sTmp[0] = '\0'; } else if (fs.thermal_average.GetCount() == 1) { - StringFormatUnsafe(sTmp, _T("%s:\r\n %3.1f %s"), + StringFormatUnsafe(sTmp, "%s:\r\n %3.1f %s", _("Avg. climb"), (double)Units::ToUserVSpeed(fs.thermal_average.GetAverageY()), Units::GetVerticalSpeedName()); } else { - StringFormatUnsafe(sTmp, _T("%s:\r\n %3.1f %s\r\n\r\n%s:\r\n %3.2f %s/hr"), + StringFormatUnsafe(sTmp, "%s:\r\n %3.1f %s\r\n\r\n%s:\r\n %3.2f %s/hr", _("Avg. climb"), (double)Units::ToUserVSpeed(fs.thermal_average.GetAverageY()), Units::GetVerticalSpeedName(), @@ -48,8 +48,8 @@ RenderClimbChart(Canvas &canvas, const PixelRect rc, const TaskManager &task) { ChartRenderer chart(chart_look, canvas, rc); - chart.SetXLabel(_T("t"), _T("hr")); - chart.SetYLabel(_T("w"), Units::GetVerticalSpeedName()); + chart.SetXLabel("t", "hr"); + chart.SetYLabel("w", Units::GetVerticalSpeedName()); chart.Begin(); if (fs.thermal_average.IsEmpty()) { @@ -98,7 +98,7 @@ RenderClimbChart(Canvas &canvas, const PixelRect rc, ChartLook::STYLE_REDTHICKDASH); chart.DrawLabel({chart.GetXMin()*0.9+chart.GetXMax()*0.1, MACCREADY}, - _T("MC")); + "MC"); chart.Finish(); } diff --git a/src/Renderer/ClimbChartRenderer.hpp b/src/Renderer/ClimbChartRenderer.hpp index 3a1d10a9dad..e542fe2926e 100644 --- a/src/Renderer/ClimbChartRenderer.hpp +++ b/src/Renderer/ClimbChartRenderer.hpp @@ -15,7 +15,7 @@ struct DerivedInfo; class TaskManager; void -ClimbChartCaption(TCHAR *buffer, +ClimbChartCaption(char *buffer, const FlightStatistics &fs); void diff --git a/src/Renderer/CuRenderer.cpp b/src/Renderer/CuRenderer.cpp index 0a317ac346b..41d5117c7bf 100644 --- a/src/Renderer/CuRenderer.cpp +++ b/src/Renderer/CuRenderer.cpp @@ -20,8 +20,8 @@ RenderTemperatureChart(Canvas &canvas, const PixelRect rc, const CuSonde &cu_sonde) { ChartRenderer chart(chart_look, canvas, rc); - chart.SetXLabel(_T("T"), Units::GetTemperatureName()); - chart.SetYLabel(_T("h"), Units::GetAltitudeName()); + chart.SetXLabel("T", Units::GetTemperatureName()); + chart.SetYLabel("h", Units::GetAltitudeName()); chart.Begin(); int hmin = 10000; @@ -103,15 +103,15 @@ RenderTemperatureChart(Canvas &canvas, const PixelRect rc, if (ipos > 2) { if (!labelDry) { chart.DrawLabel({cu_sonde.cslevels[i + 1].dry_temperature.ToUser(), alt}, - _T("DALR")); + "DALR"); labelDry = true; } else if (!labelAir) { chart.DrawLabel({cu_sonde.cslevels[i + 1].air_temperature.ToUser(), alt}, - _T("Air")); + "Air"); labelAir = true; } else if (!labelDew && has_dewpoint) { chart.DrawLabel({cu_sonde.cslevels[i + 1].dewpoint.ToUser(), alt}, - _T("Dew")); + "Dew"); labelDew = true; } } @@ -121,9 +121,9 @@ RenderTemperatureChart(Canvas &canvas, const PixelRect rc, } void -TemperatureChartCaption(TCHAR *sTmp, const CuSonde &cu_sonde) +TemperatureChartCaption(char *sTmp, const CuSonde &cu_sonde) { - StringFormatUnsafe(sTmp, _T("%s:\r\n %5.0f %s\r\n\r\n%s:\r\n %5.0f %s\r\n"), + StringFormatUnsafe(sTmp, "%s:\r\n %5.0f %s\r\n\r\n%s:\r\n %5.0f %s\r\n", _("Thermal height"), (double)Units::ToUserAltitude(cu_sonde.thermal_height), Units::GetAltitudeName(), diff --git a/src/Renderer/CuRenderer.hpp b/src/Renderer/CuRenderer.hpp index 066410447a9..a9c7213f4ee 100644 --- a/src/Renderer/CuRenderer.hpp +++ b/src/Renderer/CuRenderer.hpp @@ -16,4 +16,4 @@ RenderTemperatureChart(Canvas &canvas, const PixelRect rc, const CuSonde &cu_sonde); void -TemperatureChartCaption(TCHAR *buffer, const CuSonde &cu_sonde); +TemperatureChartCaption(char *buffer, const CuSonde &cu_sonde); diff --git a/src/Renderer/FinalGlideBarRenderer.cpp b/src/Renderer/FinalGlideBarRenderer.cpp index 47fd1954b21..5693fc34e20 100644 --- a/src/Renderer/FinalGlideBarRenderer.cpp +++ b/src/Renderer/FinalGlideBarRenderer.cpp @@ -37,7 +37,7 @@ FinalGlideBarRenderer::Draw(Canvas &canvas, const PixelRect &rc, { 0, 0 }, { 9, 9 }, { 9, 15 }, { 0, 6 } }; - TCHAR Value[10]; + char Value[10]; const TaskStats &task_stats = calculated.task_stats; const ElementStat &total = task_stats.total; diff --git a/src/Renderer/FlightListRenderer.cpp b/src/Renderer/FlightListRenderer.cpp index 3a8a7ff0486..760b8f58400 100644 --- a/src/Renderer/FlightListRenderer.cpp +++ b/src/Renderer/FlightListRenderer.cpp @@ -21,7 +21,7 @@ FlightListRenderer::Draw(Canvas &canvas, PixelRect rc) if (flights.empty()) { auto center = rc.GetCenter(); - const TCHAR *text = _T("No flights"); + const char *text = "No flights"; PixelSize size = canvas.CalcTextSize(text); canvas.DrawText(center - size / 2u, text); return; @@ -36,8 +36,8 @@ FlightListRenderer::Draw(Canvas &canvas, PixelRect rc) return; const unsigned row_height = font_height + padding; - const unsigned date_width = canvas.CalcTextWidth(_T("2222-22-22")) + padding * 4; - const unsigned time_width = canvas.CalcTextWidth(_T("22:22")) + padding * 4; + const unsigned date_width = canvas.CalcTextWidth("2222-22-22") + padding * 4; + const unsigned time_width = canvas.CalcTextWidth("22:22") + padding * 4; canvas.Select(header_font); @@ -51,36 +51,36 @@ FlightListRenderer::Draw(Canvas &canvas, PixelRect rc) StaticString<64> buffer; if (flight.date.IsPlausible()) { - buffer.UnsafeFormat(_T("%04u-%02u-%02u "), flight.date.year, + buffer.UnsafeFormat("%04u-%02u-%02u ", flight.date.year, flight.date.month, flight.date.day); canvas.DrawText({x, y}, buffer); } else - canvas.DrawText({x, y}, _T("____-__-__")); + canvas.DrawText({x, y}, "____-__-__"); x += date_width; if (flight.start_time.IsPlausible()) { - buffer.UnsafeFormat(_T("%02u:%02u "), + buffer.UnsafeFormat("%02u:%02u ", flight.start_time.hour, flight.start_time.minute); canvas.DrawText({x, y}, buffer); } else - canvas.DrawText({x, y}, _T("--:--")); + canvas.DrawText({x, y}, "--:--"); x += time_width; if (flight.end_time.IsPlausible()) { - buffer.UnsafeFormat(_T("%02u:%02u"), + buffer.UnsafeFormat("%02u:%02u", flight.end_time.hour, flight.end_time.minute); canvas.DrawText({x, y}, buffer); } else - canvas.DrawText({x, y}, _T("--:--")); + canvas.DrawText({x, y}, "--:--"); x += time_width; if (flight.Duration().count() >= 0) { BrokenTime duration = BrokenTime::FromSinceMidnight(flight.Duration()); - buffer.UnsafeFormat(_T("%02u:%02u"), + buffer.UnsafeFormat("%02u:%02u", duration.hour, duration.minute); canvas.DrawText({x, y}, buffer); } else - canvas.DrawText({x, y}, _T("--:--")); + canvas.DrawText({x, y}, "--:--"); x += time_width; y -= row_height; @@ -89,13 +89,13 @@ FlightListRenderer::Draw(Canvas &canvas, PixelRect rc) { int x = rc.left + padding; - canvas.DrawText({x, y}, _T("Date")); + canvas.DrawText({x, y}, "Date"); x += date_width; - canvas.DrawText({x, y}, _T("Time")); + canvas.DrawText({x, y}, "Time"); x += time_width; x += time_width; - canvas.DrawText({x, y}, _T("Duration")); + canvas.DrawText({x, y}, "Duration"); } } diff --git a/src/Renderer/FlightStatisticsRenderer.cpp b/src/Renderer/FlightStatisticsRenderer.cpp index d0d69cd8219..1b884a904ac 100644 --- a/src/Renderer/FlightStatisticsRenderer.cpp +++ b/src/Renderer/FlightStatisticsRenderer.cpp @@ -187,7 +187,7 @@ FlightStatisticsRenderer::RenderContest(Canvas &canvas, const PixelRect rc, } void -FlightStatisticsRenderer::CaptionContest(TCHAR *sTmp, +FlightStatisticsRenderer::CaptionContest(char *sTmp, const ContestSettings &settings, const DerivedInfo &derived) noexcept { @@ -203,8 +203,8 @@ FlightStatisticsRenderer::CaptionContest(TCHAR *sTmp, StringFormatUnsafe(sTmp, (Layout::landscape - ? _T("%s:\r\n%s\r\n%s (FAI)\r\n%s:\r\n%.1f %s\r\n%s: %s\r\n%s: %s\r\n") - : _T("%s: %s\r\n%s (FAI)\r\n%s: %.1f %s\r\n%s: %s\r\n%s: %s\r\n")), + ? "%s:\r\n%s\r\n%s (FAI)\r\n%s:\r\n%.1f %s\r\n%s: %s\r\n%s: %s\r\n" + : "%s: %s\r\n%s (FAI)\r\n%s: %.1f %s\r\n%s: %s\r\n%s: %s\r\n"), _("Distance"), FormatUserDistanceSmart(result_classic.distance).c_str(), FormatUserDistanceSmart(result_fai.distance).c_str(), @@ -222,8 +222,8 @@ FlightStatisticsRenderer::CaptionContest(TCHAR *sTmp, StringFormatUnsafe(sTmp, (Layout::landscape - ? _T("%s:\r\n%s (Free)\r\n%s (Triangle)\r\n%s:\r\n%.1f %s\r\n%s: %s\r\n%s: %s\r\n") - : _T("%s: %s (Free)\r\n%s (Triangle)\r\n%s: %.1f %s\r\n%s: %s\r\n%s: %s\r\n")), + ? "%s:\r\n%s (Free)\r\n%s (Triangle)\r\n%s:\r\n%.1f %s\r\n%s: %s\r\n%s: %s\r\n" + : "%s: %s (Free)\r\n%s (Triangle)\r\n%s: %.1f %s\r\n%s: %s\r\n%s: %s\r\n"), _("Distance"), FormatUserDistanceSmart(result_free.distance).c_str(), FormatUserDistanceSmart(result_triangle.distance).c_str(), @@ -249,8 +249,8 @@ FlightStatisticsRenderer::CaptionContest(TCHAR *sTmp, StringFormatUnsafe(sTmp, (Layout::landscape - ? _T("%s:\r\n%s\r\n%s:\r\n%.1f %s\r\n%s: %s\r\n%s: %s\r\n") - : _T("%s: %s\r\n%s: %.1f %s\r\n%s: %s\r\n%s: %s\r\n")), + ? "%s:\r\n%s\r\n%s:\r\n%.1f %s\r\n%s: %s\r\n%s: %s\r\n" + : "%s: %s\r\n%s: %.1f %s\r\n%s: %s\r\n%s: %s\r\n"), _("Distance"), FormatUserDistanceSmart(result_olc.distance).c_str(), _("Score"), (double)result_olc.score, _("pts"), @@ -336,14 +336,14 @@ FlightStatisticsRenderer::RenderTask(Canvas &canvas, const PixelRect rc, } void -FlightStatisticsRenderer::CaptionTask(TCHAR *sTmp, const DerivedInfo &derived) noexcept +FlightStatisticsRenderer::CaptionTask(char *sTmp, const DerivedInfo &derived) noexcept { const TaskStats &task_stats = derived.ordered_task_stats; const CommonStats &common = derived.common_stats; if (!task_stats.task_valid || !derived.task_stats.total.remaining.IsDefined()) { - _tcscpy(sTmp, _("No task")); + strcpy(sTmp, _("No task")); } else { const auto d_remaining = derived.task_stats.total.remaining.GetDistance(); if (task_stats.has_targets) { @@ -352,7 +352,7 @@ FlightStatisticsRenderer::CaptionTask(TCHAR *sTmp, const DerivedInfo &derived) n if (Layout::landscape) { StringFormatUnsafe(sTmp, - _T("%s:\r\n %s\r\n%s:\r\n %s\r\n%s:\r\n %5.0f %s\r\n%s:\r\n %5.0f %s\r\n"), + "%s:\r\n %s\r\n%s:\r\n %s\r\n%s:\r\n %5.0f %s\r\n%s:\r\n %5.0f %s\r\n", _("Task to go"), timetext1.c_str(), _("AAT to go"), timetext2.c_str(), _("Distance to go"), @@ -362,7 +362,7 @@ FlightStatisticsRenderer::CaptionTask(TCHAR *sTmp, const DerivedInfo &derived) n Units::GetTaskSpeedName()); } else { StringFormatUnsafe(sTmp, - _T("%s: %s\r\n%s: %s\r\n%s: %5.0f %s\r\n%s: %5.0f %s\r\n"), + "%s: %s\r\n%s: %s\r\n%s: %5.0f %s\r\n%s: %5.0f %s\r\n", _("Task to go"), timetext1.c_str(), _("AAT to go"), timetext2.c_str(), _("Distance to go"), @@ -373,7 +373,7 @@ FlightStatisticsRenderer::CaptionTask(TCHAR *sTmp, const DerivedInfo &derived) n Units::GetTaskSpeedName()); } } else { - StringFormatUnsafe(sTmp, _T("%s: %s\r\n%s: %5.0f %s\r\n"), + StringFormatUnsafe(sTmp, "%s: %s\r\n%s: %5.0f %s\r\n", _("Task to go"), FormatSignedTimeHHMM(task_stats.total.time_remaining_now).c_str(), _("Distance to go"), diff --git a/src/Renderer/FlightStatisticsRenderer.hpp b/src/Renderer/FlightStatisticsRenderer.hpp index ca7a67f20a5..79e7f4caa4c 100644 --- a/src/Renderer/FlightStatisticsRenderer.hpp +++ b/src/Renderer/FlightStatisticsRenderer.hpp @@ -62,8 +62,8 @@ class FlightStatisticsRenderer { const ProtectedTaskManager &task, const TraceComputer *trace_computer) noexcept; - static void CaptionTask(TCHAR *sTmp, const DerivedInfo &derived) noexcept; - static void CaptionContest(TCHAR *sTmp, const ContestSettings &settings, + static void CaptionTask(char *sTmp, const DerivedInfo &derived) noexcept; + static void CaptionContest(char *sTmp, const ContestSettings &settings, const DerivedInfo &derived) noexcept; private: diff --git a/src/Renderer/GlidePolarInfoRenderer.cpp b/src/Renderer/GlidePolarInfoRenderer.cpp index 741761ce248..2308b60b3f3 100644 --- a/src/Renderer/GlidePolarInfoRenderer.cpp +++ b/src/Renderer/GlidePolarInfoRenderer.cpp @@ -27,14 +27,14 @@ RenderGlidePolarInfo(Canvas &canvas, const PixelRect rc, int left = rc.left*0.8 + rc.right*0.2; - text.Format(_T("%s: %s"), _("Mass"), value.c_str()); + text.Format("%s: %s", _("Mass"), value.c_str()); canvas.DrawText({left, rc.bottom - (int)Layout::Scale(50u)}, text); double wl = glide_polar.GetWingLoading(); if (wl != 0) { FormatUserWingLoading(wl, value.buffer(), true); - text.Format(_T("%s: %s"), _("Wing loading"), value.c_str()); + text.Format("%s: %s", _("Wing loading"), value.c_str()); canvas.DrawText({left, rc.bottom - (int)Layout::Scale(35u)}, text); diff --git a/src/Renderer/GlidePolarRenderer.cpp b/src/Renderer/GlidePolarRenderer.cpp index e2dabc38251..835874439e4 100644 --- a/src/Renderer/GlidePolarRenderer.cpp +++ b/src/Renderer/GlidePolarRenderer.cpp @@ -16,16 +16,16 @@ #include void -GlidePolarCaption(TCHAR *sTmp, const GlidePolar &glide_polar) +GlidePolarCaption(char *sTmp, const GlidePolar &glide_polar) { if (!glide_polar.IsValid()) { - *sTmp = _T('\0'); + *sTmp = '\0'; return; } _stprintf(sTmp, Layout::landscape ? - _T("%s:\r\n %d\r\n at %d %s\r\n\r\n%s:\r\n %3.2f %s\r\n at %d %s") : - _T("%s:\r\n %d at %d %s\r\n%s:\r\n %3.2f %s at %d %s"), + "%s:\r\n %d\r\n at %d %s\r\n\r\n%s:\r\n %3.2f %s\r\n at %d %s" : + "%s:\r\n %d at %d %s\r\n%s:\r\n %3.2f %s at %d %s", _("L/D"), (int)glide_polar.GetBestLD(), (int)Units::ToUserSpeed(glide_polar.GetVBestLD()), @@ -44,8 +44,8 @@ RenderGlidePolar(Canvas &canvas, const PixelRect rc, const GlidePolar &glide_polar) { ChartRenderer chart(chart_look, canvas, rc); - chart.SetXLabel(_T("V"), Units::GetSpeedName()); - chart.SetYLabel(_T("w"), Units::GetVerticalSpeedName()); + chart.SetXLabel("V", Units::GetSpeedName()); + chart.SetYLabel("w", Units::GetVerticalSpeedName()); chart.Begin(); if (!glide_polar.IsValid()) { @@ -127,10 +127,10 @@ RenderGlidePolar(Canvas &canvas, const PixelRect rc, // draw labels and other overlays double vv = 0.9*vmax+0.1*vmin; - chart.DrawLabel({vv, -glide_polar.SinkRate(vv)}, _T("Polar")); + chart.DrawLabel({vv, -glide_polar.SinkRate(vv)}, "Polar"); vv = 0.8*vmax+0.2*vmin; - chart.DrawLabel({vv, MACCREADY + slope * vv}, _T("Best glide")); - chart.DrawLabel({v_dolphin_last_l, w_dolphin_last_l},_T("Dolphin")); + chart.DrawLabel({vv, MACCREADY + slope * vv}, "Best glide"); + chart.DrawLabel({v_dolphin_last_l, w_dolphin_last_l},"Dolphin"); RenderGlidePolarInfo(canvas, rc, chart_look, glide_polar); diff --git a/src/Renderer/GlidePolarRenderer.hpp b/src/Renderer/GlidePolarRenderer.hpp index 8ae3188640d..5978700b2bb 100644 --- a/src/Renderer/GlidePolarRenderer.hpp +++ b/src/Renderer/GlidePolarRenderer.hpp @@ -12,7 +12,7 @@ class ClimbHistory; class GlidePolar; void -GlidePolarCaption(TCHAR *buffer, const GlidePolar &glide_polar); +GlidePolarCaption(char *buffer, const GlidePolar &glide_polar); void RenderGlidePolar(Canvas &canvas, const PixelRect rc, diff --git a/src/Renderer/MacCreadyRenderer.cpp b/src/Renderer/MacCreadyRenderer.cpp index 2257e94db88..1b8102d5fd2 100644 --- a/src/Renderer/MacCreadyRenderer.cpp +++ b/src/Renderer/MacCreadyRenderer.cpp @@ -16,15 +16,15 @@ static constexpr double MAX_MACCREADY = 5.2; static constexpr unsigned STEPS_MACCREADY = 25; void -MacCreadyCaption(TCHAR *sTmp, const GlidePolar &glide_polar) +MacCreadyCaption(char *sTmp, const GlidePolar &glide_polar) { if (!glide_polar.IsValid()) { - *sTmp = _T('\0'); + *sTmp = '\0'; return; } _stprintf(sTmp, - _T("%s: %d %s\r\n%s: %d %s"), + "%s: %d %s\r\n%s: %d %s", _("Vopt"), (int)Units::ToUserSpeed(glide_polar.GetVBestLD()), Units::GetSpeedName(), @@ -40,8 +40,8 @@ RenderMacCready(Canvas &canvas, const PixelRect rc, const GlidePolar &glide_polar) { ChartRenderer chart(chart_look, canvas, rc); - chart.SetYLabel(_T("V"), Units::GetSpeedName()); - chart.SetXLabel(_T("MC"), Units::GetVerticalSpeedName()); + chart.SetYLabel("V", Units::GetSpeedName()); + chart.SetXLabel("MC", Units::GetVerticalSpeedName()); chart.Begin(); if (!glide_polar.IsValid()) { @@ -83,9 +83,9 @@ RenderMacCready(Canvas &canvas, const PixelRect rc, // draw labels and other overlays gp.SetMC(0.9*MAX_MACCREADY); - chart.DrawLabel({0.9*MAX_MACCREADY, gp.GetVBestLD()}, _T("Vopt")); + chart.DrawLabel({0.9*MAX_MACCREADY, gp.GetVBestLD()}, "Vopt"); gp.SetMC(0.9*MAX_MACCREADY); - chart.DrawLabel({0.9*MAX_MACCREADY, gp.GetAverageSpeed()}, _T("Vave")); + chart.DrawLabel({0.9*MAX_MACCREADY, gp.GetAverageSpeed()}, "Vave"); chart.Finish(); diff --git a/src/Renderer/MacCreadyRenderer.hpp b/src/Renderer/MacCreadyRenderer.hpp index f24f5ffe8ef..162cd50bc3c 100644 --- a/src/Renderer/MacCreadyRenderer.hpp +++ b/src/Renderer/MacCreadyRenderer.hpp @@ -11,7 +11,7 @@ struct ChartLook; class GlidePolar; void -MacCreadyCaption(TCHAR *sTmp, const GlidePolar &glide_polar); +MacCreadyCaption(char *sTmp, const GlidePolar &glide_polar); void RenderMacCready(Canvas &canvas, const PixelRect rc, diff --git a/src/Renderer/MapItemListRenderer.cpp b/src/Renderer/MapItemListRenderer.cpp index 4e10f26c142..c18d8ae848b 100644 --- a/src/Renderer/MapItemListRenderer.cpp +++ b/src/Renderer/MapItemListRenderer.cpp @@ -53,23 +53,23 @@ Draw(Canvas &canvas, const PixelRect rc, const LocationMapItem &item, const TwoTextRowsRenderer &row_renderer) { - TCHAR info_buffer[256]; + char info_buffer[256]; if (item.vector.IsValid()) - StringFormatUnsafe(info_buffer, _T("%s: %s, %s: %s"), + StringFormatUnsafe(info_buffer, "%s: %s, %s: %s", _("Distance"), FormatUserDistanceSmart(item.vector.distance).c_str(), _("Direction"), FormatBearing(item.vector.bearing).c_str()); else - StringFormatUnsafe(info_buffer, _T("%s: %s, %s: %s"), - _("Distance"), _T("???"), _("Direction"), _T("???")); + StringFormatUnsafe(info_buffer, "%s: %s, %s: %s", + _("Distance"), "???", _("Direction"), "???"); row_renderer.DrawFirstRow(canvas, rc, info_buffer); - StringFormatUnsafe(info_buffer, _T("%s: %s"), _("Elevation"), + StringFormatUnsafe(info_buffer, "%s: %s", _("Elevation"), item.HasElevation() ? FormatUserAltitude(item.elevation).c_str() - : _T("???")); + : "???"); row_renderer.DrawSecondRow(canvas, rc, info_buffer); } @@ -120,7 +120,7 @@ Draw(Canvas &canvas, PixelRect rc, // Format title row - TCHAR altitude_buffer[32]; + char altitude_buffer[32]; StaticString<256> buffer; buffer.clear(); @@ -130,10 +130,10 @@ Draw(Canvas &canvas, PixelRect rc, FormatRelativeUserAltitude(relative_arrival_altitude, altitude_buffer); - buffer.AppendFormat(_T("%s %s, "), altitude_buffer, _("AGL")); + buffer.AppendFormat("%s %s, ", altitude_buffer, _("AGL")); } - buffer.AppendFormat(_T("%s %s"), + buffer.AppendFormat("%s %s", FormatUserAltitude(item.reach.direct).c_str(), _("MSL")); @@ -144,7 +144,7 @@ Draw(Canvas &canvas, PixelRect rc, // Format comment row if (reach_relevant) { - buffer.Format(_T("%s: "), _("around terrain")); + buffer.Format("%s: ", _("around terrain")); if (item.HasElevation()) { int relative_arrival_altitude = @@ -153,16 +153,16 @@ Draw(Canvas &canvas, PixelRect rc, FormatRelativeUserAltitude(relative_arrival_altitude, altitude_buffer); - buffer.AppendFormat(_T("%s %s, "), altitude_buffer, _("AGL")); + buffer.AppendFormat("%s %s, ", altitude_buffer, _("AGL")); } - buffer.AppendFormat(_T("%s %s, "), + buffer.AppendFormat("%s %s, ", FormatUserAltitude(item.reach.terrain).c_str(), _("MSL")); } else if (item.HasElevation() && item.reach.direct >= item.elevation + item.safety_height && item.reach.terrain_valid == ReachResult::Validity::UNREACHABLE) { - buffer.UnsafeFormat(_T("%s "), _("Unreachable due to terrain.")); + buffer.UnsafeFormat("%s ", _("Unreachable due to terrain.")); } else { buffer.clear(); } @@ -254,7 +254,7 @@ Draw(Canvas &canvas, PixelRect rc, if (timespan.count() < 0) timespan += hours{24}; - buffer.Format(_T("%s: %s - left %s ago (%s)"), + buffer.Format("%s: %s - left %s ago (%s)", _("Avg. lift"), FormatUserVerticalSpeed(thermal.lift_rate).c_str(), FormatTimespanSmart(timespan).c_str(), @@ -283,7 +283,7 @@ Draw(Canvas &canvas, PixelRect rc, rc.left += line_height + text_padding; - TCHAR buffer[256]; + char buffer[256]; // Draw details line OrderedTaskPointRadiusLabel(*item.oz, buffer); @@ -330,9 +330,9 @@ Draw(Canvas &canvas, PixelRect rc, title_string = _("FLARM Traffic"); // Append name to the title, if it exists - const TCHAR *callsign = FlarmDetails::LookupCallsign(item.id); + const char *callsign = FlarmDetails::LookupCallsign(item.id); if (callsign != nullptr && !StringIsEmpty(callsign)) { - title_string.append(_T(", ")); + title_string.append(", "); title_string.append(callsign); } @@ -349,11 +349,11 @@ Draw(Canvas &canvas, PixelRect rc, // Generate the line of info about the target, if it's available if (traffic != nullptr) { if (traffic->altitude_available) - info_string.AppendFormat(_T(", %s: %s"), _("Altitude"), + info_string.AppendFormat(", %s: %s", _("Altitude"), FormatUserAltitude(traffic->altitude).c_str()); if (traffic->climb_rate_avg30s_available) { - info_string.AppendFormat(_T(", %s: %s"), _("Vario"), + info_string.AppendFormat(", %s: %s", _("Vario"), FormatUserVerticalSpeed(traffic->climb_rate_avg30s).c_str()); } } diff --git a/src/Renderer/NOAAListRenderer.cpp b/src/Renderer/NOAAListRenderer.cpp index efc53e44667..1663479e027 100644 --- a/src/Renderer/NOAAListRenderer.cpp +++ b/src/Renderer/NOAAListRenderer.cpp @@ -17,11 +17,11 @@ NOAAListRenderer::Draw(Canvas &canvas, const PixelRect rc, title = station.GetCodeT(); if (station.parsed_metar_available && station.parsed_metar.name_available) - title.AppendFormat(_T(": %s"), station.parsed_metar.name.c_str()); + title.AppendFormat(": %s", station.parsed_metar.name.c_str()); row_renderer.DrawFirstRow(canvas, rc, title); - const TCHAR *tmp; + const char *tmp; if (!station.metar_available) tmp = _("No METAR available"); else diff --git a/src/Renderer/TabRenderer.cpp b/src/Renderer/TabRenderer.cpp index d0d4c992a2e..0171e481c6b 100644 --- a/src/Renderer/TabRenderer.cpp +++ b/src/Renderer/TabRenderer.cpp @@ -9,7 +9,7 @@ void TabRenderer::Draw(Canvas &canvas, const PixelRect &rc, const DialogLook &look, - const TCHAR *caption, const MaskedIcon *icon, + const char *caption, const MaskedIcon *icon, bool focused, bool pressed, bool selected) const noexcept { canvas.DrawFilledRectangle(rc, diff --git a/src/Renderer/TabRenderer.hpp b/src/Renderer/TabRenderer.hpp index 26c04aed64f..a3a66d1dc2b 100644 --- a/src/Renderer/TabRenderer.hpp +++ b/src/Renderer/TabRenderer.hpp @@ -31,6 +31,6 @@ class TabRenderer { void Draw(Canvas &canvas, const PixelRect &rc, const DialogLook &look, - const TCHAR *caption, const MaskedIcon *icon, + const char *caption, const MaskedIcon *icon, bool focused, bool pressed, bool selected) const noexcept; }; diff --git a/src/Renderer/TaskLegRenderer.cpp b/src/Renderer/TaskLegRenderer.cpp index 1fb300e2510..58195cb6bec 100644 --- a/src/Renderer/TaskLegRenderer.cpp +++ b/src/Renderer/TaskLegRenderer.cpp @@ -43,7 +43,7 @@ RenderTaskLegs(ChartRenderer &chart, if (!task_stats.start.HasStarted()) return; - TCHAR sTmp[5]; + char sTmp[5]; const OrderedTask &task = task_manager.GetOrderedTask(); for (unsigned i = 0, n = task.TaskSize(); i < n; ++i) { @@ -66,7 +66,7 @@ RenderTaskLegs(ChartRenderer &chart, ChartLook::STYLE_GRIDZERO); } if (y>=0) { - StringFormatUnsafe(sTmp, _T("%d"), i); + StringFormatUnsafe(sTmp, "%d", i); chart.DrawLabel({x, chart.GetYMax()*y + chart.GetYMin()*(1-y)}, sTmp); } diff --git a/src/Renderer/TaskSpeedRenderer.cpp b/src/Renderer/TaskSpeedRenderer.cpp index df7a3d4d0fc..306ca70e244 100644 --- a/src/Renderer/TaskSpeedRenderer.cpp +++ b/src/Renderer/TaskSpeedRenderer.cpp @@ -15,17 +15,17 @@ #include "Engine/GlideSolvers/GlidePolar.hpp" void -TaskSpeedCaption(TCHAR *sTmp, +TaskSpeedCaption(char *sTmp, const FlightStatistics &fs, const GlidePolar &glide_polar) { if (!glide_polar.IsValid() || fs.task_speed.IsEmpty()) { - *sTmp = _T('\0'); + *sTmp = '\0'; return; } _stprintf(sTmp, - _T("%s: %d %s\r\n%s: %d %s"), + "%s: %d %s\r\n%s: %d %s", _("Vave"), (int)Units::ToUserTaskSpeed(fs.task_speed.GetAverageY()), Units::GetTaskSpeedName(), @@ -44,8 +44,8 @@ RenderSpeed(Canvas &canvas, const PixelRect rc, const GlidePolar &glide_polar) { ChartRenderer chart(chart_look, canvas, rc); - chart.SetXLabel(_T("t"), _T("hr")); - chart.SetYLabel(_T("V"), Units::GetTaskSpeedName()); + chart.SetXLabel("t", "hr"); + chart.SetYLabel("V", Units::GetTaskSpeedName()); chart.Begin(); if (!fs.task_speed.HasResult() || !task.CheckOrderedTask()) { @@ -93,10 +93,10 @@ RenderSpeed(Canvas &canvas, const PixelRect rc, chart.DrawTrend(fs.task_speed, ChartLook::STYLE_BLUETHINDASH); chart.DrawLabel({chart.GetXMin()*0.9+chart.GetXMax()*0.1, vref}, - _T("Vest")); + "Vest"); const double tref = chart.GetXMin()*0.5+chart.GetXMax()*0.5; - chart.DrawLabel({tref, fs.task_speed.GetYAt(tref)}, _T("Vave")); + chart.DrawLabel({tref, fs.task_speed.GetYAt(tref)}, "Vave"); chart.Finish(); } diff --git a/src/Renderer/TaskSpeedRenderer.hpp b/src/Renderer/TaskSpeedRenderer.hpp index 57e915c5e60..19cc704778d 100644 --- a/src/Renderer/TaskSpeedRenderer.hpp +++ b/src/Renderer/TaskSpeedRenderer.hpp @@ -15,7 +15,7 @@ class GlidePolar; #include void -TaskSpeedCaption(TCHAR *sTmp, +TaskSpeedCaption(char *sTmp, const FlightStatistics &fs, const GlidePolar &glide_polar); diff --git a/src/Renderer/TextButtonRenderer.cpp b/src/Renderer/TextButtonRenderer.cpp index 5e6c712ba33..f46f43990d7 100644 --- a/src/Renderer/TextButtonRenderer.cpp +++ b/src/Renderer/TextButtonRenderer.cpp @@ -8,7 +8,7 @@ unsigned TextButtonRenderer::GetMinimumButtonWidth(const ButtonLook &look, - tstring_view caption) noexcept + std::string_view caption) noexcept { return 2 * (ButtonFrameRenderer::GetMargin() + Layout::GetTextPadding()) + look.font->TextSize(caption).width; diff --git a/src/Renderer/TextButtonRenderer.hpp b/src/Renderer/TextButtonRenderer.hpp index b17d91d11db..f9ab4c43b3f 100644 --- a/src/Renderer/TextButtonRenderer.hpp +++ b/src/Renderer/TextButtonRenderer.hpp @@ -36,7 +36,7 @@ class TextButtonRenderer : public ButtonRenderer { [[gnu::pure]] static unsigned GetMinimumButtonWidth(const ButtonLook &look, - tstring_view caption) noexcept; + std::string_view caption) noexcept; const ButtonLook &GetLook() const noexcept { return frame_renderer.GetLook(); diff --git a/src/Renderer/TextInBox.cpp b/src/Renderer/TextInBox.cpp index d42c1325bde..6eb4878ed16 100644 --- a/src/Renderer/TextInBox.cpp +++ b/src/Renderer/TextInBox.cpp @@ -52,7 +52,7 @@ TextInBoxMoveInView(PixelRect &rc, const PixelRect &map_rc) noexcept } static void -RenderShadowedText(Canvas &canvas, const TCHAR *text, +RenderShadowedText(Canvas &canvas, const char *text, PixelPoint p, bool inverted) noexcept { @@ -71,7 +71,7 @@ RenderShadowedText(Canvas &canvas, const TCHAR *text, // returns true if really wrote something bool -TextInBox(Canvas &canvas, const TCHAR *text, PixelPoint p, +TextInBox(Canvas &canvas, const char *text, PixelPoint p, TextInBoxMode mode, const PixelRect &map_rc, LabelBlock *label_block) noexcept { @@ -144,7 +144,7 @@ TextInBox(Canvas &canvas, const TCHAR *text, PixelPoint p, } bool -TextInBox(Canvas &canvas, const TCHAR *text, PixelPoint p, +TextInBox(Canvas &canvas, const char *text, PixelPoint p, TextInBoxMode mode, PixelSize screen_size, LabelBlock *label_block) noexcept diff --git a/src/Renderer/TextInBox.hpp b/src/Renderer/TextInBox.hpp index 111df0c1e86..18c05f1a11d 100644 --- a/src/Renderer/TextInBox.hpp +++ b/src/Renderer/TextInBox.hpp @@ -33,12 +33,12 @@ struct TextInBoxMode { }; bool -TextInBox(Canvas &canvas, const TCHAR *value, PixelPoint p, +TextInBox(Canvas &canvas, const char *value, PixelPoint p, TextInBoxMode mode, const PixelRect &map_rc, LabelBlock *label_block=nullptr) noexcept; bool -TextInBox(Canvas &canvas, const TCHAR *value, PixelPoint p, +TextInBox(Canvas &canvas, const char *value, PixelPoint p, TextInBoxMode mode, PixelSize screen_size, LabelBlock *label_block=nullptr) noexcept; diff --git a/src/Renderer/TextRenderer.cpp b/src/Renderer/TextRenderer.cpp index 18ca85415dd..c69cad66ee8 100644 --- a/src/Renderer/TextRenderer.cpp +++ b/src/Renderer/TextRenderer.cpp @@ -10,21 +10,21 @@ unsigned TextRenderer::GetHeight(Canvas &canvas, PixelRect rc, - tstring_view text) const noexcept + std::string_view text) const noexcept { return canvas.DrawFormattedText(rc, text, DT_CALCRECT); } unsigned TextRenderer::GetHeight(Canvas &canvas, unsigned width, - tstring_view text) const noexcept + std::string_view text) const noexcept { return GetHeight(canvas, PixelRect(0, 0, width, 0), text); } unsigned TextRenderer::GetHeight(const Font &font, unsigned width, - tstring_view text) const noexcept + std::string_view text) const noexcept { AnyCanvas canvas; canvas.Select(font); @@ -33,7 +33,7 @@ TextRenderer::GetHeight(const Font &font, unsigned width, void TextRenderer::Draw(Canvas &canvas, PixelRect rc, - tstring_view text) const noexcept + std::string_view text) const noexcept { unsigned format = (center ? DT_CENTER : DT_LEFT); diff --git a/src/Renderer/TextRenderer.hpp b/src/Renderer/TextRenderer.hpp index 7e5670367dc..a1b43048c36 100644 --- a/src/Renderer/TextRenderer.hpp +++ b/src/Renderer/TextRenderer.hpp @@ -3,7 +3,7 @@ #pragma once -#include "util/tstring_view.hxx" +#include struct PixelRect; class Canvas; @@ -38,15 +38,15 @@ class TextRenderer { [[gnu::pure]] unsigned GetHeight(Canvas &canvas, PixelRect rc, - tstring_view text) const noexcept; + std::string_view text) const noexcept; [[gnu::pure]] unsigned GetHeight(Canvas &canvas, unsigned width, - tstring_view text) const noexcept; + std::string_view text) const noexcept; [[gnu::pure]] unsigned GetHeight(const Font &font, unsigned width, - tstring_view text) const noexcept; + std::string_view text) const noexcept; - void Draw(Canvas &canvas, PixelRect rc, tstring_view text) const noexcept; + void Draw(Canvas &canvas, PixelRect rc, std::string_view text) const noexcept; }; diff --git a/src/Renderer/TextRowRenderer.cpp b/src/Renderer/TextRowRenderer.cpp index babb57839dc..1a9081e48d5 100644 --- a/src/Renderer/TextRowRenderer.cpp +++ b/src/Renderer/TextRowRenderer.cpp @@ -24,7 +24,7 @@ TextRowRenderer::CalculateLayout(const Font &font) noexcept void TextRowRenderer::DrawTextRow(Canvas &canvas, const PixelRect &rc, - const TCHAR *text) const noexcept + const char *text) const noexcept { canvas.DrawClippedText(rc.GetTopLeft() + PixelSize{left_padding, top_padding}, rc, text); @@ -32,7 +32,7 @@ TextRowRenderer::DrawTextRow(Canvas &canvas, const PixelRect &rc, int TextRowRenderer::NextColumn(Canvas &canvas, const PixelRect &rc, - const TCHAR *text) const noexcept + const char *text) const noexcept { return std::min(rc.left + int(2 * left_padding + canvas.CalcTextWidth(text)), rc.right); @@ -40,7 +40,7 @@ TextRowRenderer::NextColumn(Canvas &canvas, const PixelRect &rc, int TextRowRenderer::DrawColumn(Canvas &canvas, const PixelRect &rc, - const TCHAR *text) const noexcept + const char *text) const noexcept { DrawTextRow(canvas, rc, text); return NextColumn(canvas, rc, text); @@ -48,7 +48,7 @@ TextRowRenderer::DrawColumn(Canvas &canvas, const PixelRect &rc, int TextRowRenderer::PreviousRightColumn(Canvas &canvas, const PixelRect &rc, - const TCHAR *text) const noexcept + const char *text) const noexcept { int text_width = canvas.CalcTextWidth(text); int x = rc.right - int(left_padding + text_width); @@ -62,7 +62,7 @@ TextRowRenderer::PreviousRightColumn(Canvas &canvas, const PixelRect &rc, int TextRowRenderer::DrawRightColumn(Canvas &canvas, const PixelRect &rc, - const TCHAR *text) const noexcept + const char *text) const noexcept { int text_width = canvas.CalcTextWidth(text); int x = rc.right - int(left_padding + text_width); diff --git a/src/Renderer/TextRowRenderer.hpp b/src/Renderer/TextRowRenderer.hpp index 0f54590d6b1..b034cc1ad7e 100644 --- a/src/Renderer/TextRowRenderer.hpp +++ b/src/Renderer/TextRowRenderer.hpp @@ -22,7 +22,7 @@ class TextRowRenderer { unsigned CalculateLayout(const Font &font) noexcept; void DrawTextRow(Canvas &canvas, const PixelRect &rc, - const TCHAR *text) const noexcept; + const char *text) const noexcept; /** * Returns the minimum X coordinate of the column after the given @@ -30,13 +30,13 @@ class TextRowRenderer { */ [[gnu::pure]] int NextColumn(Canvas &canvas, const PixelRect &rc, - const TCHAR *text) const noexcept; + const char *text) const noexcept; /** * Combine DrawTextRow() and NextColumn(). */ int DrawColumn(Canvas &canvas, const PixelRect &rc, - const TCHAR *text) const noexcept; + const char *text) const noexcept; /** * Returns the maximum X coordinate of the column before the given @@ -44,12 +44,12 @@ class TextRowRenderer { */ [[gnu::pure]] int PreviousRightColumn(Canvas &canvas, const PixelRect &rc, - const TCHAR *text) const noexcept; + const char *text) const noexcept; /** * Draws a right-aligned column and returns the new "right" * coordinate. */ int DrawRightColumn(Canvas &canvas, const PixelRect &rc, - const TCHAR *text) const noexcept; + const char *text) const noexcept; }; diff --git a/src/Renderer/ThermalBandRenderer.cpp b/src/Renderer/ThermalBandRenderer.cpp index d2b116b81a1..cdc0d375872 100644 --- a/src/Renderer/ThermalBandRenderer.cpp +++ b/src/Renderer/ThermalBandRenderer.cpp @@ -133,7 +133,7 @@ ThermalBandRenderer::DrawRiskMC(const DerivedInfo &calculated, chart.DrawLineGraph(tmp, (is_map || is_infobox)? ChartLook::STYLE_WHITE: ChartLook::STYLE_REDTHICKDASH); if (!is_map && !is_infobox) { - chart.DrawLabel({rmc, h_m}, _T("MC")); + chart.DrawLabel({rmc, h_m}, "MC"); } } @@ -225,8 +225,8 @@ ThermalBandRenderer::DrawThermalBand(const MoreData &basic, { ChartRenderer chart(chart_look, canvas, rc, !is_map); if (!is_map) { - chart.SetXLabel(_T("w"), Units::GetVerticalSpeedName()); - chart.SetYLabel(_T("h AGL"), Units::GetAltitudeName()); + chart.SetXLabel("w", Units::GetVerticalSpeedName()); + chart.SetYLabel("h AGL", Units::GetAltitudeName()); } chart.Begin(); diff --git a/src/Renderer/TwoTextRowsRenderer.cpp b/src/Renderer/TwoTextRowsRenderer.cpp index 9f134eb887e..5ab5d21f3c6 100644 --- a/src/Renderer/TwoTextRowsRenderer.cpp +++ b/src/Renderer/TwoTextRowsRenderer.cpp @@ -33,7 +33,7 @@ TwoTextRowsRenderer::CalculateLayout(const Font &_first_font, void TwoTextRowsRenderer::DrawFirstRow(Canvas &canvas, const PixelRect &rc, - const TCHAR *text) const noexcept + const char *text) const noexcept { canvas.Select(*first_font); canvas.DrawClippedText({rc.left + x, rc.top + first_y}, rc, text); @@ -41,7 +41,7 @@ TwoTextRowsRenderer::DrawFirstRow(Canvas &canvas, const PixelRect &rc, void TwoTextRowsRenderer::DrawSecondRow(Canvas &canvas, const PixelRect &rc, - const TCHAR *text) const noexcept + const char *text) const noexcept { canvas.Select(*second_font); canvas.DrawClippedText({rc.left + x, rc.top + second_y}, rc, text); @@ -49,7 +49,7 @@ TwoTextRowsRenderer::DrawSecondRow(Canvas &canvas, const PixelRect &rc, int TwoTextRowsRenderer::DrawRightFirstRow(Canvas &canvas, const PixelRect &rc, - const TCHAR *text) const noexcept + const char *text) const noexcept { canvas.Select(*second_font); int text_width = canvas.CalcTextWidth(text); @@ -65,7 +65,7 @@ TwoTextRowsRenderer::DrawRightFirstRow(Canvas &canvas, const PixelRect &rc, int TwoTextRowsRenderer::DrawRightSecondRow(Canvas &canvas, const PixelRect &rc, - const TCHAR *text) const noexcept + const char *text) const noexcept { canvas.Select(*second_font); int text_width = canvas.CalcTextWidth(text); diff --git a/src/Renderer/TwoTextRowsRenderer.hpp b/src/Renderer/TwoTextRowsRenderer.hpp index ada8a4346cc..b914462510f 100644 --- a/src/Renderer/TwoTextRowsRenderer.hpp +++ b/src/Renderer/TwoTextRowsRenderer.hpp @@ -45,10 +45,10 @@ class TwoTextRowsRenderer { } void DrawFirstRow(Canvas &canvas, const PixelRect &rc, - const TCHAR *text) const noexcept; + const char *text) const noexcept; void DrawSecondRow(Canvas &canvas, const PixelRect &rc, - const TCHAR *text) const noexcept; + const char *text) const noexcept; /** * Draws a right-aligned column in the first row (but with the @@ -56,12 +56,12 @@ class TwoTextRowsRenderer { * coordinate. */ int DrawRightFirstRow(Canvas &canvas, const PixelRect &rc, - const TCHAR *text) const noexcept; + const char *text) const noexcept; /** * Draws a right-aligned column in the second row and returns the * new "right" coordinate. */ int DrawRightSecondRow(Canvas &canvas, const PixelRect &rc, - const TCHAR *text) const noexcept; + const char *text) const noexcept; }; diff --git a/src/Renderer/UnitSymbolRenderer.cpp b/src/Renderer/UnitSymbolRenderer.cpp index cb5f43a415e..e1037748d6d 100644 --- a/src/Renderer/UnitSymbolRenderer.cpp +++ b/src/Renderer/UnitSymbolRenderer.cpp @@ -11,40 +11,40 @@ #include struct UnitSymbolStrings { - const TCHAR *line1; - const TCHAR *line2; + const char *line1; + const char *line2; bool is_fraction; }; static constexpr UnitSymbolStrings symbol_strings[] = { { nullptr, nullptr }, - { nullptr, _T("km"), false }, - { nullptr, _T("NM"), false }, - { nullptr, _T("mi"), false }, - { _T("km"), _T("h"), true }, - { nullptr, _T("kt"), false }, - { _T("mp"), _T("h"), false }, - { _T("m"), _T("s"), true }, - { _T("ft"), _T("min"), true }, - { nullptr, _T("m"), false }, - { nullptr, _T("ft"), false }, - { nullptr, _T("FL"), false }, - { nullptr, _T("K"), false }, - { _T(DEG), _T("C"), false }, - { _T(DEG), _T("F"), false }, - { _T("h"), _T("Pa"), false }, - { nullptr, _T("mb"), false }, - { _T("mm"), _T("Hg"), false }, - { _T("in"), _T("Hg"), false }, - { _T("kg"), _T("m²"), true }, - { _T("lb"), _T("ft²"), true }, - { nullptr, _T("kg"), false }, - { nullptr, _T("lb"), false }, - { _T("%"), _T(" "), false }, - { nullptr, _T(":1"), false }, - { nullptr, _T("V"), false }, - { nullptr, _T("Hz"), false }, - { nullptr, _T("rpm"), false }, + { nullptr, "km", false }, + { nullptr, "NM", false }, + { nullptr, "mi", false }, + { "km", "h", true }, + { nullptr, "kt", false }, + { "mp", "h", false }, + { "m", "s", true }, + { "ft", "min", true }, + { nullptr, "m", false }, + { nullptr, "ft", false }, + { nullptr, "FL", false }, + { nullptr, "K", false }, + { DEG, "C", false }, + { DEG, "F", false }, + { "h", "Pa", false }, + { nullptr, "mb", false }, + { "mm", "Hg", false }, + { "in", "Hg", false }, + { "kg", "m²", true }, + { "lb", "ft²", true }, + { nullptr, "kg", false }, + { nullptr, "lb", false }, + { "%", " ", false }, + { nullptr, ":1", false }, + { nullptr, "V", false }, + { nullptr, "Hz", false }, + { nullptr, "rpm", false }, }; static_assert(ARRAY_SIZE(symbol_strings) == (size_t)Unit::COUNT, diff --git a/src/Renderer/VarioBarRenderer.cpp b/src/Renderer/VarioBarRenderer.cpp index 8c829282f80..ee1a8ca414a 100644 --- a/src/Renderer/VarioBarRenderer.cpp +++ b/src/Renderer/VarioBarRenderer.cpp @@ -41,7 +41,7 @@ VarioBarRenderer::Draw(Canvas &canvas, const PixelRect &rc, { 0, 0 }, { 9, -9 }, { 18, 0 }, { 18, -2 }, { 9, -11 }, { 0, -2 } }; - TCHAR Value[10]; + char Value[10]; const int y0 = (rc.bottom + rc.top) / 2; diff --git a/src/Renderer/VarioHistogramRenderer.cpp b/src/Renderer/VarioHistogramRenderer.cpp index 9fef157d17a..548169280cb 100644 --- a/src/Renderer/VarioHistogramRenderer.cpp +++ b/src/Renderer/VarioHistogramRenderer.cpp @@ -24,7 +24,7 @@ RenderVarioHistogram(Canvas &canvas, const PixelRect rc, const GlidePolar &glide_polar) { ChartRenderer chart(chart_look, canvas, rc); - chart.SetYLabel(_T("w"), Units::GetVerticalSpeedName()); + chart.SetYLabel("w", Units::GetVerticalSpeedName()); chart.Begin(); if (fs.vario_cruise_histogram.empty() && @@ -92,8 +92,8 @@ RenderVarioHistogram(Canvas &canvas, const PixelRect rc, chart.DrawYGrid(Units::ToSysVSpeed(1), 1, ChartRenderer::UnitFormat::NUMERIC); const double tref = chart.GetXMin()*0.1+chart.GetXMax()*0.9; - chart.DrawLabel({tref, mc}, _T("MC")); - chart.DrawLabel({tref, s}, _T("S cruise")); + chart.DrawLabel({tref, mc}, "MC"); + chart.DrawLabel({tref, s}, "S cruise"); chart.Finish(); } diff --git a/src/Renderer/WaypointLabelList.cpp b/src/Renderer/WaypointLabelList.cpp index 43c50227028..a0929dccb68 100644 --- a/src/Renderer/WaypointLabelList.cpp +++ b/src/Renderer/WaypointLabelList.cpp @@ -46,7 +46,7 @@ MapWaypointLabelListCompare(const WaypointLabelList::Label &e1, } void -WaypointLabelList::Add(const TCHAR *Name, PixelPoint p, +WaypointLabelList::Add(const char *Name, PixelPoint p, TextInBoxMode Mode, bool bold, int AltArivalAGL, bool inTask, bool isLandable, bool isAirport, diff --git a/src/Renderer/WaypointLabelList.hpp b/src/Renderer/WaypointLabelList.hpp index f66f56b4b90..2c840931e4d 100644 --- a/src/Renderer/WaypointLabelList.hpp +++ b/src/Renderer/WaypointLabelList.hpp @@ -17,7 +17,7 @@ class WaypointLabelList : private NonCopyable { public: struct Label{ - TCHAR Name[NAME_SIZE+1]; + char Name[NAME_SIZE+1]; PixelPoint Pos; TextInBoxMode Mode; int AltArivalAGL; @@ -41,7 +41,7 @@ class WaypointLabelList : private NonCopyable { clip_rect.right += WPCIRCLESIZE * 2; } - void Add(const TCHAR *name, PixelPoint p, + void Add(const char *name, PixelPoint p, TextInBoxMode Mode, bool bold, int AltArivalAGL, bool inTask, bool isLandable, bool isAirport, diff --git a/src/Renderer/WaypointListRenderer.cpp b/src/Renderer/WaypointListRenderer.cpp index ee4ebc61073..0697f32bb07 100644 --- a/src/Renderer/WaypointListRenderer.cpp +++ b/src/Renderer/WaypointListRenderer.cpp @@ -20,19 +20,19 @@ static void FormatWaypointDetails(Buffer &buffer, const Waypoint &waypoint) { if (waypoint.has_elevation) - buffer.Format(_T("%s: %s"), _("Elevation"), + buffer.Format("%s: %s", _("Elevation"), FormatUserAltitude(waypoint.elevation).c_str()); else - buffer.Format(_T("%s: %s"), _("Elevation"), _T("?")); + buffer.Format("%s: %s", _("Elevation"), "?"); if (waypoint.radio_frequency.IsDefined()) { - TCHAR radio[16]; + char radio[16]; waypoint.radio_frequency.Format(radio, 16); - buffer.AppendFormat(_T(" - %s MHz"), radio); + buffer.AppendFormat(" - %s MHz", radio); } if (!waypoint.comment.empty()) { - buffer.AppendFormat(_T(" - %s"), waypoint.comment.c_str()); + buffer.AppendFormat(" - %s", waypoint.comment.c_str()); } } @@ -74,7 +74,7 @@ Draw(Canvas &canvas, PixelRect rc, // Draw waypoint name if (!waypoint.shortname.empty()) { const auto waypoint_title = waypoint.name + - _T(" (") + waypoint.shortname + _T(")"); + " (" + waypoint.shortname + ")"; row_renderer.DrawFirstRow(canvas, rc, waypoint_title.c_str()); } else { @@ -128,16 +128,16 @@ WaypointListRenderer::Draw(Canvas &canvas, PixelRect rc, // Draw distance and arrival altitude StaticString<256> buffer; - TCHAR alt[20], radio[20]; + char alt[20], radio[20]; FormatRelativeUserAltitude(arrival_altitude, alt, true); - buffer.Format(_T("%s: %s - %s: %s"), _("Distance"), + buffer.Format("%s: %s - %s: %s", _("Distance"), FormatUserDistanceSmart(distance).c_str(), _("Arrival Alt"), alt); if (waypoint.radio_frequency.IsDefined()) { waypoint.radio_frequency.Format(radio, ARRAY_SIZE(radio)); - buffer.AppendFormat(_T(" - %s MHz"), radio); + buffer.AppendFormat(" - %s MHz", radio); } row_renderer.DrawSecondRow(canvas, rc, buffer); @@ -145,7 +145,7 @@ WaypointListRenderer::Draw(Canvas &canvas, PixelRect rc, // Draw waypoint name if (!waypoint.shortname.empty()) { const auto waypoint_title = waypoint.name + - _(" (") + waypoint.shortname + _T(")"); + _(" (") + waypoint.shortname + ")"; row_renderer.DrawFirstRow(canvas, rc, waypoint_title.c_str()); } else { diff --git a/src/Renderer/WaypointRenderer.cpp b/src/Renderer/WaypointRenderer.cpp index 2733906b220..569d968aa9a 100644 --- a/src/Renderer/WaypointRenderer.cpp +++ b/src/Renderer/WaypointRenderer.cpp @@ -134,7 +134,7 @@ class WaypointVisitorMap final const TaskBehaviour &task_behaviour; const MoreData &basic; - TCHAR altitude_unit[4]; + char altitude_unit[4]; bool task_valid; /** @@ -168,14 +168,14 @@ class WaypointVisitorMap final projection.GetScreenAngle()), labels(projection.GetScreenRect()) { - _tcscpy(altitude_unit, Units::GetAltitudeName()); + strcpy(altitude_unit, Units::GetAltitudeName()); } protected: - void FormatTitle(TCHAR *buffer, size_t buffer_size, + void FormatTitle(char *buffer, size_t buffer_size, const Waypoint &way_point) const noexcept { - buffer[0] = _T('\0'); + buffer[0] = '\0'; switch (settings.display_text_type) { case WaypointRendererSettings::DisplayTextType::NAME: @@ -196,8 +196,8 @@ class WaypointVisitorMap final case WaypointRendererSettings::DisplayTextType::FIRST_WORD: CopyTruncateString(buffer, buffer_size, way_point.name.c_str()); - TCHAR *tmp; - tmp = _tcsstr(buffer, _T(" ")); + char *tmp; + tmp = strstr(buffer, " "); if (tmp != nullptr) tmp[0] = '\0'; break; @@ -216,7 +216,7 @@ class WaypointVisitorMap final } } - void FormatLabel(TCHAR *buffer, size_t buffer_size, + void FormatLabel(char *buffer, size_t buffer_size, const Waypoint &way_point, WaypointReachability reachable, const ReachResult &reach) const noexcept { @@ -243,19 +243,19 @@ class WaypointVisitorMap final if (!GradientValid(gr)) return; - size_t length = _tcslen(buffer); + size_t length = strlen(buffer); if (length > 0) - buffer[length++] = _T(':'); + buffer[length++] = ':'; if (settings.arrival_height_display == WaypointRendererSettings::ArrivalHeightDisplay::REQUIRED_GR_AND_TERRAIN && reach.IsReachableTerrain()) { int uah_terrain = (int)Units::ToUserAltitude(reach.terrain); - StringFormatUnsafe(buffer + length, _T("%.1f/%d%s"), (double) gr, + StringFormatUnsafe(buffer + length, "%.1f/%d%s", (double) gr, uah_terrain, altitude_unit); return; } - StringFormatUnsafe(buffer + length, _T("%.1f"), (double) gr); + StringFormatUnsafe(buffer + length, "%.1f", (double) gr); return; } @@ -268,32 +268,32 @@ class WaypointVisitorMap final if (settings.arrival_height_display == WaypointRendererSettings::ArrivalHeightDisplay::NONE) return; - size_t length = _tcslen(buffer); + size_t length = strlen(buffer); int uah_glide = (int)Units::ToUserAltitude(reach.direct); int uah_terrain = (int)Units::ToUserAltitude(reach.terrain); if (settings.arrival_height_display == WaypointRendererSettings::ArrivalHeightDisplay::TERRAIN) { if (reach.IsReachableTerrain()) { if (length > 0) - buffer[length++] = _T(':'); - StringFormatUnsafe(buffer + length, _T("%d%s"), + buffer[length++] = ':'; + StringFormatUnsafe(buffer + length, "%d%s", uah_terrain, altitude_unit); } return; } if (length > 0) - buffer[length++] = _T(':'); + buffer[length++] = ':'; if (settings.arrival_height_display == WaypointRendererSettings::ArrivalHeightDisplay::GLIDE_AND_TERRAIN && reach.IsReachableDirect() && reach.IsReachableTerrain() && reach.IsDeltaConsiderable()) { - StringFormatUnsafe(buffer + length, _T("%d/%d%s"), uah_glide, + StringFormatUnsafe(buffer + length, "%d/%d%s", uah_glide, uah_terrain, altitude_unit); return; } - StringFormatUnsafe(buffer + length, _T("%d%s"), uah_glide, altitude_unit); + StringFormatUnsafe(buffer + length, "%d%s", uah_glide, altitude_unit); } void DrawWaypoint(const VisibleWaypoint &vwp) noexcept { @@ -342,7 +342,7 @@ class WaypointVisitorMap final text_mode.move_in_view = true; } - TCHAR buffer[NAME_SIZE+1]; + char buffer[NAME_SIZE+1]; FormatLabel(buffer, ARRAY_SIZE(buffer), way_point, vwp.reachable, vwp.reach); diff --git a/src/Renderer/WindArrowRenderer.cpp b/src/Renderer/WindArrowRenderer.cpp index 6248c507d0d..23eb69360a9 100644 --- a/src/Renderer/WindArrowRenderer.cpp +++ b/src/Renderer/WindArrowRenderer.cpp @@ -11,6 +11,7 @@ #include "Math/Util.hpp" #include "Math/Screen.hpp" #include "NMEA/Derived.hpp" +#include "NMEA/MoreData.hpp" #include "Units/Units.hpp" #include "util/Macros.hpp" #include "MapSettings.hpp" @@ -27,7 +28,8 @@ WindArrowRenderer::DrawArrow(Canvas &canvas, PixelPoint pos, Angle angle, unsigned tail_length, WindArrowStyle arrow_style, int offset, - unsigned scale) noexcept + unsigned scale, + const Brush &brush) noexcept { // Draw arrow @@ -42,7 +44,7 @@ WindArrowRenderer::DrawArrow(Canvas &canvas, PixelPoint pos, Angle angle, PolygonRotateShift({arrow, ARRAY_SIZE(arrow)}, pos, angle, scale); canvas.Select(look.arrow_pen); - canvas.Select(look.arrow_brush); + canvas.Select(brush); { #ifdef ENABLE_OPENGL const ScopeAlphaBlend alpha_blend; @@ -68,8 +70,8 @@ WindArrowRenderer::DrawArrow(Canvas &canvas, PixelPoint pos, Angle angle, void WindArrowRenderer::Draw(Canvas &canvas, const Angle screen_angle, const SpeedVector wind, const PixelPoint pos, - const PixelRect &rc, - WindArrowStyle arrow_style) noexcept + const PixelRect &rc, WindArrowStyle arrow_style, + const Brush &brush) noexcept { constexpr unsigned arrow_width = 6; constexpr unsigned arrow_tail_length = 3; @@ -85,12 +87,11 @@ WindArrowRenderer::Draw(Canvas &canvas, const Angle screen_angle, arrow_width, length, arrow_tail_length, arrow_style, arrow_offset, - scale); + scale, brush); // Draw wind speed label - StaticString<12> buffer; - buffer.Format(_T("%i"), iround(Units::ToUserWindSpeed(wind.norm))); + buffer.Format("%i", iround(Units::ToUserWindSpeed(wind.norm))); canvas.SetTextColor(COLOR_BLACK); canvas.Select(*look.font); @@ -111,7 +112,7 @@ WindArrowRenderer::Draw(Canvas &canvas, const Angle screen_angle, void WindArrowRenderer::Draw(Canvas &canvas, const Angle screen_angle, const PixelPoint pos, const PixelRect &rc, - const DerivedInfo &calculated, + const DerivedInfo &calculated, const MoreData &basic, const MapSettings &settings) noexcept { if (!calculated.wind_available || @@ -123,5 +124,17 @@ WindArrowRenderer::Draw(Canvas &canvas, const Angle screen_angle, return; WindArrowRenderer::Draw(canvas, screen_angle, calculated.wind, pos, rc, - settings.wind_arrow_style); + settings.wind_arrow_style, + (calculated.wind_source == + DerivedInfo::WindSource::EXTERNAL) ? + look.arrow_brush_extern : look.arrow_brush); + + if (!basic.external_instantaneous_wind_available) { + return; + } + + WindArrowRenderer::Draw(canvas, screen_angle, + basic.external_instantaneous_wind, pos, rc, + settings.wind_arrow_style, + look.arrow_brush_instantaneous); } diff --git a/src/Renderer/WindArrowRenderer.hpp b/src/Renderer/WindArrowRenderer.hpp index a683956892e..7b3f5e8ebe2 100644 --- a/src/Renderer/WindArrowRenderer.hpp +++ b/src/Renderer/WindArrowRenderer.hpp @@ -7,12 +7,14 @@ class Canvas; class Angle; +class Brush; struct PixelPoint; struct PixelRect; struct WindArrowLook; struct SpeedVector; struct DerivedInfo; struct MapSettings; +struct MoreData; enum class WindArrowStyle : uint8_t; class WindArrowRenderer { @@ -23,15 +25,16 @@ class WindArrowRenderer { :look(_look) {} void Draw(Canvas &canvas, Angle screen_angle, SpeedVector wind, - PixelPoint pos, const PixelRect &rc, WindArrowStyle arrow_style) noexcept; + PixelPoint pos, const PixelRect &rc, WindArrowStyle arrow_style, + const Brush &brush) noexcept; void Draw(Canvas &canvas, Angle screen_angle, PixelPoint pos, const PixelRect &rc, const DerivedInfo &calculated, - const MapSettings &settings) noexcept; + const MoreData &basic, const MapSettings &settings) noexcept; void DrawArrow(Canvas &canvas, PixelPoint pos, Angle angle, unsigned width, unsigned length, unsigned tail_length, WindArrowStyle arrow_style, - int offset, - unsigned scale) noexcept; + int offset, unsigned scale, + const Brush &brush) noexcept; }; diff --git a/src/Renderer/WindChartRenderer.cpp b/src/Renderer/WindChartRenderer.cpp index 8366c3357e3..3442ce835b6 100644 --- a/src/Renderer/WindChartRenderer.cpp +++ b/src/Renderer/WindChartRenderer.cpp @@ -43,8 +43,8 @@ RenderWindChart(Canvas &canvas, const PixelRect rc, LeastSquares windstats_mag; ChartRenderer chart(chart_look, canvas, rc); - chart.SetXLabel(_T("w"), Units::GetSpeedName()); - chart.SetYLabel(_T("h"), Units::GetAltitudeName()); + chart.SetXLabel("w", Units::GetSpeedName()); + chart.SetYLabel("h", Units::GetAltitudeName()); chart.Begin(); if (fs.altitude_base.IsEmpty() || fs.altitude_ceiling.IsEmpty()) { diff --git a/src/Replay/CMakeLists.txt b/src/Replay/CMakeLists.txt new file mode 100644 index 00000000000..17ec7109054 --- /dev/null +++ b/src/Replay/CMakeLists.txt @@ -0,0 +1,54 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories + + +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) + +target_link_libraries(${TARGET_NAME} PUBLIC Logger) + +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/Replay/CMakeSource.cmake b/src/Replay/CMakeSource.cmake new file mode 100644 index 00000000000..624163de509 --- /dev/null +++ b/src/Replay/CMakeSource.cmake @@ -0,0 +1,15 @@ +set(_SOURCES + Replay/AircraftSim.cpp + Replay/DemoReplay.cpp + Replay/DemoReplayGlue.cpp + Replay/IgcReplay.cpp + Replay/NmeaReplay.cpp + Replay/Replay.cpp + Replay/TaskAutoPilot.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake +) + + diff --git a/src/Replay/Replay.cpp b/src/Replay/Replay.cpp index f9aa826a593..79c3f9eefb7 100644 --- a/src/Replay/Replay.cpp +++ b/src/Replay/Replay.cpp @@ -49,7 +49,7 @@ Replay::Start(Path _path) if (path == nullptr || path.empty()) { replay = new DemoReplayGlue(device_blackboard, task_manager); - } else if (path.EndsWithIgnoreCase(_T(".igc"))) { + } else if (path.EndsWithIgnoreCase(".igc")) { replay = new IgcReplay(std::make_unique(path)); cli = new CatmullRomInterpolator(FloatDuration{0.98}); diff --git a/src/Repository/AvailableFile.hpp b/src/Repository/AvailableFile.hpp index b65c8750cf2..93b1fae8289 100644 --- a/src/Repository/AvailableFile.hpp +++ b/src/Repository/AvailableFile.hpp @@ -32,7 +32,7 @@ struct AvailableFile { * A short symbolic name for the area. Empty means this file is * global. */ - NarrowString<8> area; + StaticString<8> area; FileType type; diff --git a/src/Repository/CMakeLists.txt b/src/Repository/CMakeLists.txt new file mode 100644 index 00000000000..c79a42de2ee --- /dev/null +++ b/src/Repository/CMakeLists.txt @@ -0,0 +1,51 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories + + +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/Repository/CMakeSource.cmake b/src/Repository/CMakeSource.cmake new file mode 100644 index 00000000000..4b78b5f3c7f --- /dev/null +++ b/src/Repository/CMakeSource.cmake @@ -0,0 +1,9 @@ +set(_SOURCES + Repository/FileRepository.cpp + Repository/Glue.cpp + Repository/Parser.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake +) diff --git a/src/Repository/FileType.hpp b/src/Repository/FileType.hpp index f7f2c7318be..00994ed8a3d 100644 --- a/src/Repository/FileType.hpp +++ b/src/Repository/FileType.hpp @@ -16,4 +16,5 @@ enum class FileType : uint8_t { RASP, XCI, TASK, + IMAGE, }; diff --git a/src/Repository/Glue.cpp b/src/Repository/Glue.cpp index fbeb8b23ef3..959ffaa661e 100644 --- a/src/Repository/Glue.cpp +++ b/src/Repository/Glue.cpp @@ -18,5 +18,5 @@ EnqueueRepositoryDownload(bool force) return; repository_downloaded = true; - Net::DownloadManager::Enqueue(REPOSITORY_URI, Path(_T("repository"))); + Net::DownloadManager::Enqueue(REPOSITORY_URI, Path("repository")); } diff --git a/src/ResourceId.hpp b/src/ResourceId.hpp index a4e1c1fecc4..d52616a6dd5 100644 --- a/src/ResourceId.hpp +++ b/src/ResourceId.hpp @@ -5,6 +5,9 @@ #include +#ifdef USE_WIN32_RESOURCES +#include +#endif /** * The identifier for a resource to be passed to * ResourceLoader::Load() or other resource-loading functions. @@ -12,6 +15,7 @@ class ResourceId { #ifdef USE_WIN32_RESOURCES unsigned id; + const char *name; #elif defined(ANDROID) const char *name; #else @@ -23,8 +27,13 @@ class ResourceId { ResourceId() = default; #ifdef USE_WIN32_RESOURCES - constexpr explicit ResourceId(unsigned _id) noexcept - :id(_id) {} +// constexpr explicit ResourceId(unsigned _id, const char* _res_name) noexcept + constexpr explicit ResourceId(unsigned _id) noexcept : id(_id) { + name = nullptr; + } + constexpr explicit ResourceId(unsigned _id, const char *_name) noexcept : id(_id) { + name = _name; + } #elif defined(ANDROID) constexpr explicit ResourceId(const char *_name) noexcept :name(_name) {} @@ -77,6 +86,14 @@ class ResourceId { #endif } +#ifdef USE_WIN32_RESOURCES +std::string_view +GetName() +{ + return name; +} +#endif + constexpr bool operator!=(ResourceId other) const noexcept { #ifdef USE_WIN32_RESOURCES return id != other.id; diff --git a/src/ResourceLoader.cpp b/src/ResourceLoader.cpp index 10a3d86f71f..78b107e32de 100644 --- a/src/ResourceLoader.cpp +++ b/src/ResourceLoader.cpp @@ -13,8 +13,13 @@ static HINSTANCE ResourceLoaderInstance; -void -ResourceLoader::Init(HINSTANCE hInstance) +bool +ResourceLoader::Initialized() +{ + return ResourceLoaderInstance != nullptr; +} + +void ResourceLoader::Init(HINSTANCE hInstance) { assert(ResourceLoaderInstance == nullptr); @@ -29,7 +34,7 @@ ResourceLoader::Init(HINSTANCE hInstance) #endif /* !WIN32 */ ResourceLoader::Data -ResourceLoader::Load(const TCHAR *name, [[maybe_unused]] const TCHAR *type) +ResourceLoader::Load(const char *name, [[maybe_unused]] const char *type) { #ifdef USE_WIN32_RESOURCES assert(ResourceLoaderInstance != nullptr); @@ -75,10 +80,11 @@ ResourceLoader::Load(ResourceId id) #endif +#include #ifdef USE_WIN32_RESOURCES HBITMAP -ResourceLoader::LoadBitmap2(ResourceId id) +ResourceLoader::LoadResBitmap(ResourceId id) { - return ::LoadBitmap(ResourceLoaderInstance, MAKEINTRESOURCE((unsigned)id)); + return LoadBitmapA(ResourceLoaderInstance, id.GetName().data()); } #endif diff --git a/src/ResourceLoader.hpp b/src/ResourceLoader.hpp index f6c4ca66593..bb3f9d613d6 100644 --- a/src/ResourceLoader.hpp +++ b/src/ResourceLoader.hpp @@ -16,6 +16,8 @@ class ResourceId; namespace ResourceLoader { #ifdef _WIN32 +bool Initialized(); + void Init(HINSTANCE hInstance); #endif @@ -23,16 +25,16 @@ Init(HINSTANCE hInstance); using Data = std::span; Data -Load(const TCHAR *name, const TCHAR *type); +Load(const char *name, const char *type); #ifndef ANDROID Data Load(ResourceId id); #endif -#ifdef _WIN32 +#ifdef USE_WIN32_RESOURCES HBITMAP -LoadBitmap2(ResourceId id); +LoadResBitmap(ResourceId id); #endif } // namespace ResourceLoader diff --git a/src/Resources.hpp b/src/Resources.hpp index 5b89fec7494..93a46f75146 100644 --- a/src/Resources.hpp +++ b/src/Resources.hpp @@ -4,9 +4,10 @@ #include "ResourceId.hpp" #ifdef USE_WIN32_RESOURCES +#include #define MAKE_RESOURCE(name, file, id) \ - static constexpr ResourceId name(id); + static constexpr ResourceId name(id, #name) #elif defined(ANDROID) diff --git a/src/Screen/CMakeLists.txt b/src/Screen/CMakeLists.txt new file mode 100644 index 00000000000..c605e7f41b6 --- /dev/null +++ b/src/Screen/CMakeLists.txt @@ -0,0 +1,40 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +include(CMakeSource.cmake) +# organize the files in subdirectories + + +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + string(REPLACE "${SRC}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) ### for VisualStudio-IDE + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + ## message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +source_group("Scripts" FILES ${SCRIPT_FILES}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +target_link_libraries(${TARGET_NAME} PUBLIC Hardware) + +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER FrontEnd) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/Screen/CMakeSource.cmake b/src/Screen/CMakeSource.cmake new file mode 100644 index 00000000000..a48ae8a8e62 --- /dev/null +++ b/src/Screen/CMakeSource.cmake @@ -0,0 +1,11 @@ + +# list(APPEND _SOURCES +set(_SOURCES + Debug.cpp + Layout.cpp +) + +set(SCRIPT_FILES CMakeSource.cmake) + + + diff --git a/src/Simulator.cpp b/src/Simulator.cpp index 717cc64628f..a9f4e0f1665 100644 --- a/src/Simulator.cpp +++ b/src/Simulator.cpp @@ -5,6 +5,6 @@ #ifdef SIMULATOR_AVAILABLE -bool global_simulator_flag; -bool sim_set_in_cmd_line_flag; +bool global_simulator_flag = false; +bool sim_set_in_cmd_line_flag = true; #endif diff --git a/src/Startup.cpp b/src/Startup.cpp index 942620cb590..ff9c17b166c 100644 --- a/src/Startup.cpp +++ b/src/Startup.cpp @@ -57,7 +57,9 @@ #include "io/FileCache.hpp" #include "io/async/AsioThread.hpp" #include "io/async/GlobalAsioThread.hpp" +// #ifdef HAVE_TRACKING #include "net/http/Init.hpp" +// #endif #include "net/http/DownloadManager.hpp" #include "net/client/tim/Glue.hpp" #include "Hardware/DisplayDPI.hpp" @@ -86,7 +88,9 @@ #include "Weather/NOAAStore.hpp" #include "Plane/PlaneGlue.hpp" #include "UIState.hpp" +// #ifdef HAVE_TRACKING #include "Tracking/TrackingGlue.hpp" +// #endif #include "Units/Units.hpp" #include "Formatter/UserGeoPointFormatter.hpp" #include "thread/Debug.hpp" @@ -108,6 +112,10 @@ #include "Android/NativeView.hpp" #endif +#ifdef IS_OPENVARIO +# include "OpenVario/System/OpenVarioDevice.hpp" +#endif + static TaskManager *task_manager; static GlideComputerEvents *glide_computer_events; static AllMonitors *all_monitors; @@ -134,8 +142,8 @@ static void AfterStartup() { try { - const auto lua_path = LocalPath(_T("lua")); - Lua::StartFile(AllocatedPath::Build(lua_path, _T("init.lua"))); + const auto lua_path = LocalPath("lua"); + Lua::StartFile(AllocatedPath::Build(lua_path, "init.lua")); } catch (...) { LogError(std::current_exception()); } @@ -248,7 +256,12 @@ Startup(UI::Display &display) style.Resizable(); #ifdef SOFTWARE_ROTATE_DISPLAY - style.InitialOrientation(Display::DetectInitialOrientation()); +# ifdef IS_OPENVARIO + style.InitialOrientation(ovdevice.GetRotation()); +# else + style.InitialOrientation(Display::DetectInitialOrientation()); +# endif + #endif MainWindow *const main_window = CommonInterface::main_window = @@ -549,7 +562,7 @@ Startup(UI::Display &display) if (!is_simulator() && computer_settings.logger.enable_flight_logger) { backend_components->flight_logger = std::make_unique(live_blackboard); - backend_components->flight_logger->SetPath(LocalPath(_T("flights.log"))); + backend_components->flight_logger->SetPath(LocalPath("flights.log")); } if (computer_settings.logger.enable_nmea_logger) diff --git a/src/StatusMessage.cpp b/src/StatusMessage.cpp index ee2ea57fab4..1dc4f4333d2 100644 --- a/src/StatusMessage.cpp +++ b/src/StatusMessage.cpp @@ -13,7 +13,7 @@ static constexpr StatusMessage default_status_messages[] = { [[gnu::pure]] const StatusMessage & -FindStatusMessage(const TCHAR *key) +FindStatusMessage(const char *key) { assert(ARRAY_SIZE(default_status_messages) > 0); diff --git a/src/StatusMessage.hpp b/src/StatusMessage.hpp index baf55b485f4..6e8d961a6db 100644 --- a/src/StatusMessage.hpp +++ b/src/StatusMessage.hpp @@ -11,10 +11,10 @@ */ struct StatusMessage { /** English key */ - const TCHAR *key; + const char *key; /** What sound entry to play */ - const TCHAR *sound; + const char *sound; bool visible; @@ -24,4 +24,4 @@ struct StatusMessage { [[gnu::pure]] const StatusMessage & -FindStatusMessage(const TCHAR *key); +FindStatusMessage(const char *key); diff --git a/src/SystemSettings.cpp b/src/SystemSettings.cpp index 45767d2c966..7b2200bc364 100644 --- a/src/SystemSettings.cpp +++ b/src/SystemSettings.cpp @@ -15,11 +15,11 @@ SystemSettings::SetDefaults() } else { devices[0].port_type = DeviceConfig::PortType::SERIAL; #ifdef _WIN32 - devices[0].path = _T("COM1:"); + devices[0].path = "COM1"; #else - devices[0].path = _T("/dev/tty0"); + devices[0].path = "/dev/tty0"; #endif devices[0].baud_rate = 4800; - devices[0].driver_name = _T("Generic"); + devices[0].driver_name = "Generic"; } } diff --git a/src/Task/CMakeLists.txt b/src/Task/CMakeLists.txt new file mode 100644 index 00000000000..878c3ed1cb1 --- /dev/null +++ b/src/Task/CMakeLists.txt @@ -0,0 +1,52 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories + + +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +target_link_libraries(${TARGET_NAME} json) +add_dependencies(${TARGET_NAME} util) diff --git a/src/Task/CMakeSource.cmake b/src/Task/CMakeSource.cmake new file mode 100644 index 00000000000..cae68a22d2e --- /dev/null +++ b/src/Task/CMakeSource.cmake @@ -0,0 +1,26 @@ +set(_SOURCES + Task/DefaultTask.cpp + Task/Deserialiser.cpp + Task/FileProtectedTaskManager.cpp + Task/LoadFile.cpp + Task/MapTaskManager.cpp + Task/ProtectedRoutePlanner.cpp + Task/ProtectedTaskManager.cpp + Task/RoutePlannerGlue.cpp + Task/SaveFile.cpp + Task/Serialiser.cpp + Task/TaskFile.cpp + Task/TaskFileIGC.cpp + Task/TaskFileSeeYou.cpp + Task/TaskFileXCSoar.cpp + Task/TaskStore.cpp + Task/TypeStrings.cpp + Task/ValidationErrorStrings.cpp + Task/XCTrackTaskFile.cpp # add 7.38 + Task/XCTrackTaskDecoder.cpp # add 7.38 + Task/PolylineDecoder.cpp # add 7.38 +) + +set(SCRIPT_FILES + CMakeSource.cmake +) diff --git a/src/Task/DefaultTask.hpp b/src/Task/DefaultTask.hpp index cee174e9187..83362c7f734 100644 --- a/src/Task/DefaultTask.hpp +++ b/src/Task/DefaultTask.hpp @@ -9,7 +9,7 @@ struct TaskBehaviour; class OrderedTask; class Waypoints; -#define default_task_path _T("Default.tsk") +#define default_task_path "Default.tsk" /** * Creates an ordered task based on the Default.tsk file diff --git a/src/Task/Deserialiser.cpp b/src/Task/Deserialiser.cpp index 049c8f817c2..add690d0b69 100644 --- a/src/Task/Deserialiser.cpp +++ b/src/Task/Deserialiser.cpp @@ -14,7 +14,6 @@ #include "Task/Factory/AbstractTaskFactory.hpp" #include "XML/DataNode.hpp" #include "Engine/Waypoint/Waypoints.hpp" -#include "util/ConvertString.hpp" #include @@ -35,16 +34,14 @@ DeserialiseWaypoint(const ConstDataNode &node, const Waypoints *waypoints) GeoPoint loc; Deserialise(loc, *loc_node); - const char *_name = node.GetAttribute("name"); - if (_name == nullptr) + const char *name = node.GetAttribute("name"); + if (name == nullptr) // Turnpoints need names return nullptr; - const UTF8ToWideConverter name{_name}; - if (waypoints != nullptr) { // Try to find waypoint by name - auto from_database = waypoints->LookupName(name.c_str()); + auto from_database = waypoints->LookupName(name); // If waypoint by name found and closer than 10m to the original if (from_database != nullptr && @@ -70,7 +67,7 @@ DeserialiseWaypoint(const ConstDataNode &node, const Waypoints *waypoints) const char *comment = node.GetAttribute("comment"); if (comment != nullptr) - wp->comment = UTF8ToWideConverter{comment}; + wp->comment = comment; if (node.GetAttribute("altitude", wp->elevation)) wp->has_elevation = true; diff --git a/src/Task/Serialiser.cpp b/src/Task/Serialiser.cpp index 56df3111474..bca0802a47e 100644 --- a/src/Task/Serialiser.cpp +++ b/src/Task/Serialiser.cpp @@ -12,13 +12,12 @@ #include "Task/ObservationZones/SymmetricSectorZone.hpp" #include "XML/DataNode.hpp" #include "util/Compiler.h" -#include "util/ConvertString.hpp" #include #include [[gnu::const]] -static const TCHAR * +static const char * GetName(TaskPointType type, bool mode_optional_start) { switch (type) { @@ -26,23 +25,23 @@ GetName(TaskPointType type, bool mode_optional_start) gcc_unreachable(); case TaskPointType::START: - return mode_optional_start ? _T("OptionalStart") : _T("Start"); + return mode_optional_start ? "OptionalStart" : "Start"; case TaskPointType::AST: - return _T("Turn"); + return "Turn"; case TaskPointType::AAT: - return _T("Area"); + return "Area"; case TaskPointType::FINISH: - return _T("Finish"); + return "Finish"; } gcc_unreachable(); } [[gnu::pure]] -static const TCHAR * +static const char * GetName(const OrderedTaskPoint &tp, bool mode_optional_start) { return GetName(tp.GetType(), mode_optional_start); @@ -58,9 +57,9 @@ Serialise(WritableDataNode &node, const GeoPoint &data) static void Serialise(WritableDataNode &node, const Waypoint &data) { - node.SetAttribute("name", WideToUTF8Converter(data.name.c_str())); + node.SetAttribute("name", data.name.c_str()); node.SetAttribute("id", data.id); - node.SetAttribute("comment", WideToUTF8Converter(data.comment.c_str())); + node.SetAttribute("comment", data.comment.c_str()); if (data.has_elevation) node.SetAttribute("altitude", data.elevation); @@ -166,11 +165,11 @@ Serialise(WritableDataNode &node, const ObservationZonePoint &data) static void Serialise(WritableDataNode &node, const OrderedTaskPoint &data, - const TCHAR *name) + const char *name) { // do nothing auto child = node.AppendChild("Point"); - child->SetAttribute("type", WideToUTF8Converter(name)); + child->SetAttribute("type", name); Serialise(*child->AppendChild("Waypoint"), data.GetWaypoint()); Serialise(*child->AppendChild("ObservationZone"), @@ -187,7 +186,7 @@ static void Serialise(WritableDataNode &node, const OrderedTaskPoint &tp, bool mode_optional_start) { - const TCHAR *name = GetName(tp, mode_optional_start); + const char *name = GetName(tp, mode_optional_start); assert(name != nullptr); Serialise(node, tp, name); } @@ -210,28 +209,28 @@ GetHeightRef(AltitudeReference height_ref) } [[gnu::const]] -static const TCHAR * +static const char * GetTaskFactoryType(TaskFactoryType type) { switch(type) { case TaskFactoryType::FAI_GENERAL: - return _T("FAIGeneral"); + return "FAIGeneral"; case TaskFactoryType::FAI_TRIANGLE: - return _T("FAITriangle"); + return "FAITriangle"; case TaskFactoryType::FAI_OR: - return _T("FAIOR"); + return "FAIOR"; case TaskFactoryType::FAI_GOAL: - return _T("FAIGoal"); + return "FAIGoal"; case TaskFactoryType::RACING: - return _T("RT"); + return "RT"; case TaskFactoryType::AAT: - return _T("AAT"); + return "AAT"; case TaskFactoryType::MAT: - return _T("MAT"); + return "MAT"; case TaskFactoryType::MIXED: - return _T("Mixed"); + return "Mixed"; case TaskFactoryType::TOURING: - return _T("Touring"); + return "Touring"; case TaskFactoryType::COUNT: gcc_unreachable(); } @@ -269,7 +268,7 @@ Serialise(WritableDataNode &node, const OrderedTaskSettings &data) void SaveTask(WritableDataNode &node, const OrderedTask &task) { - node.SetAttribute("type", WideToUTF8Converter(GetTaskFactoryType(task.GetFactoryType()))); + node.SetAttribute("type", GetTaskFactoryType(task.GetFactoryType())); Serialise(node, task.GetOrderedTaskSettings()); for (const auto &tp : task.GetPoints()) diff --git a/src/Task/TaskFile.cpp b/src/Task/TaskFile.cpp index cc7dfe62975..0847d67a281 100644 --- a/src/Task/TaskFile.cpp +++ b/src/Task/TaskFile.cpp @@ -14,20 +14,20 @@ std::unique_ptr TaskFile::Create(Path path) { // If XCSoar task file -> return new TaskFileXCSoar - if (path.EndsWithIgnoreCase(_T(".tsk"))) + if (path.EndsWithIgnoreCase(".tsk")) return std::make_unique(path); // If SeeYou task file -> return new TaskFileSeeYou - if (path.EndsWithIgnoreCase(_T(".cup"))) + if (path.EndsWithIgnoreCase(".cup")) return std::make_unique(path); // If IGC file -> return new TaskFileIGC - if (path.EndsWithIgnoreCase(_T(".igc"))) + if (path.EndsWithIgnoreCase(".igc")) return std::make_unique(path); /* TODO ".xctsk" is not a real filename suffix; there is just the MIME type "application/xctsk" */ - if (path.EndsWithIgnoreCase(_T(".xctsk"))) + if (path.EndsWithIgnoreCase(".xctsk")) return std::make_unique(path); // unknown task file type diff --git a/src/Task/TaskFile.hpp b/src/Task/TaskFile.hpp index 25aee2cc252..4c871c97198 100644 --- a/src/Task/TaskFile.hpp +++ b/src/Task/TaskFile.hpp @@ -4,7 +4,7 @@ #pragma once #include "system/Path.hpp" -#include "util/tstring.hpp" +#include #include #include @@ -41,7 +41,7 @@ class TaskFile /** * Throws on error. */ - virtual std::vector GetList() const = 0; + virtual std::vector GetList() const = 0; virtual std::unique_ptr GetTask(const TaskBehaviour &task_behaviour, const Waypoints *waypoints, diff --git a/src/Task/TaskFileIGC.cpp b/src/Task/TaskFileIGC.cpp index 42899812915..835b0ac30e6 100644 --- a/src/Task/TaskFileIGC.cpp +++ b/src/Task/TaskFileIGC.cpp @@ -27,7 +27,7 @@ try { bool header_found = false; while ((line = reader.ReadLine()) != nullptr) { // Skip lines which are not declaration records - if (*line != _T('C')) + if (*line != 'C') continue; if (!header_found) { @@ -49,7 +49,7 @@ try { } static WaypointPtr -MakeWaypoint(GeoPoint location, const TCHAR *name) +MakeWaypoint(GeoPoint location, const char *name) { Waypoint *wp = new Waypoint(location); wp->name = name; @@ -91,11 +91,11 @@ TaskFileIGC::GetTask(const TaskBehaviour &task_behaviour, waypoint_name.clear(); waypoint_name.UnsafeAppendASCII(it.name); } else if (i == 0) - waypoint_name = _T("Start"); + waypoint_name = "Start"; else if (i == num_turnpoints - 1) - waypoint_name = _T("Finish"); + waypoint_name = "Finish"; else - waypoint_name.Format(_T("%s #%u"), _T("Turnpoint"), i); + waypoint_name.Format("%s #%u", "Turnpoint", i); auto wp = MakeWaypoint(it.location, waypoint_name.c_str()); @@ -118,7 +118,7 @@ TaskFileIGC::GetTask(const TaskBehaviour &task_behaviour, return task; } -std::vector +std::vector TaskFileIGC::GetList() const { // Open the IGC file @@ -136,7 +136,7 @@ TaskFileIGC::GetList() const header.num_turnpoints == 0) return {}; - std::vector result; + std::vector result; if (!header.task_name.empty() && !StringIsEqual(header.task_name, "Task")) { diff --git a/src/Task/TaskFileIGC.hpp b/src/Task/TaskFileIGC.hpp index 301af424c67..fe97ffa601d 100644 --- a/src/Task/TaskFileIGC.hpp +++ b/src/Task/TaskFileIGC.hpp @@ -10,7 +10,7 @@ class TaskFileIGC: public TaskFile public: using TaskFile::TaskFile; - std::vector GetList() const override; + std::vector GetList() const override; std::unique_ptr GetTask(const TaskBehaviour &task_behaviour, const Waypoints *waypoints, diff --git a/src/Task/TaskFileSeeYou.cpp b/src/Task/TaskFileSeeYou.cpp index d495d99fd82..3431811a180 100644 --- a/src/Task/TaskFileSeeYou.cpp +++ b/src/Task/TaskFileSeeYou.cpp @@ -553,10 +553,10 @@ try { return nullptr; } -std::vector +std::vector TaskFileSeeYou::GetList() const { - std::vector result; + std::vector result; // Open the CUP file FileReader file_reader{path}; diff --git a/src/Task/TaskFileSeeYou.hpp b/src/Task/TaskFileSeeYou.hpp index 35723970977..93825cfdf7b 100644 --- a/src/Task/TaskFileSeeYou.hpp +++ b/src/Task/TaskFileSeeYou.hpp @@ -15,7 +15,7 @@ class TaskFileSeeYou: public TaskFile public: using TaskFile::TaskFile; - std::vector GetList() const override; + std::vector GetList() const override; std::unique_ptr GetTask(const TaskBehaviour &task_behaviour, const Waypoints *waypoints, unsigned index) const override; diff --git a/src/Task/TaskFileXCSoar.hpp b/src/Task/TaskFileXCSoar.hpp index 1bf9487ae08..cedde6ec8b8 100644 --- a/src/Task/TaskFileXCSoar.hpp +++ b/src/Task/TaskFileXCSoar.hpp @@ -10,7 +10,7 @@ class TaskFileXCSoar: public TaskFile public: using TaskFile::TaskFile; - std::vector GetList() const override { + std::vector GetList() const override { return {{}}; } diff --git a/src/Task/TaskStore.cpp b/src/Task/TaskStore.cpp index ff7dfe20190..e0c27f799d1 100644 --- a/src/Task/TaskStore.cpp +++ b/src/Task/TaskStore.cpp @@ -42,11 +42,11 @@ class TaskFileVisitor: public File::Visitor // If the task file holds more than one task const auto &saved_name = list[i]; if (!saved_name.empty()) { - name += _T(": "); + name += ": "; name += saved_name.c_str(); } else if (count > 1) { // .. append " - Task #[n]" suffix to the task name - name.AppendFormat(_T(": %s #%d"), _("Task"), i + 1); + name.AppendFormat(": %s #%d", _("Task"), i + 1); } // Add the task to the TaskStore @@ -71,11 +71,11 @@ TaskStore::Scan(bool extra) // scan files TaskFileVisitor tfv(store); - VisitDataFiles(_T("*.tsk"), tfv); + VisitDataFiles("*.tsk", tfv); if (extra) { - VisitDataFiles(_T("*.cup"), tfv); - VisitDataFiles(_T("*.igc"), tfv); + VisitDataFiles("*.cup", tfv); + VisitDataFiles("*.igc", tfv); } std::sort(store.begin(), store.end()); @@ -102,7 +102,7 @@ TaskStore::Item::GetTask(const TaskBehaviour &task_behaviour, return task.get(); } -const TCHAR * +const char * TaskStore::GetName(unsigned index) const { return store[index].GetName(); diff --git a/src/Task/TaskStore.hpp b/src/Task/TaskStore.hpp index 30689b22d7b..9a8ff4353d6 100644 --- a/src/Task/TaskStore.hpp +++ b/src/Task/TaskStore.hpp @@ -4,7 +4,7 @@ #pragma once #include "system/Path.hpp" -#include "util/tstring.hpp" +#include #include #include @@ -21,14 +21,14 @@ class TaskStore public: struct Item { - tstring task_name; + std::string task_name; AllocatedPath filename; unsigned task_index; std::unique_ptr task; bool valid; Item(Path the_filename, - tstring::const_pointer _task_name, + std::string::const_pointer _task_name, unsigned _task_index = 0) :task_name(_task_name), filename(the_filename), @@ -41,7 +41,7 @@ class TaskStore Item &operator=(Item &&) = default; [[gnu::pure]] - tstring::const_pointer GetName() const { + std::string::const_pointer GetName() const { return task_name.c_str(); } @@ -97,7 +97,7 @@ class TaskStore * @return Filename of the task defined by the given index */ [[gnu::pure]] - tstring::const_pointer GetName(unsigned index) const; + std::string::const_pointer GetName(unsigned index) const; /** * Return the pathname of the task defined by the given index diff --git a/src/Task/TypeStrings.cpp b/src/Task/TypeStrings.cpp index df2b488330d..2e1785d523d 100644 --- a/src/Task/TypeStrings.cpp +++ b/src/Task/TypeStrings.cpp @@ -7,7 +7,7 @@ #include "Language/Language.hpp" #include "util/Macros.hpp" -static const TCHAR *const task_factory_names[] = { +static const char *const task_factory_names[] = { N_("FAI badges/records"), N_("FAI triangle"), N_("FAI out and return"), @@ -22,13 +22,13 @@ static const TCHAR *const task_factory_names[] = { static_assert(ARRAY_SIZE(task_factory_names) == unsigned(TaskFactoryType::COUNT), "Wrong array size"); -const TCHAR* +const char* OrderedTaskFactoryName(TaskFactoryType type) { return gettext(task_factory_names[unsigned(type)]); } -static const TCHAR *const task_factory_descriptions[] = { +static const char *const task_factory_descriptions[] = { N_("FAI rules, allows only FAI start, finish and turn point types, for badges and " "records. Enables FAI finish height for final glide calculation."), N_("FAI rules, path from a start to two turn points and return."), @@ -46,13 +46,13 @@ static const TCHAR *const task_factory_descriptions[] = { static_assert(ARRAY_SIZE(task_factory_descriptions) == unsigned(TaskFactoryType::COUNT), "Wrong array size"); -const TCHAR* +const char* OrderedTaskFactoryDescription(TaskFactoryType type) { return gettext(task_factory_descriptions[unsigned(type)]); } -static const TCHAR *const tp_factory_descriptions[] = { +static const char *const tp_factory_descriptions[] = { N_("A 90 degree sector with 1km radius. Cross corner edge from inside area to start."), N_("A straight line start gate. Cross start gate from inside area to start."), N_("A cylinder. Exit area to start."), @@ -83,13 +83,13 @@ static const TCHAR *const tp_factory_descriptions[] = { static_assert(ARRAY_SIZE(tp_factory_descriptions) == unsigned(TaskPointFactoryType::COUNT), "Wrong array size"); -const TCHAR* +const char* OrderedTaskPointDescription(TaskPointFactoryType type) { return tp_factory_descriptions[unsigned(type)]; } -static const TCHAR *const tp_factory_names[] = { +static const char *const tp_factory_names[] = { N_("FAI start quadrant"), N_("Start line"), N_("Start cylinder"), @@ -114,7 +114,7 @@ static const TCHAR *const tp_factory_names[] = { static_assert(ARRAY_SIZE(tp_factory_names) == unsigned(TaskPointFactoryType::COUNT), "Wrong array size"); -const TCHAR* +const char* OrderedTaskPointName(TaskPointFactoryType type) { return tp_factory_names[unsigned(type)]; diff --git a/src/Task/TypeStrings.hpp b/src/Task/TypeStrings.hpp index 216010ade60..8baab7af9c5 100644 --- a/src/Task/TypeStrings.hpp +++ b/src/Task/TypeStrings.hpp @@ -11,17 +11,17 @@ enum class TaskFactoryType : uint8_t; enum class TaskPointFactoryType : uint8_t; [[gnu::const]] -const TCHAR * +const char * OrderedTaskFactoryDescription(TaskFactoryType type); [[gnu::const]] -const TCHAR * +const char * OrderedTaskFactoryName(TaskFactoryType type); [[gnu::const]] -const TCHAR * +const char * OrderedTaskPointDescription(TaskPointFactoryType type); [[gnu::const]] -const TCHAR * +const char * OrderedTaskPointName(TaskPointFactoryType type); diff --git a/src/Task/ValidationErrorStrings.cpp b/src/Task/ValidationErrorStrings.cpp index 65bcde13246..77e741f2325 100644 --- a/src/Task/ValidationErrorStrings.cpp +++ b/src/Task/ValidationErrorStrings.cpp @@ -8,7 +8,7 @@ #include // for MAX_PATH #include -static const TCHAR *const validation_error_strings[] = { +static const char *const validation_error_strings[] = { N_("No valid start"), N_("No valid finish"), N_("Task not closed"), @@ -26,10 +26,10 @@ static const TCHAR *const validation_error_strings[] = { static_assert(ARRAY_SIZE(validation_error_strings) == unsigned(TaskValidationErrorType::COUNT), "Wrong array size"); -const TCHAR* +const char* getTaskValidationErrors(const TaskValidationErrorSet v) { - static TCHAR err[MAX_PATH]; + static char err[MAX_PATH]; err[0] = '\0'; for (unsigned i = 0; i < v.N; i++) { @@ -37,10 +37,10 @@ getTaskValidationErrors(const TaskValidationErrorSet v) if (!v.Contains(error)) continue; - const TCHAR *current = gettext(validation_error_strings[i]); - if (_tcslen(err) + _tcslen(current) + 1 < MAX_PATH) { - _tcscat(err, current); - _tcscat(err, _T("\n")); + const char *current = gettext(validation_error_strings[i]); + if (strlen(err) + strlen(current) + 1 < MAX_PATH) { + strcat(err, current); + strcat(err, "\n"); } } diff --git a/src/Task/ValidationErrorStrings.hpp b/src/Task/ValidationErrorStrings.hpp index ef3f4c479c0..17519c3a566 100644 --- a/src/Task/ValidationErrorStrings.hpp +++ b/src/Task/ValidationErrorStrings.hpp @@ -8,5 +8,5 @@ #include [[gnu::const]] -const TCHAR * +const char * getTaskValidationErrors(const TaskValidationErrorSet v); diff --git a/src/Task/XCTrackTaskDecoder.cpp b/src/Task/XCTrackTaskDecoder.cpp index 50717acef73..a87d999fef6 100644 --- a/src/Task/XCTrackTaskDecoder.cpp +++ b/src/Task/XCTrackTaskDecoder.cpp @@ -12,7 +12,6 @@ #include "Engine/Task/Ordered/Points/ASTPoint.hpp" #include "Engine/Waypoint/Ptr.hpp" #include "Engine/Waypoint/Waypoint.hpp" -#include "util/ConvertString.hpp" #include @@ -50,7 +49,7 @@ DecodeXCTrackZ(std::string_view src) } static WaypointPtr -MakeWaypoint(GeoPoint location, const TCHAR *name) +MakeWaypoint(GeoPoint location, const char *name) { Waypoint *wp = new Waypoint(location); wp->name = name; @@ -95,12 +94,11 @@ DecodeXCTrackTask(const boost::json::value &_j, if (name.empty()) throw std::invalid_argument{"Name is empty"}; - const UTF8ToWideConverter name_t{name.c_str()}; - if (!name_t.IsValid()) + if (!name.c_str()) throw std::invalid_argument{"Malfored name"}; auto oz = std::make_unique(z.location, z.radius); - auto wp = MakeWaypoint(z.location, name_t.c_str()); + auto wp = MakeWaypoint(z.location, name.c_str()); std::unique_ptr tp; diff --git a/src/Task/XCTrackTaskFile.hpp b/src/Task/XCTrackTaskFile.hpp index 00d88fd8024..8de76ccbe13 100644 --- a/src/Task/XCTrackTaskFile.hpp +++ b/src/Task/XCTrackTaskFile.hpp @@ -9,7 +9,7 @@ class XCTrackTaskFile final : public TaskFile { public: using TaskFile::TaskFile; - std::vector GetList() const override { + std::vector GetList() const override { return {{}}; } diff --git a/src/TeamActions.cpp b/src/TeamActions.cpp index ad9820c320d..071af504b4c 100644 --- a/src/TeamActions.cpp +++ b/src/TeamActions.cpp @@ -8,7 +8,7 @@ #include "FLARM/Global.hpp" void -TeamActions::TrackFlarm(FlarmId id, const TCHAR *callsign) noexcept +TeamActions::TrackFlarm(FlarmId id, const char *callsign) noexcept { TeamCodeSettings &settings = CommonInterface::SetComputerSettings().team_code; diff --git a/src/TeamActions.hpp b/src/TeamActions.hpp index 1e39f2d02c8..547a49347ed 100644 --- a/src/TeamActions.hpp +++ b/src/TeamActions.hpp @@ -13,6 +13,6 @@ namespace TeamActions { * Track the specified FLARM peer. */ void -TrackFlarm(FlarmId id, const TCHAR *callsign=nullptr) noexcept; +TrackFlarm(FlarmId id, const char *callsign=nullptr) noexcept; }; diff --git a/src/TeamCode/CMakeLists.txt b/src/TeamCode/CMakeLists.txt new file mode 100644 index 00000000000..c79a42de2ee --- /dev/null +++ b/src/TeamCode/CMakeLists.txt @@ -0,0 +1,51 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories + + +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/TeamCode/CMakeSource.cmake b/src/TeamCode/CMakeSource.cmake new file mode 100644 index 00000000000..97f4017b7f4 --- /dev/null +++ b/src/TeamCode/CMakeSource.cmake @@ -0,0 +1,8 @@ +set(_SOURCES + TeamCode/Settings.cpp + TeamCode/TeamCode.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake +) diff --git a/src/TeamCode/Settings.cpp b/src/TeamCode/Settings.cpp index 1e84814bd2b..5cf66d26ae2 100644 --- a/src/TeamCode/Settings.cpp +++ b/src/TeamCode/Settings.cpp @@ -12,7 +12,7 @@ TeamCodeSettings::SetDefaults() } void -TeamCodeSettings::TrackFlarm(FlarmId id, const TCHAR *name) +TeamCodeSettings::TrackFlarm(FlarmId id, const char *name) { // Start tracking team_flarm_id = id; diff --git a/src/TeamCode/Settings.hpp b/src/TeamCode/Settings.hpp index 935ab0c8dfa..09ff8f9342d 100644 --- a/src/TeamCode/Settings.hpp +++ b/src/TeamCode/Settings.hpp @@ -38,7 +38,7 @@ struct TeamCodeSettings { * Don't use this method directory, use TeamActions::TrackFlarm() * instead. */ - void TrackFlarm(FlarmId id, const TCHAR *callsign); + void TrackFlarm(FlarmId id, const char *callsign); }; static_assert(std::is_trivial::value, "type is not trivial"); diff --git a/src/TeamCode/TeamCode.cpp b/src/TeamCode/TeamCode.cpp index a5929accd9a..e0d67b4e3aa 100644 --- a/src/TeamCode/TeamCode.cpp +++ b/src/TeamCode/TeamCode.cpp @@ -20,7 +20,7 @@ static constexpr Angle ANGLE_FACTOR = * @return The decoded value */ static unsigned -GetValueFromTeamCode(const TCHAR *code, unsigned length) +GetValueFromTeamCode(const char *code, unsigned length) { unsigned val = 0; unsigned position = 0; @@ -63,21 +63,21 @@ CountDigits(unsigned value) * @param n_digits Number of chars for the teamcode */ static void -NumberToTeamCode(unsigned value, TCHAR *code, unsigned n_digits) +NumberToTeamCode(unsigned value, char *code, unsigned n_digits) { if (n_digits == 0) n_digits = CountDigits(value); - TCHAR *p = code + n_digits; - *p-- = _T('\0'); + char *p = code + n_digits; + *p-- = '\0'; do { unsigned digit_value = value % BASE; value /= BASE; *p = digit_value < 10 - ? TCHAR('0' + digit_value) - : TCHAR('A' + digit_value - 10); + ? char('0' + digit_value) + : char('A' + digit_value - 10); } while (--p >= code); } @@ -87,7 +87,7 @@ NumberToTeamCode(unsigned value, TCHAR *code, unsigned n_digits) * @param code The teamcode (pointer) */ static void -ConvertBearingToTeamCode(const Angle bearing, TCHAR *code) +ConvertBearingToTeamCode(const Angle bearing, char *code) { const unsigned value = uround(bearing.AsBearing().Native() / ANGLE_FACTOR.Native()); @@ -122,7 +122,7 @@ TeamCode::Update(Angle bearing, double range) } void -TeamCode::Update(const TCHAR* _code) +TeamCode::Update(const char* _code) { code = _code; } diff --git a/src/TeamCode/TeamCode.hpp b/src/TeamCode/TeamCode.hpp index bfaaf30363d..7115cfa3f4e 100644 --- a/src/TeamCode/TeamCode.hpp +++ b/src/TeamCode/TeamCode.hpp @@ -30,7 +30,7 @@ class TeamCode * Returns the current team code * @return Current team code */ - const TCHAR *GetCode() const { + const char *GetCode() const { return code; } @@ -66,7 +66,7 @@ class TeamCode * Updates the team code to the given code * @param _code The new team code */ - void Update(const TCHAR* _code); + void Update(const char* _code); }; static_assert(std::is_trivial::value, "type is not trivial"); diff --git a/src/Terrain/CMakeLists.txt b/src/Terrain/CMakeLists.txt new file mode 100644 index 00000000000..a4b8378b371 --- /dev/null +++ b/src/Terrain/CMakeLists.txt @@ -0,0 +1,78 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + + project(${TARGET_NAME} CXX) # Your project name + +# include(${CMAKE_CURRENT_SOURCE_DIR}/CMakeSource.cmake) +if (EXISTS CMakeSource.cmake) + include(CMakeSource.cmake) +elseif(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/CMakeSource.cmake) + # message(FATAL_ERROR "Stop: ${CMAKE_CURRENT_SOURCE_DIR}/CMakeSource.cmake found") + # message(STATUS "!!! ${CMAKE_CURRENT_SOURCE_DIR}/CMakeSource.cmake found") + include(${CMAKE_CURRENT_SOURCE_DIR}/CMakeSource.cmake) +else() + message(FATAL_ERROR "Stop!") + # include(../../CMakeSource.cmake) +endif() +# organize the files in subdirectories + +# list(APPEND ${TARGET_NAME}_SOURCES ${TARGET_NAME}/jpc_rtc.cpp) +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + list(APPEND SOURCE_FILES ${source_file}) + # string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" source_file ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES "${source_file}") + ### hide: message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +# with jasper...: +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# without jasper...: file(GLOB HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() + ## message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +target_link_libraries(${TARGET_NAME} PUBLIC + io + ui + thread + # Screen + Renderer +# ${JASPER_LIB} # internal or external... +# ${ZZIP_LIB} # internal or external... + jasper + zzip +) + +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Topo) + +add_dependencies(${TARGET_NAME} util jasper zzip) + diff --git a/src/Terrain/CMakeSource.cmake b/src/Terrain/CMakeSource.cmake new file mode 100644 index 00000000000..c7e2942805d --- /dev/null +++ b/src/Terrain/CMakeSource.cmake @@ -0,0 +1,53 @@ +set(TERRAIN_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +set(_SOURCES + ${TERRAIN_DIR}/HeightMatrix.cpp + ${TERRAIN_DIR}/Intersection.cpp + ${TERRAIN_DIR}/Loader.cpp + ${TERRAIN_DIR}/RasterBuffer.cpp + ${TERRAIN_DIR}/RasterMap.cpp + ${TERRAIN_DIR}/RasterProjection.cpp + ${TERRAIN_DIR}/RasterRenderer.cpp + ${TERRAIN_DIR}/RasterTerrain.cpp + ${TERRAIN_DIR}/RasterTile.cpp + ${TERRAIN_DIR}/RasterTileCache.cpp + ${TERRAIN_DIR}/ScanLine.cpp + ${TERRAIN_DIR}/TerrainRenderer.cpp + ${TERRAIN_DIR}/TerrainSettings.cpp + ${TERRAIN_DIR}/Thread.cpp + ${TERRAIN_DIR}/WorldFile.cpp + ${TERRAIN_DIR}/ZzipStream.cpp + + ${TERRAIN_DIR}/AsyncLoader.cpp +) +if(0) # # jasper is an own project.. + +# set(JASSRC Terrain/jasper) # klappt nicht... +set(JASSRC jasper) +# set(JASSRC ${CMAKE_CURRENT_SOURCE_DIR}/jasper) +list(APPEND _SOURCES +# list(APPEND jasper_SOURCES + ${JASSRC}/jpc/jpc_bs.c + ${JASSRC}/jpc/jpc_cs.c + ${JASSRC}/jpc/jpc_dec.c + ${JASSRC}/jpc/jpc_math.c + ${JASSRC}/jpc/jpc_mqdec.c + ${JASSRC}/jpc/jpc_mqcod.c + ${JASSRC}/jpc/jpc_qmfb.c + ${JASSRC}/jpc/jpc_rtc.cpp + ${JASSRC}/jpc/jpc_t1dec.c + ${JASSRC}/jpc/jpc_t1cod.c + ${JASSRC}/jpc/jpc_t2dec.c + ${JASSRC}/jpc/jpc_t2cod.c + ${JASSRC}/jpc/jpc_tagtree.c + ${JASSRC}/jpc/jpc_tsfb.c + + ${JASSRC}/base/jas_stream.c + ${JASSRC}/base/jas_seq.c + ${JASSRC}/base/jas_malloc.c +) +endif(0) # # jasper is an own project.. + + +set(SCRIPT_FILES CMakeSource.cmake) + +add_compile_definitions(JAS_INCLUDE_JPG_CODEC=1) diff --git a/src/Terrain/Loader.cpp b/src/Terrain/Loader.cpp index 68cf7ebe580..492f8b303ff 100644 --- a/src/Terrain/Loader.cpp +++ b/src/Terrain/Loader.cpp @@ -43,7 +43,9 @@ TerrainLoader::SkipMarkerSegment(long file_offset) const while (segment->IsTileSegment() && !raster_tile_cache.tiles.GetLinear(segment->tile).IsRequested()) { ++segment; - if (segment >= raster_tile_cache.segments.end()) +// TODO(August2111): if (segment >= raster_tile_cache.segments.end()) +// MSVC: not allowed too: if (segment == raster_tile_cache.segments.end()) + if (segment == &(*raster_tile_cache.segments.end())) /* last segment is hidden; shouldn't happen either, because we expect EOC there */ break; @@ -112,7 +114,7 @@ TerrainLoader::ParseBounds(const char *data) /* this code is obsolete, since new map files include a "world file", but we keep it for compatibility */ - data = strstr(data, "XCSoar"); + data = strstr(data, "OpenSoar"); if (data == nullptr) return; diff --git a/src/Terrain/RasterTerrain.cpp b/src/Terrain/RasterTerrain.cpp index 08ed7dde7b6..84d06a9f280 100644 --- a/src/Terrain/RasterTerrain.cpp +++ b/src/Terrain/RasterTerrain.cpp @@ -12,10 +12,9 @@ #include "io/BufferedReader.hxx" #include "system/ConvertPathName.hpp" #include "Operation/Operation.hpp" -#include "util/ConvertString.hpp" #include "LogFile.hpp" -static const TCHAR *const terrain_cache_name = _T("terrain"); +static const char *const terrain_cache_name = "terrain"; inline bool RasterTerrain::LoadCache(FileCache &cache, Path path) diff --git a/src/Terrain/RasterTileCache.cpp b/src/Terrain/RasterTileCache.cpp index 874e6c76006..6a9b77b2c74 100644 --- a/src/Terrain/RasterTileCache.cpp +++ b/src/Terrain/RasterTileCache.cpp @@ -267,8 +267,17 @@ RasterTileCache::SaveCache(BufferedOutputStream &os) const header.num_marker_segments = segments.size(); header.bounds = bounds; +#ifdef TEST_AUGUST + // TODO(August2111): Das war der Workaround vor 7.32?? + // TODO(August2111): wieder neu angefasst beo merge 7.40 + // kann ich es jetzt so lassen + os.Write(&header, sizeof(header)); + // TODO(August2111): error MSVC! + os.Write(&(*segments.begin()), sizeof(*segments.begin()) * segments.size()); +#else os.Write(ReferenceAsBytes(header)); os.Write(std::as_bytes(std::span{segments})); +#endif /* save tiles */ unsigned i; diff --git a/src/Terrain/jasper/CMakeLists.txt b/src/Terrain/jasper/CMakeLists.txt new file mode 100644 index 00000000000..543e70323b8 --- /dev/null +++ b/src/Terrain/jasper/CMakeLists.txt @@ -0,0 +1,78 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + + project(${TARGET_NAME}) ### CXX) # Your project name + +# include(${CMAKE_CURRENT_SOURCE_DIR}/CMakeSource.cmake) +if (EXISTS CMakeSource.cmake) + include(CMakeSource.cmake) +# message(FATAL_ERROR "Stop: ${CMAKE_CURRENT_SOURCE_DIR}/CMakeSource.cmake found") +elseif(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/CMakeSource.cmake) + # message(STATUS "!!! ${CMAKE_CURRENT_SOURCE_DIR}/CMakeSource.cmake found") + include(${CMAKE_CURRENT_SOURCE_DIR}/CMakeSource.cmake) +endif() +# organize the files in subdirectories + +# list(APPEND ${TARGET_NAME}_SOURCES ${TARGET_NAME}/jpc_rtc.cpp) +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + list(APPEND SOURCE_FILES ${source_file}) + + # set_source_files_properties(${source_file} PROPERTIES LANGUAGE CXX) + + # string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" source_file ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES "${source_file}") + ### hide: message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +# with jasper...: +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# without jasper...: file(GLOB HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() + ## message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +get_filename_component(INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/.. ABSOLUTE) +include_directories(${INCLUDE_DIR}) +# include_directories(${3rd_Party}/jasper/Jasper-2.0.0/src/jasper) +# include_directories(${3rd_Party}/_install/jasper/JasPer_2.0.0/include) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +target_link_libraries(${TARGET_NAME} PUBLIC + ${ZZIP_LIB} +) + +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Topo) + +add_dependencies(${TARGET_NAME} util) + +if (ON) # aug: nur bei MinGW notwendig??? + add_dependencies(${TARGET_NAME} zzip) +endif() + diff --git a/src/Terrain/jasper/CMakeSource.cmake b/src/Terrain/jasper/CMakeSource.cmake new file mode 100644 index 00000000000..e49652caf0a --- /dev/null +++ b/src/Terrain/jasper/CMakeSource.cmake @@ -0,0 +1,28 @@ +# set(JASSRC Terrain/jasper) # klappt nicht... +# set(JASSRC jasper) +set(JASSRC .) +# set(JASSRC ${CMAKE_CURRENT_SOURCE_DIR}/jasper) +list(APPEND _SOURCES + ${JASSRC}/jpc/jpc_bs.c + ${JASSRC}/jpc/jpc_cs.c + ${JASSRC}/jpc/jpc_dec.c + ${JASSRC}/jpc/jpc_math.c + ${JASSRC}/jpc/jpc_mqdec.c + ${JASSRC}/jpc/jpc_mqcod.c + ${JASSRC}/jpc/jpc_qmfb.c + ${JASSRC}/jpc/jpc_rtc.cpp + ${JASSRC}/jpc/jpc_t1dec.c + ${JASSRC}/jpc/jpc_t1cod.c + ${JASSRC}/jpc/jpc_t2dec.c + ${JASSRC}/jpc/jpc_t2cod.c + ${JASSRC}/jpc/jpc_tagtree.c + ${JASSRC}/jpc/jpc_tsfb.c + + ${JASSRC}/jp2/jp2_cod.c + + ${JASSRC}/base/jas_stream.c + ${JASSRC}/base/jas_seq.c + ${JASSRC}/base/jas_malloc.c +) + +set(SCRIPT_FILES CMakeSource.cmake) diff --git a/src/Terrain/jasper/jas_config.h b/src/Terrain/jasper/jas_config.h index 73128e869f9..dbe28aa845a 100644 --- a/src/Terrain/jasper/jas_config.h +++ b/src/Terrain/jasper/jas_config.h @@ -5,11 +5,19 @@ #define JAS_VERSION "unknown" #define JAS_ENABLE_32BIT 1 #define JAS_HAVE_FCNTL_H 1 -#undef JAS_HAVE_IO_H -#define JAS_HAVE_UNISTD_H 1 -#undef JAS_HAVE_WINDOWS_H -#define JAS_HAVE_SYS_TIME_H 1 -#define JAS_HAVE_SYS_TYPES_H 1 +#ifdef _WIN32// TODO(August2111) +# define JAS_HAVE_IO_H 1 +# undef JAS_HAVE_UNISTD_H +# define JAS_HAVE_WINDOWS_H 1 +# undef JAS_HAVE_SYS_TIME_H +# undef JAS_HAVE_SYS_TYPES_H +#else // _WIN32// TODO(August2111) +# undef JAS_HAVE_IO_H +# define JAS_HAVE_UNISTD_H 1 +# undef JAS_HAVE_WINDOWS_H +# define JAS_HAVE_SYS_TIME_H 1 +# define JAS_HAVE_SYS_TYPES_H 1 +#endif // _WIN32// TODO(August2111) #undef JAS_HAVE_GETTIMEOFDAY #undef JAS_HAVE_GETRUSAGE diff --git a/src/Topography/CMakeLists.txt b/src/Topography/CMakeLists.txt new file mode 100644 index 00000000000..5581c12dfaf --- /dev/null +++ b/src/Topography/CMakeLists.txt @@ -0,0 +1,56 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories + + +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) + +target_link_libraries(${TARGET_NAME} PUBLIC + thread +) + +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Topo) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/Topography/CMakeSource.cmake b/src/Topography/CMakeSource.cmake new file mode 100644 index 00000000000..ea86c33589c --- /dev/null +++ b/src/Topography/CMakeSource.cmake @@ -0,0 +1,30 @@ +set(_SOURCES + Topography/CachedTopographyRenderer.cpp + Topography/Thread.cpp + Topography/TopographyFile.cpp + Topography/TopographyFileRenderer.cpp + Topography/TopographyGlue.cpp + Topography/TopographyRenderer.cpp + Topography/TopographyStore.cpp + Topography/XShape.cpp + Topography/Index.cpp + Topography/ShapeFile.cpp +) + +list(APPEND _SOURCES + Topography/shapelib/mapalloc.c + Topography/shapelib/mapbits.c + Topography/shapelib/mapprimitive.c + Topography/shapelib/mapsearch.c + Topography/shapelib/mapshape.c + Topography/shapelib/mapstring.cpp + Topography/shapelib/maptree.c + Topography/shapelib/mapxbase.c +) + +set(SCRIPT_FILES + CMakeSource.cmake +) + + + diff --git a/src/Topography/Index.cpp b/src/Topography/Index.cpp index a96641b4830..a54373da5a6 100644 --- a/src/Topography/Index.cpp +++ b/src/Topography/Index.cpp @@ -82,7 +82,7 @@ ParseTopographyIndexLine(const char *line) noexcept // Parse shape range char *endptr; entry.shape_range = strtod(p + 1, &endptr) * 1000; - if (*endptr != _T(',')) + if (*endptr != ',') return std::nullopt; p = endptr + 1; @@ -112,21 +112,21 @@ ParseTopographyIndexLine(const char *line) noexcept // Parse shape field for text display entry.shape_field = strtol(p + 1, &endptr, 10) - 1; - if (*endptr != _T(',')) + if (*endptr != ',') return std::nullopt; p = endptr + 1; // Parse red component of line / shading colour uint8_t red = (uint8_t)strtol(p, &endptr, 10); - if (*endptr != _T(',')) + if (*endptr != ',') return std::nullopt; p = endptr + 1; // Parse green component of line / shading colour uint8_t green = (uint8_t)strtol(p, &endptr, 10); - if (*endptr != _T(',')) + if (*endptr != ',') return std::nullopt; p = endptr + 1; @@ -138,7 +138,7 @@ ParseTopographyIndexLine(const char *line) noexcept // Parse pen width of lines entry.pen_width = 1; - if (*p == _T(',')) { + if (*p == ',') { entry.pen_width = strtoul(p + 1, &endptr, 10); if (entry.pen_width < 1) entry.pen_width = 1; @@ -150,14 +150,14 @@ ParseTopographyIndexLine(const char *line) noexcept // Parse range for displaying labels entry.label_range = entry.shape_range; - if (*p == _T(',')) { + if (*p == ',') { entry.label_range = strtod(p + 1, &endptr) * 1000; p = endptr; } // Parse range for displaying labels with "important" rendering style entry.important_label_range = 0; - if (*p == _T(',')) { + if (*p == ',') { entry.important_label_range = strtod(p + 1, &endptr) * 1000; p = endptr; } @@ -165,7 +165,7 @@ ParseTopographyIndexLine(const char *line) noexcept // Handle alpha component // If not present at all (i.e. v6.6 or earlier file), default to 100% opaque uint8_t alpha = 255; - if (*p == _T(',')) { + if (*p == ',') { // An alpha component of shading colour is present (v6.7 or later file). alpha = (uint8_t)strtol(p + 1, &endptr, 10); // Ignore a totally transparent file! diff --git a/src/Topography/TopographyFileRenderer.cpp b/src/Topography/TopographyFileRenderer.cpp index 97d1000603b..40e2e0a32f6 100644 --- a/src/Topography/TopographyFileRenderer.cpp +++ b/src/Topography/TopographyFileRenderer.cpp @@ -12,7 +12,7 @@ #include "Screen/Layout.hpp" #include "shapelib/mapserver.h" #include "util/AllocatedArray.hxx" -#include "util/tstring.hpp" +#include #include "Geo/GeoClip.hpp" #include "Geo/FAISphere.hpp" @@ -370,14 +370,14 @@ TopographyFileRenderer::PaintLabels(Canvas &canvas, int iskip = file.GetSkipSteps(map_scale); - std::set drawn_labels; + std::set drawn_labels; // Iterate over all shapes in the file for (const XShape *shape_p : visible_labels) { const XShape &shape = *shape_p; // Skip shapes without a label - const TCHAR *label = shape.GetLabel(); + const char *label = shape.GetLabel(); assert(label != nullptr); const auto lines = shape.GetLines(); diff --git a/src/Topography/XShape.cpp b/src/Topography/XShape.cpp index 55b67db4ffa..9446de616f2 100644 --- a/src/Topography/XShape.cpp +++ b/src/Topography/XShape.cpp @@ -14,16 +14,12 @@ #include "ui/canvas/opengl/Triangulate.hpp" #endif -#ifdef _UNICODE -#include "util/ConvertString.hpp" -#endif - #include #include #include -static BasicAllocatedString +static BasicAllocatedString ImportLabel(const char *src) noexcept { if (src == nullptr) @@ -35,14 +31,10 @@ ImportLabel(const char *src) noexcept StringIsEqual(src, "UNK")) return nullptr; -#ifdef _UNICODE - return ConvertUTF8ToWide(src); -#else if (!ValidateUTF8(src)) return nullptr; - return BasicAllocatedString(src); -#endif + return BasicAllocatedString(src); } /** diff --git a/src/Topography/XShape.hpp b/src/Topography/XShape.hpp index 1a3a9a937cf..be6467f647d 100644 --- a/src/Topography/XShape.hpp +++ b/src/Topography/XShape.hpp @@ -75,7 +75,7 @@ class XShape { mutable unsigned offset; #endif - BasicAllocatedString label; + BasicAllocatedString label; public: /** @@ -129,7 +129,7 @@ class XShape { return points.get(); } - const TCHAR *GetLabel() const noexcept { + const char *GetLabel() const noexcept { return label.c_str(); } }; diff --git a/src/Topography/shapelib/mapshape.c b/src/Topography/shapelib/mapshape.c index 9abf0cf58d0..da07633b2a7 100644 --- a/src/Topography/shapelib/mapshape.c +++ b/src/Topography/shapelib/mapshape.c @@ -43,7 +43,6 @@ #include #include -#include #include #include #include "mapserver.h" diff --git a/src/Topography/shapelib/maptree.c b/src/Topography/shapelib/maptree.c index 2b940a83760..60fadb54724 100644 --- a/src/Topography/shapelib/maptree.c +++ b/src/Topography/shapelib/maptree.c @@ -49,7 +49,6 @@ #include #include -#include #include /* -------------------------------------------------------------------- */ diff --git a/src/Tracking/CMakeLists.txt b/src/Tracking/CMakeLists.txt new file mode 100644 index 00000000000..649a62c18a9 --- /dev/null +++ b/src/Tracking/CMakeLists.txt @@ -0,0 +1,55 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories + + +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +target_link_libraries(${TARGET_NAME} PUBLIC co net) + +# add_dependencies(${TARGET_NAME} curl) +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} + PROPERTIES FOLDER Libs +# DEPENDENCIES curl +) diff --git a/src/Tracking/CMakeSource.cmake b/src/Tracking/CMakeSource.cmake new file mode 100644 index 00000000000..d97b8674787 --- /dev/null +++ b/src/Tracking/CMakeSource.cmake @@ -0,0 +1,16 @@ +set(_SOURCES + Tracking/LiveTrack24/SessionID.cpp + Tracking/LiveTrack24/Glue.cpp + Tracking/LiveTrack24/Client.cpp + + Tracking/SkyLines/Assemble.cpp + Tracking/SkyLines/Client.cpp + Tracking/SkyLines/Glue.cpp + Tracking/SkyLines/Key.cpp + + Tracking/TrackingGlue.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake +) diff --git a/src/Tracking/LiveTrack24/Client.cpp b/src/Tracking/LiveTrack24/Client.cpp index 494264289dc..28c05d23ee7 100644 --- a/src/Tracking/LiveTrack24/Client.cpp +++ b/src/Tracking/LiveTrack24/Client.cpp @@ -4,7 +4,6 @@ #include "Client.hpp" #include "Operation/Operation.hpp" #include "util/StringCompare.hxx" -#include "util/ConvertString.hpp" #include "lib/curl/CoRequest.hxx" #include "lib/curl/Setup.hxx" #include "lib/fmt/RuntimeError.hxx" @@ -22,7 +21,7 @@ using std::string_view_literals::operator""sv; namespace LiveTrack24 { Co::Task -Client::GetUserID(const TCHAR *username, const TCHAR *password) +Client::GetUserID(const char *username, const char *password) { // http://www.livetrack24.com/client.php?op=login&user=&pass= @@ -35,16 +34,11 @@ Client::GetUserID(const TCHAR *username, const TCHAR *password) CurlEasy easy; { - const WideToUTF8Converter username2(username); - const WideToUTF8Converter password2(password); - if (!username2.IsValid() || !password2.IsValid()) - throw std::runtime_error("WideToUTF8Converter failed"); - - NarrowString<1024> url; + StaticString<1024> url; url.Format("http://%s/client.php?op=login&user=%s&pass=%s", GetServer(), - easy.Escape(username2).c_str(), - easy.Escape(password2).c_str()); + easy.Escape(username).c_str(), + easy.Escape(password).c_str()); easy.SetURL(url); } @@ -63,9 +57,9 @@ Client::GetUserID(const TCHAR *username, const TCHAR *password) } Co::Task -Client::StartTracking(SessionID session, const TCHAR *username, - const TCHAR *password, [[maybe_unused]] unsigned tracking_interval, - VehicleType vtype, const TCHAR *vname) +Client::StartTracking(SessionID session, const char *username, + const char *password, [[maybe_unused]] unsigned tracking_interval, + VehicleType vtype, const char *vname) { // http://www.livetrack24.com/track.php?leolive=2&sid=42664778&pid=1& // client=YourProgramName&v=1&user=yourusername&pass=yourpass& @@ -75,28 +69,17 @@ Client::StartTracking(SessionID session, const TCHAR *username, CurlEasy easy; { - const WideToUTF8Converter username2(username); - const WideToUTF8Converter password2(password); - const WideToUTF8Converter vname2(vname); - if (!username2.IsValid() || !password2.IsValid() || !vname2.IsValid()) - throw std::runtime_error("WideToUTF8Converter failed"); - -#ifdef _UNICODE - NarrowString<32> version; - version.SetASCII(XCSoar_VersionLong); -#else - const char *version = XCSoar_VersionLong; -#endif - - NarrowString<2048> url; + const char *version = OpenSoar_VersionLong; + StaticString<2048> url; url.Format("http://%s/track.php?leolive=2&sid=%u&pid=%u&" "client=%s&v=%s&user=%s&pass=%s&vtype=%u&vname=%s", GetServer(), session, 1, +// "OpenSoar", easy.Escape(version).c_str(), "XCSoar", easy.Escape(version).c_str(), - easy.Escape(username2).c_str(), - easy.Escape(password2).c_str(), + easy.Escape(username).c_str(), + easy.Escape(password).c_str(), vtype, - easy.Escape(vname2).c_str()); + easy.Escape(vname).c_str()); easy.SetURL(url); } @@ -113,7 +96,7 @@ Client::SendPosition(SessionID session, unsigned packet_id, // http://www.livetrack24.com/track.php?leolive=4&sid=42664778&pid=321& // lat=22.3&lon=40.2&alt=23&sog=40&cog=160&tm=1241422845 - NarrowString<2048> url; + StaticString<2048> url; url.Format("http://%s/track.php?leolive=4&sid=%u&pid=%u&" "lat=%f&lon=%f&alt=%d&sog=%d&cog=%d&tm=%lld", GetServer(), session, packet_id, @@ -131,7 +114,7 @@ Client::EndTracking(SessionID session, unsigned packet_id) { // http://www.livetrack24.com/track.php?leolive=3&sid=42664778&pid=453&prid=0 - NarrowString<1024> url; + StaticString<1024> url; url.Format("http://%s/track.php?leolive=3&sid=%u&pid=%u&prid=0", GetServer(), session, packet_id); @@ -139,7 +122,7 @@ Client::EndTracking(SessionID session, unsigned packet_id) } void -Client::SetServer(const TCHAR * _server) noexcept +Client::SetServer(const char * _server) noexcept { server.SetASCII(_server); } diff --git a/src/Tracking/LiveTrack24/Client.hpp b/src/Tracking/LiveTrack24/Client.hpp index f66baddadc6..e1f0739113f 100644 --- a/src/Tracking/LiveTrack24/Client.hpp +++ b/src/Tracking/LiveTrack24/Client.hpp @@ -42,7 +42,7 @@ namespace LiveTrack24 { class Client final { CurlGlobal &curl; - NarrowString<256> server; + StaticString<256> server; public: explicit Client(CurlGlobal &_curl) noexcept @@ -54,12 +54,12 @@ class Client final { * @param password Case-insensitive password * @return 0 if userdata are incorrect, or else the userID of the user */ - Co::Task GetUserID(const TCHAR *username, const TCHAR *password); + Co::Task GetUserID(const char *username, const char *password); /** Sends the "start of track" packet to the tracking server */ - Co::Task StartTracking(SessionID session, const TCHAR *username, - const TCHAR *password, unsigned tracking_interval, - VehicleType vtype, const TCHAR *vname); + Co::Task StartTracking(SessionID session, const char *username, + const char *password, unsigned tracking_interval, + VehicleType vtype, const char *vname); /** * Sends a "gps point" packet to the tracking server @@ -79,7 +79,7 @@ class Client final { * Set the tracking server * @param server e.g. www.livetrack24.com (without http:// prefix) */ - void SetServer(const TCHAR *server) noexcept; + void SetServer(const char *server) noexcept; private: const char *GetServer() const noexcept { diff --git a/src/Tracking/LiveTrack24/Settings.hpp b/src/Tracking/LiveTrack24/Settings.hpp index 57ec426ec18..059469249c6 100644 --- a/src/Tracking/LiveTrack24/Settings.hpp +++ b/src/Tracking/LiveTrack24/Settings.hpp @@ -36,7 +36,7 @@ struct Settings { void SetDefaults() { enabled = false; - server = _T("www.livetrack24.com"); + server = "www.livetrack24.com"; username.clear(); password.clear(); diff --git a/src/Tracking/SkyLines/Assemble.cpp b/src/Tracking/SkyLines/Assemble.cpp index 924e9e71904..d09ec7247a7 100644 --- a/src/Tracking/SkyLines/Assemble.cpp +++ b/src/Tracking/SkyLines/Assemble.cpp @@ -211,7 +211,7 @@ SkyLinesTracking::MakeThermalRequest(uint64_t key) SkyLinesTracking::TrafficRequestPacket SkyLinesTracking::MakeTrafficRequest(uint64_t key, bool followees, bool club, - bool near) + bool _near) { assert(key != 0); @@ -222,7 +222,7 @@ SkyLinesTracking::MakeTrafficRequest(uint64_t key, bool followees, bool club, packet.header.key = ToBE64(key); packet.flags = ToBE32((followees ? packet.FLAG_FOLLOWEES : 0) | (club ? packet.FLAG_CLUB : 0) - | (near ? packet.FLAG_NEAR : 0)); + | (_near ? packet.FLAG_NEAR : 0)); packet.reserved = 0; packet.header.crc = ToBE16(UpdateCRC16CCITT(ReferenceAsBytes(packet), 0)); diff --git a/src/Tracking/SkyLines/Client.cpp b/src/Tracking/SkyLines/Client.cpp index c50eff09825..a3e2ee144c7 100644 --- a/src/Tracking/SkyLines/Client.cpp +++ b/src/Tracking/SkyLines/Client.cpp @@ -14,7 +14,6 @@ #include "net/UniqueSocketDescriptor.hxx" #include "util/CRC16CCITT.hpp" #include "util/UTF8.hpp" -#include "util/ConvertString.hpp" #include #include @@ -55,6 +54,10 @@ SkyLinesTracking::Client::Open(SocketAddress _address) handler->OnSkyLinesReady(); } +#ifdef _WIN32 + GetSocket().SetNonBlocking(); +#endif + return true; } @@ -163,8 +166,7 @@ SkyLinesTracking::Client::OnUserNameReceived(const UserNameResponsePacket &packe if (!ValidateUTF8(name.c_str())) return; - UTF8ToWideConverter tname(name.c_str()); - handler->OnUserName(FromBE32(packet.user_id), tname); + handler->OnUserName(FromBE32(packet.user_id), name.c_str()); } inline void diff --git a/src/Tracking/SkyLines/Data.hpp b/src/Tracking/SkyLines/Data.hpp index ec713bfda24..e724e1b99f3 100644 --- a/src/Tracking/SkyLines/Data.hpp +++ b/src/Tracking/SkyLines/Data.hpp @@ -5,7 +5,7 @@ #include "Geo/GeoPoint.hpp" #include "thread/Mutex.hxx" -#include "util/tstring.hpp" +#include #include #include @@ -76,7 +76,7 @@ struct Data { * A database of user-id to display-name. An empty string means * the server has failed/refused to supply a name. */ - std::map user_names; + std::map user_names; std::list waves; diff --git a/src/Tracking/SkyLines/Handler.hpp b/src/Tracking/SkyLines/Handler.hpp index b17ca576507..0384af110a4 100644 --- a/src/Tracking/SkyLines/Handler.hpp +++ b/src/Tracking/SkyLines/Handler.hpp @@ -27,7 +27,7 @@ class Handler { virtual void OnAck([[maybe_unused]] unsigned id) {} virtual void OnTraffic([[maybe_unused]] uint32_t pilot_id, [[maybe_unused]] unsigned time_of_day_ms, [[maybe_unused]] const ::GeoPoint &location, [[maybe_unused]] int altitude) {} - virtual void OnUserName([[maybe_unused]] uint32_t user_id, [[maybe_unused]] const TCHAR *name) {} + virtual void OnUserName([[maybe_unused]] uint32_t user_id, [[maybe_unused]] const char *name) {} virtual void OnWave([[maybe_unused]] unsigned time_of_day_ms, [[maybe_unused]] const ::GeoPoint &a, [[maybe_unused]] const ::GeoPoint &b) {} virtual void OnThermal([[maybe_unused]] unsigned time_of_day_ms, diff --git a/src/Tracking/TrackingGlue.cpp b/src/Tracking/TrackingGlue.cpp index 12daed40e2f..351d2bbb824 100644 --- a/src/Tracking/TrackingGlue.cpp +++ b/src/Tracking/TrackingGlue.cpp @@ -54,7 +54,7 @@ TrackingGlue::OnTraffic(uint32_t pilot_id, unsigned time_of_day_ms, } void -TrackingGlue::OnUserName(uint32_t user_id, const TCHAR *name) +TrackingGlue::OnUserName(uint32_t user_id, const char *name) { const std::lock_guard lock{skylines_data.mutex}; skylines_data.user_names[user_id] = name; diff --git a/src/Tracking/TrackingGlue.hpp b/src/Tracking/TrackingGlue.hpp index 9c7245177ae..9edb51ec361 100644 --- a/src/Tracking/TrackingGlue.hpp +++ b/src/Tracking/TrackingGlue.hpp @@ -37,7 +37,7 @@ class TrackingGlue final /* virtual methods from SkyLinesTracking::Handler */ virtual void OnTraffic(uint32_t pilot_id, unsigned time_of_day_ms, const GeoPoint &location, int altitude) override; - virtual void OnUserName(uint32_t user_id, const TCHAR *name) override; + virtual void OnUserName(uint32_t user_id, const char *name) override; void OnWave(unsigned time_of_day_ms, const GeoPoint &a, const GeoPoint &b) override; void OnThermal(unsigned time_of_day_ms, diff --git a/src/TransponderCode.cpp b/src/TransponderCode.cpp index a8e7aabdff4..bf29934ca4f 100644 --- a/src/TransponderCode.cpp +++ b/src/TransponderCode.cpp @@ -6,20 +6,20 @@ #include "util/NumberParser.hpp" #include "util/StringFormat.hpp" -TCHAR * -TransponderCode::Format(TCHAR *buffer, std::size_t max_size) const noexcept +char * +TransponderCode::Format(char *buffer, std::size_t max_size) const noexcept { if (!IsDefined()) return nullptr; - StringFormat(buffer, max_size, _T("%04o"), value); + StringFormat(buffer, max_size, "%04o", value); return buffer; } TransponderCode -TransponderCode::Parse(const TCHAR *s) noexcept +TransponderCode::Parse(const char *s) noexcept { - TCHAR *endptr; + char *endptr; const auto value = ParseUnsigned(s, &endptr, 8); auto result = Null(); diff --git a/src/TransponderCode.hpp b/src/TransponderCode.hpp index 17f7f7e9d35..fdb78c18d46 100644 --- a/src/TransponderCode.hpp +++ b/src/TransponderCode.hpp @@ -55,8 +55,8 @@ class TransponderCode { *this = Null(); } - TCHAR *Format(TCHAR *buffer, std::size_t max_size) const noexcept; + char *Format(char *buffer, std::size_t max_size) const noexcept; [[gnu::pure]] - static TransponderCode Parse(const TCHAR *s) noexcept; + static TransponderCode Parse(const char *s) noexcept; }; diff --git a/src/UIActions.cpp b/src/UIActions.cpp index fab4d9c0608..7cd8c173953 100644 --- a/src/UIActions.cpp +++ b/src/UIActions.cpp @@ -14,7 +14,12 @@ #include "Look/Look.hpp" #include "HorizonWidget.hpp" +#ifdef _WIN32 +// On Windows the default option should be forced! +static bool force_shutdown = true; +#else static bool force_shutdown = false; +#endif void UIActions::SignalShutdown(bool force) @@ -29,43 +34,61 @@ UIActions::CheckShutdown() if (force_shutdown) return true; - return ShowMessageBox(_("Quit program?"), _T("XCSoar"), - MB_YESNO | MB_ICONQUESTION) == IDYES; + switch (UI::TopWindow::GetExitValue()) { +#if defined(IS_OPENVARIO) + case EXIT_REBOOT: + return ShowMessageBox(_("Reboot System?"), "OpenSoar", + MB_YESNO | MB_ICONQUESTION) == IDYES; + case EXIT_SHUTDOWN: + return ShowMessageBox(_("Shutdown System?"), "OpenSoar", + MB_YESNO | MB_ICONQUESTION) == IDYES; + case EXIT_NEWSTART: + return ShowMessageBox(_("Quit and Restart OpenSoar?"), "OpenSoar", + MB_YESNO | MB_ICONQUESTION) == IDYES; +#endif + case EXIT_RESTART: + return ShowMessageBox(_("Short Internal Restart?"), "OpenSoar", + MB_YESNO | MB_ICONQUESTION) == IDYES; + case EXIT_SYSTEM: + default: + return ShowMessageBox(_("Quit program?"), "OpenSoar", + MB_YESNO | MB_ICONQUESTION) == IDYES; + } } void UIActions::ShowTrafficRadar() { - if (InputEvents::IsFlavour(_T("Traffic"))) + if (InputEvents::IsFlavour("Traffic")) return; LoadFlarmDatabases(); CommonInterface::main_window->SetWidget(new TrafficWidget()); - InputEvents::SetFlavour(_T("Traffic")); + InputEvents::SetFlavour("Traffic"); } void UIActions::ShowThermalAssistant() { - if (InputEvents::IsFlavour(_T("TA"))) + if (InputEvents::IsFlavour("TA")) return; auto ta_widget = new BigThermalAssistantWidget(CommonInterface::GetLiveBlackboard(), UIGlobals::GetLook().thermal_assistant_dialog); CommonInterface::main_window->SetWidget(ta_widget); - InputEvents::SetFlavour(_T("TA")); + InputEvents::SetFlavour("TA"); } void UIActions::ShowHorizon() { - if (InputEvents::IsFlavour(_T("Horizon"))) + if (InputEvents::IsFlavour("Horizon")) return; auto widget = new HorizonWidget(); CommonInterface::main_window->SetWidget(widget); - InputEvents::SetFlavour(_T("Horizon")); + InputEvents::SetFlavour("Horizon"); } diff --git a/src/UIGlobals.cpp b/src/UIGlobals.cpp index b0848575ffa..14cce194cc5 100644 --- a/src/UIGlobals.cpp +++ b/src/UIGlobals.cpp @@ -75,3 +75,6 @@ UIGlobals::GetMapLook() return CommonInterface::main_window->GetLook().map; } + + +const char *UIGlobals::CommandLine = nullptr; diff --git a/src/UIGlobals.hpp b/src/UIGlobals.hpp index b5f11d2e73e..200c2174410 100644 --- a/src/UIGlobals.hpp +++ b/src/UIGlobals.hpp @@ -3,6 +3,8 @@ #pragma once +#include + namespace UI { class SingleWindow; } class GlueMapWindow; struct DialogSettings; @@ -50,4 +52,7 @@ namespace UIGlobals { [[gnu::const]] const MapLook &GetMapLook(); -}; + + extern const char *CommandLine; + + }; diff --git a/src/UIUtil/CMakeLists.txt b/src/UIUtil/CMakeLists.txt new file mode 100644 index 00000000000..c79a42de2ee --- /dev/null +++ b/src/UIUtil/CMakeLists.txt @@ -0,0 +1,51 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories + + +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/UIUtil/CMakeSource.cmake b/src/UIUtil/CMakeSource.cmake new file mode 100644 index 00000000000..1e9f6052fde --- /dev/null +++ b/src/UIUtil/CMakeSource.cmake @@ -0,0 +1,9 @@ +set(_SOURCES + UIUtil/GestureManager.cpp + UIUtil/KineticManager.cpp + UIUtil/TrackingGestureManager.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake +) diff --git a/src/UIUtil/GestureManager.cpp b/src/UIUtil/GestureManager.cpp index 41d8dd819f2..a1f0654be35 100644 --- a/src/UIUtil/GestureManager.cpp +++ b/src/UIUtil/GestureManager.cpp @@ -5,19 +5,19 @@ #include "Math/FastMath.hpp" #include "util/Compiler.h" -[[gnu::const]] static TCHAR +[[gnu::const]] static char getDirection(int dx, int dy) { if (dy < 0 && -dy >= abs(dx) * 2) - return _T('U'); + return 'U'; if (dy > 0 && dy >= abs(dx) * 2) - return _T('D'); + return 'D'; if (dx > 0 && dx >= abs(dy) * 2) - return _T('R'); + return 'R'; if (dx < 0 && -dx >= abs(dy) * 2) - return _T('L'); + return 'L'; - return _T('\0'); + return '\0'; } bool @@ -34,7 +34,7 @@ GestureManager::Update(PixelPoint p) drag_last = p; // Get current dragging direction - TCHAR direction = getDirection(d.x, d.y); + char direction = getDirection(d.x, d.y); // Return if we are in an unclear direction if (direction == '\0') @@ -60,13 +60,13 @@ GestureManager::Start(PixelPoint p, int _threshold) threshold = _threshold; } -const TCHAR* +const char* GestureManager::Finish() { return GetGesture(); } -const TCHAR* +const char* GestureManager::GetGesture() const { return gesture.empty() diff --git a/src/UIUtil/GestureManager.hpp b/src/UIUtil/GestureManager.hpp index 1ee22251a7c..2f8bfaf21ec 100644 --- a/src/UIUtil/GestureManager.hpp +++ b/src/UIUtil/GestureManager.hpp @@ -34,13 +34,13 @@ class GestureManager * Returns the recognized gesture * @return NULL or recognized gesture string */ - const TCHAR* GetGesture() const; + const char* GetGesture() const; /** * Stops the GestureManager and returns the recognized gesture * @return NULL or recognized gesture string */ - const TCHAR* Finish(); + const char* Finish(); /** * Starts the GestureManager at the given coordinates diff --git a/src/UIUtil/TrackingGestureManager.cpp b/src/UIUtil/TrackingGestureManager.cpp index 2162a4d455c..c27274b29c6 100644 --- a/src/UIUtil/TrackingGestureManager.cpp +++ b/src/UIUtil/TrackingGestureManager.cpp @@ -31,7 +31,7 @@ TrackingGestureManager::Start(PixelPoint p, int threshold) GestureManager::Start(p, threshold); } -const TCHAR* +const char* TrackingGestureManager::Finish() { points.clear(); diff --git a/src/UIUtil/TrackingGestureManager.hpp b/src/UIUtil/TrackingGestureManager.hpp index d3b94268633..34f693a04f9 100644 --- a/src/UIUtil/TrackingGestureManager.hpp +++ b/src/UIUtil/TrackingGestureManager.hpp @@ -26,7 +26,7 @@ class TrackingGestureManager: public GestureManager * Stops the GestureManager and returns the recognized gesture * @return NULL or recognized gesture string */ - const TCHAR* Finish(); + const char* Finish(); /** * Starts the GestureManager at the given coordinates diff --git a/src/Units/CMakeLists.txt b/src/Units/CMakeLists.txt new file mode 100644 index 00000000000..c79a42de2ee --- /dev/null +++ b/src/Units/CMakeLists.txt @@ -0,0 +1,51 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories + + +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/Units/CMakeSource.cmake b/src/Units/CMakeSource.cmake new file mode 100644 index 00000000000..961a07073e0 --- /dev/null +++ b/src/Units/CMakeSource.cmake @@ -0,0 +1,13 @@ +set(_SOURCES + Units/Descriptor.cpp + Units/Settings.cpp + Units/System.cpp + Units/Temperature.cpp + Units/Units.cpp + Units/UnitsGlue.cpp + Units/UnitsStore.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake +) diff --git a/src/Units/Descriptor.cpp b/src/Units/Descriptor.cpp index bc8f0f055f2..ab29ee2137b 100644 --- a/src/Units/Descriptor.cpp +++ b/src/Units/Descriptor.cpp @@ -13,39 +13,39 @@ const UnitDescriptor Units::unit_descriptors[] = { { nullptr, 1, 0 }, - { _T("km"), 0.001, 0 }, - { _T("NM"), 0.000539956803, 0 }, - { _T("mi"), 0.000621371192, 0 }, - { _T("km/h"), 3.6, 0 }, - { _T("kt"), 1.94384449, 0 }, - { _T("mph"), 2.23693629, 0 }, - { _T("m/s"), 1, 0 }, - { _T("fpm"), 196.850394, 0 }, - { _T("m"), 1, 0 }, - { _T("ft"), 3.2808399, 0 }, - { _T("FL"), 0.032808399, 0 }, - { _T("K"), 1, 0 }, - { _T(DEG) _T("C"), 1, -CELSIUS_OFFSET }, - { _T(DEG) _T("F"), 1.8, -459.67 }, - { _T("hPa"), 1, 0 }, - { _T("mb"), 1, 0 }, - { _T("mmHg"), 0.7500616827041698, 0 }, - { _T("inHg"), 0.0295287441401431, 0 }, - { _T("kg/m²"), 1, 0 }, - { _T("lb/ft²"), 0.204816144, 0 }, - { _T("kg"), 1, 0 }, - { _T("lb"), 2.20462, 0 }, - { _T("%"), 1, 0 }, - { _T(":1"), 1, 0 }, - { _T("V"), 1, 0 }, - { _T("Hz"), 1, 0 }, - { _T("rpm"), 60, 0 }, + { "km", 0.001, 0 }, + { "NM", 0.000539956803, 0 }, + { "mi", 0.000621371192, 0 }, + { "km/h", 3.6, 0 }, + { "kt", 1.94384449, 0 }, + { "mph", 2.23693629, 0 }, + { "m/s", 1, 0 }, + { "fpm", 196.850394, 0 }, + { "m", 1, 0 }, + { "ft", 3.2808399, 0 }, + { "FL", 0.032808399, 0 }, + { "K", 1, 0 }, + { DEG "C", 1, -CELSIUS_OFFSET }, + { DEG "F", 1.8, -459.67 }, + { "hPa", 1, 0 }, + { "mb", 1, 0 }, + { "mmHg", 0.7500616827041698, 0 }, + { "inHg", 0.0295287441401431, 0 }, + { "kg/m²", 1, 0 }, + { "lb/ft²", 0.204816144, 0 }, + { "kg", 1, 0 }, + { "lb", 2.20462, 0 }, + { "%", 1, 0 }, + { ":1", 1, 0 }, + { "V", 1, 0 }, + { "Hz", 1, 0 }, + { "rpm", 60, 0 }, }; static_assert(ARRAY_SIZE(Units::unit_descriptors) == (size_t)Unit::COUNT, "number of unit descriptions does not match number of units"); -const TCHAR * +const char * Units::GetUnitName(Unit unit) noexcept { const unsigned i = (unsigned)unit; diff --git a/src/Units/Descriptor.hpp b/src/Units/Descriptor.hpp index e628f280a5a..1c380930120 100644 --- a/src/Units/Descriptor.hpp +++ b/src/Units/Descriptor.hpp @@ -9,7 +9,7 @@ struct UnitDescriptor { - const TCHAR *name; + const char *name; double factor_to_user; double offset_to_user; }; @@ -28,7 +28,7 @@ extern const UnitDescriptor unit_descriptors[]; * @return The name of the given Unit (e.g. "km" or "ft") */ [[gnu::const]] -const TCHAR * +const char * GetUnitName(Unit unit) noexcept; }; diff --git a/src/Units/Units.cpp b/src/Units/Units.cpp index 846bdfe4d0d..0ffed256272 100644 --- a/src/Units/Units.cpp +++ b/src/Units/Units.cpp @@ -90,49 +90,49 @@ Units::GetUserUnitByGroup(UnitGroup group) return current.GetByGroup(group); } -const TCHAR * +const char * Units::GetSpeedName() { return GetUnitName(GetUserSpeedUnit()); } -const TCHAR * +const char * Units::GetVerticalSpeedName() { return GetUnitName(GetUserVerticalSpeedUnit()); } -const TCHAR * +const char * Units::GetWindSpeedName() { return GetUnitName(GetUserWindSpeedUnit()); } -const TCHAR * +const char * Units::GetDistanceName() { return GetUnitName(GetUserDistanceUnit()); } -const TCHAR * +const char * Units::GetAltitudeName() { return GetUnitName(GetUserAltitudeUnit()); } -const TCHAR * +const char * Units::GetTemperatureName() { return GetUnitName(GetUserTemperatureUnit()); } -const TCHAR * +const char * Units::GetTaskSpeedName() { return GetUnitName(GetUserTaskSpeedUnit()); } -const TCHAR * +const char * Units::GetPressureName() { return GetUnitName(GetUserPressureUnit()); diff --git a/src/Units/Units.hpp b/src/Units/Units.hpp index d39e4b68cba..c9d108465e4 100644 --- a/src/Units/Units.hpp +++ b/src/Units/Units.hpp @@ -108,35 +108,35 @@ Unit GetUserUnitByGroup(UnitGroup group); [[gnu::pure]] -const TCHAR * +const char * GetSpeedName(); [[gnu::pure]] -const TCHAR * +const char * GetVerticalSpeedName(); [[gnu::pure]] -const TCHAR * +const char * GetWindSpeedName(); [[gnu::pure]] -const TCHAR * +const char * GetDistanceName(); [[gnu::pure]] -const TCHAR * +const char * GetAltitudeName(); [[gnu::pure]] -const TCHAR * +const char * GetTemperatureName(); [[gnu::pure]] -const TCHAR * +const char * GetTaskSpeedName(); [[gnu::pure]] -const TCHAR * +const char * GetPressureName(); static inline double diff --git a/src/Units/UnitsGlue.cpp b/src/Units/UnitsGlue.cpp index 91f758ba864..5b21767a7ec 100644 --- a/src/Units/UnitsGlue.cpp +++ b/src/Units/UnitsGlue.cpp @@ -22,7 +22,7 @@ struct language_unit_map { unsigned region_id; - const TCHAR* region_code; + const char* region_code; unsigned store_index; }; @@ -48,9 +48,9 @@ enum { #if !defined(HAVE_POSIX) || defined(ANDROID) const struct language_unit_map language_table[] = { - { MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_UK), _T("en_UK"), 1 }, - { MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), _T("en_US"), 2 }, - { MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_AUS), _T("en_AU"), 3 }, + { MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_UK), "en_UK", 1 }, + { MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), "en_US", 2 }, + { MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_AUS), "en_AU", 3 }, { 0, nullptr, 0 } }; @@ -69,7 +69,7 @@ FindLanguage(LANGID lang) } #elif defined(ANDROID) static unsigned -FindLanguage(const TCHAR* lang) +FindLanguage(const char* lang) { // Search for supported languages matching the language code for (unsigned i = 0; language_table[i].region_code != nullptr; ++i) diff --git a/src/Units/UnitsStore.cpp b/src/Units/UnitsStore.cpp index 038ebafb8a0..cb90b835d3d 100644 --- a/src/Units/UnitsStore.cpp +++ b/src/Units/UnitsStore.cpp @@ -10,7 +10,7 @@ struct UnitStoreItem { - const TCHAR* Name; + const char* Name; UnitSetting Units; }; @@ -70,7 +70,7 @@ static constexpr UnitStoreItem Presets[] = } } }; -const TCHAR * +const char * Units::Store::GetName(unsigned i) noexcept { assert(i < Count()); diff --git a/src/Units/UnitsStore.hpp b/src/Units/UnitsStore.hpp index 7dc0dde1a48..fd43063400d 100644 --- a/src/Units/UnitsStore.hpp +++ b/src/Units/UnitsStore.hpp @@ -13,7 +13,7 @@ struct UnitSetting; namespace Units::Store { [[gnu::const]] -const TCHAR * +const char * GetName(unsigned i) noexcept; [[gnu::const]] diff --git a/src/UtilsSettings.cpp b/src/UtilsSettings.cpp index efdad244fde..9884f7dc9b0 100644 --- a/src/UtilsSettings.cpp +++ b/src/UtilsSettings.cpp @@ -53,7 +53,7 @@ bool FlarmFileChanged = false; bool RaspFileChanged = false; bool InputFileChanged = false; bool LanguageChanged = false; -bool require_restart; +bool require_restart = false; static void SettingsEnter() diff --git a/src/VALI-XCS.cpp b/src/VALI-XCS.cpp index 0f944cce12a..3d4b7b00604 100644 --- a/src/VALI-XCS.cpp +++ b/src/VALI-XCS.cpp @@ -32,7 +32,7 @@ ValidateXCS(Path path, GRecord &oGRecord) STATUS_t eStatus = eValidationFileNotFound; FILE *inFile = nullptr; - inFile = _tfopen(path.c_str(), _T("r")); + inFile = _tfopen(path.c_str(), "r"); if (inFile == nullptr) return eStatus; @@ -66,7 +66,7 @@ RunValidate(Path path) int main(int argc, char* argv[]) try { printf("Vali XCS for the XCSoar Flight Computer Version %s\n", - XCSoar_Version); + OpenSoar_Version); if (argc > 1 && strcmp(argv[1], "-?") != 0) { PathName path(argv[1]); diff --git a/src/Version.cpp b/src/Version.cpp index a2375605c9b..6522ec436db 100644 --- a/src/Version.cpp +++ b/src/Version.cpp @@ -2,17 +2,20 @@ // Copyright The XCSoar Project #include "Version.hpp" +#include "ProgramVersion.h" -#ifndef XCSOAR_VERSION -#error Macro "XCSOAR_VERSION" is not defined. Check build/version.mk! +#ifndef PROGRAM_VERSION +#error Macro "PROGRAM_VERSION" is not defined. Check build/version.mk! #endif -#define VERSION XCSOAR_VERSION +#define VERSION PROGRAM_VERSION #if defined(ANDROID) #define TARGET "Android" #elif defined(KOBO) #define TARGET "Kobo" +#elif defined(IS_OPENVARIO) + #define TARGET "OpenVario" #elif defined(__linux__) #define TARGET "Linux" #elif defined(__APPLE__) @@ -31,13 +34,13 @@ #define VERSION_SUFFIX "" #ifdef GIT_COMMIT_ID -#define GIT_SUFFIX "~git#" GIT_COMMIT_ID +# define GIT_SUFFIX "~git#" GIT_COMMIT_ID #else -#define GIT_SUFFIX +# define GIT_SUFFIX #endif -const char XCSoar_Version[] = VERSION; -const TCHAR XCSoar_VersionLong[] = _T(VERSION VERSION_SUFFIX); -const TCHAR XCSoar_VersionString[] = _T(VERSION VERSION_SUFFIX "-" TARGET); -const TCHAR XCSoar_VersionStringOld[] = _T(TARGET " " VERSION VERSION_SUFFIX); -const TCHAR XCSoar_ProductToken[] = _T("XCSoar v" VERSION VERSION_SUFFIX "-" TARGET GIT_SUFFIX); +const char OpenSoar_Version[] = VERSION; +const char OpenSoar_VersionLong[] = VERSION VERSION_SUFFIX; +const char OpenSoar_VersionString[] = VERSION VERSION_SUFFIX "-" TARGET; +const char OpenSoar_VersionStringOld[] = TARGET " " VERSION VERSION_SUFFIX; +const char OpenSoar_ProductToken[] = "OpenSoar v" VERSION VERSION_SUFFIX "-" TARGET GIT_SUFFIX; diff --git a/src/Version.hpp b/src/Version.hpp index a5c38f7f855..38543c1b33b 100644 --- a/src/Version.hpp +++ b/src/Version.hpp @@ -6,12 +6,12 @@ #include /** 5.2.5 */ -extern const char XCSoar_Version[]; +extern const char OpenSoar_Version[]; /** 5.2.5F */ -extern const TCHAR XCSoar_VersionLong[]; +extern const char OpenSoar_VersionLong[]; /** 5.2.5F-PC */ -extern const TCHAR XCSoar_VersionString[]; +extern const char OpenSoar_VersionString[]; /** PC 5.2.5F 7. Oct 09 */ -extern const TCHAR XCSoar_VersionStringOld[]; +extern const char OpenSoar_VersionStringOld[]; /** XCSoar v5.2.5F-PC */ -extern const TCHAR XCSoar_ProductToken[]; +extern const char OpenSoar_ProductToken[]; diff --git a/src/Waypoint/CMakeLists.txt b/src/Waypoint/CMakeLists.txt new file mode 100644 index 00000000000..c79a42de2ee --- /dev/null +++ b/src/Waypoint/CMakeLists.txt @@ -0,0 +1,51 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories + + +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/Waypoint/CMakeSource.cmake b/src/Waypoint/CMakeSource.cmake new file mode 100644 index 00000000000..1c54cbaad7b --- /dev/null +++ b/src/Waypoint/CMakeSource.cmake @@ -0,0 +1,26 @@ +set(_SOURCES + Waypoint/CupWriter.cpp + Waypoint/CupParser.cpp + Waypoint/Factory.cpp + Waypoint/HomeGlue.cpp + Waypoint/LastUsed.cpp + Waypoint/SaveGlue.cpp + Waypoint/WaypointDetailsReader.cpp + Waypoint/WaypointFileType.cpp + Waypoint/WaypointFilter.cpp + Waypoint/WaypointGlue.cpp + Waypoint/WaypointList.cpp + Waypoint/WaypointListBuilder.cpp + Waypoint/WaypointReader.cpp + Waypoint/WaypointReaderBase.cpp + Waypoint/WaypointReaderCompeGPS.cpp + Waypoint/WaypointReaderFS.cpp + Waypoint/WaypointReaderOzi.cpp + Waypoint/WaypointReaderSeeYou.cpp + Waypoint/WaypointReaderWinPilot.cpp + Waypoint/WaypointReaderZander.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake +) diff --git a/src/Waypoint/Patterns.hpp b/src/Waypoint/Patterns.hpp index 383f63af692..f7298724424 100644 --- a/src/Waypoint/Patterns.hpp +++ b/src/Waypoint/Patterns.hpp @@ -5,4 +5,4 @@ #include -#define WAYPOINT_FILE_PATTERNS _T("*.dat\0*.xcw\0*.cup\0*.wpz\0*.wpt\0") +#define WAYPOINT_FILE_PATTERNS "*.dat\0*.xcw\0*.cup\0*.wpz\0*.wpt\0" diff --git a/src/Waypoint/SaveGlue.cpp b/src/Waypoint/SaveGlue.cpp index bc69eecc326..7f9ca026bb8 100644 --- a/src/Waypoint/SaveGlue.cpp +++ b/src/Waypoint/SaveGlue.cpp @@ -12,7 +12,7 @@ void WaypointGlue::SaveWaypoints(const Waypoints &way_points) { - const auto path = LocalPath(_T("user.cup")); + const auto path = LocalPath("user.cup"); FileOutputStream file(path); BufferedOutputStream writer(file); @@ -22,13 +22,13 @@ WaypointGlue::SaveWaypoints(const Waypoints &way_points) writer.Flush(); file.Commit(); - LogFormat(_T("Waypoint file '%s' saved"), path.c_str()); + LogFormat("Waypoint file '%s' saved", path.c_str()); } void WaypointGlue::SaveWaypoint(const Waypoint &wp) { - const auto path = LocalPath(_T("user.cup")); + const auto path = LocalPath("user.cup"); FileOutputStream file(path, FileOutputStream::Mode::APPEND_OR_CREATE); BufferedOutputStream writer(file); diff --git a/src/Waypoint/WaypointDetailsReader.cpp b/src/Waypoint/WaypointDetailsReader.cpp index dae96c229d5..e58d453cb8c 100644 --- a/src/Waypoint/WaypointDetailsReader.cpp +++ b/src/Waypoint/WaypointDetailsReader.cpp @@ -18,18 +18,18 @@ namespace WaypointDetails { static WaypointPtr -FindWaypoint(Waypoints &way_points, const TCHAR *name) +FindWaypoint(Waypoints &way_points, const char *name) { return way_points.LookupName(name); } struct WaypointDetailsBuilder { - TCHAR name[201]; - tstring details; + char name[201]; + std::string details; #ifdef HAVE_RUN_FILE - std::forward_list files_external; + std::forward_list files_external; #endif - std::forward_list files_embed; + std::forward_list files_embed; void Reset() noexcept { details.clear(); diff --git a/src/Waypoint/WaypointFileType.cpp b/src/Waypoint/WaypointFileType.cpp index ebcb92343d8..30c87c9f02a 100644 --- a/src/Waypoint/WaypointFileType.cpp +++ b/src/Waypoint/WaypointFileType.cpp @@ -13,20 +13,20 @@ WaypointFileType DetermineWaypointFileType(Path path) noexcept { // If WinPilot waypoint file -> save type and return true - if (path.EndsWithIgnoreCase(_T(".dat")) || - path.EndsWithIgnoreCase(_T(".xcw"))) + if (path.EndsWithIgnoreCase(".dat") || + path.EndsWithIgnoreCase(".xcw")) return WaypointFileType::WINPILOT; // If SeeYou waypoint file -> save type and return true - if (path.EndsWithIgnoreCase(_T(".cup"))) + if (path.EndsWithIgnoreCase(".cup")) return WaypointFileType::SEEYOU; // If Zander waypoint file -> save type and return true - if (path.EndsWithIgnoreCase(_T(".wpz"))) + if (path.EndsWithIgnoreCase(".wpz")) return WaypointFileType::ZANDER; // If FS waypoint file -> save type and return true - if (path.EndsWithIgnoreCase(_T(".wpt"))) { + if (path.EndsWithIgnoreCase(".wpt")) { try { FileReader r{path}; char buffer[4096]; diff --git a/src/Waypoint/WaypointFilter.cpp b/src/Waypoint/WaypointFilter.cpp index d9da1a55ddd..67cd44de813 100644 --- a/src/Waypoint/WaypointFilter.cpp +++ b/src/Waypoint/WaypointFilter.cpp @@ -83,9 +83,9 @@ WaypointFilter::CompareDirection(const Waypoint &waypoint, } inline bool -WaypointFilter::CompareName(const Waypoint &waypoint, const TCHAR *name) +WaypointFilter::CompareName(const Waypoint &waypoint, const char *name) { - return StringIsEqualIgnoreCase(waypoint.name.c_str(), name, _tcslen(name)); + return StringIsEqualIgnoreCase(waypoint.name.c_str(), name, strlen(name)); } inline bool diff --git a/src/Waypoint/WaypointFilter.hpp b/src/Waypoint/WaypointFilter.hpp index 759d56ce1e3..9824a864f7f 100644 --- a/src/Waypoint/WaypointFilter.hpp +++ b/src/Waypoint/WaypointFilter.hpp @@ -62,7 +62,7 @@ struct WaypointFilter bool CompareDirection(const Waypoint &waypoint, GeoPoint location) const; - static bool CompareName(const Waypoint &waypoint, const TCHAR *name); + static bool CompareName(const Waypoint &waypoint, const char *name); bool CompareName(const Waypoint &waypoint) const; }; diff --git a/src/Waypoint/WaypointGlue.cpp b/src/Waypoint/WaypointGlue.cpp index a8f465bcd18..d06e9e0884d 100644 --- a/src/Waypoint/WaypointGlue.cpp +++ b/src/Waypoint/WaypointGlue.cpp @@ -29,7 +29,7 @@ try { progress); return true; } catch (...) { - LogFormat(_T("Failed to read waypoint file: %s"), path.c_str()); + LogFormat("Failed to read waypoint file: %s", path.c_str()); LogError(std::current_exception()); return false; } @@ -45,7 +45,7 @@ try { progress); return true; } catch (...) { - LogFormat(_T("Failed to read waypoint file: %s"), path.c_str()); + LogFormat("Failed to read waypoint file: %s", path.c_str()); LogError(std::current_exception()); return false; } @@ -62,7 +62,7 @@ try { progressg); return true; } catch (...) { - LogFormat(_T("Failed to read waypoint file: %s"), path); + LogFormat("Failed to read waypoint file: %s", path); LogError(std::current_exception()); return false; } @@ -116,7 +116,7 @@ LoadWaypoints(Waypoints &way_points, const RasterTerrain *terrain, } } //Load user.cup - LoadWaypointFile(way_points, LocalPath(_T("user.cup")), + LoadWaypointFile(way_points, LocalPath("user.cup"), WaypointFileType::SEEYOU, WaypointOrigin::USER, terrain, progress); // Optimise the waypoint list after attaching new waypoints diff --git a/src/Waypoint/WaypointReader.cpp b/src/Waypoint/WaypointReader.cpp index a39527157eb..289e58dd936 100644 --- a/src/Waypoint/WaypointReader.cpp +++ b/src/Waypoint/WaypointReader.cpp @@ -15,6 +15,7 @@ #include "io/ProgressReader.hpp" #include "io/BufferedReader.hxx" +#include #include static WaypointReaderBase * diff --git a/src/Waypoint/WaypointReaderFS.cpp b/src/Waypoint/WaypointReaderFS.cpp index cc6c905bb89..96d33a838f5 100644 --- a/src/Waypoint/WaypointReaderFS.cpp +++ b/src/Waypoint/WaypointReaderFS.cpp @@ -12,11 +12,11 @@ static bool ParseAngle(const char *src, Angle &angle) noexcept { bool is_positive; - if (src[0] == _T('N') || src[0] == _T('n') || - src[0] == _T('E') || src[0] == _T('e')) + if (src[0] == 'N' || src[0] == 'n' || + src[0] == 'E' || src[0] == 'e') is_positive = true; - else if (src[0] == _T('S') || src[0] == _T('s') || - src[0] == _T('W') || src[0] == _T('w')) + else if (src[0] == 'S' || src[0] == 's' || + src[0] == 'W' || src[0] == 'w') is_positive = false; else return false; @@ -25,17 +25,17 @@ ParseAngle(const char *src, Angle &angle) noexcept src++; long deg = strtol(src, &endptr, 10); - if (endptr == src || *endptr != _T(' ')) + if (endptr == src || *endptr != ' ') return false; src = endptr; long min = strtol(src, &endptr, 10); - if (endptr == src || *endptr != _T(' ')) + if (endptr == src || *endptr != ' ') return false; src = endptr; double sec = strtod(src, &endptr); - if (endptr == src || *endptr != _T(' ')) + if (endptr == src || *endptr != ' ') return false; auto value = deg + (double)min / 60 + sec / 3600; @@ -80,12 +80,12 @@ ParseLocationUTM(const char *src, GeoPoint &p) noexcept src++; long easting = strtol(src, &endptr, 10); - if (endptr == src || *endptr != _T(' ')) + if (endptr == src || *endptr != ' ') return false; src = endptr; long northing = strtol(src, &endptr, 10); - if (endptr == src || *endptr != _T(' ')) + if (endptr == src || *endptr != ' ') return false; UTM u(zone_number, zone_letter, easting, northing); @@ -149,7 +149,7 @@ WaypointReaderFS::ParseLine(const char *line, Waypoints &way_points) Waypoint new_waypoint = factory.Create(location); - new_waypoint.name = tstring{string_converter.Convert({line, 8})}; + new_waypoint.name = std::string{string_converter.Convert({line, 8})}; if (ParseAltitude(line + (is_utm ? 32 : 41), new_waypoint.elevation)) new_waypoint.has_elevation = true; @@ -158,7 +158,7 @@ WaypointReaderFS::ParseLine(const char *line, Waypoints &way_points) // Description (Characters 35-44) if (len > (is_utm ? 38 : 47)) - new_waypoint.comment = tstring{string_converter.Convert(line + (is_utm ? 38 : 47))}; + new_waypoint.comment = std::string{string_converter.Convert(line + (is_utm ? 38 : 47))}; way_points.Append(std::move(new_waypoint)); return true; diff --git a/src/Waypoint/WaypointReaderOzi.cpp b/src/Waypoint/WaypointReaderOzi.cpp index 4f117f7a93f..f1c8a715fd8 100644 --- a/src/Waypoint/WaypointReaderOzi.cpp +++ b/src/Waypoint/WaypointReaderOzi.cpp @@ -49,15 +49,15 @@ WaypointReaderOzi::ParseLine(const char *line, Waypoints &way_points) ParseIntegerTo(NextColumn(rest), number); // Field 2 : Name - tstring name{string_converter.Convert(NextColumn(rest))}; + std::string name{string_converter.Convert(NextColumn(rest))}; GeoPoint location; // Latitude (e.g. 5115.900N) - if (!ParseAngle(NarrowString<40>(NextColumn(rest)), location.latitude)) + if (!ParseAngle(StaticString<40>(NextColumn(rest)), location.latitude)) return false; // Longitude (e.g. 00715.900W) - if (!ParseAngle(NarrowString<40>(NextColumn(rest)), location.longitude)) + if (!ParseAngle(StaticString<40>(NextColumn(rest)), location.longitude)) return false; location.Normalize(); // ensure longitude is within -180:180 @@ -70,7 +70,7 @@ WaypointReaderOzi::ParseLine(const char *line, Waypoints &way_points) NextColumn(rest); // Field 10 : Background Color // Field 11 : Description - tstring comment{string_converter.Convert(NextColumn(rest))}; + std::string comment{string_converter.Convert(NextColumn(rest))}; NextColumn(rest); // Field 12 : Pointer Direction NextColumn(rest); // Field 13 : Garmin Display Format diff --git a/src/Waypoint/WaypointReaderWinPilot.cpp b/src/Waypoint/WaypointReaderWinPilot.cpp index b2b6d6ec6c1..d96ef60c1c5 100644 --- a/src/Waypoint/WaypointReaderWinPilot.cpp +++ b/src/Waypoint/WaypointReaderWinPilot.cpp @@ -206,7 +206,7 @@ WaypointReaderWinPilot::ParseLine(const char *line, Waypoints &waypoints) return true; // If comment - if (line[0] == _T('*')) { + if (line[0] == '*') { if (first) { first = false; welt2000_format = strstr(line, "WRITTEN BY WELT2000") != nullptr; @@ -244,13 +244,13 @@ WaypointReaderWinPilot::ParseLine(const char *line, Waypoints &waypoints) ParseFlags(NextColumn(rest), new_waypoint); // Name (e.g. KAMPLI) - new_waypoint.name = tstring{string_converter.Convert(NextColumn(rest))}; + new_waypoint.name = std::string{string_converter.Convert(NextColumn(rest))}; if (new_waypoint.name.empty()) return false; // Description (e.g. 119.750 Airport) const auto comment = NextColumn(rest); - new_waypoint.comment = tstring{string_converter.Convert(comment)}; + new_waypoint.comment = std::string{string_converter.Convert(comment)}; ParseRunwayDirection(comment, new_waypoint.runway); waypoints.Append(std::move(new_waypoint)); diff --git a/src/Waypoint/WaypointReaderZander.cpp b/src/Waypoint/WaypointReaderZander.cpp index d9c3b5ed566..67e05a260d6 100644 --- a/src/Waypoint/WaypointReaderZander.cpp +++ b/src/Waypoint/WaypointReaderZander.cpp @@ -9,7 +9,7 @@ static bool ParseString(StringConverter &string_converter, - std::string_view src, tstring &dest, std::size_t len) noexcept + std::string_view src, std::string &dest, std::size_t len) noexcept { if (src.empty()) return false; @@ -51,7 +51,7 @@ ParseAngle(const char *src, Angle &dest, const bool lat) noexcept auto value = deg + min / 60. + sec / 3600.; - TCHAR sign = *endptr; + char sign = *endptr; if (sign == 'W' || sign == 'w' || sign == 'S' || sign == 's') value = -value; diff --git a/src/Weather/CMakeLists.txt b/src/Weather/CMakeLists.txt new file mode 100644 index 00000000000..c79a42de2ee --- /dev/null +++ b/src/Weather/CMakeLists.txt @@ -0,0 +1,51 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories + + +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/Weather/CMakeSource.cmake b/src/Weather/CMakeSource.cmake new file mode 100644 index 00000000000..573010eaf90 --- /dev/null +++ b/src/Weather/CMakeSource.cmake @@ -0,0 +1,21 @@ +set(_SOURCES + Weather/METARParser.cpp + Weather/NOAADownloader.cpp + Weather/NOAAFormatter.cpp + Weather/NOAAGlue.cpp + Weather/NOAAStore.cpp + Weather/NOAAUpdater.cpp + Weather/PCMet/Images.cpp + Weather/PCMet/Overlays.cpp +# Weather/Rasp/Providers.cpp + Weather/Rasp/RaspCache.cpp + Weather/Rasp/RaspRenderer.cpp + Weather/Rasp/RaspStore.cpp + Weather/Rasp/RaspStyle.cpp + Weather/Rasp/Configured.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake +) + diff --git a/src/Weather/METARParser.cpp b/src/Weather/METARParser.cpp index 40ad570aaf8..eec81b46595 100644 --- a/src/Weather/METARParser.cpp +++ b/src/Weather/METARParser.cpp @@ -25,17 +25,17 @@ ParseDecoded(const METAR::ContentString &decoded, ParsedMETAR &parsed); class METARLine { protected: - TCHAR *start, *data, *end; + char *start, *data, *end; public: /** Constructor. Duplicates the const input to be able to tokenize it. */ - METARLine(const TCHAR *line) - :start(_tcsdup(line)), data(start), end(start + _tcslen(line)) + METARLine(const char *line) + :start(strdup(line)), data(start), end(start + strlen(line)) { // Trim possible = character at the end (End-of-METAR character) - if (start != end && *(end - 1) == _T('=')) { + if (start != end && *(end - 1) == '=') { end--; - *end = _T('\0'); + *end = '\0'; } } @@ -45,15 +45,15 @@ class METARLine { } /** Returns the next token or NULL if no token is left. (Seperator is ' ') */ - const TCHAR *Next() { + const char *Next() { if (data >= end) return NULL; - const TCHAR *start = data; + const char *start = data; - auto *seperator = StringFind(data, _T(' ')); + auto *seperator = StringFind(data, ' '); if (seperator != NULL && seperator < end) { - *seperator = _T('\0'); + *seperator = '\0'; data = seperator + 1; } else { data = end; @@ -65,9 +65,9 @@ class METARLine { /** Detects a token with exactly 4 letters */ static bool -DetectICAOCodeToken(const TCHAR *token) +DetectICAOCodeToken(const char *token) { - if (_tcslen(token) != 4) + if (strlen(token) != 4) return false; for (unsigned i = 0; i < 4; i++) { @@ -83,21 +83,21 @@ DetectICAOCodeToken(const TCHAR *token) /** Detects a token with exactly 6 digits and a Z (Zulu = UTC) at the end */ static bool -DetectTimeCodeToken(const TCHAR *token) +DetectTimeCodeToken(const char *token) { - if (_tcslen(token) != 7) + if (strlen(token) != 7) return false; - return token[6] == _T('Z') || token[6] == _T('z'); + return token[6] == 'Z' || token[6] == 'z'; } static bool -ParseTimeCode(const TCHAR *token, ParsedMETAR &parsed) +ParseTimeCode(const char *token, ParsedMETAR &parsed) { assert(DetectTimeCodeToken(token)); - TCHAR *endptr; - unsigned time_code = _tcstod(token, &endptr); + char *endptr; + unsigned time_code = strtod(token, &endptr); if (endptr == NULL || endptr == token) return false; @@ -115,18 +115,18 @@ ParseTimeCode(const TCHAR *token, ParsedMETAR &parsed) * If the wind direction varies VRB is also valid. */ static bool -DetectWindToken(const TCHAR *token) +DetectWindToken(const char *token) { - unsigned length = _tcslen(token); + unsigned length = strlen(token); if (length != 8 && length != 7) return false; - if (!StringIsEqualIgnoreCase(token + 5, _T("MPS")) && - !StringIsEqualIgnoreCase(token + 5, _T("KT"))) + if (!StringIsEqualIgnoreCase(token + 5, "MPS") && + !StringIsEqualIgnoreCase(token + 5, "KT")) return false; - bool variable = (StringIsEqualIgnoreCase(token, _T("VRB"), 3)); + bool variable = (StringIsEqualIgnoreCase(token, "VRB", 3)); for (unsigned i = variable ? 3 : 0; i < 5; ++i) if (!IsDigitASCII(token[i])) @@ -136,26 +136,26 @@ DetectWindToken(const TCHAR *token) } static bool -ParseWind(const TCHAR *token, ParsedMETAR &parsed) +ParseWind(const char *token, ParsedMETAR &parsed) { assert(DetectWindToken(token)); // variable wind directions - if (StringIsEqualIgnoreCase(token, _T("VRB"), 3)) + if (StringIsEqualIgnoreCase(token, "VRB", 3)) // parsing okay but don't provide wind return true; - TCHAR *endptr; - unsigned wind_code = _tcstod(token, &endptr); + char *endptr; + unsigned wind_code = strtod(token, &endptr); if (endptr == NULL || endptr == token) return false; unsigned bearing = (int)(wind_code / 100); wind_code -= bearing * 100; - if (StringIsEqualIgnoreCase(endptr, _T("MPS"))) + if (StringIsEqualIgnoreCase(endptr, "MPS")) parsed.wind.norm = wind_code; - else if (StringIsEqualIgnoreCase(endptr, _T("KT"))) + else if (StringIsEqualIgnoreCase(endptr, "KT")) parsed.wind.norm = Units::ToSysUnit(wind_code, Unit::KNOTS); else return false; @@ -167,16 +167,16 @@ ParseWind(const TCHAR *token, ParsedMETAR &parsed) /** Detects a CAVOK token */ static bool -DetectCAVOK(const TCHAR *token) +DetectCAVOK(const char *token) { - return (_tcslen(token) == 5 && StringIsEqualIgnoreCase(token, _T("CAVOK"))); + return (strlen(token) == 5 && StringIsEqualIgnoreCase(token, "CAVOK")); } /** Detects a token with exactly 5 digits */ static bool -DetectVisibilityToken(const TCHAR *token) +DetectVisibilityToken(const char *token) { - if (_tcslen(token) != 4) + if (strlen(token) != 4) return false; for (unsigned i = 0; i < 4; ++i) @@ -187,12 +187,12 @@ DetectVisibilityToken(const TCHAR *token) } static bool -ParseVisibility(const TCHAR *token, ParsedMETAR &parsed) +ParseVisibility(const char *token, ParsedMETAR &parsed) { assert(DetectVisibilityToken(token)); - TCHAR *endptr; - parsed.visibility = _tcstol(token, &endptr, 10); + char *endptr; + parsed.visibility = strtol(token, &endptr, 10); if (endptr == NULL || endptr == token) return false; @@ -205,9 +205,9 @@ ParseVisibility(const TCHAR *token, ParsedMETAR &parsed) * If the temperatures are negative a 'M' is a valid prefix. */ static bool -DetectTemperaturesToken(const TCHAR *token) +DetectTemperaturesToken(const char *token) { - unsigned length = _tcslen(token); + unsigned length = strlen(token); bool minus_possible = true; bool divider_found = false; @@ -216,13 +216,13 @@ DetectTemperaturesToken(const TCHAR *token) if (IsDigitASCII(token[i])) continue; - if (token[i] == _T('/')) { + if (token[i] == '/') { divider_found = true; minus_possible = true; continue; } - if (minus_possible && (token[i] == _T('M') || token[i] == _T('m'))) + if (minus_possible && (token[i] == 'M' || token[i] == 'm')) continue; return false; @@ -231,15 +231,15 @@ DetectTemperaturesToken(const TCHAR *token) return divider_found; } -static const TCHAR * -ParseTemperature(const TCHAR *token, double &temperature) +static const char * +ParseTemperature(const char *token, double &temperature) { - bool negative = (token[0] == _T('M') || token[0] == _T('m')); + bool negative = (token[0] == 'M' || token[0] == 'm'); if (negative) token++; - TCHAR *endptr; - int _temperature = _tcstod(token, &endptr); + char *endptr; + int _temperature = strtod(token, &endptr); if (endptr == NULL || endptr == token) return NULL; @@ -251,14 +251,14 @@ ParseTemperature(const TCHAR *token, double &temperature) } static bool -ParseTemperatures(const TCHAR *token, ParsedMETAR &parsed) +ParseTemperatures(const char *token, ParsedMETAR &parsed) { assert(DetectTemperaturesToken(token)); if ((token = ParseTemperature(token, parsed.temperature)) == NULL) return false; - if (*token != _T('/')) + if (*token != '/') return false; token++; @@ -272,12 +272,12 @@ ParseTemperatures(const TCHAR *token, ParsedMETAR &parsed) /** Detects a token beginning with a 'T' and followed by 8 digits */ static bool -DetectAdditionalTemperaturesToken(const TCHAR *token) +DetectAdditionalTemperaturesToken(const char *token) { - if (_tcslen(token) != 9) + if (strlen(token) != 9) return false; - if (token[0] != _T('T') && token[0] != _T('t')) + if (token[0] != 'T' && token[0] != 't') return false; for (unsigned i = 1; i < 9; ++i) { @@ -289,15 +289,15 @@ DetectAdditionalTemperaturesToken(const TCHAR *token) } static bool -ParseAdditionalTemperatures(const TCHAR *token, ParsedMETAR &parsed) +ParseAdditionalTemperatures(const char *token, ParsedMETAR &parsed) { assert(DetectAdditionalTemperaturesToken(token)); // Skip 'T' token++; - TCHAR *endptr; - long temperature_code = _tcstol(token, &endptr, 10); + char *endptr; + long temperature_code = strtol(token, &endptr, 10); if (endptr == NULL || endptr == token) return false; @@ -318,32 +318,32 @@ ParseAdditionalTemperatures(const TCHAR *token, ParsedMETAR &parsed) /** Detects a token beginning with either 'Q' or 'A' and followed by 4 digits */ static bool -DetectQNHToken(const TCHAR *token) +DetectQNHToken(const char *token) { - unsigned length = _tcslen(token); + unsigned length = strlen(token); // International style - if (token[0] == _T('Q') || token[0] == _T('q')) + if (token[0] == 'Q' || token[0] == 'q') return length <= 5 && length >= 4; // American style - if (token[0] == _T('A') || token[0] == _T('a')) + if (token[0] == 'A' || token[0] == 'a') return length == 5; return false; } static bool -ParseQNH(const TCHAR *token, ParsedMETAR &parsed) +ParseQNH(const char *token, ParsedMETAR &parsed) { assert(DetectQNHToken(token)); // International style (hPa) - if (token[0] == _T('Q') || token[0] == _T('q')) { + if (token[0] == 'Q' || token[0] == 'q') { token++; - TCHAR *endptr; - unsigned hpa = _tcstod(token, &endptr); + char *endptr; + unsigned hpa = strtod(token, &endptr); if (endptr == NULL || endptr == token) return false; @@ -353,11 +353,11 @@ ParseQNH(const TCHAR *token, ParsedMETAR &parsed) } // American style (inHg) - if (token[0] == _T('A') || token[0] == _T('a')) { + if (token[0] == 'A' || token[0] == 'a') { token++; - TCHAR *endptr; - unsigned inch_hg = _tcstod(token, &endptr); + char *endptr; + unsigned inch_hg = strtod(token, &endptr); if (endptr == NULL || endptr == token) return false; @@ -378,8 +378,8 @@ METARParser::ParseLine(const METAR::ContentString &content, ParsedMETAR &parsed) // METAR ETOU 231055Z AUTO 15004KT 9999 FEW130 27/19 A2993 RMK AO2 RAB1038E1048DZB1006E1011 SLP128 P0000 T02710189= // METAR KTTN 051853Z 04011KT 1/2SM VCTS SN FZFG BKN003 OVC010 M02/M02 A3006 RMK AO2 TSB40 SLP176 P0002 T10171017= - METARLine line(content.begin()); - const TCHAR *token; + METARLine line(content.c_str()); + const char *token; // Parse four-letter ICAO code while ((token = line.Next()) != NULL) { @@ -452,10 +452,10 @@ METARParser::ParseLine(const METAR::ContentString &content, ParsedMETAR &parsed) } static bool -ParseLocation(const TCHAR *buffer, ParsedMETAR &parsed) +ParseLocation(const char *buffer, ParsedMETAR &parsed) { // 51-18N 006-46E - TCHAR *end; + char *end; unsigned lat_deg = ParseUnsigned(buffer, &end, 10); if (*end != '-') @@ -465,15 +465,15 @@ ParseLocation(const TCHAR *buffer, ParsedMETAR &parsed) unsigned lat_min = ParseUnsigned(end, &end, 10); unsigned lat_sec = 0; - if (*end == _T('-')) { + if (*end == '-') { ++end; lat_sec = ParseUnsigned(end, &end, 10); } bool north; - if (*end == _T('N') || *end == _T('n')) + if (*end == 'N' || *end == 'n') north = true; - else if (*end == _T('S') || *end == _T('s')) + else if (*end == 'S' || *end == 's') north = false; else return false; @@ -492,15 +492,15 @@ ParseLocation(const TCHAR *buffer, ParsedMETAR &parsed) unsigned lon_min = ParseUnsigned(end, &end, 10); unsigned lon_sec = 0; - if (*end == _T('-')) { + if (*end == '-') { ++end; lon_sec = ParseUnsigned(end, &end, 10); } bool east; - if (*end == _T('E') || *end == _T('e')) + if (*end == 'E' || *end == 'e') east = true; - else if (*end == _T('W') || *end == _T('w')) + else if (*end == 'W' || *end == 'w') east = false; else return false; @@ -528,11 +528,11 @@ METARParser::ParseDecoded(const METAR::ContentString &decoded, // Duesseldorf, Germany (EDDL) 51-18N 006-46E 41M // Nov 04, 2011 - 07:50 PM EDT / 2011.11.04 2350 UTC - const TCHAR *start = decoded.begin(); - const TCHAR *end = start + _tcslen(start); - const auto *opening_brace = StringFind(start, _T('(')); - const auto *closing_brace = StringFind(start, _T(')')); - const auto *line_break = StringFind(start, _T('\n')); + const char *start = decoded.c_str(); + const char *end = start + strlen(start); + const auto *opening_brace = StringFind(start, '('); + const auto *closing_brace = StringFind(start, ')'); + const auto *line_break = StringFind(start, '\n'); if (line_break == NULL || line_break >= end || opening_brace == NULL || opening_brace >= line_break || @@ -540,7 +540,7 @@ METARParser::ParseDecoded(const METAR::ContentString &decoded, return; while (opening_brace >= start && - (*opening_brace == _T('(') || *opening_brace == _T(' '))) + (*opening_brace == '(' || *opening_brace == ' ')) opening_brace--; unsigned name_length = opening_brace - start + 1; @@ -551,7 +551,7 @@ METARParser::ParseDecoded(const METAR::ContentString &decoded, do closing_brace++; - while (*closing_brace == _T(' ')); + while (*closing_brace == ' '); ParseLocation(closing_brace, parsed); } diff --git a/src/Weather/NOAAFormatter.cpp b/src/Weather/NOAAFormatter.cpp index 41c662e9fe2..88cd0bdc3ec 100644 --- a/src/Weather/NOAAFormatter.cpp +++ b/src/Weather/NOAAFormatter.cpp @@ -12,28 +12,28 @@ class NOAALineSplitter { - const TCHAR *start; + const char *start; public: - typedef std::pair Range; + typedef std::pair Range; - NOAALineSplitter(const TCHAR *_start):start(_start) {} + NOAALineSplitter(const char *_start):start(_start) {} bool HasNext() const { - return start != NULL && start[0] != _T('\0'); + return start != NULL && start[0] != '\0'; } Range Next() { assert(HasNext()); - const TCHAR *line_start = start; + const char *line_start = start; // Search for next line break - const auto *line_break = StringFind(line_start, _T('\n')); + const auto *line_break = StringFind(line_start, '\n'); if (!line_break) { // if no line break was found start = NULL; - return Range(line_start, _tcslen(line_start)); + return Range(line_start, strlen(line_start)); } unsigned length = line_break - line_start; @@ -43,21 +43,21 @@ class NOAALineSplitter }; static bool -CheckTitle(const TCHAR *title, size_t title_length, const TCHAR *check) +CheckTitle(const char *title, size_t title_length, const char *check) { - if (_tcslen(check) != title_length) + if (strlen(check) != title_length) return false; return std::equal(title, title + title_length, check); } static bool -FormatDecodedMETARLine(const TCHAR *line, unsigned length, - const ParsedMETAR &parsed, tstring &output) +FormatDecodedMETARLine(const char *line, unsigned length, + const ParsedMETAR &parsed, std::string &output) { - const TCHAR *end = line + length; + const char *end = line + length; - const TCHAR *colon = (const TCHAR *)memchr(line, _T(':'), length); + const char *colon = (const char *)memchr(line, ':', length); if (!colon) return false; @@ -65,20 +65,20 @@ FormatDecodedMETARLine(const TCHAR *line, unsigned length, if (title_length == 0) return false; - const TCHAR *value = colon + 1; - while (*value == _T(' ')) + const char *value = colon + 1; + while (*value == ' ') value++; unsigned value_length = end - value; - if (CheckTitle(line, title_length, _T("Wind"))) { + if (CheckTitle(line, title_length, "Wind")) { StaticString<256> buffer; if (!parsed.wind_available) { - buffer.Format(_T("%s: "), _("Wind")); + buffer.Format("%s: ", _("Wind")); buffer.append({value, value_length}); } else { - buffer.Format(_T("%s: %.0f" DEG " %s"), _("Wind"), + buffer.Format("%s: %.0f" DEG " %s", _("Wind"), (double)parsed.wind.bearing.Degrees(), FormatUserWindSpeed(parsed.wind.norm).c_str()); } @@ -87,61 +87,61 @@ FormatDecodedMETARLine(const TCHAR *line, unsigned length, return true; } - if (CheckTitle(line, title_length, _T("Temperature"))) { + if (CheckTitle(line, title_length, "Temperature")) { StaticString<256> buffer; if (!parsed.temperatures_available) { - buffer.Format(_T("%s: "), _("Temperature")); + buffer.Format("%s: ", _("Temperature")); buffer.append({value, value_length}); } else { - TCHAR temperature_buffer[16]; + char temperature_buffer[16]; FormatUserTemperature(parsed.temperature, temperature_buffer); - buffer.Format(_T("%s: %s"), _("Temperature"), temperature_buffer); + buffer.Format("%s: %s", _("Temperature"), temperature_buffer); } output += buffer; output += '\n'; return true; } - if (CheckTitle(line, title_length, _T("Dew Point"))) { + if (CheckTitle(line, title_length, "Dew Point")) { StaticString<256> buffer; if (!parsed.temperatures_available) { - buffer.Format(_T("%s: "), _("Dew Point")); + buffer.Format("%s: ", _("Dew Point")); buffer.append({value, value_length}); } else { - TCHAR temperature_buffer[16]; + char temperature_buffer[16]; FormatUserTemperature(parsed.dew_point, temperature_buffer); - buffer.Format(_T("%s: %s"), _("Dew Point"), temperature_buffer); + buffer.Format("%s: %s", _("Dew Point"), temperature_buffer); } output += buffer; output += '\n'; return true; } - if (CheckTitle(line, title_length, _T("Pressure (altimeter)"))) { + if (CheckTitle(line, title_length, "Pressure (altimeter)")) { StaticString<256> buffer; if (!parsed.qnh_available) { - buffer.Format(_T("%s: "), _("Pressure")); + buffer.Format("%s: ", _("Pressure")); buffer.append({value, value_length}); } else { - TCHAR qnh_buffer[16]; + char qnh_buffer[16]; FormatUserPressure(parsed.qnh, qnh_buffer); - buffer.Format(_T("%s: %s"), _("Pressure"), qnh_buffer); + buffer.Format("%s: %s", _("Pressure"), qnh_buffer); } output += buffer; output += '\n'; return true; } - if (CheckTitle(line, title_length, _T("Visibility"))) { + if (CheckTitle(line, title_length, "Visibility")) { StaticString<256> buffer; - buffer.Format(_T("%s: "), _("Visibility")); + buffer.Format("%s: ", _("Visibility")); if (!parsed.visibility_available) { buffer.append({value, value_length}); } else { @@ -156,9 +156,9 @@ FormatDecodedMETARLine(const TCHAR *line, unsigned length, return true; } - if (CheckTitle(line, title_length, _T("Sky conditions"))) { + if (CheckTitle(line, title_length, "Sky conditions")) { StaticString<256> buffer; - buffer.Format(_T("%s: "), _("Sky Conditions")); + buffer.Format("%s: ", _("Sky Conditions")); StaticString<64> _value; _value.assign({value, value_length}); @@ -170,9 +170,9 @@ FormatDecodedMETARLine(const TCHAR *line, unsigned length, return true; } - if (CheckTitle(line, title_length, _T("Weather"))) { + if (CheckTitle(line, title_length, "Weather")) { StaticString<256> buffer; - buffer.Format(_T("%s: "), _("Weather")); + buffer.Format("%s: ", _("Weather")); StaticString<64> _value; _value.assign({value, value_length}); @@ -188,7 +188,7 @@ FormatDecodedMETARLine(const TCHAR *line, unsigned length, title.assign({line, title_length}); StaticString<256> buffer; - buffer.Format(_T("%s: "), gettext(title.c_str())); + buffer.Format("%s: ", gettext(title.c_str())); buffer.append({value, value_length}); output += buffer; @@ -199,7 +199,7 @@ FormatDecodedMETARLine(const TCHAR *line, unsigned length, static void FormatDecodedMETAR(const METAR &metar, const ParsedMETAR &parsed, - tstring &output) + std::string &output) { /* 00 ## Hamburg-Fuhlsbuettel, Germany (EDDH) 53-38N 010-00E 15M ## @@ -242,7 +242,7 @@ FormatDecodedMETAR(const METAR &metar, const ParsedMETAR &parsed, } void -NOAAFormatter::Format(const NOAAStore::Item &station, tstring &output) +NOAAFormatter::Format(const NOAAStore::Item &station, std::string &output) { output.reserve(2048); @@ -254,11 +254,11 @@ NOAAFormatter::Format(const NOAAStore::Item &station, tstring &output) else output += station.metar.decoded.c_str(); - output += _T("\n\n"); + output += "\n\n"; output += station.metar.content.c_str(); } - output += _T("\n\n"); + output += "\n\n"; if (!station.taf_available) output += _("No TAF available!"); diff --git a/src/Weather/NOAAFormatter.hpp b/src/Weather/NOAAFormatter.hpp index 16303b43404..6e53c67a62f 100644 --- a/src/Weather/NOAAFormatter.hpp +++ b/src/Weather/NOAAFormatter.hpp @@ -4,11 +4,11 @@ #pragma once #include "NOAAStore.hpp" -#include "util/tstring.hpp" +#include namespace NOAAFormatter { void -Format(const NOAAStore::Item &station, tstring &output); +Format(const NOAAStore::Item &station, std::string &output); } // namespace NOAAFormatter diff --git a/src/Weather/NOAAGlue.cpp b/src/Weather/NOAAGlue.cpp index 95172a9ae2e..d14ce9e03f8 100644 --- a/src/Weather/NOAAGlue.cpp +++ b/src/Weather/NOAAGlue.cpp @@ -14,7 +14,7 @@ NOAAStore::LoadFromString(const char *string) { const char *s = string; while (s != NULL && *s) { - const char *next = strchr(s, _T(',')); + const char *next = strchr(s, ','); if ((next != NULL && next - s == 4) || (next == NULL && strlen(s) == 4)) { char code[5]; std::copy_n(s, 4, code); @@ -44,10 +44,10 @@ NOAAStore::SaveToProfile() for (auto i = begin(), e = end(); i != e; ++i) { const char *code = i->code; p = std::copy_n(code, strlen(code), p); - *p++ = _T(','); + *p++ = ','; } - *p = _T('\0'); + *p = '\0'; Profile::Set(ProfileKeys::WeatherStations, buffer); } diff --git a/src/Weather/NOAAStore.cpp b/src/Weather/NOAAStore.cpp index 323f2c84fb4..375ca2b7bb8 100644 --- a/src/Weather/NOAAStore.cpp +++ b/src/Weather/NOAAStore.cpp @@ -3,27 +3,6 @@ #include "NOAAStore.hpp" -#ifdef _UNICODE -#include "util/Macros.hpp" -#include "util/ConvertString.hpp" - -#include -#endif - -#ifdef _UNICODE - -const TCHAR * -NOAAStore::Item::GetCodeT() const -{ - static TCHAR code2[ARRAY_SIZE(Item::code)]; - if (MultiByteToWideChar(CP_UTF8, 0, code, -1, code2, ARRAY_SIZE(code2)) <= 0) - return _T(""); - - return code2; -} - -#endif - bool NOAAStore::IsValidCode(const char *code) { @@ -38,22 +17,6 @@ NOAAStore::IsValidCode(const char *code) return true; } -#ifdef _UNICODE -bool -NOAAStore::IsValidCode(const TCHAR* code) -{ - for (unsigned i = 0; i < 4; ++i) - if (! ((code[i] >= _T('A') && code[i] <= _T('Z')) || - (code[i] >= _T('0') && code[i] <= _T('9')))) - return false; - - if (code[4] != _T('\0')) - return false; - - return true; -} -#endif - NOAAStore::iterator NOAAStore::AddStation(const char *code) { @@ -74,14 +37,3 @@ NOAAStore::AddStation(const char *code) return --end(); } -#ifdef _UNICODE -NOAAStore::iterator -NOAAStore::AddStation(const TCHAR *code) -{ - assert(IsValidCode(code)); - - WideToUTF8Converter code2(code); - assert(code2.IsValid()); - return AddStation(code2); -} -#endif diff --git a/src/Weather/NOAAStore.hpp b/src/Weather/NOAAStore.hpp index 88b77252fd6..cb528197871 100644 --- a/src/Weather/NOAAStore.hpp +++ b/src/Weather/NOAAStore.hpp @@ -9,10 +9,6 @@ #include -#ifdef _UNICODE -#include -#endif - class NOAAStore { public: @@ -29,23 +25,17 @@ class NOAAStore TAF taf; /** - * Returns the four letter code as a TCHAR string. This may + * Returns the four letter code as a char string. This may * return a pointer to a static buffer, and consecutive calls * (even with different objects) may Invalidate the previous * return value. May be called only from the main thread. */ -#ifdef _UNICODE - [[gnu::pure]] - const TCHAR *GetCodeT() const; -#else const char *GetCodeT() const { return code; } -#endif }; typedef std::list StationContainer; - StationContainer stations; public: @@ -81,9 +71,6 @@ class NOAAStore * @param code Four letter code of the station/airport (upper case) */ static bool IsValidCode(const char *code); -#ifdef _UNICODE - static bool IsValidCode(const TCHAR *code); -#endif /** * Add a station to the set of stations for which @@ -91,9 +78,6 @@ class NOAAStore * @param code Four letter code of the station/airport (upper case) */ iterator AddStation(const char *code); -#ifdef _UNICODE - iterator AddStation(const TCHAR *code); -#endif /** * Returns the amount of stations in the array diff --git a/src/Weather/PCMet/Images.cpp b/src/Weather/PCMet/Images.cpp index dc449aba0b8..d97741ed8c4 100644 --- a/src/Weather/PCMet/Images.cpp +++ b/src/Weather/PCMet/Images.cpp @@ -9,7 +9,6 @@ #include "lib/curl/Setup.hxx" #include "LocalPath.hpp" #include "system/FileUtil.hpp" -#include "util/ConvertString.hpp" #include "util/StringSplit.hxx" #include @@ -19,71 +18,71 @@ #define PCMET_URI "https://www.flugwetter.de" static constexpr PCMet::ImageArea rad_lokal_areas[] = { - { "pro", _T("Prötzel") }, - { "drs", _T("Dresden") }, - { "eis", _T("Eisberg") }, - { "emd", _T("Emden") }, - { "ess", _T("Essen") }, - { "fbg", _T("Feldberg") }, - { "fld", _T("Flechtdorf") }, - { "boo", _T("Boostedt") }, - { "hnr", _T("Hannover") }, - { "mem", _T("Memmingen") }, - { "isn", _T("Isen") }, - { "neu", _T("Neuhaus") }, - { "nhb", _T("Neuheilenbach") }, - { "oft", _T("Offenthal") }, - { "ros", _T("Rostock") }, - { "tur", _T("Türkheim") }, - { "umd", _T("Ummendorf") }, - { "eddb", _T("EDDB") }, - { "eddc", _T("EDDC") }, - { "edde", _T("EDDE") }, - { "eddf", _T("EDDF") }, - { "eddg", _T("EDDG") }, - { "eddh", _T("EDDH") }, - { "eddk", _T("EDDK") }, - { "eddl", _T("EDDL") }, - { "eddm", _T("EDDM") }, - { "eddn", _T("EDDN") }, - { "eddp", _T("EDDP") }, - { "eddr", _T("EDDR") }, - { "edds", _T("EDDS") }, - { "eddt", _T("EDDT") }, - { "eddv", _T("EDDV") }, - { "eddw", _T("EDDW") }, + { "pro", "Prötzel" }, + { "drs", "Dresden" }, + { "eis", "Eisberg" }, + { "emd", "Emden" }, + { "ess", "Essen" }, + { "fbg", "Feldberg" }, + { "fld", "Flechtdorf" }, + { "boo", "Boostedt" }, + { "hnr", "Hannover" }, + { "mem", "Memmingen" }, + { "isn", "Isen" }, + { "neu", "Neuhaus" }, + { "nhb", "Neuheilenbach" }, + { "oft", "Offenthal" }, + { "ros", "Rostock" }, + { "tur", "Türkheim" }, + { "umd", "Ummendorf" }, + { "eddb", "EDDB" }, + { "eddc", "EDDC" }, + { "edde", "EDDE" }, + { "eddf", "EDDF" }, + { "eddg", "EDDG" }, + { "eddh", "EDDH" }, + { "eddk", "EDDK" }, + { "eddl", "EDDL" }, + { "eddm", "EDDM" }, + { "eddn", "EDDN" }, + { "eddp", "EDDP" }, + { "eddr", "EDDR" }, + { "edds", "EDDS" }, + { "eddt", "EDDT" }, + { "eddv", "EDDV" }, + { "eddw", "EDDW" }, { nullptr, nullptr } }; static constexpr PCMet::ImageArea rad_areas[] = { - { "de", _T("Deutschland") }, - { "eu", _T("Europa") }, + { "de", "Deutschland" }, + { "eu", "Europa" }, { nullptr, nullptr } }; static constexpr PCMet::ImageArea sat_areas[] = { - { "vis_hrv_eu", _T("Mitteleuropa HRV") }, - { "ir_rgb_eu", _T("Mitteleuropa RGB") }, - { "ir_108_eu", _T("Mitteleuropa IR") }, - { "vis_hrv_ce", _T("Mitteleuropa HRV") }, - { "ir_rgb_ce", _T("Mitteleuropa RGB") }, - { "ir_108_ce", _T("Mitteleuropa IR") }, - { "vis_hrv_mdl", _T("Deutschland HRV") }, - { "ir_rgb_mdl", _T("Deutschland RGB") }, - { "ir_108_mdl", _T("Deutschland IR") }, - { "vis_hrv_ndl", _T("Deutschland Nord HRV") }, - { "ir_rgb_ndl", _T("Deutschland Nord RGB") }, - { "ir_108_ndl", _T("Deutschland Nord IR") }, - { "vis_hrv_sdl", _T("Deutschland Süd HRV") }, - { "ir_rgb_sdl", _T("Deutschland Süd RGB") }, - { "ir_108_sdl", _T("Deutschland Süd IR") }, + { "vis_hrv_eu", "Mitteleuropa HRV" }, + { "ir_rgb_eu", "Mitteleuropa RGB" }, + { "ir_108_eu", "Mitteleuropa IR" }, + { "vis_hrv_ce", "Mitteleuropa HRV" }, + { "ir_rgb_ce", "Mitteleuropa RGB" }, + { "ir_108_ce", "Mitteleuropa IR" }, + { "vis_hrv_mdl", "Deutschland HRV" }, + { "ir_rgb_mdl", "Deutschland RGB" }, + { "ir_108_mdl", "Deutschland IR" }, + { "vis_hrv_ndl", "Deutschland Nord HRV" }, + { "ir_rgb_ndl", "Deutschland Nord RGB" }, + { "ir_108_ndl", "Deutschland Nord IR" }, + { "vis_hrv_sdl", "Deutschland Süd HRV" }, + { "ir_rgb_sdl", "Deutschland Süd RGB" }, + { "ir_108_sdl", "Deutschland Süd IR" }, { nullptr, nullptr } }; const PCMet::ImageType PCMet::image_types[] = { - { "rad_lokal/einzelstandorte.htm", _T("Lokale RADAR-Bilder"), rad_lokal_areas }, - { "rad/index.htm", _T("RADAR"), rad_areas }, - { "sat/index.htm", _T("Satellitenbilder"), sat_areas }, + { "rad_lokal/einzelstandorte.htm", "Lokale RADAR-Bilder", rad_lokal_areas }, + { "rad/index.htm", "RADAR", rad_areas }, + { "sat/index.htm", "Satellitenbilder", sat_areas }, { nullptr, nullptr, nullptr }, }; @@ -111,17 +110,14 @@ PCMet::DownloadLatestImage(const char *type, const char *area, const PCMetSettings &settings, CurlGlobal &curl, ProgressListener &progress) { - const WideToUTF8Converter username(settings.www_credentials.username); - const WideToUTF8Converter password(settings.www_credentials.password); - char url[256]; snprintf(url, sizeof(url), PCMET_URI "/fw/bilder/%s?type=%s", type, area); // download the HTML page - const auto response = - co_await CoGet(curl, url, username, password, progress); + const auto response = co_await CoGet(curl, url, settings.www_credentials.username, + settings.www_credentials.password, progress); static constexpr char img_needle[] = " label; - label.Format(_T("%s %s %um +%uh"), + label.Format("%s %s %um +%uh", type_labels[unsigned(info.type)], area_labels[unsigned(info.area)], info.level, @@ -83,9 +82,9 @@ FindLatestOverlay(PCMet::OverlayInfo &info) } } visitor(info); - const auto cache_path = MakeCacheDirectory(_T("pc_met")); + const auto cache_path = MakeCacheDirectory("pc_met"); StaticString<256> pattern; - pattern.Format(_T("%s_%s_lv_%06u_p_%03u_*.tiff"), + pattern.Format("%s_%s_lv_%06u_p_%03u_*.tiff", type_names[unsigned(info.type)], area_names[unsigned(info.area)], info.level, info.step); @@ -121,25 +120,20 @@ PCMet::DownloadOverlay(const OverlayInfo &info, BrokenDateTime now_utc, const unsigned run_hour = (now_utc.hour / 3) * 3; unsigned run = (now_utc.hour / 3) * 300; - NarrowString<256> url; + StaticString<256> url; url.Format(PCMET_FTP "/%s_%s_lv_%06u_p_%03u_%04u.tiff", type_names[unsigned(info.type)], area_names[unsigned(info.area)], info.level, info.step, run); - const auto cache_path = MakeCacheDirectory(_T("pc_met")); + const auto cache_path = MakeCacheDirectory("pc_met"); auto path = AllocatedPath::Build(cache_path, - UTF8ToWideConverter(url.c_str() + sizeof(PCMET_FTP))); + url.c_str() + sizeof(PCMET_FTP)); { - const WideToUTF8Converter username(settings.ftp_credentials.username); - const WideToUTF8Converter password(settings.ftp_credentials.password); - - const auto ignored_response = co_await - Net::CoDownloadToFile(curl, url, - username, password, - path, nullptr, - progress); + const auto ignored_response = co_await Net::CoDownloadToFile( + curl, url, settings.ftp_credentials.username, + settings.ftp_credentials.password, path, nullptr, progress); } BrokenDateTime run_time(now_utc.GetDate(), BrokenTime(run_hour, 0)); diff --git a/src/Weather/PCMet/Overlays.hpp b/src/Weather/PCMet/Overlays.hpp index 80b01dee5b9..de70aac6084 100644 --- a/src/Weather/PCMet/Overlays.hpp +++ b/src/Weather/PCMet/Overlays.hpp @@ -5,7 +5,7 @@ #include "system/Path.hpp" #include "time/BrokenDateTime.hpp" -#include "util/tstring.hpp" +#include #include @@ -35,7 +35,7 @@ struct OverlayInfo { unsigned level; unsigned step; - tstring label; + std::string label; AllocatedPath path; }; diff --git a/src/Weather/Rasp/Configured.cpp b/src/Weather/Rasp/Configured.cpp index f19cd84f8a8..f7cd84fc15b 100644 --- a/src/Weather/Rasp/Configured.cpp +++ b/src/Weather/Rasp/Configured.cpp @@ -14,7 +14,7 @@ LoadConfiguredRasp() noexcept if (path == nullptr) /* if no path is configured, attempt to load xcsoar-rasp.dat (XCSoar < 7.29) */ - path = LocalPath(_T(RASP_FILENAME)); + path = LocalPath(RASP_FILENAME); auto rasp = std::make_shared(std::move(path)); rasp->ScanAll(); diff --git a/src/Weather/Rasp/RaspCache.cpp b/src/Weather/Rasp/RaspCache.cpp index c2fe959033c..2d9553cd9e1 100644 --- a/src/Weather/Rasp/RaspCache.cpp +++ b/src/Weather/Rasp/RaspCache.cpp @@ -24,13 +24,13 @@ ToQuarterHours(BrokenTime t) return t.hour * 4u + t.minute / 15; } -const TCHAR * +const char * RaspCache::GetMapName() const { return store.GetItemInfo(parameter).name; } -const TCHAR * +const char * RaspCache::GetMapLabel() const { const auto &info = store.GetItemInfo(parameter); diff --git a/src/Weather/Rasp/RaspCache.hpp b/src/Weather/Rasp/RaspCache.hpp index 3d1bdfe53e5..ca62561c519 100644 --- a/src/Weather/Rasp/RaspCache.hpp +++ b/src/Weather/Rasp/RaspCache.hpp @@ -44,14 +44,14 @@ class RaspCache { * Returns the current map's name. */ [[gnu::pure]] - const TCHAR *GetMapName() const; + const char *GetMapName() const; /** * Returns the human-readable name for the current RASP map, or * nullptr if no RASP map is enabled. */ [[gnu::pure]] - const TCHAR *GetMapLabel() const; + const char *GetMapLabel() const; /** * Returns the index of the weather map being displayed. diff --git a/src/Weather/Rasp/RaspRenderer.cpp b/src/Weather/Rasp/RaspRenderer.cpp index 3da43e6c85d..5cd2123d733 100644 --- a/src/Weather/Rasp/RaspRenderer.cpp +++ b/src/Weather/Rasp/RaspRenderer.cpp @@ -12,7 +12,7 @@ [[gnu::pure]] static const RaspStyle & -LookupWeatherTerrainStyle(const TCHAR *name) +LookupWeatherTerrainStyle(const char *name) { const auto *i = rasp_styles; while (i->name != nullptr && !StringIsEqual(i->name, name)) diff --git a/src/Weather/Rasp/RaspRenderer.hpp b/src/Weather/Rasp/RaspRenderer.hpp index b7d864775c7..e425862ad04 100644 --- a/src/Weather/Rasp/RaspRenderer.hpp +++ b/src/Weather/Rasp/RaspRenderer.hpp @@ -48,7 +48,7 @@ class RaspRenderer { * nullptr if no RASP map is enabled. */ [[gnu::pure]] - const TCHAR *GetLabel() const { + const char *GetLabel() const { return cache.GetMapLabel(); } diff --git a/src/Weather/Rasp/RaspStore.cpp b/src/Weather/Rasp/RaspStore.cpp index f5a203cfe49..b8181947af6 100644 --- a/src/Weather/Rasp/RaspStore.cpp +++ b/src/Weather/Rasp/RaspStore.cpp @@ -9,7 +9,7 @@ #include "io/ZipArchive.hpp" #include "util/StringCompare.hxx" #include "util/Macros.hpp" -#include "util/tstring.hpp" +#include #include "zzip/zzip.h" #include "LogFile.hpp" @@ -24,58 +24,58 @@ static constexpr RaspStore::MapInfo WeatherDescriptors[] = { { - _T("wstar"), + "wstar", N_("W*"), N_("Average dry thermal updraft strength near mid-BL height. Subtract glider descent rate to get average vario reading for cloudless thermals. Updraft strengths will be stronger than this forecast if convective clouds are present, since cloud condensation adds buoyancy aloft (i.e. this neglects \"cloudsuck\"). W* depends upon both the surface heating and the BL depth."), }, { - _T("wstar_bsratio"), + "wstar_bsratio", N_("W*"), N_("Average dry thermal updraft strength near mid-BL height. Subtract glider descent rate to get average vario reading for cloudless thermals. Updraft strengths will be stronger than this forecast if convective clouds are present, since cloud condensation adds buoyancy aloft (i.e. this neglects \"cloudsuck\"). W* depends upon both the surface heating and the BL depth."), }, { - _T("blwindspd"), + "blwindspd", N_("BL Wind spd"), N_("The speed and direction of the vector-averaged wind in the BL. This prediction can be misleading if there is a large change in wind direction through the BL."), }, { - _T("hbl"), + "hbl", N_("H bl"), N_("Height of the top of the mixing layer, which for thermal convection is the average top of a dry thermal. Over flat terrain, maximum thermalling heights will be lower due to the glider descent rate and other factors. In the presence of clouds (which release additional buoyancy aloft, creating \"cloudsuck\") the updraft top will be above this forecast, but the maximum thermalling height will then be limited by the cloud base. Further, when the mixing results from shear turbulence rather than thermal mixing this parameter is not useful for glider flying. "), }, { - _T("dwcrit"), + "dwcrit", N_("dwcrit"), N_("This parameter estimates the height above ground at which the average dry updraft strength drops below 225 fpm and is expected to give better quantitative numbers for the maximum cloudless thermalling height than the BL Top height, especially when mixing results from vertical wind shear rather than thermals. (Note: the present assumptions tend to underpredict the max. thermalling height for dry consitions.) In the presence of clouds the maximum thermalling height may instead be limited by the cloud base. Being for \"dry\" thermals, this parameter omits the effect of \"cloudsuck\"."), }, { - _T("blcloudpct"), + "blcloudpct", N_("bl cloud"), N_("This parameter provides an additional means of evaluating the formation of clouds within the BL and might be used either in conjunction with or instead of the other cloud prediction parameters. It assumes a very simple relationship between cloud cover percentage and the maximum relative humidity within the BL. The cloud base height is not predicted, but is expected to be below the BL Top height."), }, { - _T("sfctemp"), + "sfctemp", N_("Sfc temp"), N_("The temperature at a height of 2m above ground level. This can be compared to observed surface temperatures as an indication of model simulation accuracy; e.g. if observed surface temperatures are significantly below those forecast, then soaring conditions will be poorer than forecast."), }, { - _T("hwcrit"), + "hwcrit", N_("hwcrit"), N_("This parameter estimates the height at which the average dry updraft strength drops below 225 fpm and is expected to give better quantitative numbers for the maximum cloudless thermalling height than the BL Top height, especially when mixing results from vertical wind shear rather than thermals. (Note: the present assumptions tend to underpredict the max. thermalling height for dry consitions.) In the presence of clouds the maximum thermalling height may instead be limited by the cloud base. Being for \"dry\" thermals, this parameter omits the effect of \"cloudsuck\"."), }, { - _T("wblmaxmin"), + "wblmaxmin", N_("wblmaxmin"), N_("Maximum grid-area-averaged extensive upward or downward motion within the BL as created by horizontal wind convergence. Positive convergence is associated with local small-scale convergence lines. Negative convergence (divergence) produces subsiding vertical motion, creating low-level inversions which limit thermalling heights."), }, { - _T("blcwbase"), + "blcwbase", N_("blcwbase"), nullptr, }, }; -RaspStore::MapItem::MapItem(const TCHAR *_name) +RaspStore::MapItem::MapItem(const char *_name) :name(_name) { std::fill_n(times, ARRAY_SIZE(times), false); @@ -158,7 +158,7 @@ try { maps.clear(); - std::set names; + std::set names; for (const auto &i : WeatherDescriptors) { if (maps.full()) @@ -178,7 +178,7 @@ try { if (!StringEndsWith(name.c_str(), ".jp2")) continue; - MapItem item(_T("")); + MapItem item(""); auto dot = name.find('.'); if (dot == name.npos || dot == 0 || diff --git a/src/Weather/Rasp/RaspStore.hpp b/src/Weather/Rasp/RaspStore.hpp index 2afa7a1e908..1382af40072 100644 --- a/src/Weather/Rasp/RaspStore.hpp +++ b/src/Weather/Rasp/RaspStore.hpp @@ -30,18 +30,18 @@ class RaspStore { static constexpr unsigned MAX_WEATHER_TIMES = 96; /**< Max time segments of each item */ struct MapInfo { - const TCHAR *name; + const char *name; /** * Human-readable label. Call gettext() for internationalization. */ - const TCHAR *label; + const char *label; /** * Human-readable help text. Call gettext() for * internationalization. */ - const TCHAR *help; + const char *help; }; struct MapItem { @@ -50,18 +50,18 @@ class RaspStore { /** * Human-readable label. Call gettext() for internationalization. */ - const TCHAR *label; + const char *label; /** * Human-readable help text. Call gettext() for * internationalization. */ - const TCHAR *help; + const char *help; bool times[MAX_WEATHER_TIMES]; MapItem() = default; - explicit MapItem(const TCHAR *_name); + explicit MapItem(const char *_name); }; typedef StaticArray MapList; diff --git a/src/Weather/Rasp/RaspStyle.cpp b/src/Weather/Rasp/RaspStyle.cpp index 94443649172..39a3f0bd8d7 100644 --- a/src/Weather/Rasp/RaspStyle.cpp +++ b/src/Weather/Rasp/RaspStyle.cpp @@ -419,65 +419,65 @@ static constexpr ColorRamp rasp_colors_cloudfraction_accumulated[NUM_COLOR_RAMP_ }; const RaspStyle rasp_styles[] = { - { _T("wstar"), rasp_colors[0], + { "wstar", rasp_colors[0], 2, // max range 256*(2**2) = 1024 cm/s = 10 m/s false }, - { _T("wstar_bsratio"), rasp_colors[0], + { "wstar_bsratio", rasp_colors[0], 2, // max range 256*(2**2) = 1024 cm/s = 10 m/s false }, - { _T("blwindspd"), rasp_colors[1], 3, false }, - { _T("hbl"), rasp_colors[2], 4, false }, - { _T("dwcrit"), rasp_colors[2], 4, false }, - { _T("blcloudpct"), rasp_colors[3], 0, true }, - { _T("sfctemp"), rasp_colors[4], 0, false }, - { _T("hwcrit"), rasp_colors[2], 4, false }, - { _T("wblmaxmin"), rasp_colors[5], + { "blwindspd", rasp_colors[1], 3, false }, + { "hbl", rasp_colors[2], 4, false }, + { "dwcrit", rasp_colors[2], 4, false }, + { "blcloudpct", rasp_colors[3], 0, true }, + { "sfctemp", rasp_colors[4], 0, false }, + { "hwcrit", rasp_colors[2], 4, false }, + { "wblmaxmin", rasp_colors[5], 1, // max range 256*(1**2) = 512 cm/s = 5.0 m/s false }, - { _T("blcwbase"), rasp_colors[2], 4, false }, + { "blcwbase", rasp_colors[2], 4, false }, // Thermalmap.info Colorschemes and Rasp file names - { _T("ThermalStrength"), rasp_colors_thermalstrength, 4, false }, - { _T("ThermalHeight"), rasp_colors_thermalheight, 4, false }, - { _T("Convergence"), rasp_colors_verticalspeed, 5, false }, - { _T("Wave_1000m"), rasp_colors_verticalspeed, 5, false }, - { _T("Wave_2000m"), rasp_colors_verticalspeed, 5, false }, - { _T("Wave_3000m"), rasp_colors_verticalspeed, 5, false }, - { _T("Wave_4000m"), rasp_colors_verticalspeed, 5, false }, - { _T("Wave_5000m"), rasp_colors_verticalspeed, 5, false }, - { _T("Wave_6000m"), rasp_colors_verticalspeed, 5, false }, - { _T("Wave_7000m"), rasp_colors_verticalspeed, 5, false }, - { _T("Temperature2m"), rasp_colors_temperature, 4, false }, - { _T("Rain"), rasp_colors_rain, 3, false }, - { _T("PFD_Day_DuoDiscus"), rasp_colors_pfd_ls4, 3, false }, - { _T("PFD_Day_LS4"), rasp_colors_pfd_ls4, 3, false }, - { _T("PFD_Day_K8"), rasp_colors_pfd_ls4, 3, false }, - { _T("Windspeed_10m"), rasp_colors_bl_avg_windspeed, 3, false }, - { _T("Windspeed_500m"), rasp_colors_bl_avg_windspeed, 3, false }, - { _T("Windspeed_1000m"), rasp_colors_bl_avg_windspeed, 3, false }, - { _T("Windspeed_1500m"), rasp_colors_bl_avg_windspeed, 3, false }, - { _T("Windspeed_2000m"), rasp_colors_bl_avg_windspeed, 3, false }, - { _T("Windspeed_2500m"), rasp_colors_bl_avg_windspeed, 3, false }, - { _T("Windspeed_3000m"), rasp_colors_bl_avg_windspeed, 3, false }, - { _T("Windspeed_3500m"), rasp_colors_bl_avg_windspeed, 3, false }, - { _T("Windspeed_4000m"), rasp_colors_bl_avg_windspeed, 3, false }, - { _T("Windspeed_4500m"), rasp_colors_bl_avg_windspeed, 3, false }, - { _T("Windspeed_5000m"), rasp_colors_bl_avg_windspeed, 3, false }, - { _T("Windspeed_5500m"), rasp_colors_bl_avg_windspeed, 3, false }, - { _T("Windspeed_6000m"), rasp_colors_bl_avg_windspeed, 3, false }, - { _T("Windspeed_6500m"), rasp_colors_bl_avg_windspeed, 3, false }, - { _T("Windspeed_7000m"), rasp_colors_bl_avg_windspeed, 3, false }, - { _T("VerticalWindShear"), rasp_colors_bl_avg_windspeed, 3, false }, - { _T("BL_AverageWindSpeed"), rasp_colors_bl_avg_windspeed, 3, false }, - { _T("XCSpeed_LS4"), rasp_colors_xcspeed_ls4, 3, false }, - { _T("XCSpeed_DuoDiscus"), rasp_colors_xcspeed_ls4, 3, false }, - { _T("XCSpeed_K8"), rasp_colors_xcspeed_k8, 3, false }, - { _T("SurfaceHeatFlux"), rasp_colors_surface_heat_flux, 6, false }, - { _T("SeaLevelPressure"), rasp_colors_sealevel_pressure, 7, false }, - { _T("Cloudfraction_Low"), rasp_colors_cloudfraction_low, 4, false }, - { _T("Cloudfraction_Mid"), rasp_colors_cloudfraction_mid, 4, false }, - { _T("Cloudfraction_High"), rasp_colors_cloudfraction_high, 4, false }, - { _T("Cloudfraction_Accumulated"), rasp_colors_cloudfraction_accumulated, 4, false }, + { "ThermalStrength", rasp_colors_thermalstrength, 4, false }, + { "ThermalHeight", rasp_colors_thermalheight, 4, false }, + { "Convergence", rasp_colors_verticalspeed, 5, false }, + { "Wave_1000m", rasp_colors_verticalspeed, 5, false }, + { "Wave_2000m", rasp_colors_verticalspeed, 5, false }, + { "Wave_3000m", rasp_colors_verticalspeed, 5, false }, + { "Wave_4000m", rasp_colors_verticalspeed, 5, false }, + { "Wave_5000m", rasp_colors_verticalspeed, 5, false }, + { "Wave_6000m", rasp_colors_verticalspeed, 5, false }, + { "Wave_7000m", rasp_colors_verticalspeed, 5, false }, + { "Temperature2m", rasp_colors_temperature, 4, false }, + { "Rain", rasp_colors_rain, 3, false }, + { "PFD_Day_DuoDiscus", rasp_colors_pfd_ls4, 3, false }, + { "PFD_Day_LS4", rasp_colors_pfd_ls4, 3, false }, + { "PFD_Day_K8", rasp_colors_pfd_ls4, 3, false }, + { "Windspeed_10m", rasp_colors_bl_avg_windspeed, 3, false }, + { "Windspeed_500m", rasp_colors_bl_avg_windspeed, 3, false }, + { "Windspeed_1000m", rasp_colors_bl_avg_windspeed, 3, false }, + { "Windspeed_1500m", rasp_colors_bl_avg_windspeed, 3, false }, + { "Windspeed_2000m", rasp_colors_bl_avg_windspeed, 3, false }, + { "Windspeed_2500m", rasp_colors_bl_avg_windspeed, 3, false }, + { "Windspeed_3000m", rasp_colors_bl_avg_windspeed, 3, false }, + { "Windspeed_3500m", rasp_colors_bl_avg_windspeed, 3, false }, + { "Windspeed_4000m", rasp_colors_bl_avg_windspeed, 3, false }, + { "Windspeed_4500m", rasp_colors_bl_avg_windspeed, 3, false }, + { "Windspeed_5000m", rasp_colors_bl_avg_windspeed, 3, false }, + { "Windspeed_5500m", rasp_colors_bl_avg_windspeed, 3, false }, + { "Windspeed_6000m", rasp_colors_bl_avg_windspeed, 3, false }, + { "Windspeed_6500m", rasp_colors_bl_avg_windspeed, 3, false }, + { "Windspeed_7000m", rasp_colors_bl_avg_windspeed, 3, false }, + { "VerticalWindShear", rasp_colors_bl_avg_windspeed, 3, false }, + { "BL_AverageWindSpeed", rasp_colors_bl_avg_windspeed, 3, false }, + { "XCSpeed_LS4", rasp_colors_xcspeed_ls4, 3, false }, + { "XCSpeed_DuoDiscus", rasp_colors_xcspeed_ls4, 3, false }, + { "XCSpeed_K8", rasp_colors_xcspeed_k8, 3, false }, + { "SurfaceHeatFlux", rasp_colors_surface_heat_flux, 6, false }, + { "SeaLevelPressure", rasp_colors_sealevel_pressure, 7, false }, + { "Cloudfraction_Low", rasp_colors_cloudfraction_low, 4, false }, + { "Cloudfraction_Mid", rasp_colors_cloudfraction_mid, 4, false }, + { "Cloudfraction_High", rasp_colors_cloudfraction_high, 4, false }, + { "Cloudfraction_Accumulated", rasp_colors_cloudfraction_accumulated, 4, false }, { nullptr, rasp_colors[0], 2, false } }; diff --git a/src/Weather/Rasp/RaspStyle.hpp b/src/Weather/Rasp/RaspStyle.hpp index 52cf8f10a02..7b20e2436c7 100644 --- a/src/Weather/Rasp/RaspStyle.hpp +++ b/src/Weather/Rasp/RaspStyle.hpp @@ -8,7 +8,7 @@ struct ColorRamp; struct RaspStyle { - const TCHAR *name; + const char *name; const ColorRamp *color_ramp; unsigned height_scale; bool do_water; diff --git a/src/Widget/ArrowPagerWidget.cpp b/src/Widget/ArrowPagerWidget.cpp index b8678104c84..ded14075897 100644 --- a/src/Widget/ArrowPagerWidget.cpp +++ b/src/Widget/ArrowPagerWidget.cpp @@ -111,10 +111,10 @@ ArrowPagerWidget::Prepare(ContainerWindow &parent, style.TabStop(); previous_button.Create(parent, layout.previous_button, style, - std::make_unique(look, _T("<")), + std::make_unique(look, "<"), [this](){ Previous(false); }); next_button.Create(parent, layout.next_button, style, - std::make_unique(look, _T(">")), + std::make_unique(look, ">"), [this](){ Next(false); }); close_button.Create(parent, look, _("Close"), layout.close_button, style, close_callback); diff --git a/src/Widget/ButtonWidget.cpp b/src/Widget/ButtonWidget.cpp index 3bd783bb7fd..143dcd0d92a 100644 --- a/src/Widget/ButtonWidget.cpp +++ b/src/Widget/ButtonWidget.cpp @@ -12,7 +12,7 @@ ButtonWidget::ButtonWidget(std::unique_ptr _renderer, :renderer(std::move(_renderer)), callback(std::move(_callback)) {} -ButtonWidget::ButtonWidget(const ButtonLook &look, const TCHAR *caption, +ButtonWidget::ButtonWidget(const ButtonLook &look, const char *caption, std::function _callback) noexcept :renderer(std::make_unique(look, caption)), callback(std::move(_callback)) {} diff --git a/src/Widget/ButtonWidget.hpp b/src/Widget/ButtonWidget.hpp index 6e485e03573..ec9bd8aab6a 100644 --- a/src/Widget/ButtonWidget.hpp +++ b/src/Widget/ButtonWidget.hpp @@ -25,7 +25,7 @@ class ButtonWidget : public WindowWidget { ButtonWidget(std::unique_ptr _renderer, std::function _callback) noexcept; - ButtonWidget(const ButtonLook &look, const TCHAR *caption, + ButtonWidget(const ButtonLook &look, const char *caption, std::function _callback) noexcept; ~ButtonWidget() noexcept override; diff --git a/src/Widget/CMakeLists.txt b/src/Widget/CMakeLists.txt new file mode 100644 index 00000000000..e7c8d34a10b --- /dev/null +++ b/src/Widget/CMakeLists.txt @@ -0,0 +1,55 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories +file(GLOB_RECURSE SCRIPT_FILES *.txt *.cmake) + +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +source_group("Scripts" FILES ${SCRIPT_FILES}) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +target_link_libraries(${TARGET_NAME} PUBLIC IGC Form Airspace) + +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER FrontEnd) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/Widget/CMakeSource.cmake b/src/Widget/CMakeSource.cmake new file mode 100644 index 00000000000..9639a6db92a --- /dev/null +++ b/src/Widget/CMakeSource.cmake @@ -0,0 +1,43 @@ +set(_SOURCES + Widget/ActionWidget.cpp + Widget/ArrowPagerWidget.cpp + Widget/ButtonPanelWidget.cpp + Widget/ButtonWidget.cpp + Widget/CallbackWidget.cpp + Widget/ContainerWidget.cpp + Widget/CreateWindowWidget.cpp + Widget/EditRowFormWidget.cpp + Widget/KeyboardWidget.cpp + Widget/LargeTextWidget.cpp + Widget/ListWidget.cpp + Widget/ManagedWidget.cpp + Widget/OffsetButtonsWidget.cpp + Widget/OverlappedWidget.cpp + Widget/PagerWidget.cpp + Widget/PanelWidget.cpp + Widget/ProfileRowFormWidget.cpp + Widget/QuestionWidget.cpp + Widget/RowFormWidget.cpp + Widget/FileRowFormWidget.cpp + Widget/SolidWidget.cpp + Widget/TabWidget.cpp + Widget/TextListWidget.cpp + Widget/TextWidget.cpp + Widget/TwoWidgets.cpp + Widget/UnitRowFormWidget.cpp + Widget/ViewImageWidget.cpp + Widget/Widget.cpp + Widget/WindowWidget.cpp + + Widget/ProgressWidget.cpp + Widget/LargeTextWidget.cpp + Widget/VScrollWidget.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake + + ../../build/libwidget.mk +) + + diff --git a/src/Widget/EditRowFormWidget.cpp b/src/Widget/EditRowFormWidget.cpp index 1ba48bc937d..433f8186cd9 100644 --- a/src/Widget/EditRowFormWidget.cpp +++ b/src/Widget/EditRowFormWidget.cpp @@ -24,7 +24,7 @@ #include std::unique_ptr -RowFormWidget::CreateEdit(const TCHAR *label, const TCHAR *help, +RowFormWidget::CreateEdit(const char *label, const char *help, bool read_only) noexcept { assert(IsDefined()); @@ -50,7 +50,7 @@ RowFormWidget::CreateEdit(const TCHAR *label, const TCHAR *help, } WndProperty * -RowFormWidget::Add(const TCHAR *label, const TCHAR *help, +RowFormWidget::Add(const char *label, const char *help, bool read_only) noexcept { return (WndProperty *)&Add(Row::Type::EDIT, @@ -58,8 +58,8 @@ RowFormWidget::Add(const TCHAR *label, const TCHAR *help, } void -RowFormWidget::AddReadOnly(const TCHAR *label, const TCHAR *help, - const TCHAR *text) noexcept +RowFormWidget::AddReadOnly(const char *label, const char *help, + const char *text) noexcept { WndProperty *control = Add(label, help, true); if (text != nullptr) @@ -67,8 +67,8 @@ RowFormWidget::AddReadOnly(const TCHAR *label, const TCHAR *help, } void -RowFormWidget::AddReadOnly(const TCHAR *label, const TCHAR *help, - const TCHAR *display_format, +RowFormWidget::AddReadOnly(const char *label, const char *help, + const char *display_format, double value) noexcept { WndProperty *edit = Add(label, help, true); @@ -78,7 +78,7 @@ RowFormWidget::AddReadOnly(const TCHAR *label, const TCHAR *help, } void -RowFormWidget::AddReadOnly(const TCHAR *label, const TCHAR *help, +RowFormWidget::AddReadOnly(const char *label, const char *help, bool value) noexcept { WndProperty *edit = Add(label, help, true); @@ -87,7 +87,7 @@ RowFormWidget::AddReadOnly(const TCHAR *label, const TCHAR *help, } WndProperty * -RowFormWidget::Add(const TCHAR *label, const TCHAR *help, +RowFormWidget::Add(const char *label, const char *help, DataField *df) noexcept { WndProperty *edit = Add(label, help); @@ -96,7 +96,7 @@ RowFormWidget::Add(const TCHAR *label, const TCHAR *help, } WndProperty * -RowFormWidget::AddBoolean(const TCHAR *label, const TCHAR *help, +RowFormWidget::AddBoolean(const char *label, const char *help, bool value, DataFieldListener *listener) noexcept { @@ -108,9 +108,9 @@ RowFormWidget::AddBoolean(const TCHAR *label, const TCHAR *help, } WndProperty * -RowFormWidget::AddInteger(const TCHAR *label, const TCHAR *help, - const TCHAR *display_format, - const TCHAR *edit_format, +RowFormWidget::AddInteger(const char *label, const char *help, + const char *display_format, + const char *edit_format, int min_value, int max_value, int step, int value, DataFieldListener *listener) noexcept { @@ -123,9 +123,9 @@ RowFormWidget::AddInteger(const TCHAR *label, const TCHAR *help, } WndProperty * -RowFormWidget::AddFloat(const TCHAR *label, const TCHAR *help, - const TCHAR *display_format, - const TCHAR *edit_format, +RowFormWidget::AddFloat(const char *label, const char *help, + const char *display_format, + const char *edit_format, double min_value, double max_value, double step, bool fine, double value, @@ -140,7 +140,7 @@ RowFormWidget::AddFloat(const TCHAR *label, const TCHAR *help, } WndProperty * -RowFormWidget::AddAngle(const TCHAR *label, const TCHAR *help, +RowFormWidget::AddAngle(const char *label, const char *help, Angle value, unsigned step, bool fine, DataFieldListener *listener) noexcept { @@ -151,7 +151,7 @@ RowFormWidget::AddAngle(const TCHAR *label, const TCHAR *help, } WndProperty * -RowFormWidget::AddEnum(const TCHAR *label, const TCHAR *help, +RowFormWidget::AddEnum(const char *label, const char *help, const StaticEnumChoice *list, unsigned value, DataFieldListener *listener) noexcept { @@ -171,7 +171,7 @@ RowFormWidget::AddEnum(const TCHAR *label, const TCHAR *help, } WndProperty * -RowFormWidget::AddEnum(const TCHAR *label, const TCHAR *help, +RowFormWidget::AddEnum(const char *label, const char *help, DataFieldListener *listener) noexcept { WndProperty *edit = Add(label, help); @@ -182,8 +182,8 @@ RowFormWidget::AddEnum(const TCHAR *label, const TCHAR *help, } WndProperty * -RowFormWidget::AddText(const TCHAR *label, const TCHAR *help, - const TCHAR *content, +RowFormWidget::AddText(const char *label, const char *help, + const char *content, DataFieldListener *listener) noexcept { WndProperty *edit = Add(label, help); @@ -194,8 +194,8 @@ RowFormWidget::AddText(const TCHAR *label, const TCHAR *help, } WndProperty * -RowFormWidget::AddPassword(const TCHAR *label, const TCHAR *help, - const TCHAR *content) noexcept +RowFormWidget::AddPassword(const char *label, const char *help, + const char *content) noexcept { WndProperty *edit = Add(label, help); PasswordDataField *df = new PasswordDataField(content); @@ -205,7 +205,7 @@ RowFormWidget::AddPassword(const TCHAR *label, const TCHAR *help, } WndProperty * -RowFormWidget::AddDuration(const TCHAR *label, const TCHAR *help, +RowFormWidget::AddDuration(const char *label, const char *help, std::chrono::seconds min_value, std::chrono::seconds max_value, std::chrono::seconds step, @@ -222,7 +222,7 @@ RowFormWidget::AddDuration(const TCHAR *label, const TCHAR *help, } WndProperty * -RowFormWidget::AddDate(const TCHAR *label, const TCHAR *help, +RowFormWidget::AddDate(const char *label, const char *help, BrokenDate date, DataFieldListener *listener) noexcept { @@ -233,7 +233,7 @@ RowFormWidget::AddDate(const TCHAR *label, const TCHAR *help, } WndProperty * -RowFormWidget::AddRoughTime(const TCHAR *label, const TCHAR *help, +RowFormWidget::AddRoughTime(const char *label, const char *help, RoughTime value, RoughTimeDelta time_zone, DataFieldListener *listener) noexcept { @@ -264,7 +264,7 @@ RowFormWidget::LoadValue(unsigned i, bool value) noexcept } void -RowFormWidget::LoadValueEnum(unsigned i, const TCHAR *text) noexcept +RowFormWidget::LoadValueEnum(unsigned i, const char *text) noexcept { WndProperty &control = GetControl(i); DataFieldEnum &df = *(DataFieldEnum *)control.GetDataField(); @@ -294,7 +294,7 @@ RowFormWidget::LoadValue(unsigned i, double value) noexcept } void -RowFormWidget::LoadValue(unsigned i, const TCHAR *value) noexcept +RowFormWidget::LoadValue(unsigned i, const char *value) noexcept { WndProperty &control = GetControl(i); DataFieldString &df = *(DataFieldString *)control.GetDataField(); @@ -463,9 +463,9 @@ RowFormWidget::SaveValue(unsigned i, RoughTime &value_r) const noexcept bool RowFormWidget::SaveValue(unsigned i, - TCHAR *string, size_t max_size) const noexcept + char *string, size_t max_size) const noexcept { - const TCHAR *new_value = GetDataField(i).GetAsString(); + const char *new_value = GetDataField(i).GetAsString(); assert(new_value != nullptr); if (StringIsEqual(string, new_value)) diff --git a/src/Widget/KeyboardWidget.cpp b/src/Widget/KeyboardWidget.cpp index 555dd7c785f..e03a05a4e1a 100644 --- a/src/Widget/KeyboardWidget.cpp +++ b/src/Widget/KeyboardWidget.cpp @@ -11,31 +11,31 @@ #include #include -static constexpr TCHAR keyboard_letters[] = - _T("1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ"); +static constexpr char keyboard_letters[] = + "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ"; void KeyboardWidget::Prepare(ContainerWindow &parent, const PixelRect &rc) noexcept { PrepareSize(rc); - TCHAR caption[] = _T(" "); + char caption[] = " "; - for (const TCHAR *i = keyboard_letters; !StringIsEmpty(i); ++i) { + for (const char *i = keyboard_letters; !StringIsEmpty(i); ++i) { caption[0] = *i; AddButton(parent, caption, *i); } - AddButton(parent, _T("Space"), ' '); - AddButton(parent, _T("."), '.'); - AddButton(parent, _T("@"), '@'); - AddButton(parent, _T("-"), '-'); + AddButton(parent, "Space", ' '); + AddButton(parent, ".", '.'); + AddButton(parent, "@", '@'); + AddButton(parent, "-", '-'); if (show_shift_button) { WindowStyle style; style.Hide(); shift_button.Create(parent, { 0, 0, 16, 16 }, style, - std::make_unique(look, _T("v")), + std::make_unique(look, "v"), [this](){ OnShiftClicked(); }); } UpdateShiftState(); @@ -70,7 +70,7 @@ KeyboardWidget::Move(const PixelRect &rc) noexcept } void -KeyboardWidget::SetAllowedCharacters(const TCHAR *allowed) +KeyboardWidget::SetAllowedCharacters(const char *allowed) { for (unsigned i = 0; i < num_buttons; ++i) buttons[i].SetVisible(allowed == nullptr || @@ -133,13 +133,13 @@ KeyboardWidget::ResizeButtons() void KeyboardWidget::MoveButtonsToRow(const PixelRect &rc, - const TCHAR *buttons, unsigned row, + const char *buttons, unsigned row, int offset) { if (StringIsEmpty(buttons)) return; - for (unsigned i = 0; buttons[i] != _T('\0'); i++) { + for (unsigned i = 0; buttons[i] != '\0'; i++) { MoveButton(buttons[i], rc.GetTopLeft() + PixelSize(i * button_size.width + offset, row * button_size.height)); @@ -149,25 +149,25 @@ KeyboardWidget::MoveButtonsToRow(const PixelRect &rc, void KeyboardWidget::MoveButtons(const PixelRect &rc) { - MoveButtonsToRow(rc, _T("1234567890"), 0); - MoveButtonsToRow(rc, _T("QWERTYUIOP"), 1); - MoveButtonsToRow(rc, _T("ASDFGHJKL"), 2, button_size.width / 3); - MoveButtonsToRow(rc, _T("ZXCVBNM@."), 3, button_size.width); + MoveButtonsToRow(rc, "1234567890", 0); + MoveButtonsToRow(rc, "QWERTYUIOP", 1); + MoveButtonsToRow(rc, "ASDFGHJKL", 2, button_size.width / 3); + MoveButtonsToRow(rc, "ZXCVBNM@.", 3, button_size.width); if (IsLandscape(rc)) { - MoveButton(_T('-'), + MoveButton('-', rc.GetTopLeft() + PixelSize{button_size.width * 9, Layout::Scale(160U)}); - MoveButton(_T(' '), + MoveButton(' ', rc.GetTopLeft() + PixelSize{Layout::Scale(80U), Layout::Scale(160U)}); - ResizeButton(_T(' '), {Layout::Scale(93U), Layout::Scale(40U)}); + ResizeButton(' ', {Layout::Scale(93U), Layout::Scale(40U)}); } else { - MoveButton(_T('-'), + MoveButton('-', rc.GetTopLeft() + PixelSize{button_size.width * 8, button_size.height * 4}); - MoveButton(_T(' '), + MoveButton(' ', rc.GetTopLeft() + PixelSize{button_size.width * 2, button_size.height * 4}); - ResizeButton(_T(' '), {button_size.width * 11 / 2, button_size.height}); + ResizeButton(' ', {button_size.width * 11 / 2, button_size.height}); } if (show_shift_button) @@ -191,7 +191,7 @@ KeyboardWidget::OnResize(const PixelRect &rc) void KeyboardWidget::AddButton(ContainerWindow &parent, - const TCHAR *caption, unsigned ch) + const char *caption, unsigned ch) { assert(num_buttons < MAX_BUTTONS); @@ -207,7 +207,7 @@ void KeyboardWidget::UpdateShiftState() { if (show_shift_button) - shift_button.SetCaption(shift_state ? _T("v") : _T("^")); + shift_button.SetCaption(shift_state ? "v" : "^"); for (unsigned i = 0; i < num_buttons; ++i) { unsigned uch = buttons[i].GetCharacter(); diff --git a/src/Widget/KeyboardWidget.hpp b/src/Widget/KeyboardWidget.hpp index 9c153b0c8ab..413b64ba4cf 100644 --- a/src/Widget/KeyboardWidget.hpp +++ b/src/Widget/KeyboardWidget.hpp @@ -45,7 +45,7 @@ class KeyboardWidget : public NullWidget { /** * Show only the buttons representing the specified character list. */ - void SetAllowedCharacters(const TCHAR *allowed); + void SetAllowedCharacters(const char *allowed); private: void PrepareSize(const PixelRect &rc); @@ -59,7 +59,7 @@ class KeyboardWidget : public NullWidget { void ResizeButtons(); void SetButtonsSize(); void MoveButtonsToRow(const PixelRect &rc, - const TCHAR *buttons, unsigned row, + const char *buttons, unsigned row, int offset_left = 0); void MoveButtons(const PixelRect &rc); @@ -71,7 +71,7 @@ class KeyboardWidget : public NullWidget { /* updates UI based on value of shift_state property */ void UpdateShiftState(); - void AddButton(ContainerWindow &parent, const TCHAR *caption, unsigned ch); + void AddButton(ContainerWindow &parent, const char *caption, unsigned ch); public: /* virtual methods from class Widget */ diff --git a/src/Widget/LargeTextWidget.cpp b/src/Widget/LargeTextWidget.cpp index b3f85878806..e626b64dd07 100644 --- a/src/Widget/LargeTextWidget.cpp +++ b/src/Widget/LargeTextWidget.cpp @@ -6,7 +6,7 @@ #include "Look/DialogLook.hpp" void -LargeTextWidget::SetText(const TCHAR *text) noexcept +LargeTextWidget::SetText(const char *text) noexcept { LargeTextWindow &w = (LargeTextWindow &)GetWindow(); w.SetText(text); diff --git a/src/Widget/LargeTextWidget.hpp b/src/Widget/LargeTextWidget.hpp index 78507389d8e..7ce88a4fa8e 100644 --- a/src/Widget/LargeTextWidget.hpp +++ b/src/Widget/LargeTextWidget.hpp @@ -14,15 +14,14 @@ struct DialogLook; */ class LargeTextWidget : public WindowWidget { const DialogLook &look; - const TCHAR *text; + const char *text; public: explicit LargeTextWidget(const DialogLook &_look, - const TCHAR *_text=nullptr) noexcept + const char *_text=nullptr) noexcept :look(_look), text(_text) {} - void SetText(const TCHAR *text) noexcept; - + void SetText(const char *text) noexcept; /* virtual methods from class Widget */ void Prepare(ContainerWindow &parent, const PixelRect &rc) noexcept override; bool SetFocus() noexcept override; diff --git a/src/Widget/OffsetButtonsWidget.cpp b/src/Widget/OffsetButtonsWidget.cpp index bc0d385f883..ba94b4f3043 100644 --- a/src/Widget/OffsetButtonsWidget.cpp +++ b/src/Widget/OffsetButtonsWidget.cpp @@ -41,7 +41,7 @@ inline Button OffsetButtonsWidget::MakeButton(ContainerWindow &parent, const PixelRect &r, unsigned i) noexcept { - TCHAR caption[16]; + char caption[16]; _stprintf(caption, format, offsets[i]); WindowStyle style; diff --git a/src/Widget/OffsetButtonsWidget.hpp b/src/Widget/OffsetButtonsWidget.hpp index 9df5f5f2e89..ae9be2e8b42 100644 --- a/src/Widget/OffsetButtonsWidget.hpp +++ b/src/Widget/OffsetButtonsWidget.hpp @@ -21,12 +21,12 @@ class Button; */ class OffsetButtonsWidget : public NullWidget { const ButtonLook &look; - const TCHAR *const format; + const char *const format; const double offsets[4]; std::unique_ptr> buttons; public: - OffsetButtonsWidget(const ButtonLook &_look, const TCHAR *_format, + OffsetButtonsWidget(const ButtonLook &_look, const char *_format, double small_offset, double large_offset) noexcept :look(_look), format(_format), offsets{-large_offset, -small_offset, small_offset, large_offset} {} diff --git a/src/Widget/PagerWidget.cpp b/src/Widget/PagerWidget.cpp index 40855d410c3..a8bcbb2625a 100644 --- a/src/Widget/PagerWidget.cpp +++ b/src/Widget/PagerWidget.cpp @@ -4,6 +4,8 @@ #include "PagerWidget.hpp" #include +#include + PagerWidget::Child::~Child() noexcept { @@ -26,6 +28,12 @@ PagerWidget::Add(std::unique_ptr w) noexcept } else { assert(current < children.size()); } + // current is always 0 + if (children.size() >= children.capacity()) + std::cout << "PagerWidget::Add - children-limit is reached:" << children.size() + << ", capacity: " << children.capacity() << std::endl; + + assert(children.size() < children.capacity()); auto &child = children.emplace_back(std::move(w)); diff --git a/src/Widget/PagerWidget.hpp b/src/Widget/PagerWidget.hpp index 4fa6e6bde51..8263d2e0170 100644 --- a/src/Widget/PagerWidget.hpp +++ b/src/Widget/PagerWidget.hpp @@ -37,7 +37,7 @@ class PagerWidget : public Widget { PixelRect position; unsigned current; - boost::container::static_vector children; + boost::container::static_vector children; PageFlippedCallback page_flipped_callback; diff --git a/src/Widget/ProfileRowFormWidget.cpp b/src/Widget/ProfileRowFormWidget.cpp index 87410bfb589..ad87830c3eb 100644 --- a/src/Widget/ProfileRowFormWidget.cpp +++ b/src/Widget/ProfileRowFormWidget.cpp @@ -7,12 +7,11 @@ #include "Form/DataField/Date.hpp" #include "Profile/Profile.hpp" #include "LocalPath.hpp" -#include "util/ConvertString.hpp" #include "Formatter/TimeFormatter.hpp" WndProperty * -RowFormWidget::AddFile(const TCHAR *label, const TCHAR *help, - std::string_view profile_key, const TCHAR *filters, +RowFormWidget::AddFile(const char *label, const char *help, + std::string_view profile_key, const char *filters, FileType file_type, bool nullable) noexcept { @@ -45,7 +44,7 @@ RowFormWidget::SetProfile(std::string_view profile_key, unsigned value) noexcept bool RowFormWidget::SaveValue(unsigned i, std::string_view profile_key, - TCHAR *string, size_t max_size) const noexcept + char *string, size_t max_size) const noexcept { if (!SaveValue(i, string, max_size)) return false; @@ -85,15 +84,14 @@ RowFormWidget::SaveValueFileReader(unsigned i, if (contracted != nullptr) new_value = contracted; - const WideToUTF8Converter new_value2(new_value.c_str()); - if (!new_value2.IsValid()) + if (!new_value.c_str()) return false; const char *old_value = Profile::Get(profile_key, ""); - if (StringIsEqual(old_value, new_value2)) + if (StringIsEqual(old_value, new_value.c_str())) return false; - Profile::Set(profile_key, new_value2); + Profile::Set(profile_key, new_value.c_str()); return true; } @@ -113,7 +111,7 @@ RowFormWidget::SaveValue(unsigned i, if (new_value == value) return false; - TCHAR buffer[0x10]; + char buffer[0x10]; FormatISO8601(buffer, new_value); Profile::Set(profile_key, buffer); value = new_value; diff --git a/src/Widget/ProgressWidget.cpp b/src/Widget/ProgressWidget.cpp index 92221cdc06d..c24f5f9b1dd 100644 --- a/src/Widget/ProgressWidget.cpp +++ b/src/Widget/ProgressWidget.cpp @@ -8,16 +8,16 @@ #include "Renderer/ProgressBarRenderer.hpp" #include "Screen/Layout.hpp" #include "Look/DialogLook.hpp" -#include "util/tstring_view.hxx" +#include #include "UIGlobals.hpp" class ProgressWidget::ProgressBar final : public PaintWindow { unsigned range = 0, position = 0; - tstring text; + std::string text; public: - explicit ProgressBar(tstring &&_text) noexcept + explicit ProgressBar(std::string &&_text) noexcept :text(std::move(_text)) {} void SetRange(unsigned _range) noexcept { @@ -32,7 +32,7 @@ class ProgressWidget::ProgressBar final : public PaintWindow { Invalidate(); } - void SetText(const TCHAR *_text) noexcept { + void SetText(const char *_text) noexcept { text = _text; Invalidate(); } @@ -52,7 +52,7 @@ class ProgressWidget::ProgressBar final : public PaintWindow { canvas.SetTextColor(COLOR_BLACK); canvas.SetBackgroundTransparent(); - const tstring_view _text{text}; + const std::string_view _text{text}; canvas.DrawText({padding, padding}, _text); } } @@ -97,7 +97,7 @@ ProgressWidget::Unprepare() noexcept } void -ProgressWidget::SetText(const TCHAR *_text) noexcept +ProgressWidget::SetText(const char *_text) noexcept { if (IsDefined()) { auto &pb = (ProgressBar &)GetWindow(); diff --git a/src/Widget/ProgressWidget.hpp b/src/Widget/ProgressWidget.hpp index f374bdbea73..de6d12dbc57 100644 --- a/src/Widget/ProgressWidget.hpp +++ b/src/Widget/ProgressWidget.hpp @@ -5,7 +5,7 @@ #include "WindowWidget.hpp" #include "Operation/MessageOperationEnvironment.hpp" -#include "util/tstring.hpp" +#include class PluggableOperationEnvironment; @@ -17,11 +17,11 @@ class ProgressWidget final : public WindowWidget, MessageOperationEnvironment { PluggableOperationEnvironment &env; - tstring text; + std::string text; public: explicit ProgressWidget(PluggableOperationEnvironment &_env, - const TCHAR *_text) noexcept + const char *_text) noexcept :env(_env), text(_text) {} /* virtual methods from class Widget */ @@ -32,7 +32,7 @@ class ProgressWidget final : public WindowWidget, MessageOperationEnvironment { private: /* virtual methods from class OperationEnvironment */ - void SetText(const TCHAR *text) noexcept override; + void SetText(const char *text) noexcept override; void SetProgressRange(unsigned range) noexcept override; void SetProgressPosition(unsigned position) noexcept override; }; diff --git a/src/Widget/QuestionWidget.cpp b/src/Widget/QuestionWidget.cpp index ab4b68a0f74..e02416e9213 100644 --- a/src/Widget/QuestionWidget.cpp +++ b/src/Widget/QuestionWidget.cpp @@ -6,13 +6,13 @@ #include "TextWidget.hpp" #include "Form/ButtonPanel.hpp" -QuestionWidget::QuestionWidget(const TCHAR *_message) noexcept +QuestionWidget::QuestionWidget(const char *_message) noexcept :SolidWidget(std::make_unique(std::make_unique(), ButtonPanelWidget::Alignment::BOTTOM)), message(_message) {} void -QuestionWidget::SetMessage(const TCHAR *_message) noexcept +QuestionWidget::SetMessage(const char *_message) noexcept { auto &bpw = (ButtonPanelWidget &)GetWidget(); auto &tw = (TextWidget &)bpw.GetWidget(); diff --git a/src/Widget/QuestionWidget.hpp b/src/Widget/QuestionWidget.hpp index f19d4ab6ee1..c7ac4deba55 100644 --- a/src/Widget/QuestionWidget.hpp +++ b/src/Widget/QuestionWidget.hpp @@ -17,20 +17,20 @@ */ class QuestionWidget : public SolidWidget { struct Button { - const TCHAR *caption; + const char *caption; std::function callback; }; - const TCHAR *const message; + const char *const message; StaticArray buttons; public: - explicit QuestionWidget(const TCHAR *_message) noexcept; + explicit QuestionWidget(const char *_message) noexcept; - void SetMessage(const TCHAR *_message) noexcept; + void SetMessage(const char *_message) noexcept; - void AddButton(const TCHAR *caption, + void AddButton(const char *caption, std::function callback) noexcept { buttons.append({caption, std::move(callback)}); } diff --git a/src/Widget/RowFormWidget.cpp b/src/Widget/RowFormWidget.cpp index 083c0e59679..4548ed4280b 100644 --- a/src/Widget/RowFormWidget.cpp +++ b/src/Widget/RowFormWidget.cpp @@ -4,6 +4,7 @@ #include "RowFormWidget.hpp" #include "Form/Panel.hpp" #include "Form/Button.hpp" +#include "Form/Frame.hpp" #include "Form/HLine.hpp" #include "Look/DialogLook.hpp" #include "Dialogs/DialogSettings.hpp" @@ -266,7 +267,20 @@ RowFormWidget::AddSpacer() noexcept } void -RowFormWidget::AddMultiLine(const TCHAR *text) noexcept +RowFormWidget::AddLabel(const char *text, unsigned lines) noexcept +{ + ContainerWindow &panel = (ContainerWindow &)GetWindow(); + if (lines == 0) lines = 1; + const PixelRect rc = InitialControlRect( + Layout::Scale(lines * look.text_font.GetHeight())); + + auto window = std::make_unique(panel, look, rc); + window->SetText(text); + Add(std::move(window)); +} + +void +RowFormWidget::AddMultiLine(const char *text) noexcept { assert(IsDefined()); @@ -288,7 +302,7 @@ RowFormWidget::AddMultiLine(const TCHAR *text) noexcept } Button * -RowFormWidget::AddButton(const TCHAR *label, +RowFormWidget::AddButton(const char *label, std::function callback) noexcept { assert(IsDefined()); @@ -308,7 +322,7 @@ RowFormWidget::AddButton(const TCHAR *label, } void -RowFormWidget::SetMultiLineText(unsigned i, const TCHAR *text) noexcept +RowFormWidget::SetMultiLineText(unsigned i, const char *text) noexcept { assert(text != nullptr); assert(rows[i].type == Row::Type::MULTI_LINE); @@ -417,7 +431,7 @@ PixelSize RowFormWidget::GetMinimumSize() const noexcept { const unsigned value_width = - look.text_font.TextSize(_T("Foo Bar Foo Bar")).width; + look.text_font.TextSize("Foo Bar Foo Bar").width; const bool expert = UIGlobals::GetDialogSettings().expert; @@ -437,7 +451,7 @@ PixelSize RowFormWidget::GetMaximumSize() const noexcept { const unsigned value_width = - look.text_font.TextSize(_T("Foo Bar Foo Bar")).width * 2; + look.text_font.TextSize("Foo Bar Foo Bar").width * 2; const unsigned edit_width = vertical ? std::max(GetRecommendedCaptionWidth(), value_width) diff --git a/src/Widget/RowFormWidget.hpp b/src/Widget/RowFormWidget.hpp index 70dc976c6e7..6fe3bd1cce4 100644 --- a/src/Widget/RowFormWidget.hpp +++ b/src/Widget/RowFormWidget.hpp @@ -207,7 +207,8 @@ class RowFormWidget : public WindowWidget { [[gnu::pure]] WndProperty &GetControl() noexcept { - assert(type == Type::EDIT); + // aug(2024-03-08): Type::BUTTON is also ok? + assert(type == Type::EDIT || type == Type::BUTTON); assert(window != nullptr); return (WndProperty &)*window; @@ -215,7 +216,8 @@ class RowFormWidget : public WindowWidget { [[gnu::pure]] const WndProperty &GetControl() const noexcept { - assert(type == Type::EDIT); + // aug(2024-03-08): Type::BUTTON is also ok? + assert(type == Type::EDIT || type == Type::BUTTON); assert(window != nullptr); return (WndProperty &)*window; @@ -277,8 +279,8 @@ class RowFormWidget : public WindowWidget { Window &Add(Row::Type type, std::unique_ptr window) noexcept; - std::unique_ptr CreateEdit(const TCHAR *label, - const TCHAR *help=nullptr, + std::unique_ptr CreateEdit(const char *label, + const char *help=nullptr, bool read_only=false) noexcept; public: @@ -312,91 +314,91 @@ class RowFormWidget : public WindowWidget { Add(Row::Type::REMAINING, std::move(window)); } - WndProperty *Add(const TCHAR *label, const TCHAR *help=nullptr, + WndProperty *Add(const char *label, const char *help=nullptr, bool read_only=false) noexcept; /** * Add a read-only control. You can use SetText() to update its * text. */ - void AddReadOnly(const TCHAR *label, const TCHAR *help=nullptr, - const TCHAR *text=nullptr) noexcept; + void AddReadOnly(const char *label, const char *help=nullptr, + const char *text=nullptr) noexcept; /** * Add a read-only control displaying a floating-point value. Use * LoadValue() to update the displayed value. */ - void AddReadOnly(const TCHAR *label, const TCHAR *help, - const TCHAR *display_format, + void AddReadOnly(const char *label, const char *help, + const char *display_format, double value) noexcept; /** * Add a read-only control displaying a floating-point value. Use * LoadValue() to update the displayed value. */ - void AddReadOnly(const TCHAR *label, const TCHAR *help, - const TCHAR *display_format, + void AddReadOnly(const char *label, const char *help, + const char *display_format, UnitGroup unit_group, double value) noexcept; /** * Add a read-only control displaying a boolean value. Use * LoadValue() to update the displayed value. */ - void AddReadOnly(const TCHAR *label, const TCHAR *help, + void AddReadOnly(const char *label, const char *help, bool value) noexcept; - WndProperty *Add(const TCHAR *label, const TCHAR *help, + WndProperty *Add(const char *label, const char *help, DataField *df) noexcept; - WndProperty *AddBoolean(const TCHAR *label, const TCHAR *help, + WndProperty *AddBoolean(const char *label, const char *help, bool value=false, DataFieldListener *listener=nullptr) noexcept; - WndProperty *AddInteger(const TCHAR *label, const TCHAR *help, - const TCHAR *display_format, - const TCHAR *edit_format, + WndProperty *AddInteger(const char *label, const char *help, + const char *display_format, + const char *edit_format, int min_value, int max_value, int step, int value, DataFieldListener *listener=nullptr) noexcept; - WndProperty *AddFloat(const TCHAR *label, const TCHAR *help, - const TCHAR *display_format, - const TCHAR *edit_format, + WndProperty *AddFloat(const char *label, const char *help, + const char *display_format, + const char *edit_format, double min_value, double max_value, double step, bool fine, double value, DataFieldListener *listener=nullptr) noexcept; - WndProperty *AddFloat(const TCHAR *label, const TCHAR *help, - const TCHAR *display_format, - const TCHAR *edit_format, + WndProperty *AddFloat(const char *label, const char *help, + const char *display_format, + const char *edit_format, double min_value, double max_value, double step, bool fine, UnitGroup unit_group, double value, DataFieldListener *listener=nullptr) noexcept; - WndProperty *AddAngle(const TCHAR *label, const TCHAR *help, + WndProperty *AddAngle(const char *label, const char *help, Angle value, unsigned step, bool fine, DataFieldListener *listener=nullptr) noexcept; - WndProperty *AddEnum(const TCHAR *label, const TCHAR *help, + WndProperty *AddEnum(const char *label, const char *help, const StaticEnumChoice *list, unsigned value=0, DataFieldListener *listener=nullptr) noexcept; - WndProperty *AddEnum(const TCHAR *label, const TCHAR *help, + WndProperty *AddEnum(const char *label, const char *help, DataFieldListener *listener=nullptr) noexcept; - WndProperty *AddText(const TCHAR *label, const TCHAR *help, - const TCHAR *content, + WndProperty *AddText(const char *label, const char *help, + const char *content, DataFieldListener *listener=nullptr) noexcept; /** * Add a password edit control. The password is obfuscated while * not editing. */ - WndProperty *AddPassword(const TCHAR *label, const TCHAR *help, - const TCHAR *content) noexcept; + WndProperty *AddPassword(const char *label, const char *help, + const char *content) noexcept; - WndProperty *AddDuration(const TCHAR *label, const TCHAR *help, + WndProperty *AddDuration(const char *label, const char *help, std::chrono::seconds min_value, std::chrono::seconds max_value, std::chrono::seconds step, @@ -405,7 +407,7 @@ class RowFormWidget : public WindowWidget { DataFieldListener *listener=nullptr) noexcept; template - WndProperty *AddDuration(const TCHAR *label, const TCHAR *help, + WndProperty *AddDuration(const char *label, const char *help, std::chrono::seconds min_value, std::chrono::seconds max_value, std::chrono::seconds step, @@ -417,35 +419,42 @@ class RowFormWidget : public WindowWidget { max_tokens, listener); } - WndProperty *AddDate(const TCHAR *label, const TCHAR *help, + WndProperty *AddDate(const char *label, const char *help, BrokenDate date, DataFieldListener *listener=nullptr) noexcept; - WndProperty *AddRoughTime(const TCHAR *label, const TCHAR *help, + WndProperty *AddRoughTime(const char *label, const char *help, RoughTime value, RoughTimeDelta time_zone, DataFieldListener *listener=nullptr) noexcept; void AddSpacer() noexcept; - WndProperty *AddFile(const TCHAR *label, const TCHAR *help, - std::string_view profile_key, const TCHAR *filters, + WndProperty *AddFile(const char *label, const char *help, + std::string_view profile_key, const char *filters, FileType file_type, bool nullable = true) noexcept; - WndProperty *AddFile(const TCHAR *label, const TCHAR *help, - std::string_view profile_key, const TCHAR *filters, + WndProperty *AddFile(const char *label, const char *help, + std::string_view profile_key, const char *filters, bool nullable = true) noexcept { return AddFile(label, help, profile_key, filters, FileType::UNKNOWN, nullable); } + /** + * Add a label panel control, not editable, only for some explanations, + * descriptions or messages. You can use SetText() to update its text. + * the parameter lines controls the height if this panel! + */ + void AddLabel(const char *label, unsigned lines = 1) noexcept; + /** * Add a read-only multi-line control. You can use * SetMultiLineText() to update its text. */ - void AddMultiLine(const TCHAR *text=nullptr) noexcept; + void AddMultiLine(const char *text=nullptr) noexcept; - Button *AddButton(const TCHAR *label, std::function callback) noexcept; + Button *AddButton(const char *label, std::function callback) noexcept; [[gnu::pure]] Widget &GetRowWidget(unsigned i) noexcept { @@ -510,7 +519,7 @@ class RowFormWidget : public WindowWidget { /** * Update the text of a multi line control. */ - void SetText(unsigned i, const TCHAR *text) noexcept { + void SetText(unsigned i, const char *text) noexcept { assert(text != nullptr); WndProperty &control = GetControl(i); @@ -519,13 +528,13 @@ class RowFormWidget : public WindowWidget { } void ClearText(unsigned i) noexcept { - SetText(i, _T("")); + SetText(i, ""); } /** * Update the text of a multi line control. */ - void SetMultiLineText(unsigned i, const TCHAR *text) noexcept; + void SetMultiLineText(unsigned i, const char *text) noexcept; [[gnu::pure]] DataField &GetDataField(unsigned i) noexcept { @@ -563,7 +572,7 @@ class RowFormWidget : public WindowWidget { } void LoadValue(unsigned i, bool value) noexcept; - void LoadValueEnum(unsigned i, const TCHAR *text) noexcept; + void LoadValueEnum(unsigned i, const char *text) noexcept; void LoadValueEnum(unsigned i, unsigned value) noexcept; template @@ -572,7 +581,7 @@ class RowFormWidget : public WindowWidget { LoadValueEnum(i, unsigned(value)); } - void LoadValue(unsigned i, const TCHAR *value) noexcept; + void LoadValue(unsigned i, const char *value) noexcept; void LoadValue(unsigned i, double value) noexcept; void LoadValue(unsigned i, Angle value) noexcept; @@ -591,7 +600,7 @@ class RowFormWidget : public WindowWidget { * Return the raw text of the #WndProperty, bypassing the * #DataField. */ - const TCHAR *GetText(unsigned i) const noexcept { + const char *GetText(unsigned i) const noexcept { return GetControl(i).GetText(); } @@ -601,7 +610,7 @@ class RowFormWidget : public WindowWidget { * to indicate that there's no valid value currently. */ void ClearValue(unsigned i) noexcept { - GetControl(i).SetText(_T("")); + GetControl(i).SetText(""); } [[gnu::pure]] @@ -632,7 +641,7 @@ class RowFormWidget : public WindowWidget { Path GetValueFile(unsigned i) const noexcept; [[gnu::pure]] - const TCHAR *GetValueString(unsigned i) const noexcept { + const char *GetValueString(unsigned i) const noexcept { return GetDataField(i).GetAsString(); } @@ -670,19 +679,19 @@ class RowFormWidget : public WindowWidget { } bool SaveValue(unsigned i, RoughTime &value_r) const noexcept; - bool SaveValue(unsigned i, TCHAR *string, size_t max_size) const noexcept; + bool SaveValue(unsigned i, char *string, size_t max_size) const noexcept; template - bool SaveValue(unsigned i, BasicStringBuffer &value) const noexcept { + bool SaveValue(unsigned i, BasicStringBuffer &value) const noexcept { return SaveValue(i, value.data(), value.capacity()); } bool SaveValue(unsigned i, std::string_view profile_key, - TCHAR *string, size_t max_size) const noexcept; + char *string, size_t max_size) const noexcept; template bool SaveValue(unsigned i, std::string_view profile_key, - BasicStringBuffer &value) const noexcept { + BasicStringBuffer &value) const noexcept { return SaveValue(i, profile_key, value.data(), value.capacity()); } diff --git a/src/Widget/TabWidget.cpp b/src/Widget/TabWidget.cpp index 70ac0d4c5ab..8f905ac0aa1 100644 --- a/src/Widget/TabWidget.cpp +++ b/src/Widget/TabWidget.cpp @@ -83,14 +83,14 @@ TabWidget::RestoreExtra() noexcept } void -TabWidget::AddTab(std::unique_ptr widget, const TCHAR *caption, +TabWidget::AddTab(std::unique_ptr widget, const char *caption, const MaskedIcon *icon) noexcept { tab_display->Add(caption, icon); PagerWidget::Add(std::move(widget)); } -const TCHAR * +const char * TabWidget::GetButtonCaption(unsigned i) const noexcept { return tab_display->GetCaption(i); diff --git a/src/Widget/TabWidget.hpp b/src/Widget/TabWidget.hpp index 08a7da1ed26..722beed928c 100644 --- a/src/Widget/TabWidget.hpp +++ b/src/Widget/TabWidget.hpp @@ -114,11 +114,11 @@ class TabWidget : public PagerWidget, TabHandler { LargeExtra(); } - void AddTab(std::unique_ptr widget, const TCHAR *caption, + void AddTab(std::unique_ptr widget, const char *caption, const MaskedIcon *icon=nullptr) noexcept; [[gnu::pure]] - const TCHAR *GetButtonCaption(unsigned i) const noexcept; + const char *GetButtonCaption(unsigned i) const noexcept; public: /* virtual methods from class Widget */ diff --git a/src/Widget/TextListWidget.hpp b/src/Widget/TextListWidget.hpp index 462a709ad93..ef21a84b5c5 100644 --- a/src/Widget/TextListWidget.hpp +++ b/src/Widget/TextListWidget.hpp @@ -14,7 +14,7 @@ class TextListWidget : public ListWidget { TextRowRenderer row_renderer; [[gnu::pure]] - virtual const TCHAR *GetRowText(unsigned i) const noexcept = 0; + virtual const char *GetRowText(unsigned i) const noexcept = 0; public: /* virtual methods from class Widget */ diff --git a/src/Widget/TextWidget.cpp b/src/Widget/TextWidget.cpp index eec54a167f7..0f220d5632d 100644 --- a/src/Widget/TextWidget.cpp +++ b/src/Widget/TextWidget.cpp @@ -9,7 +9,7 @@ #include "Look/DialogLook.hpp" void -TextWidget::SetText(const TCHAR *text) noexcept +TextWidget::SetText(const char *text) noexcept { WndFrame &w = (WndFrame &)GetWindow(); w.SetText(text); diff --git a/src/Widget/TextWidget.hpp b/src/Widget/TextWidget.hpp index acbca12cd05..ed6225e38db 100644 --- a/src/Widget/TextWidget.hpp +++ b/src/Widget/TextWidget.hpp @@ -14,7 +14,7 @@ class Color; */ class TextWidget : public WindowWidget { public: - void SetText(const TCHAR *text) noexcept; + void SetText(const char *text) noexcept; void SetColor(Color _color) noexcept; /* virtual methods from class Widget */ diff --git a/src/Widget/UnitRowFormWidget.cpp b/src/Widget/UnitRowFormWidget.cpp index bc685174224..6a8b54e2e5e 100644 --- a/src/Widget/UnitRowFormWidget.cpp +++ b/src/Widget/UnitRowFormWidget.cpp @@ -11,8 +11,8 @@ #include void -RowFormWidget::AddReadOnly(const TCHAR *label, const TCHAR *help, - const TCHAR *display_format, +RowFormWidget::AddReadOnly(const char *label, const char *help, + const char *display_format, UnitGroup unit_group, double value) noexcept { WndProperty *edit = Add(label, help, true); @@ -26,9 +26,9 @@ RowFormWidget::AddReadOnly(const TCHAR *label, const TCHAR *help, } WndProperty * -RowFormWidget::AddFloat(const TCHAR *label, const TCHAR *help, - const TCHAR *display_format, - const TCHAR *edit_format, +RowFormWidget::AddFloat(const char *label, const char *help, + const char *display_format, + const char *edit_format, double min_value, double max_value, double step, bool fine, UnitGroup unit_group, double value, diff --git a/src/XCSoar.cpp b/src/XCSoar.cpp index 69c80be26ff..99206e94ec1 100644 --- a/src/XCSoar.cpp +++ b/src/XCSoar.cpp @@ -129,7 +129,7 @@ try { InitialiseDataPath(); // Write startup note + version to logfile - LogFormat(_T("Starting XCSoar %s"), XCSoar_ProductToken); + LogFormat("Starting XCSoar %s", XCSoar_ProductToken); // Read options from the command line { diff --git a/src/XML/CMakeLists.txt b/src/XML/CMakeLists.txt new file mode 100644 index 00000000000..fcf95062267 --- /dev/null +++ b/src/XML/CMakeLists.txt @@ -0,0 +1,53 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories + + +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/XML/CMakeSource.cmake b/src/XML/CMakeSource.cmake new file mode 100644 index 00000000000..460a5a18e72 --- /dev/null +++ b/src/XML/CMakeSource.cmake @@ -0,0 +1,14 @@ +set(_SOURCES + XML/DataNode.cpp + XML/DataNodeXML.cpp + XML/Node.cpp + XML/Parser.cpp + XML/Writer.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake + +# ../../build/libxml.mk ??? +) + diff --git a/src/XML/DataNode.cpp b/src/XML/DataNode.cpp index ba5a47829b8..4df0d116049 100644 --- a/src/XML/DataNode.cpp +++ b/src/XML/DataNode.cpp @@ -132,7 +132,7 @@ WritableDataNode::SetAttribute(const char *name, Angle value) noexcept void WritableDataNode::SetAttribute(const char *name, double value) noexcept { - NarrowString<48> buf; + StaticString<48> buf; buf.UnsafeFormat("%g", value); SetAttribute(name, buf); } @@ -162,7 +162,7 @@ WritableDataNode::SetAttribute(const char *name, RoughTime value) noexcept /* no-op */ return; - NarrowString<8> buffer; + StaticString<8> buffer; buffer.UnsafeFormat("%02u:%02u", value.GetHour(), value.GetMinute()); SetAttribute(name, buffer); } diff --git a/src/XML/DataNode.hpp b/src/XML/DataNode.hpp index ccb779ec882..6aed51ebefa 100644 --- a/src/XML/DataNode.hpp +++ b/src/XML/DataNode.hpp @@ -198,6 +198,6 @@ class WritableDataNode { void SetAttribute(const char *name, RoughTime value) noexcept; /* just here to prevent implicit pointer-to-bool casts - (e.g. TCHAR/wchar_t strings) */ + (e.g. char/wchar_t strings) */ void SetAttribute(const char *name, const auto *value) noexcept = delete; }; diff --git a/src/XML/Parser.cpp b/src/XML/Parser.cpp index d6b845f7a47..612182e00a2 100644 --- a/src/XML/Parser.cpp +++ b/src/XML/Parser.cpp @@ -185,7 +185,7 @@ FromXMLString(std::string_view src) noexcept return nullptr; } - // XXX convert to UTF-8 if !_UNICODE + // XXX convert to UTF-8 if !UNI-CODE char ch = (char)i; if (ch == 0) ch = ' '; diff --git a/src/co/CMakeLists.txt b/src/co/CMakeLists.txt new file mode 100644 index 00000000000..ade4abc24b5 --- /dev/null +++ b/src/co/CMakeLists.txt @@ -0,0 +1,51 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + # message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) + +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Net) + +add_dependencies(${TARGET_NAME} util) + +# message(FATAL_ERROR "Stop!") diff --git a/src/co/CMakeSource.cmake b/src/co/CMakeSource.cmake new file mode 100644 index 00000000000..2eb80f77053 --- /dev/null +++ b/src/co/CMakeSource.cmake @@ -0,0 +1,7 @@ +set(_SOURCES + co/InjectTask.cxx +) + +set(SCRIPT_FILES + CMakeSource.cmake +) diff --git a/src/event/CMakeLists.txt b/src/event/CMakeLists.txt new file mode 100644 index 00000000000..16f61be9242 --- /dev/null +++ b/src/event/CMakeLists.txt @@ -0,0 +1,48 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +source_group("Scripts" FILES ${SCRIPT_FILES}) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_compile_definitions(CARES_STATICLIB) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) + +# message(STATUS "CARES-Lib = ${CARES_LIB}") +# message(STATUS "CARES-Lib = ${CARES_LIB}") +# set(XCSOAR_CARES_VERSION c-ares-1.17.1) +# set(CARES_LIB ${LINK_LIBS}/c-ares/${XCSOAR_CARES_VERSION}/lib/${TOOLCHAIN}/cares.lib) + +# message(STATUS "CARES-Lib = ${CARES_LIB}") +# message(FATAL_ERROR "CARES-Lib = ${CARES_LIB} ") + +# target_link_libraries(${TARGET_NAME} PUBLIC ${CARES_LIB} system time) +target_link_libraries(${TARGET_NAME} PUBLIC system time ${CARES_LIB}) + +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) + diff --git a/src/event/CMakeSource.cmake b/src/event/CMakeSource.cmake new file mode 100644 index 00000000000..584cf953135 --- /dev/null +++ b/src/event/CMakeSource.cmake @@ -0,0 +1,39 @@ +set(_SOURCES + Loop.cxx + Call.cxx + DeferEvent.cxx + InjectEvent.cxx + SocketEvent.cxx + SignalMonitor.cxx + TimerWheel.cxx + TimerList.cxx + CoarseTimerEvent.cxx + + net/ConnectSocket.cxx + net/cares/Error.cxx + net/cares/Init.cxx + net/cares/Channel.cxx + net/cares/SimpleResolver.cxx + + ../io/async/AsioThread.cpp + ../io/async/GlobalAsioThread.cpp +) + +if(UNIX) + list(APPEND _SOURCES + PollBackend.cxx + PollBackend.hxx + PollEvents.hxx + PollResultGeneric.hxx + ) +elseif(WIN32) + list(APPEND _SOURCES + WinSelectBackend.cxx + WinSelectBackend.hxx + WinSelectEvents.hxx + ) +endif() + +set(SCRIPT_FILES + CMakeSource.cmake +) diff --git a/src/event/PipeEvent.hxx b/src/event/PipeEvent.hxx index 1df423f5517..a33e6adefa6 100644 --- a/src/event/PipeEvent.hxx +++ b/src/event/PipeEvent.hxx @@ -20,9 +20,13 @@ public: template PipeEvent(EventLoop &event_loop, C callback, FileDescriptor fd=FileDescriptor::Undefined()) noexcept - :event(event_loop, callback, +#ifdef _WIN32 + // TODO(August2111): needs work! + : event(event_loop, callback, SocketDescriptor()){} +#else + : event(event_loop, callback, SocketDescriptor::FromFileDescriptor(fd)) {} - +#endif EventLoop &GetEventLoop() const noexcept { return event.GetEventLoop(); } @@ -31,7 +35,21 @@ public: return event.IsDefined(); } +#ifdef _WIN32 + // TODO(August2111): needs work! FileDescriptor GetFileDescriptor() const noexcept { + return FileDescriptor(); + } + + FileDescriptor ReleaseFileDescriptor() noexcept { + return FileDescriptor(); + } + + void Open([[maybe_unused]] FileDescriptor fd) noexcept { + // event.Open(SocketDescriptor::FromFileDescriptor(fd)); + } +#else + FileDescriptor GetFileDescriptor() const noexcept { return event.GetSocket().ToFileDescriptor(); } @@ -42,6 +60,7 @@ public: void Open(FileDescriptor fd) noexcept { event.Open(SocketDescriptor::FromFileDescriptor(fd)); } + #endif void Close() noexcept { event.Close(); diff --git a/src/event/PollResultGeneric.hxx b/src/event/PollResultGeneric.hxx index 0fbdd879052..e1a9dfc5d40 100644 --- a/src/event/PollResultGeneric.hxx +++ b/src/event/PollResultGeneric.hxx @@ -7,6 +7,7 @@ #include #ifdef _WIN32 +#include #include /* damn you, windows.h! */ #ifdef GetObject diff --git a/src/event/net/cares/Error.hxx b/src/event/net/cares/Error.hxx index 9b00850a96a..606c89cd299 100644 --- a/src/event/net/cares/Error.hxx +++ b/src/event/net/cares/Error.hxx @@ -6,6 +6,14 @@ #include +#if defined(__AUGUST__) // TODO(August2111): This isn't correct for make... +#ifdef SSIZE_T +typedef SSIZE_T ssize_t; +#else // SSIZE_T +typedef long long ssize_t; +#endif +#endif + namespace Cares { class Error : public std::runtime_error { diff --git a/src/event/net/cares/Init.hxx b/src/event/net/cares/Init.hxx index 4b96f94dea5..27777edc0b2 100644 --- a/src/event/net/cares/Init.hxx +++ b/src/event/net/cares/Init.hxx @@ -4,6 +4,14 @@ #pragma once +#if defined(__AUGUST__) // TODO(August2111): Tis isn't correct for make... +#if defined(SSIZE_T) +typedef SSIZE_T ssize_t; +#else // SSIZE_T +typedef long long ssize_t; +#endif +#endif + namespace Cares { /** diff --git a/src/io/BufferedOutputStream.cxx b/src/io/BufferedOutputStream.cxx index 0c706e8b771..15a47cf716f 100644 --- a/src/io/BufferedOutputStream.cxx +++ b/src/io/BufferedOutputStream.cxx @@ -11,11 +11,6 @@ #include -#ifdef _UNICODE -#include "system/Error.hxx" -#include -#endif - bool BufferedOutputStream::AppendToBuffer(std::span src) noexcept { @@ -60,47 +55,6 @@ BufferedOutputStream::VFmt(fmt::string_view format_str, fmt::format_args args) return Write(std::as_bytes(std::span{b.data(), b.size()})); } -#ifdef _UNICODE - -void -BufferedOutputStream::WriteWideToUTF8(std::wstring_view src) -{ - if (src.empty()) - return; - - auto r = buffer.Write(); - if (r.empty()) { - Flush(); - r = buffer.Write(); - } - - int length = WideCharToMultiByte(CP_UTF8, 0, src.data(), src.size(), - (char *)r.data(), r.size(), - nullptr, nullptr); - if (length <= 0) { - const auto error = GetLastError(); - if (error != ERROR_INSUFFICIENT_BUFFER) - throw MakeLastError(error, "UTF-8 conversion failed"); - - /* how much buffer do we need? */ - length = WideCharToMultiByte(CP_UTF8, 0, src.data(), src.size(), - nullptr, 0, nullptr, nullptr); - if (length <= 0) - throw MakeLastError(error, "UTF-8 conversion failed"); - - /* grow the buffer and try again */ - length = WideCharToMultiByte(CP_UTF8, 0, src.data(), src.size(), - (char *)buffer.Write(length), length, - nullptr, nullptr); - if (length <= 0) - throw MakeLastError(error, "UTF-8 conversion failed"); - } - - buffer.Append(length); -} - -#endif - void BufferedOutputStream::Flush() { diff --git a/src/io/BufferedOutputStream.hxx b/src/io/BufferedOutputStream.hxx index 660bd479d21..8853297729e 100644 --- a/src/io/BufferedOutputStream.hxx +++ b/src/io/BufferedOutputStream.hxx @@ -15,10 +15,6 @@ #include #include -#ifdef _UNICODE -#include -#endif - class OutputStream; /** @@ -82,22 +78,6 @@ public: #endif } -#ifdef _UNICODE - /** - * Write one wide character. - */ - void Write(const wchar_t &ch) { - WriteWideToUTF8({&ch, 1}); - } - - /** - * Write a wide string. - */ - void Write(std::wstring_view src) { - WriteWideToUTF8(src); - } -#endif - /** * Finish the current line. */ @@ -123,9 +103,6 @@ public: private: bool AppendToBuffer(std::span src) noexcept; -#ifdef _UNICODE - void WriteWideToUTF8(std::wstring_view src); -#endif }; /** diff --git a/src/io/CMakeLists.txt b/src/io/CMakeLists.txt new file mode 100644 index 00000000000..8c327c6af18 --- /dev/null +++ b/src/io/CMakeLists.txt @@ -0,0 +1,65 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + string(REPLACE "lib/zlib" "../lib/zlib" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR} + ${CARES_INCLUDE_DIR} + ) + +## find_package(Boost 1.60 REQUIRED COMPONENTS date_time) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) + +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +## add_dependencies(${TARGET_NAME} util) + +# target_link_libraries(${TARGET_NAME} +# ${Boost_LIBRARIES} +# ${CARES_LIB} +# ${ZLIB_LIB} +# ) + +add_dependencies(${TARGET_NAME} util Data) + diff --git a/src/io/CMakeSource.cmake b/src/io/CMakeSource.cmake new file mode 100644 index 00000000000..fea0df7b20b --- /dev/null +++ b/src/io/CMakeSource.cmake @@ -0,0 +1,36 @@ +set(_SOURCES + lib/zlib/Error.cxx + lib/zlib/GunzipReader.cxx + io/async/AsioThread.cpp + io/async/GlobalAsioThread.cpp + io/BufferedOutputStream.cxx + io/BufferedReader.cxx + io/BufferedLineReader.cpp + io/ConfiguredFile.cpp + io/CSVLine.cpp + io/DataFile.cpp + io/FileCache.cpp + io/FileLineReader.cpp + io/FileOutputStream.cxx + io/FileDescriptor.cxx + io/FileMapping.cpp + io/FileReader.cxx + io/FileTransaction.cpp + io/KeyValueFileReader.cpp + io/KeyValueFileWriter.cpp + io/MapFile.cpp + io/StringConverter.cpp + io/ZipArchive.cpp + io/ZipReader.cpp + io/Reader.cxx + io/BufferedCsvReader.cpp +) +# if(UNIX) +# list(APPEND _SOURCES +# io/async/SignalListener.cpp +# ) +# endif() + +set(SCRIPT_FILES + CMakeSource.cmake +) diff --git a/src/io/DataFile.cpp b/src/io/DataFile.cpp index 41f3ee18081..aa8cd215837 100644 --- a/src/io/DataFile.cpp +++ b/src/io/DataFile.cpp @@ -10,7 +10,7 @@ #include std::unique_ptr -OpenDataFile(const TCHAR *name) +OpenDataFile(const char *name) { assert(name != nullptr); assert(!StringIsEmpty(name)); diff --git a/src/io/DataFile.hpp b/src/io/DataFile.hpp index a7328c4f624..3ce1f268442 100644 --- a/src/io/DataFile.hpp +++ b/src/io/DataFile.hpp @@ -17,4 +17,4 @@ class Reader; * @param name the file name relative to the data directory */ std::unique_ptr -OpenDataFile(const TCHAR *name); +OpenDataFile(const char *name); diff --git a/src/io/FileCache.cpp b/src/io/FileCache.cpp index d4ee7a69621..2d596722f2e 100644 --- a/src/io/FileCache.cpp +++ b/src/io/FileCache.cpp @@ -75,13 +75,13 @@ FileCache::FileCache(AllocatedPath &&_cache_path) :cache_path(std::move(_cache_path)) {} void -FileCache::Flush(const TCHAR *name) +FileCache::Flush(const char *name) { File::Delete(MakeCachePath(name)); } std::unique_ptr -FileCache::Load(const TCHAR *name, Path original_path) noexcept +FileCache::Load(const char *name, Path original_path) noexcept { FileInfo original_info; if (!GetRegularFileInfo(original_path, original_info)) @@ -121,7 +121,7 @@ FileCache::Load(const TCHAR *name, Path original_path) noexcept } std::unique_ptr -FileCache::Save(const TCHAR *name, Path original_path) +FileCache::Save(const char *name, Path original_path) { FileInfo original_info; if (!GetRegularFileInfo(original_path, original_info)) diff --git a/src/io/FileCache.hpp b/src/io/FileCache.hpp index 62e3acb14ee..087e26fecc8 100644 --- a/src/io/FileCache.hpp +++ b/src/io/FileCache.hpp @@ -20,20 +20,20 @@ class FileCache { protected: [[gnu::pure]] - AllocatedPath MakeCachePath(const TCHAR *name) const { + AllocatedPath MakeCachePath(const char *name) const { return AllocatedPath::Build(cache_path, name); } public: - void Flush(const TCHAR *name); + void Flush(const char *name); /** * Returns nullptr on error. */ - std::unique_ptr Load(const TCHAR *name, Path original_path) noexcept; + std::unique_ptr Load(const char *name, Path original_path) noexcept; /** * Throws on error. */ - std::unique_ptr Save(const TCHAR *name, Path original_path); + std::unique_ptr Save(const char *name, Path original_path); }; diff --git a/src/io/FileDescriptor.cxx b/src/io/FileDescriptor.cxx index 45c740ee222..84d329f1286 100644 --- a/src/io/FileDescriptor.cxx +++ b/src/io/FileDescriptor.cxx @@ -73,17 +73,6 @@ FileDescriptor::Open(const char *pathname, int flags, mode_t mode) noexcept return IsDefined(); } -#ifdef _WIN32 - -bool -FileDescriptor::Open(const wchar_t *pathname, int flags, mode_t mode) noexcept -{ - fd = ::_wopen(pathname, flags | O_NOCTTY | O_CLOEXEC, mode); - return IsDefined(); -} - -#endif - bool FileDescriptor::OpenReadOnly(const char *pathname) noexcept { diff --git a/src/io/FileDescriptor.hxx b/src/io/FileDescriptor.hxx index 64ae824ce82..1f84f80539f 100644 --- a/src/io/FileDescriptor.hxx +++ b/src/io/FileDescriptor.hxx @@ -7,13 +7,19 @@ #include #include -#include -#include - -#ifdef _WIN32 -#include +#ifdef _MSC_VER +# include +# include +# include + typedef SSIZE_T ssize_t; + typedef size_t mode_t; +# define lseek _lseek +#else +# include #endif +#include + class UniqueFileDescriptor; /** @@ -106,11 +112,6 @@ public: [[nodiscard]] bool Open(const char *pathname, int flags, mode_t mode=0666) noexcept; -#ifdef _WIN32 - [[nodiscard]] - bool Open(const wchar_t *pathname, int flags, mode_t mode=0666) noexcept; -#endif - [[nodiscard]] bool OpenReadOnly(const char *pathname) noexcept; diff --git a/src/io/FileOutputStream.cxx b/src/io/FileOutputStream.cxx index b6bcb3493a5..c61b96d6cc2 100644 --- a/src/io/FileOutputStream.cxx +++ b/src/io/FileOutputStream.cxx @@ -64,7 +64,7 @@ FileOutputStream::OpenCreate(bool visible) { if (!visible) { /* attempt to create a temporary file */ - tmp_path = path.WithSuffix(_T(".tmp")); + tmp_path = path.WithSuffix(".tmp"); Delete(tmp_path); handle = CreateFile(tmp_path.c_str(), GENERIC_WRITE, 0, nullptr, diff --git a/src/io/FileTransaction.cpp b/src/io/FileTransaction.cpp index 7c14df06fd9..6a0ba4c3cca 100644 --- a/src/io/FileTransaction.cpp +++ b/src/io/FileTransaction.cpp @@ -14,9 +14,9 @@ MakeTemporaryPath(Path path) noexcept assert(path != nullptr); #ifdef HAVE_POSIX - return path + _T(".tmp"); + return path + ".tmp"; #else - return path.WithSuffix(_T(".tmp")); + return path.WithSuffix(".tmp"); #endif } diff --git a/src/io/KeyValueFileWriter.cpp b/src/io/KeyValueFileWriter.cpp index e6abb0d0780..563df5e4ffd 100644 --- a/src/io/KeyValueFileWriter.cpp +++ b/src/io/KeyValueFileWriter.cpp @@ -8,10 +8,6 @@ #include #include -#ifdef _UNICODE -#include -#endif - void KeyValueFileWriter::Write(const char *key, const char *value) { @@ -27,17 +23,3 @@ KeyValueFileWriter::Write(const char *key, const char *value) os.Fmt("{}=\"{}\"\n", key, value); } -#ifdef _UNICODE - -void -KeyValueFileWriter::Write(const char *key, const TCHAR *value) -{ - char buffer[1024]; - int result = WideCharToMultiByte(CP_UTF8, 0, value, -1, - buffer, ARRAY_SIZE(buffer), - nullptr, nullptr); - if (result > 0) - Write(key, buffer); -} - -#endif diff --git a/src/io/KeyValueFileWriter.hpp b/src/io/KeyValueFileWriter.hpp index c5e9a627c28..65040d0ba3d 100644 --- a/src/io/KeyValueFileWriter.hpp +++ b/src/io/KeyValueFileWriter.hpp @@ -3,10 +3,6 @@ #pragma once -#ifdef _UNICODE -#include -#endif - class BufferedOutputStream; class KeyValueFileWriter { @@ -17,7 +13,4 @@ class KeyValueFileWriter { void Write(const char *key, const char *value); -#ifdef _UNICODE - void Write(const char *key, const TCHAR *value); -#endif }; diff --git a/src/io/StringConverter.cpp b/src/io/StringConverter.cpp index 1361e0a19c2..d62651158c4 100644 --- a/src/io/StringConverter.cpp +++ b/src/io/StringConverter.cpp @@ -10,23 +10,6 @@ #include #include -#ifdef _UNICODE -#include "system/Error.hxx" -#include -#endif - -#ifdef _UNICODE - -static constexpr TCHAR * -iso_latin_1_to_tchar(TCHAR *dest, std::string_view src) noexcept -{ - for (unsigned char ch : src) - *dest++ = ch; - return dest; -} - -#endif - char * StringConverter::DetectStrip(char *src) noexcept { @@ -69,40 +52,11 @@ StringConverter::DetectStrip(std::string_view src) noexcept return src; } -TCHAR * +char * StringConverter::Convert(char *narrow) { narrow = DetectStrip(narrow); -#ifdef _UNICODE - const std::string_view src{narrow}; - - TCHAR *t = tbuffer.get(src.size() + 1); - assert(t != nullptr); - - if (src.empty()) { - t[0] = _T('\0'); - return t; - } - - switch (charset) { - case Charset::ISO_LATIN_1: - *iso_latin_1_to_tchar(t, src) = _T('\0'); - break; - - default: - int length = MultiByteToWideChar(CP_UTF8, 0, src.data(), src.size(), - t, src.size()); - if (length == 0) - throw MakeLastError("Failed to convert string"); - - t[length] = _T('\0'); - - break; - } - - return t; -#else switch (charset) { size_t buffer_size; const char *utf8; @@ -128,34 +82,15 @@ StringConverter::Convert(char *narrow) /* unreachable */ gcc_unreachable(); -#endif } -tstring_view +std::string_view StringConverter::Convert(std::string_view src) { src = DetectStrip(src); if (src.empty()) return {}; -#ifdef _UNICODE - TCHAR *t = tbuffer.get(src.size()); - assert(t != nullptr); - - switch (charset) { - case Charset::ISO_LATIN_1: - iso_latin_1_to_tchar(t, src); - return {t, src.size()}; - - default: - int length = MultiByteToWideChar(CP_UTF8, 0, src.data(), src.size(), - t, src.size()); - if (length == 0) - throw MakeLastError("Failed to convert string"); - - return {t, std::size_t(length)}; - } -#else switch (charset) { size_t buffer_size; @@ -181,5 +116,4 @@ StringConverter::Convert(std::string_view src) /* unreachable */ gcc_unreachable(); -#endif } diff --git a/src/io/StringConverter.hpp b/src/io/StringConverter.hpp index a00f7580b40..14ae6666c9f 100644 --- a/src/io/StringConverter.hpp +++ b/src/io/StringConverter.hpp @@ -5,17 +5,17 @@ #include "Charset.hpp" #include "util/ReusableArray.hpp" -#include "util/tstring_view.hxx" +#include #include /** - * Helper which imports strings from a file to `TCHAR*`. + * Helper which imports strings from a file to `char*`. */ class StringConverter { Charset charset; - ReusableArray tbuffer; + ReusableArray tbuffer; public: explicit StringConverter(Charset cs=Charset::AUTO) noexcept @@ -47,7 +47,7 @@ class StringConverter { * * Throws on error. */ - TCHAR *Convert(char *src); + char *Convert(char *src); - tstring_view Convert(std::string_view src); + std::string_view Convert(std::string_view src); }; diff --git a/src/json/Boost.cxx b/src/json/Boost.cxx index 5f8b76d8f7b..0a5d6a0eb12 100644 --- a/src/json/Boost.cxx +++ b/src/json/Boost.cxx @@ -12,6 +12,6 @@ #endif /* suppress -Wundef */ -#define BOOST_VERSION 0 - +// #define BOOST_VERSION 0 +#include #include diff --git a/src/json/CMakeLists.txt b/src/json/CMakeLists.txt new file mode 100644 index 00000000000..56aa92f5a7d --- /dev/null +++ b/src/json/CMakeLists.txt @@ -0,0 +1,51 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# target_link_libraries(${TARGET_NAME} PUBLIC boost Logger) #boost geht noch nicht... +target_link_libraries(${TARGET_NAME} PUBLIC Logger) + + # message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/json/CMakeSource.cmake b/src/json/CMakeSource.cmake new file mode 100644 index 00000000000..2212e53db1e --- /dev/null +++ b/src/json/CMakeSource.cmake @@ -0,0 +1,12 @@ +set(_SOURCES + json/Boost.cxx + json/ParserOutputStream.cxx + json/Serialize.cxx + json/Parse.cxx # add 7.38 +) + +set(SCRIPT_FILES + CMakeSource.cmake +) + +file(GLOB_RECURSE HEADER_FILES "*.h;*.hxx;*.hpp") diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt new file mode 100644 index 00000000000..3d83b634b37 --- /dev/null +++ b/src/lib/CMakeLists.txt @@ -0,0 +1,60 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") + +### target_link_libraries(${TARGET_NAME} PUBLIC +### Form +### libOpenSoar +### Blackboard +### UIUtil +### Dialogs +### # ${LIBPNG_LIB} +### ${ZZIP_LIB} # internal or external... +### ) + +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +# add_dependencies(${TARGET_NAME} util) diff --git a/src/lib/CMakeSource.cmake b/src/lib/CMakeSource.cmake new file mode 100644 index 00000000000..f845042450d --- /dev/null +++ b/src/lib/CMakeSource.cmake @@ -0,0 +1,10 @@ +set(_SOURCES + fmt/RuntimeError.cxx + fmt/SystemError.cxx +) + +set(SCRIPT_FILES + CMakeSource.cmake + +# ../../build/lib.mk # menu sorces in main.mk! +) diff --git a/src/lib/curl/Setup.cxx b/src/lib/curl/Setup.cxx index 9e7b944daa8..9e968fc2d6c 100644 --- a/src/lib/curl/Setup.cxx +++ b/src/lib/curl/Setup.cxx @@ -13,7 +13,8 @@ void Setup(CurlEasy &easy) { char user_agent[32]; - snprintf(user_agent, 32, "XCSoar/%s", XCSoar_Version); + snprintf(user_agent, 32, "XCSoar/%s", // "OpenSoar/%s" ?? + OpenSoar_Version); easy.SetUserAgent(user_agent); #if !defined(ANDROID) && !defined(_WIN32) diff --git a/src/lib/fmt/tchar.hxx b/src/lib/fmt/tchar.hxx index 9f9a9762f28..2cf40af2312 100644 --- a/src/lib/fmt/tchar.hxx +++ b/src/lib/fmt/tchar.hxx @@ -5,18 +5,7 @@ #include -#ifdef _UNICODE - -#include - -using fmt_tstring_view = fmt::wstring_view; -using fmt_tformat_context = fmt::wformat_context; -using fmt_tformat_args = fmt::wformat_args; - -#else - using fmt_tstring_view = fmt::string_view; using fmt_tformat_context = fmt::format_context; using fmt_tformat_args = fmt::format_args; -#endif diff --git a/src/lua/Airspace.cpp b/src/lua/Airspace.cpp index fe37ef15349..bb038007979 100644 --- a/src/lua/Airspace.cpp +++ b/src/lua/Airspace.cpp @@ -55,7 +55,8 @@ l_airspace_index(lua_State *L) void Lua::InitAirspace(lua_State *L) { - lua_getglobal(L, "xcsoar"); + // lua_getglobal(L, "xcsoar"); + lua_getglobal(L, PROGRAM_NAME_LC ); lua_newtable(L); diff --git a/src/lua/Background.cpp b/src/lua/Background.cpp index e1d8c48bc42..9912b049e47 100644 --- a/src/lua/Background.cpp +++ b/src/lua/Background.cpp @@ -13,7 +13,8 @@ extern "C" { #include -static constexpr char background_lua_key[] = "xcsoar.background"; +// static constexpr char background_lua_key[] = "xcsoar.background"; +static constexpr char background_lua_key[] = PROGRAM_NAME_LC ".background"; class BackgroundLua final : public IntrusiveListHook diff --git a/src/lua/Basic.cpp b/src/lua/Basic.cpp index 63e434b8918..2d44a6477aa 100644 --- a/src/lua/Basic.cpp +++ b/src/lua/Basic.cpp @@ -42,9 +42,11 @@ Lua::NewBasicState() /* create the "xcsoar" namespace */ lua_newtable(L); - SetField(L, RelativeStackIndex{-1}, "VERSION", XCSoar_Version); + SetField(L, RelativeStackIndex{-1}, + "VERSION", OpenSoar_Version); - lua_setglobal(L, "xcsoar"); +// lua_setglobal(L, "xcsoar"); + lua_setglobal(L, PROGRAM_NAME_LC); return L; } diff --git a/src/lua/Blackboard.cpp b/src/lua/Blackboard.cpp index 960c3b912ba..73eb7d8e5ae 100644 --- a/src/lua/Blackboard.cpp +++ b/src/lua/Blackboard.cpp @@ -108,7 +108,8 @@ l_blackboard_index(lua_State *L) void Lua::InitBlackboard(lua_State *L) { - lua_getglobal(L, "xcsoar"); + // lua_getglobal(L, "xcsoar"); + lua_getglobal(L, PROGRAM_NAME_LC ); lua_newtable(L); diff --git a/src/lua/CMakeLists.txt b/src/lua/CMakeLists.txt new file mode 100644 index 00000000000..b30eb7da799 --- /dev/null +++ b/src/lua/CMakeLists.txt @@ -0,0 +1,62 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(PUR_TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + set(TARGET_NAME "${PUR_TARGET_NAME}") + +include(CMakeSource.cmake) + +# add_compile_definitions("PROGRAM_NAME_LC=\"${PROGRAM_NAME_LC}\"") +add_compile_definitions("PROGRAM_NAME_LC=\"xcsoar\"") + +# organize the files in subdirectories +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${PUR_TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # predefined in CMakeSource.cmake? +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR} + ${PROJECT_OUTPUT_FOLDER}/include) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +target_link_libraries(${TARGET_NAME} PUBLIC util) + +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +# if(NOT EXISTS "${INSTALL_LIB}") +if(${WITH_3RD_PARTY}) +add_dependencies(${TARGET_NAME} util Input lua_3rd) +else() +add_dependencies(${TARGET_NAME} util Input) +endif() \ No newline at end of file diff --git a/src/lua/CMakeSource.cmake b/src/lua/CMakeSource.cmake new file mode 100644 index 00000000000..47138ef0b23 --- /dev/null +++ b/src/lua/CMakeSource.cmake @@ -0,0 +1,34 @@ +set(_SOURCES + lua/Airspace.cpp + lua/Associate.cpp + lua/Background.cpp + lua/Basic.cpp + lua/Blackboard.cpp + lua/Catch.cpp + lua/Dialogs.cpp + lua/Error.cxx + lua/Full.cpp + lua/Geo.cpp + lua/InputEvent.cpp + lua/Legacy.cpp + lua/Log.cpp + lua/Http.cpp + lua/Logger.cpp + lua/Map.cpp + lua/Persistent.cpp + lua/Ptr.cpp + lua/Replay.cpp + lua/RunFile.cxx + lua/Settings.cpp + lua/StartFile.cpp + lua/Task.cpp + lua/Timer.cpp + lua/Tracking.cpp + lua/Wind.cpp +) +set(xcslua_SOURCES ${_SOURCES}) + +set(SCRIPT_FILES + CMakeSource.cmake + ${PROJECTGROUP_SOURCE_DIR}/doc/lua.rst +) diff --git a/src/lua/Catch.cpp b/src/lua/Catch.cpp index e3703f575ae..869360adee9 100644 --- a/src/lua/Catch.cpp +++ b/src/lua/Catch.cpp @@ -10,7 +10,8 @@ extern "C" { #include -static constexpr char catch_callback[] = "xcsoar.catch_callback"; +// static constexpr char catch_callback[] = "xcsoar.catch_callback"; +static constexpr char catch_callback[] = PROGRAM_NAME_LC ".catch_callback "; void Lua::SetCatchCallback(lua_State *L, CatchCallback callback) diff --git a/src/lua/Dialogs.cpp b/src/lua/Dialogs.cpp index 0d686d6a73e..d79fb4d15f1 100644 --- a/src/lua/Dialogs.cpp +++ b/src/lua/Dialogs.cpp @@ -4,7 +4,6 @@ #include "Dialogs.hpp" #include "Catch.hpp" #include "Error.hxx" -#include "util/ConvertString.hpp" #include "Dialogs/Message.hpp" #include "Dialogs/Error.hpp" @@ -17,9 +16,7 @@ l_alert(lua_State *L) { const char *message = lua_tostring(L, 1); if (message != nullptr) { - const UTF8ToWideConverter c_message(message); - if (c_message.IsValid()) - ShowMessageBox(c_message, _T("Lua"), MB_OK|MB_ICONINFORMATION); + ShowMessageBox(message, "Lua", MB_OK|MB_ICONINFORMATION); } return 0; @@ -28,7 +25,7 @@ l_alert(lua_State *L) static void DialogCatchCallback(Lua::Error &&error) { - ShowError(std::make_exception_ptr(std::move(error)), _T("Lua")); + ShowError(std::make_exception_ptr(std::move(error)), "Lua"); } void diff --git a/src/lua/Full.cpp b/src/lua/Full.cpp index 3148039025a..780a5409fff 100644 --- a/src/lua/Full.cpp +++ b/src/lua/Full.cpp @@ -16,7 +16,6 @@ #include "LocalPath.hpp" #include "Compatibility/path.h" #include "system/Path.hpp" -#include "util/ConvertString.hpp" #include "Airspace.hpp" #include "Task.hpp" #include "Settings.hpp" @@ -50,9 +49,7 @@ Lua::NewFullState() InitInputEvent(L); { - SetPackagePath(L, - WideToUTF8Converter(LocalPath(_T("lua" DIR_SEPARATOR_S "?.lua")).c_str())); + SetPackagePath(L, LocalPath("lua" DIR_SEPARATOR_S "?.lua").c_str()); } - return L; } diff --git a/src/lua/Geo.cpp b/src/lua/Geo.cpp index 7f48461f36d..3b338cc5bed 100644 --- a/src/lua/Geo.cpp +++ b/src/lua/Geo.cpp @@ -6,12 +6,12 @@ #include "Util.hxx" #include "Geo/GeoPoint.hpp" #include "Formatter/GeoPointFormatter.hpp" -#include "util/ConvertString.hpp" #include "util/StringAPI.hxx" namespace Lua { -static constexpr char lua_geo_point_class[] = "xcsoar.GeoPoint"; +// static constexpr char lua_geo_point_class[] = "xcsoar.GeoPoint"; +static constexpr char lua_geo_point_class[] = PROGRAM_NAME_LC ".GeoPoint"; using LuaGeoPointClass = Lua::Class; static int @@ -65,7 +65,7 @@ static int GeoPointToString(lua_State *L) { auto &gp = LuaGeoPointClass::Cast(L, 1); - Lua::Push(L, WideToUTF8Converter(FormatGeoPoint(gp, CoordinateFormat::DDMMSS))); + Lua::Push(L, FormatGeoPoint(gp, CoordinateFormat::DDMMSS)); return 1; } @@ -88,7 +88,8 @@ InitGeo(lua_State *L) noexcept { const Lua::ScopeCheckStack check_stack(L); - lua_getglobal(L, "xcsoar"); +// lua_getglobal(L, "xcsoar"); + lua_getglobal(L, PROGRAM_NAME_LC ); luaL_newlib(L, geo_point_funcs); lua_setfield(L, -2, "GeoPoint"); // xcsoar.GeoPoint = geo_point_funcs diff --git a/src/lua/Http.cpp b/src/lua/Http.cpp index 0bc74aff50e..ecce5d9d26b 100644 --- a/src/lua/Http.cpp +++ b/src/lua/Http.cpp @@ -139,9 +139,11 @@ CreateHttpRequestMetatable(lua_State *L) void Lua::InitHttp(lua_State *L) { + const Lua::ScopeCheckStack check_stack(L); - lua_getglobal(L, "xcsoar"); +// lua_getglobal(L, "xcsoar"); + lua_getglobal(L, PROGRAM_NAME_LC ); /* create the "http" namespace */ lua_newtable(L); diff --git a/src/lua/InputEvent.cpp b/src/lua/InputEvent.cpp index 4aeee6b38a7..3dbb32a0acb 100644 --- a/src/lua/InputEvent.cpp +++ b/src/lua/InputEvent.cpp @@ -12,12 +12,11 @@ #include "Input/InputKeys.hpp" #include "util/Compiler.h" #include "util/StringAPI.hxx" -#include "util/ConvertString.hpp" #include "Util.hxx" #include "Interface.hpp" #include -#include "util/tstring.hpp" +#include extern "C" { #include @@ -56,7 +55,7 @@ class LuaEventRegistry { }; static LuaEventRegistry event_store_enum; -static LuaEventRegistry event_store_gesture; +static LuaEventRegistry event_store_gesture; static LuaEventRegistry event_store_key; static constexpr const char* event_enum_names[] = { @@ -72,13 +71,13 @@ class LuaInputEvent final { Lua::Value callback; public: - static constexpr const char *registry_table = "xcsoar.input_events"; + static constexpr const char *registry_table = PROGRAM_NAME_LC ".input_events"; explicit LuaInputEvent(lua_State *_l, int callback_idx):L(_l), callback(L, Lua::StackIndex(callback_idx)) { auto d = (LuaInputEvent **)lua_newuserdata(L, sizeof(LuaInputEvent **)); *d = this; - luaL_setmetatable(L, "xcsoar.input_event"); + luaL_setmetatable(L, PROGRAM_NAME_LC ".input_event"); Register(RelativeStackIndex{-1}); @@ -96,7 +95,7 @@ class LuaInputEvent final { } } - void AttachGesture(const TCHAR* gesture) { + void AttachGesture(const char* gesture) { if (event_store_gesture.Insert(gesture, this)) { Lua::AddPersistent(L, this); } @@ -154,8 +153,8 @@ class LuaInputEvent final { [[gnu::pure]] static LuaInputEvent &Check(lua_State *L, int idx) { - auto d = (LuaInputEvent **)luaL_checkudata(L, idx, "xcsoar.input_event"); - luaL_argcheck(L, d != nullptr, idx, "`xcsoar.input_event' expected"); + auto d = (LuaInputEvent **)luaL_checkudata(L, idx, PROGRAM_NAME_LC ".input_event"); + luaL_argcheck(L, d != nullptr, idx, "'" PROGRAM_NAME_LC ".input_event' expected"); return **d; } @@ -173,21 +172,19 @@ class LuaInputEvent final { else if (StringIsEqual(name, "gesture_", 8)) { // scan for gesture - const UTF8ToWideConverter gesture(name+8); - if (gesture.IsValid()) { + if (strlen(name) > 8) { auto *input_event = new LuaInputEvent(L, 2); - input_event->AttachGesture(gesture); + input_event->AttachGesture(name + 8); return 1; } } else if (StringIsEqual(name, "key_", 4)) { // scan for key code - const UTF8ToWideConverter keycode(name+4); - if (keycode.IsValid()) { - const unsigned code = ParseKeyCode(keycode); - auto *input_event = new LuaInputEvent(L, 2); - input_event->AttachKey(code); - return 1; - } + if (strlen(name) > 4) { + const unsigned code = ParseKeyCode(name + 4); + auto *input_event = new LuaInputEvent(L, 2); + input_event->AttachKey(code); + return 1; + } } else { // scan for other enums const unsigned code = luaL_checkoption(L, 1, NULL, event_enum_names); @@ -223,16 +220,14 @@ class LuaInputEvent final { return luaL_error(L, "Invalid parameters"); else if (StringIsEqual(name, "gesture_", 8)) { - const UTF8ToWideConverter gesture(name+8); - if (gesture.IsValid()) { - event_store_gesture.Clear(tstring(gesture)); + if (strlen(name) > 8) { + event_store_gesture.Clear(std::string(name + 8)); return 1; } } else if (StringIsEqual(name, "key_", 4)) { // scan for key code - const UTF8ToWideConverter keycode(name+4); - if (keycode.IsValid()) { - const unsigned code = ParseKeyCode(keycode); + if (strlen(name) > 4) { + const unsigned code = ParseKeyCode(name + 4); event_store_key.Clear(code); return 1; } @@ -264,7 +259,7 @@ static constexpr struct luaL_Reg input_event_methods[] = { static void CreateInputEventMetatable(lua_State *L) { - luaL_newmetatable(L, "xcsoar.input_event"); + luaL_newmetatable(L, PROGRAM_NAME_LC ".input_event"); /* metatable.__index = input_event_methods */ luaL_newlib(L, input_event_methods); @@ -285,7 +280,8 @@ Lua::InitInputEvent(lua_State *L) const int old_top = lua_gettop(L); #endif - lua_getglobal(L, "xcsoar"); +// lua_getglobal(L, "xcsoar"); + lua_getglobal(L, PROGRAM_NAME_LC ); luaL_newlib(L, input_event_funcs); // create 'input_event' @@ -346,11 +342,11 @@ bool Lua::FireNMEAEvent(unsigned event) { return event_store_enum.Fire(event + GCE_COUNT); } -bool Lua::FireGesture(const TCHAR* gesture) { +bool Lua::FireGesture(const char* gesture) { return event_store_gesture.Fire(gesture); } -bool Lua::IsGesture(const TCHAR* gesture) { +bool Lua::IsGesture(const char* gesture) { return event_store_gesture.HasHandler(gesture); } diff --git a/src/lua/InputEvent.hpp b/src/lua/InputEvent.hpp index a204c606240..739132ba0b4 100644 --- a/src/lua/InputEvent.hpp +++ b/src/lua/InputEvent.hpp @@ -23,12 +23,12 @@ bool FireNMEAEvent(unsigned event); bool -FireGesture(const TCHAR *gesture); +FireGesture(const char *gesture); bool FireKey(unsigned key); bool -IsGesture(const TCHAR *gesture); +IsGesture(const char *gesture); } diff --git a/src/lua/Legacy.cpp b/src/lua/Legacy.cpp index 8fa1d7d8e7d..67e21b662ef 100644 --- a/src/lua/Legacy.cpp +++ b/src/lua/Legacy.cpp @@ -4,7 +4,6 @@ #include "Legacy.hpp" #include "Util.hxx" #include "Input/InputLookup.hpp" -#include "util/ConvertString.hpp" extern "C" { #include @@ -18,22 +17,21 @@ l_fire_legacy_event(lua_State *L) if (event == nullptr) return luaL_error(L, "No InputEvent specified"); - auto *event_function = InputEvents::findEvent(UTF8ToWideConverter(event).c_str()); + auto *event_function = InputEvents::findEvent(event); if (event_function == nullptr) return luaL_error(L, "Unknown InputEvent"); const char *parameter = lua_tostring(L, 2); - if (parameter == nullptr) - parameter = ""; - - event_function(UTF8ToWideConverter(parameter)); + if (parameter != nullptr) + event_function(parameter); return 0; } void Lua::InitLegacy(lua_State *L) { - lua_getglobal(L, "xcsoar"); + // lua_getglobal(L, "xcsoar"); + lua_getglobal(L, PROGRAM_NAME_LC ); SetField(L, RelativeStackIndex{-1}, "fire_legacy_event", l_fire_legacy_event); lua_pop(L, 1); diff --git a/src/lua/Logger.cpp b/src/lua/Logger.cpp index 22ff96aa7b5..cb84c66717b 100644 --- a/src/lua/Logger.cpp +++ b/src/lua/Logger.cpp @@ -190,7 +190,8 @@ static constexpr struct luaL_Reg settings_funcs[] = { void Lua::InitLogger(lua_State *L) { - lua_getglobal(L, "xcsoar"); + // lua_getglobal(L, "xcsoar"); + lua_getglobal(L, PROGRAM_NAME_LC ); lua_newtable(L); diff --git a/src/lua/Map.cpp b/src/lua/Map.cpp index 64e48b5accc..5b42f50125f 100644 --- a/src/lua/Map.cpp +++ b/src/lua/Map.cpp @@ -224,7 +224,8 @@ static constexpr struct luaL_Reg map_funcs[] = { void Lua::InitMap(lua_State *L) { - lua_getglobal(L, "xcsoar"); + // lua_getglobal(L, "xcsoar"); + lua_getglobal(L, PROGRAM_NAME_LC ); lua_newtable(L); diff --git a/src/lua/Persistent.cpp b/src/lua/Persistent.cpp index daf7fe95b37..ee2df5512e2 100644 --- a/src/lua/Persistent.cpp +++ b/src/lua/Persistent.cpp @@ -8,8 +8,10 @@ extern "C" { #include } -static constexpr char persistent_table[] = "xcsoar.persistent_table"; -static constexpr char persistent_callback[] = "xcsoar.persistent_callback"; +// static constexpr char persistent_table[] = "xcsoar.persistent_table"; +// static constexpr char persistent_callback[] = "xcsoar.persistent_callback"; +static constexpr char persistent_table[] = PROGRAM_NAME_LC ".persistent_table"; +static constexpr char persistent_callback[] = PROGRAM_NAME_LC ".persistent_callback"; void Lua::InitPersistent(lua_State *L) diff --git a/src/lua/Replay.cpp b/src/lua/Replay.cpp index 1b067cf5f49..d3c5985445b 100644 --- a/src/lua/Replay.cpp +++ b/src/lua/Replay.cpp @@ -7,7 +7,6 @@ #include "Util.hxx" #include "system/Path.hpp" #include "Replay/Replay.hpp" -#include "util/ConvertString.hpp" #include "Components.hpp" #include "BackendComponents.hpp" @@ -61,8 +60,8 @@ l_replay_start(lua_State *L) if (lua_gettop(L) != 1) return luaL_error(L, "Invalid parameters"); - const UTF8ToWideConverter filename(luaL_checkstring(L, 1)); - if (filename.IsValid()) { + const char *filename = luaL_checkstring(L, 1); + if (filename) { Path p(filename); try { @@ -92,7 +91,8 @@ static constexpr struct luaL_Reg settings_funcs[] = { void Lua::InitReplay(lua_State *L) { - lua_getglobal(L, "xcsoar"); + // lua_getglobal(L, "xcsoar"); + lua_getglobal(L, PROGRAM_NAME_LC ); lua_newtable(L); diff --git a/src/lua/Settings.cpp b/src/lua/Settings.cpp index 1710c0cb107..317a5e29ccf 100644 --- a/src/lua/Settings.cpp +++ b/src/lua/Settings.cpp @@ -170,7 +170,8 @@ static constexpr struct luaL_Reg settings_funcs[] = { void Lua::InitSettings(lua_State *L) { - lua_getglobal(L, "xcsoar"); + // lua_getglobal(L, "xcsoar"); + lua_getglobal(L, PROGRAM_NAME_LC ); lua_newtable(L); diff --git a/src/lua/Task.cpp b/src/lua/Task.cpp index b844c96da6b..1d1cebed5e8 100644 --- a/src/lua/Task.cpp +++ b/src/lua/Task.cpp @@ -369,7 +369,8 @@ l_task_index(lua_State *L) void Lua::InitTask(lua_State *L) { - lua_getglobal(L, "xcsoar"); + // lua_getglobal(L, "xcsoar"); + lua_getglobal(L, PROGRAM_NAME_LC ); lua_newtable(L); diff --git a/src/lua/Timer.cpp b/src/lua/Timer.cpp index 6082633765a..f77ca879313 100644 --- a/src/lua/Timer.cpp +++ b/src/lua/Timer.cpp @@ -83,7 +83,8 @@ static constexpr struct luaL_Reg timer_methods[] = { {nullptr, nullptr} }; -static constexpr char lua_timer_class[] = "xcsoar.timer"; +// static constexpr char lua_timer_class[] = "xcsoar.timer"; +static constexpr char lua_timer_class[] = PROGRAM_NAME_LC ".timer"; using LuaTimerClass = Lua::Class; static constexpr auto @@ -152,7 +153,8 @@ Lua::InitTimer(lua_State *L) { const Lua::ScopeCheckStack check_stack(L); - lua_getglobal(L, "xcsoar"); +// lua_getglobal(L, "xcsoar"); + lua_getglobal(L, PROGRAM_NAME_LC ); luaL_newlib(L, timer_funcs); // create 'timer' lua_setfield(L, -2, "timer"); // xcsoar.timer = timer diff --git a/src/lua/Tracking.cpp b/src/lua/Tracking.cpp index 7b29d2276ce..13b5919ed5a 100644 --- a/src/lua/Tracking.cpp +++ b/src/lua/Tracking.cpp @@ -206,7 +206,8 @@ static constexpr struct luaL_Reg settings_funcs[] = { void Lua::InitTracking(lua_State *L) { - lua_getglobal(L, "xcsoar"); + // lua_getglobal(L, "xcsoar"); + lua_getglobal(L, PROGRAM_NAME_LC ); lua_newtable(L); diff --git a/src/lua/Wind.cpp b/src/lua/Wind.cpp index 9d2fcfba343..529c2fd7661 100644 --- a/src/lua/Wind.cpp +++ b/src/lua/Wind.cpp @@ -159,7 +159,8 @@ static constexpr struct luaL_Reg settings_funcs[] = { void Lua::InitWind(lua_State *L) { - lua_getglobal(L, "xcsoar"); + // lua_getglobal(L, "xcsoar"); + lua_getglobal(L, PROGRAM_NAME_LC ); lua_newtable(L); diff --git a/src/net/CMakeLists.txt b/src/net/CMakeLists.txt new file mode 100644 index 00000000000..3c40b37cf94 --- /dev/null +++ b/src/net/CMakeLists.txt @@ -0,0 +1,58 @@ +# XCSoar-Net# XCSoar-Net# XCSoar-Net# XCSoar-Net# XCSoar-Net# XCSoar-Net# XCSoar-Net# XCSoar-Net# XCSoar-Net# XCSoar-Net +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories + +if(OFF) +# if(${XCSOAR_CURL_VERSION} STREQUAL "curl-7.69.1") + set(CURL_DIR "${LINK_LIBS}/curl/${XCSOAR_CURL_VERSION}/lib/msvc2019/cmake/CURL") + find_package(CURL REQUIRED) +# endif() +endif() +# add_compile_definitions(CURL_STATICLIB) +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Net) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/net/CMakeSource.cmake b/src/net/CMakeSource.cmake new file mode 100644 index 00000000000..5e95d11b122 --- /dev/null +++ b/src/net/CMakeSource.cmake @@ -0,0 +1,36 @@ +set(_SOURCES + net/AddressInfo.cxx + net/HostParser.cxx + net/Resolver.cxx + net/SocketError.cxx + net/State.cpp + net/ToString.cxx + net/IPv4Address.cxx + net/IPv6Address.cxx + net/StaticSocketAddress.cxx + net/AllocatedSocketAddress.cxx + net/SocketAddress.cxx + net/SocketDescriptor.cxx +) +list(APPEND _SOURCES + net/client/tim/Client.cpp + net/client/tim/Glue.cpp +) +list(APPEND _SOURCES + net/http/DownloadManager.cpp + net/http/Progress.cpp + ../lib/curl/OutputStreamHandler.cxx + ../lib/curl/Adapter.cxx + ../lib/curl/Setup.cxx + ../lib/curl/Request.cxx + ../lib/curl/CoRequest.cxx + ../lib/curl/CoStreamRequest.cxx + net/http/CoDownloadToFile.cpp + ../lib/curl/Global.cxx + net/http/Init.cpp +) + +set (SCRIPT_FILES + CMakeSource.cmake +) + diff --git a/src/net/SocketDescriptor.hxx b/src/net/SocketDescriptor.hxx index 49ec6c74dad..f9c6f5b9796 100644 --- a/src/net/SocketDescriptor.hxx +++ b/src/net/SocketDescriptor.hxx @@ -16,6 +16,9 @@ #ifdef _WIN32 #include // for SOCKET, INVALID_SOCKET +#if defined(__MSVC__) || defined(__clang__) // not defined in MSVC only + typedef SSIZE_T ssize_t; +# endif #endif struct msghdr; diff --git a/src/net/SocketError.cxx b/src/net/SocketError.cxx index 1b1dceb1bc7..bcae6e090c8 100644 --- a/src/net/SocketError.cxx +++ b/src/net/SocketError.cxx @@ -11,12 +11,7 @@ SocketErrorMessage::SocketErrorMessage(socket_error_t code) noexcept { -#ifdef _UNICODE - wchar_t buffer[msg_size]; -#else auto *buffer = msg; -#endif - DWORD nbytes = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK, @@ -26,16 +21,6 @@ SocketErrorMessage::SocketErrorMessage(socket_error_t code) noexcept strcpy(msg, "Unknown error"); return; } - -#ifdef _UNICODE - auto length = WideCharToMultiByte(CP_UTF8, 0, buffer, -1, - msg, std::size(msg), - nullptr, nullptr); - if (length <= 0) { - strcpy(msg, "WideCharToMultiByte() error"); - return; - } -#endif } #else diff --git a/src/net/client/WeGlide/CMakeLists.txt b/src/net/client/WeGlide/CMakeLists.txt new file mode 100644 index 00000000000..1566e0033e2 --- /dev/null +++ b/src/net/client/WeGlide/CMakeLists.txt @@ -0,0 +1,35 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) + +target_link_libraries(${TARGET_NAME} PUBLIC IGC Formatter util json co) + +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/net/client/WeGlide/CMakeSource.cmake b/src/net/client/WeGlide/CMakeSource.cmake new file mode 100644 index 00000000000..68a6ecb1769 --- /dev/null +++ b/src/net/client/WeGlide/CMakeSource.cmake @@ -0,0 +1,15 @@ +set(_SOURCES + UploadFlight.cpp + UploadIGCFile.cpp + + DownloadTask.cpp + ListTasks.cpp + + Error.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake +) + + diff --git a/src/net/client/WeGlide/UploadFlight.cpp b/src/net/client/WeGlide/UploadFlight.cpp index 81b98972bfd..4b324443d02 100644 --- a/src/net/client/WeGlide/UploadFlight.cpp +++ b/src/net/client/WeGlide/UploadFlight.cpp @@ -42,7 +42,7 @@ UploadFlight(CurlGlobal &curl, const WeGlideSettings &settings, Path igc_path, ProgressListener &progress) { - NarrowString<0x200> url(settings.default_url); + StaticString<0x200> url(settings.default_url); url += "/igcfile"; CurlEasy easy{url}; diff --git a/src/net/client/WeGlide/UploadIGCFile.cpp b/src/net/client/WeGlide/UploadIGCFile.cpp index 87e816e06aa..2dc97a06bf6 100644 --- a/src/net/client/WeGlide/UploadIGCFile.cpp +++ b/src/net/client/WeGlide/UploadIGCFile.cpp @@ -18,15 +18,14 @@ #include "Operation/PluggableOperationEnvironment.hpp" #include "system/Path.hpp" #include "util/StaticString.hxx" -#include "util/ConvertString.hpp" #include // Wrapper for getting converted string values of a json string -static const UTF8ToWideConverter +static const char * GetJsonString(boost::json::value json_value, std::string_view key) { - return UTF8ToWideConverter(json_value.at(key).get_string().c_str()); + return json_value.at(key).get_string().c_str(); } namespace WeGlide { @@ -59,20 +58,20 @@ UploadJsonInterpreter(const boost::json::value &json) FlightData flight_data; // flight is the 1st flight object in this array ('at(0)') auto flight = json.as_array().at(0); - flight_data.scoring_date = GetJsonString(flight, "scoring_date").c_str(); + flight_data.scoring_date = GetJsonString(flight, "scoring_date"); flight_data.flight_id = flight.at("id").to_number(); - flight_data.registration = GetJsonString(flight, "registration").c_str(); - flight_data.competition_id = GetJsonString(flight, "competition_id").c_str(); + flight_data.registration = GetJsonString(flight, "registration"); + flight_data.competition_id = GetJsonString(flight, "competition_id"); auto user = flight.at("user").as_object(); flight_data.user.id = user.at("id").to_number(); - flight_data.user.name = GetJsonString(user, "name").c_str(); + flight_data.user.name = GetJsonString(user, "name"); auto aircraft = flight.at("aircraft").as_object(); flight_data.aircraft.id = aircraft.at("id").to_number(); - flight_data.aircraft.name = GetJsonString(aircraft, "name").c_str(); - flight_data.aircraft.kind = GetJsonString(aircraft, "kind").c_str(); - flight_data.aircraft.sc_class = GetJsonString(aircraft, "sc_class").c_str(); + flight_data.aircraft.name = GetJsonString(aircraft, "name"); + flight_data.aircraft.kind = GetJsonString(aircraft, "kind"); + flight_data.aircraft.sc_class = GetJsonString(aircraft, "sc_class"); return flight_data; } @@ -85,9 +84,9 @@ UploadSuccessDialog(const FlightData &flight_data) noexcept // TODO: Create a real Dialog with fields in 'src/Dialogs/Cloud/weglide'! // With this Dialog insert the possibilty to update/patch the flight // f.e. copilot in double seater, scoring class, short comment and so on - const auto display_string = fmt::format(_T("{}: {}\n{}: {}\n{}: {} ({})\n" - "{}: {} ({})\n{}: {}, {}: {}"), - _T("Flight ID"), flight_data.flight_id, + const auto display_string = fmt::format("{}: {}\n{}: {}\n{}: {} ({})\n" + "{}: {} ({})\n{}: {}, {}: {}", + "Flight ID", flight_data.flight_id, _("Date"), flight_data.scoring_date.c_str(), _("Username"), flight_data.user.name.c_str(), flight_data.user.id, _("Plane"), flight_data.aircraft.name.c_str(), flight_data.aircraft.id, diff --git a/src/net/http/DownloadManager.cpp b/src/net/http/DownloadManager.cpp index 0aed6245cdb..293a477f2b6 100644 --- a/src/net/http/DownloadManager.cpp +++ b/src/net/http/DownloadManager.cpp @@ -296,6 +296,7 @@ Net::DownloadManager::Deinitialise() noexcept assert(thread != nullptr); delete thread; + thread = nullptr; } bool diff --git a/src/system/Args.hpp b/src/system/Args.hpp index 9e60ca71207..2df85f297ac 100644 --- a/src/system/Args.hpp +++ b/src/system/Args.hpp @@ -4,13 +4,11 @@ #pragma once #include "util/Compiler.h" -#include "util/tstring.hpp" +#include #include "util/NumberParser.hpp" #include "system/Path.hpp" -#ifdef _UNICODE -#include "system/ConvertPathName.hpp" -#endif +#include #include #include @@ -55,7 +53,7 @@ class Args { } #ifdef _WIN32 - Args(const TCHAR *_cmdline, const char *_usage) + Args(const char *_cmdline, const char *_usage) :usage(_usage) { ParseCommandLine(_cmdline); } @@ -100,12 +98,6 @@ class Args { name = ""; } -#ifdef _UNICODE - void ParseCommandLine(const TCHAR *_cmdline) { - WideToACPConverter convert(_cmdline); - ParseCommandLine(convert); - } -#endif #endif Args &operator=(const Args &other) = delete; @@ -170,33 +162,19 @@ class Args { return result; } - tstring ExpectNextT() { + std::string ExpectNextT() { const char *p = ExpectNext(); assert(p != nullptr); -#ifdef _UNICODE - PathName convert(p); - return tstring(((Path)convert).c_str()); -#else - return tstring(p); -#endif + return std::string(p); } -#ifdef _UNICODE - AllocatedPath ExpectNextPath() { - const char *p = ExpectNext(); - assert(p != nullptr); - - return AllocatedPath(PathName(p)); - } -#else Path ExpectNextPath() { const char *p = ExpectNext(); assert(p != nullptr); return Path(p); } -#endif void ExpectEnd() { if (!IsEmpty()) diff --git a/src/system/CMakeLists.txt b/src/system/CMakeLists.txt new file mode 100644 index 00000000000..68105e12bf9 --- /dev/null +++ b/src/system/CMakeLists.txt @@ -0,0 +1,54 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories + +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) + +target_link_libraries(${TARGET_NAME} PUBLIC + util +) \ No newline at end of file diff --git a/src/system/CMakeSource.cmake b/src/system/CMakeSource.cmake new file mode 100644 index 00000000000..0dcde8fba63 --- /dev/null +++ b/src/system/CMakeSource.cmake @@ -0,0 +1,18 @@ +set(_SOURCES + system/EventPipe.cxx + system/FileUtil.cpp + system/Path.cpp + system/PathName.cpp + system/Process.cpp + system/RunFile.cpp + system/SystemLoad.cpp +) +if(UNIX) + list(APPEND _SOURCES +## system/EventPipe.cpp + ) +endif() + +set(SCRIPT_FILES + CMakeSource.cmake +) diff --git a/src/system/ConvertPathName.hpp b/src/system/ConvertPathName.hpp index 7ff51a17ea2..19d5c0be829 100644 --- a/src/system/ConvertPathName.hpp +++ b/src/system/ConvertPathName.hpp @@ -6,14 +6,7 @@ #include "Path.hpp" #include "util/Compiler.h" -#ifdef _UNICODE -#include "util/ConvertString.hpp" -#include "util/LightString.hxx" - -#include -#else #include "util/StringPointer.hxx" -#endif /** * Representation of a file name. It is automatically converted to @@ -22,23 +15,13 @@ * must not be Invalidated. */ class PathName { -#ifdef _UNICODE - typedef LightString Value; -#else typedef StringPointer<> Value; -#endif - Value value; public: explicit PathName(Value::const_pointer _value) noexcept :value(_value) {} -#ifdef _UNICODE - explicit PathName(const char *_value) noexcept - :value(ConvertACPToWide(_value)) {} -#endif - public: bool IsDefined() const noexcept { return !value.IsNull(); @@ -55,22 +38,13 @@ class PathName { * original input string; it must not be Invalidated. */ class NarrowPathName { -#ifdef _UNICODE - typedef LightString Value; -#else typedef StringPointer<> Value; -#endif Value value; public: -#ifdef _UNICODE - explicit NarrowPathName(Path _value) noexcept - :value(ConvertWideToACP(_value.c_str())) {} -#else explicit NarrowPathName(Path _value) noexcept :value(_value.c_str()) {} -#endif public: bool IsDefined() const noexcept { diff --git a/src/system/FileUtil.cpp b/src/system/FileUtil.cpp index 38b2917a13c..5fa418be80a 100644 --- a/src/system/FileUtil.cpp +++ b/src/system/FileUtil.cpp @@ -23,6 +23,10 @@ #include #include #include +#elif defined( _MSC_VER) +# include +# include + typedef SSIZE_T ssize_t; #endif void @@ -58,9 +62,9 @@ Directory::Exists(Path path) noexcept */ #ifndef HAVE_POSIX static bool -IsDots(const TCHAR *str) noexcept +IsDots(const char *str) noexcept { - return StringIsEqual(str, _T(".")) || StringIsEqual(str, _T("..")); + return StringIsEqual(str, ".") || StringIsEqual(str, ".."); } #endif @@ -68,7 +72,7 @@ IsDots(const TCHAR *str) noexcept [[gnu::pure]] static bool -checkFilter(const TCHAR *filename, const TCHAR *filter) noexcept +checkFilter(const char *filename, const char *filter) noexcept { // filter = e.g. "*.igc" or "config/*.prf" // todo: make filters like "config/*.prf" work @@ -83,23 +87,23 @@ checkFilter(const TCHAR *filename, const TCHAR *filter) noexcept static bool ScanFiles(File::Visitor &visitor, Path sPath, - const TCHAR* filter = _T("*")) + const char* filter = "*") { - TCHAR DirPath[MAX_PATH]; - TCHAR FileName[MAX_PATH]; + char DirPath[MAX_PATH]; + char FileName[MAX_PATH]; if (sPath != nullptr) // e.g. "/test/data/something" - _tcscpy(DirPath, sPath.c_str()); + strcpy(DirPath, sPath.c_str()); else DirPath[0] = 0; // "/test/data/something/" - _tcscat(DirPath, _T(DIR_SEPARATOR_S)); - _tcscpy(FileName, DirPath); + strcat(DirPath, DIR_SEPARATOR_S); + strcpy(FileName, DirPath); // "/test/data/something/*.igc" - _tcscat(FileName, filter); + strcat(FileName, filter); // Find the first matching file WIN32_FIND_DATA FindFileData; @@ -115,9 +119,9 @@ ScanFiles(File::Visitor &visitor, Path sPath, !(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && checkFilter(FindFileData.cFileName, filter)) { // "/test/data/something/" - _tcscpy(FileName, DirPath); + strcpy(FileName, DirPath); // "/test/data/something/blubb.txt" - _tcscat(FileName, FindFileData.cFileName); + strcat(FileName, FindFileData.cFileName); // Call visitor with the file that was found visitor.Visit(Path(FileName), Path(FindFileData.cFileName)); } @@ -145,25 +149,25 @@ ScanFiles(File::Visitor &visitor, Path sPath, static bool ScanDirectories(File::Visitor &visitor, bool recursive, - Path sPath, const TCHAR* filter = _T("*")) + Path sPath, const char* filter = "*") { #ifdef HAVE_POSIX DIR *dir = opendir(sPath.c_str()); if (dir == nullptr) return false; - TCHAR FileName[MAX_PATH]; - _tcscpy(FileName, sPath.c_str()); - size_t FileNameLength = _tcslen(FileName); + char FileName[MAX_PATH]; + strcpy(FileName, sPath.c_str()); + size_t FileNameLength = strlen(FileName); FileName[FileNameLength++] = '/'; struct dirent *ent; while ((ent = readdir(dir)) != nullptr) { // omit '.', '..' and any other files/directories starting with '.' - if (*ent->d_name == _T('.')) + if (*ent->d_name == '.') continue; - _tcscpy(FileName + FileNameLength, ent->d_name); + strcpy(FileName + FileNameLength, ent->d_name); struct stat st; if (stat(FileName, &st) < 0) @@ -183,13 +187,13 @@ ScanDirectories(File::Visitor &visitor, bool recursive, closedir(dir); #else /* !HAVE_POSIX */ - TCHAR DirPath[MAX_PATH]; - TCHAR FileName[MAX_PATH]; + char DirPath[MAX_PATH]; + char FileName[MAX_PATH]; if (sPath != nullptr) { // e.g. "/test/data/something" - _tcscpy(DirPath, sPath.c_str()); - _tcscpy(FileName, sPath.c_str()); + strcpy(DirPath, sPath.c_str()); + strcpy(FileName, sPath.c_str()); } else { DirPath[0] = 0; FileName[0] = 0; @@ -203,9 +207,9 @@ ScanDirectories(File::Visitor &visitor, bool recursive, return true; // "test/data/something/" - _tcscat(DirPath, _T(DIR_SEPARATOR_S)); + strcat(DirPath, DIR_SEPARATOR_S); // "test/data/something/*" - _tcscat(FileName, _T(DIR_SEPARATOR_S "*")); + strcat(FileName, DIR_SEPARATOR_S "*"); // Find the first file WIN32_FIND_DATA FindFileData; @@ -220,9 +224,9 @@ ScanDirectories(File::Visitor &visitor, bool recursive, if (!IsDots(FindFileData.cFileName) && (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { // "test/data/something/" - _tcscpy(FileName, DirPath); + strcpy(FileName, DirPath); // "test/data/something/SUBFOLDER" - _tcscat(FileName, FindFileData.cFileName); + strcat(FileName, FindFileData.cFileName); // Scan subfolder for matching files too ScanDirectories(visitor, true, Path(FileName), filter); } @@ -256,7 +260,7 @@ Directory::VisitFiles(Path path, File::Visitor &visitor, bool recursive) } void -Directory::VisitSpecificFiles(Path path, const TCHAR* filter, +Directory::VisitSpecificFiles(Path path, const char* filter, File::Visitor &visitor, bool recursive) { ScanDirectories(visitor, recursive, path, filter); @@ -300,18 +304,6 @@ File::IsCharDev(Path path) noexcept #endif // HAVE_POSIX -#if defined(_WIN32) && defined(UNICODE) - -bool -File::Exists(const char *path) noexcept -{ - DWORD attributes = GetFileAttributesA(path); - return attributes != INVALID_FILE_ATTRIBUTES && - (attributes & FILE_ATTRIBUTE_DIRECTORY) == 0; -} - -#endif - uint64_t File::GetSize(Path path) noexcept { diff --git a/src/system/FileUtil.hpp b/src/system/FileUtil.hpp index 5e2520117ff..6cff7876941 100644 --- a/src/system/FileUtil.hpp +++ b/src/system/FileUtil.hpp @@ -73,7 +73,7 @@ VisitFiles(Path path, File::Visitor &visitor, * @param recursive If true all subfolders will be visited too */ void -VisitSpecificFiles(Path path, const TCHAR *filter, +VisitSpecificFiles(Path path, const char *filter, File::Visitor &visitor, bool recursive = false); } // namespace Directory @@ -110,12 +110,6 @@ IsCharDev(Path path) noexcept; #endif // HAVE_POSIX -#if defined(_WIN32) && defined(UNICODE) -[[gnu::pure]] -bool -Exists(const char *path) noexcept; -#endif - /** * Deletes the given file * @param path Path to the file that should be deleted diff --git a/src/system/Path.cpp b/src/system/Path.cpp index b2801da6fff..260e337ea55 100644 --- a/src/system/Path.cpp +++ b/src/system/Path.cpp @@ -7,10 +7,6 @@ #include "util/StringAPI.hxx" #include "util/CharUtil.hxx" -#ifdef _UNICODE -#include "util/ConvertString.hpp" -#endif - #include #include @@ -21,15 +17,7 @@ Path::ToUTF8() const noexcept if (*this == nullptr) return std::string(); -#ifdef _UNICODE - const WideToUTF8Converter utf8(c_str()); - if (!utf8.IsValid()) - return std::string(); - - return (const char *)utf8; -#else return c_str(); -#endif } AllocatedPath @@ -78,9 +66,9 @@ Path::IsBase() const noexcept assert(*this != nullptr); #ifdef _WIN32 - return _tcspbrk(c_str(), _T("/\\")) == nullptr; + return strpbrk(c_str(), "/\\") == nullptr; #else - return StringFind(c_str(), _T('/')) == nullptr; + return StringFind(c_str(), '/') == nullptr; #endif } @@ -88,9 +76,9 @@ Path::IsBase() const noexcept static Path::const_pointer LastSeparator(Path::const_pointer path) noexcept { - const auto *p = StringFindLast(path, _T('/')); + const auto *p = StringFindLast(path, '/'); #ifdef _WIN32 - const auto *backslash = StringFindLast(path, _T('\\')); + const auto *backslash = StringFindLast(path, '\\'); if (p == nullptr || backslash > p) p = backslash; #endif @@ -105,7 +93,7 @@ Path::GetParent() const noexcept const const_pointer v = c_str(); const const_pointer p = LastSeparator(v); if (p == nullptr || p == v) - return AllocatedPath(_T(".")); + return AllocatedPath("."); return AllocatedPath(v, p); } @@ -161,14 +149,14 @@ Path::GetSuffix() const noexcept assert(!StringIsEmpty(base.c_str())); - return StringFindLast(base.c_str() + 1, _T('.')); + return StringFindLast(base.c_str() + 1, '.'); } AllocatedPath Path::WithSuffix(const_pointer new_suffix) const noexcept { assert(new_suffix != nullptr); - assert(*new_suffix == _T('.')); + assert(*new_suffix == '.'); auto old_suffix = GetSuffix(); return old_suffix != nullptr diff --git a/src/system/Path.hpp b/src/system/Path.hpp index cbf0f7db1df..c13ac17e780 100644 --- a/src/system/Path.hpp +++ b/src/system/Path.hpp @@ -9,10 +9,6 @@ #include #include -#ifdef _UNICODE -#include -#endif - #include class AllocatedPath; @@ -26,11 +22,8 @@ class AllocatedPath; */ class Path { public: -#ifdef _UNICODE - using char_type = wchar_t; -#else using char_type = char; -#endif + using value_type = StringPointer; using const_pointer = value_type::const_pointer; using pointer = value_type::pointer; @@ -49,7 +42,7 @@ class Path { AllocatedPath operator+(const_pointer other) const noexcept; bool empty() const noexcept { - return value.empty(); + return (value == 0) || value.empty(); } constexpr const_pointer c_str() const noexcept { diff --git a/src/system/PathName.cpp b/src/system/PathName.cpp index f853d88b1ff..86ffd9dc6bb 100644 --- a/src/system/PathName.cpp +++ b/src/system/PathName.cpp @@ -5,12 +5,12 @@ #include "util/StringAPI.hxx" [[gnu::pure]] -static const TCHAR * -LastSeparator(const TCHAR *path) +static const char * +LastSeparator(const char *path) { - const auto *p = StringFindLast(path, _T('/')); + const auto *p = StringFindLast(path, '/'); #ifdef _WIN32 - const auto *backslash = StringFindLast(path, _T('\\')); + const auto *backslash = StringFindLast(path, '\\'); if (p == nullptr || backslash > p) p = backslash; #endif @@ -18,19 +18,19 @@ LastSeparator(const TCHAR *path) } [[gnu::pure]] -static TCHAR * -LastSeparator(TCHAR *path) +static char * +LastSeparator(char *path) { - return const_cast(LastSeparator((const TCHAR *)path)); + return const_cast(LastSeparator((const char *)path)); } void -ReplaceBaseName(TCHAR *path, const TCHAR *new_base) +ReplaceBaseName(char *path, const char *new_base) { - TCHAR *q = LastSeparator(path); + char *q = LastSeparator(path); if (q != nullptr) ++q; else q = path; - _tcscpy(q, new_base); + strcpy(q, new_base); } diff --git a/src/system/PathName.hpp b/src/system/PathName.hpp index 0ad1df235cc..7441f860ac6 100644 --- a/src/system/PathName.hpp +++ b/src/system/PathName.hpp @@ -16,4 +16,4 @@ * @param new_base the new base name to be copied to #path */ void -ReplaceBaseName(TCHAR *path, const TCHAR *new_base); +ReplaceBaseName(char *path, const char *new_base); diff --git a/src/system/Process.cpp b/src/system/Process.cpp index cbc077c30a1..aa827e629a1 100644 --- a/src/system/Process.cpp +++ b/src/system/Process.cpp @@ -11,6 +11,29 @@ #include #include +#include +#include + +#include +#endif + +#include "LogFile.hpp" +#include "system/FileUtil.hpp" + +#include + +#include +#include +#include + +// static std::filesystem::path output; +// static Path output = Path(""); +static Path output; + +#include +#include + +#ifdef HAVE_POSIX static bool UnblockAllSignals() noexcept { @@ -22,36 +45,54 @@ UnblockAllSignals() noexcept static pid_t ForkExec(const char *const*argv) noexcept { + LogFormat("ForkExec: Call '%s'", argv[0]); const pid_t pid = fork(); if (pid == 0) { UnblockAllSignals(); + if (!output.empty()) { + auto fd = open(output.ToUTF8().c_str(), O_WRONLY | O_CREAT, + 0666); // open the file + dup2(fd, STDOUT_FILENO); // replace standard output with output file + } + // exec or die: execv(argv[0], const_cast(argv)); - _exit(1); + // ...die: + LogFormat("ForkExec: After execv => FAIL?"); + _exit(EXIT_FAILURE); } - + LogFormat("ForkExec: pid = %d > 0", pid); return pid; - } -static bool +static int Wait(pid_t pid) noexcept { + LogFormat("Process.cpp - Wait: pid = %d (for assert)", pid); assert(pid > 0); int status; pid_t pid2 = waitpid(pid, &status, 0); + LogFormat("Process.cpp - Wait: pid2 = %d ", pid2); if (pid2 <= 0) - return false; + return -1; - if (WIFSIGNALED(status) || !WIFEXITED(status) || WEXITSTATUS(status) != 0) - return false; + if (WIFSIGNALED(status) || !WIFEXITED(status)) + return -1; - return true; + if (!output.empty()) { + auto fd = dup(STDOUT_FILENO); + close(fd); + } + int ret_value = WEXITSTATUS(status); + LogFormat("Process.cpp - Wait: return %d", ret_value); + return ret_value; } +#endif bool -Start(const char *const*argv) noexcept +Start(const char *const *argv) noexcept { +#ifdef HAVE_POSIX /* double fork to detach from this process */ const pid_t pid = fork(); if (pid < 0) [[unlikely]] @@ -60,14 +101,64 @@ Start(const char *const*argv) noexcept if (pid == 0) _exit(ForkExec(argv) ? 0 : 1); - return Wait(pid); + return Wait(pid) == 0; +#elif defined(_WIN32) + LogFormat("Process.cpp - on Windows no Start() function"); + for (unsigned count = 0; argv[count] != nullptr; count++) { + LogFormat("Process.cpp - Start, Arg %u: %s", count, argv[count]); + std::cout << argv[count] << ' '; + } + + return false; +#else + error "Unknown system" +#endif } -bool -Run(const char *const*argv) noexcept -{ +#define PROCESS_DEBUG_OUTPUT 0 +int +Run(const char *const *argv) noexcept +try { +#if PROCESS_DEBUG_OUTPUT // def DEBUG_OPENVARIO + std::cout << "Start Run with:" << std::endl; + if (!output.empty()) + LogFormat("Process.cpp - Run with output: %s", output.c_str()); + else + LogFormat("Process.cpp - Run w/o output"); +#endif + std::stringstream ss; + + for (unsigned count = 0; argv[count] != nullptr; count++) { + ss << argv[count] << ' '; + std::cout << argv[count] << ' '; + } +#if PROCESS_DEBUG_OUTPUT // def DEBUG_OPENVARIO + std::cout << '!' << std::endl; + LogFormat("Process.cpp: %s", ss.str().c_str()); +#endif + + int ret_value = -1; +#ifdef HAVE_POSIX const pid_t pid = ForkExec(argv); - return pid > 0 && Wait(pid); + if (pid > 0) + ret_value = Wait(pid); +#elif defined(_WIN32) + ret_value = system(ss.str().c_str()); +#else + error "Unknown system" +#endif + if (!output.empty()) + output = Path(); // for the next call.. + return ret_value; +} catch (std::exception &e) { + LogFormat("Process.cpp - exception: %s", e.what()); + return -1; } -#endif + +int +Run(const Path &output_path, const char *const *argv) noexcept +{ + output = output_path; + return Run(argv); +} diff --git a/src/system/Process.hpp b/src/system/Process.hpp index 1fbcb33c987..8a6cafb53ae 100644 --- a/src/system/Process.hpp +++ b/src/system/Process.hpp @@ -3,7 +3,7 @@ #pragma once -#ifdef HAVE_POSIX +#include /** * Launch a child process but don't wait for it to exit. @@ -22,15 +22,40 @@ Start(const char *path, Args... args) noexcept /** * Launch a child process and wait for it to exit. */ -bool +class Path; + +int Run(const char *const*argv) noexcept; +int +Run(const Path &output, const char *const *argv) noexcept; template -static inline bool +static inline int Run(const char *path, Args... args) noexcept { const char *const argv[]{path, args..., nullptr}; return Run(argv); } -#endif +template +static inline int +Run(const Path &output, const char *path, Args... args) noexcept +{ + const char *const argv[]{path, args..., nullptr}; + return Run(output, argv); +} + +// int +// Run(const Path &output, const char *path, ...) noexcept; + +// static inline +// int +// RunX(const std::filesystem::path output, const char *path) noexcept +// { + +// int +// RunX(const Path &output, const char *path) noexcept +// { +// const char *const argv[]{path, nullptr}; +// return Run(output, argv); +// } diff --git a/src/system/RunFile.cpp b/src/system/RunFile.cpp index a8d47c0dcf5..95b945e3286 100644 --- a/src/system/RunFile.cpp +++ b/src/system/RunFile.cpp @@ -10,7 +10,7 @@ #include "Process.hpp" bool -RunFile(const TCHAR *path) noexcept +RunFile(const char *path) noexcept { #if defined(__APPLE__) return Start("/usr/bin/open", path); diff --git a/src/system/RunFile.hpp b/src/system/RunFile.hpp index 94b2f4cc907..1da3957b86d 100644 --- a/src/system/RunFile.hpp +++ b/src/system/RunFile.hpp @@ -13,6 +13,6 @@ * Opens a file in the user's preferred application. */ bool -RunFile(const TCHAR *path) noexcept; +RunFile(const char *path) noexcept; #endif diff --git a/src/system/SystemLoad.cpp b/src/system/SystemLoad.cpp index d68353d89b2..ab9af409e94 100644 --- a/src/system/SystemLoad.cpp +++ b/src/system/SystemLoad.cpp @@ -34,7 +34,10 @@ SystemLoadCPU() noexcept unsigned dt_user = userTime-userTime_last; unsigned dt_kernel = kernelTime-kernelTime_last; unsigned dt = tick-tick_last; - retval = (100*(dt_user+dt_kernel))/dt; + if (dt) + retval = (100 * (dt_user + dt_kernel)) / dt; + else + retval = 0; } tick_last = tick; diff --git a/src/system/WindowsRegistry.hpp b/src/system/WindowsRegistry.hpp index e079dc661e1..fbe3e5e33cd 100644 --- a/src/system/WindowsRegistry.hpp +++ b/src/system/WindowsRegistry.hpp @@ -22,7 +22,7 @@ class RegistryKey { public: RegistryKey() noexcept = default; - RegistryKey(HKEY parent, const TCHAR *key) { + RegistryKey(HKEY parent, const char *key) { const auto result = RegOpenKeyEx(parent, key, 0, KEY_READ, &h); if (result != ERROR_SUCCESS) throw MakeLastError("RegOpenKeyEx() failed"); @@ -46,7 +46,7 @@ class RegistryKey { return h; } - bool GetValue(const TCHAR *name, LPDWORD type_r, + bool GetValue(const char *name, LPDWORD type_r, LPBYTE data, LPDWORD length_r) const noexcept { return RegQueryValueEx(h, name, nullptr, type_r, data, length_r) == ERROR_SUCCESS; @@ -58,19 +58,19 @@ class RegistryKey { * * @return true on success */ - bool GetValue(const TCHAR *name, std::span value) const noexcept { + bool GetValue(const char *name, std::span value) const noexcept { const auto s = std::as_writable_bytes(value); DWORD type, length = s.size(); return GetValue(name, &type, (LPBYTE)s.data(), &length) && type == REG_SZ; } - bool EnumKey(DWORD idx, std::span name) const noexcept { + bool EnumKey(DWORD idx, std::span name) const noexcept { DWORD name_max_size = (DWORD)name.size(); return RegEnumKeyEx(h, idx, name.data(), &name_max_size, nullptr, nullptr, nullptr, nullptr) == ERROR_SUCCESS; } - bool EnumValue(DWORD idx, std::span name, LPDWORD type, + bool EnumValue(DWORD idx, std::span name, LPDWORD type, std::span value) const noexcept { DWORD name_max_size = (DWORD)name.size(); DWORD value_max_size = (DWORD)name.size(); diff --git a/src/thread/CMakeLists.txt b/src/thread/CMakeLists.txt new file mode 100644 index 00000000000..c79a42de2ee --- /dev/null +++ b/src/thread/CMakeLists.txt @@ -0,0 +1,51 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories + + +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/thread/CMakeSource.cmake b/src/thread/CMakeSource.cmake new file mode 100644 index 00000000000..27196352481 --- /dev/null +++ b/src/thread/CMakeSource.cmake @@ -0,0 +1,12 @@ +set(_SOURCES + thread/Debug.cpp + thread/RecursivelySuspensibleThread.cpp + thread/StandbyThread.cpp + thread/SuspensibleThread.cpp + thread/Thread.cpp + thread/WorkerThread.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake +) diff --git a/src/thread/Thread.cpp b/src/thread/Thread.cpp index b7fad203449..83622b9f848 100644 --- a/src/thread/Thread.cpp +++ b/src/thread/Thread.cpp @@ -12,6 +12,10 @@ #include +#ifdef __MSVC__ +# include "LogFile.hpp" +#endif + void Thread::SetIdlePriority() noexcept { @@ -74,7 +78,13 @@ Thread::Join() noexcept pthread_join(handle, nullptr); defined = false; #else - ::WaitForSingleObject(handle, INFINITE); + DWORD result = ::WaitForSingleObject(handle, 1000); + if (result != WAIT_OBJECT_0) { // TODO(August2111): Too much? INFINITE); +# ifdef __MSVC__ + // TODO(August2111) commented out for PC and WIN64: + LogFormat("WaitForSingleObject with error %lu", result); +# endif + } ::CloseHandle(handle); handle = nullptr; #endif diff --git a/src/time/CMakeLists.txt b/src/time/CMakeLists.txt new file mode 100644 index 00000000000..c79a42de2ee --- /dev/null +++ b/src/time/CMakeLists.txt @@ -0,0 +1,51 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories + + +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/time/CMakeSource.cmake b/src/time/CMakeSource.cmake new file mode 100644 index 00000000000..85c26bff35a --- /dev/null +++ b/src/time/CMakeSource.cmake @@ -0,0 +1,13 @@ +set(_SOURCES + time/BrokenDate.cpp + time/BrokenDateTime.cpp + time/BrokenTime.cpp + time/Convert.cxx + time/DeltaTime.cpp + time/LocalTime.cpp + time/WrapClock.cpp + time/Zone.cxx +) + +set(SCRIPT_FILES CMakeSource.cmake) + diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt new file mode 100644 index 00000000000..ed2062f8a6d --- /dev/null +++ b/src/ui/CMakeLists.txt @@ -0,0 +1,51 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories + +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + string(REPLACE "${SRC}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) ### for VisualStudio-IDE + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + ### hide: message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER FrontEnd) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/ui/CMakeSource.cmake b/src/ui/CMakeSource.cmake new file mode 100644 index 00000000000..ff08aa1737a --- /dev/null +++ b/src/ui/CMakeSource.cmake @@ -0,0 +1,412 @@ +set(SCREEN_SRC_DIR ../Screen) +set(CANVAS_SRC_DIR ui/canvas) # branch cmake!!! +set(CONTROL_SRC_DIR ui/control) +set(WINDOW_SRC_DIR ui/window) +set(DISPLAY_SRC_DIR ui/display) + +set(SCREEN_SOURCES + ${SCREEN_SRC_DIR}/Debug.cpp + ${WINDOW_SRC_DIR}/Init.cpp + ../Renderer/ProgressBarRenderer.cpp + ${CONTROL_SRC_DIR}/ProgressBar.cpp + ${CANVAS_SRC_DIR}/Ramp.cpp + ${CANVAS_SRC_DIR}/Util.cpp + ${CANVAS_SRC_DIR}/Icon.cpp + ${CANVAS_SRC_DIR}/Color.cpp + ${CANVAS_SRC_DIR}/BufferCanvas.cpp + ${WINDOW_SRC_DIR}/Window.cpp + ${WINDOW_SRC_DIR}/ContainerWindow.cpp + ${WINDOW_SRC_DIR}/SolidContainerWindow.cpp + ${WINDOW_SRC_DIR}/BufferWindow.cpp + ${WINDOW_SRC_DIR}/DoubleBufferWindow.cpp + ${WINDOW_SRC_DIR}/SingleWindow.cpp +) +set(SCREEN_CUSTOM_SOURCES + ${WINDOW_SRC_DIR}/custom/DoubleClick.cpp + ${CANVAS_SRC_DIR}/custom/GeoBitmap.cpp + ${CANVAS_SRC_DIR}/custom/Pen.cpp + ${CONTROL_SRC_DIR}/custom/LargeTextWindow.cpp + ${WINDOW_SRC_DIR}/custom/Window.cpp + ${WINDOW_SRC_DIR}/custom/WList.cpp + ${WINDOW_SRC_DIR}/custom/ContainerWindow.cpp + ${WINDOW_SRC_DIR}/custom/TopWindow.cpp + ${WINDOW_SRC_DIR}/custom/SingleWindow.cpp + ${CANVAS_SRC_DIR}/custom/MoreCanvas.cpp +) + +set(SCREEN_CUSTOM_SOURCES_IMG "") # Reset +if (COREGRAPHICS) + list (APPEND SCREEN_CUSTOM_SOURCES_IMG + ${CANVAS_SRC_DIR}/apple/ImageDecoder.cpp) +endif() + +if (LIBPNG) + list (APPEND SCREEN_CUSTOM_SOURCES_IMG + ${CANVAS_SRC_DIR}/custom/LibPNG.cpp) +endif() + +if (LIBJPEG) + list (APPEND SCREEN_CUSTOM_SOURCES_IMG + ${CANVAS_SRC_DIR}/custom/LibJPEG.cpp) +endif() + +if (TIFF) + list (APPEND SCREEN_CUSTOM_SOURCES_IMG + ${CANVAS_SRC_DIR}/custom/LibTiff.cpp) +endif() + +if (ENABLE_MESA_KMS) + list (APPEND SCREEN_SOURCES + ${CANVAS_SRC_DIR}/egl/GbmSurface.cpp + ${CANVAS_SRC_DIR}/egl/DrmFrameBuffer.cpp + ${DISPLAY_SRC_DIR}/egl/DrmDisplay.cpp + ${DISPLAY_SRC_DIR}/egl/GbmDisplay.cpp + ) +endif() + +if(TARGET_IS_ANDROID) ## ${TARGET} STREQUAL ANDROID) + list (APPEND SCREEN_SOURCES + ${SCREEN_CUSTOM_SOURCES} + ## ${SCREEN_CUSTOM_SOURCES_IMG} + ${DISPLAY_SRC_DIR}/display/egl/Display.cpp + ${DISPLAY_SRC_DIR}/egl/ConfigChooser.cpp + ${CANVAS_SRC_DIR}/egl/TopCanvas.cpp + ${WINDOW_SRC_DIR}/android/Window.cpp + ${WINDOW_SRC_DIR}/android/TopWindow.cpp + ${WINDOW_SRC_DIR}/android/SingleWindow.cpp + ${CANVAS_SRC_DIR}/android/Bitmap.cpp + ${CANVAS_SRC_DIR}/android/Font.cpp + ) + if (TIFF) + list (APPEND SCREEN_SOURCES + ${CANVAS_SRC_DIR}/custom/LibTiff.cpp) + endif() + +endif() + +if (DITHER) + list (APPEND SCREEN_SOURCES + ${CANVAS_SRC_DIR}/memory/Dither.cpp + ) +endif() + +if (FREETYPE) + list (APPEND SCREEN_SOURCES + ${CANVAS_SRC_DIR}/freetype/Font.cpp + ${CANVAS_SRC_DIR}/freetype/Init.cpp + ) +endif() + +if (0) # ?? call bool_or,${APPKIT),${UIKIT)) + list (APPEND SCREEN_SOURCES + ${CANVAS_SRC_DIR}/apple/Font.cpp) +endif() + +if (USE_X11) + list (APPEND SCREEN_SOURCES + ${DISPLAY_SRC_DIR}/x11/Display.cpp + ${WINDOW_SRC_DIR}/x11/TopWindow.cpp + ) +endif() + +if (USE_WAYLAND) + list (APPEND SCREEN_SOURCES + ${DISPLAY_SRC_DIR}/wayland/Display.cpp + ${WINDOW_SRC_DIR}/wayland/TopWindow.cpp + ) +endif() + +if(ENABLE_OPENGL) + list(APPEND SCREEN_SOURCES + ${DISPLAY_SRC_DIR}/opengl/Display.cpp + ${CANVAS_SRC_DIR}/custom/Cache.cpp + ${CANVAS_SRC_DIR}/opengl/Init.cpp + ${CANVAS_SRC_DIR}/opengl/Dynamic.cpp + ${CANVAS_SRC_DIR}/opengl/Rotate.cpp + ${CANVAS_SRC_DIR}/opengl/Geo.cpp + ${CANVAS_SRC_DIR}/opengl/Globals.cpp + ${CANVAS_SRC_DIR}/opengl/Extension.cpp + ${CANVAS_SRC_DIR}/opengl/VertexArray.cpp + ${CANVAS_SRC_DIR}/opengl/ConstantAlpha.cpp + ${CANVAS_SRC_DIR}/opengl/Bitmap.cpp + ${CANVAS_SRC_DIR}/opengl/RawBitmap.cpp + ${CANVAS_SRC_DIR}/opengl/Canvas.cpp + ${CANVAS_SRC_DIR}/opengl/BufferCanvas.cpp + ${CANVAS_SRC_DIR}/opengl/TopCanvas.cpp + ${CANVAS_SRC_DIR}/opengl/SubCanvas.cpp + ${CANVAS_SRC_DIR}/opengl/Texture.cpp + ${CANVAS_SRC_DIR}/opengl/UncompressedImage.cpp + ${CANVAS_SRC_DIR}/opengl/Buffer.cpp + ${CANVAS_SRC_DIR}/opengl/Shapes.cpp + ${CANVAS_SRC_DIR}/opengl/Shaders.cpp + ${CANVAS_SRC_DIR}/opengl/CanvasRotateShift.cpp + ${CANVAS_SRC_DIR}/opengl/Triangulate.cpp + ) + endif() + +if (ENABLE_SDL) + list(APPEND SCREEN_SOURCES + ${SCREEN_CUSTOM_SOURCES} + ${SCREEN_CUSTOM_SOURCES_IMG} + ${DISPLAY_SRC_DIR}/sdl/Display.cpp + ${CANVAS_SRC_DIR}/custom/Files.cpp + ${CANVAS_SRC_DIR}/custom/Bitmap.cpp + ${CANVAS_SRC_DIR}/custom/ResourceBitmap.cpp + ${CANVAS_SRC_DIR}/sdl/TopCanvas.cpp + ${WINDOW_SRC_DIR}/sdl/Window.cpp + ${WINDOW_SRC_DIR}/sdl/TopWindow.cpp + ${WINDOW_SRC_DIR}/sdl/SingleWindow.cpp + ) + + if (NOT OPENGL) + set(USE_MEMORY_CANVAS ON) + endif() +elseif (EGL AND NOT TARGET_IS_ANDROID) + list(APPEND SCREEN_SOURCES + ${SCREEN_CUSTOM_SOURCES_IMG} + ${SCREEN_CUSTOM_SOURCES} + ${CANVAS_SRC_DIR}/custom/Files.cpp + ${CANVAS_SRC_DIR}/custom/Bitmap.cpp + ${CANVAS_SRC_DIR}/custom/ResourceBitmap.cpp + ${CANVAS_SRC_DIR}/egl/TopCanvas.cpp + ${DISPLAY_SRC_DIR}/egl/ConfigChooser.cpp + ${DISPLAY_SRC_DIR}/egl/Display.cpp + ${WINDOW_SRC_DIR}/poll/TopWindow.cpp + ${WINDOW_SRC_DIR}/fb/Window.cpp + ${WINDOW_SRC_DIR}/fb/SingleWindow.cpp + ) +elseif (GLX) + list(APPEND SCREEN_SOURCES + ${SCREEN_CUSTOM_SOURCES_IMG} + ${SCREEN_CUSTOM_SOURCES} + ${CANVAS_SRC_DIR}/custom/Files.cpp + ${CANVAS_SRC_DIR}/custom/Bitmap.cpp + ${CANVAS_SRC_DIR}/custom/ResourceBitmap.cpp + ${CANVAS_SRC_DIR}/glx/TopCanvas.cpp + ${WINDOW_SRC_DIR}/poll/TopWindow.cpp + ${WINDOW_SRC_DIR}/fb/Window.cpp + ${WINDOW_SRC_DIR}/fb/SingleWindow.cpp + ) +elseif (VFB) + list(APPEND SCREEN_SOURCES + ${SCREEN_CUSTOM_SOURCES_IMG} + ${SCREEN_CUSTOM_SOURCES} + ${CANVAS_SRC_DIR}/custom/Files.cpp + ${CANVAS_SRC_DIR}/custom/Bitmap.cpp + ${CANVAS_SRC_DIR}/custom/ResourceBitmap.cpp + ${CANVAS_SRC_DIR}/fb/TopCanvas.cpp + ${WINDOW_SRC_DIR}/poll/TopWindow.cpp + ${WINDOW_SRC_DIR}/fb/Window.cpp + ${WINDOW_SRC_DIR}/fb/SingleWindow.cpp + ) + set(FB_CPPFLAGS -DUSE_VFB) +elseif (USE_FB) + list(APPEND SCREEN_SOURCES + ${SCREEN_CUSTOM_SOURCES_IMG} + ${SCREEN_CUSTOM_SOURCES} + ${CANVAS_SRC_DIR}/custom/Files.cpp + ${CANVAS_SRC_DIR}/custom/Bitmap.cpp + ${CANVAS_SRC_DIR}/custom/ResourceBitmap.cpp + ${CANVAS_SRC_DIR}/memory/Export.cpp + ${WINDOW_SRC_DIR}/poll/TopWindow.cpp + ${WINDOW_SRC_DIR}/fb/TopWindow.cpp + ${CANVAS_SRC_DIR}/fb/TopCanvas.cpp + ${WINDOW_SRC_DIR}/fb/Window.cpp + ${WINDOW_SRC_DIR}/fb/SingleWindow.cpp + ) + set(FB_CPPFLAGS -DUSE_FB) +# elseif (HAVE_WIN32) +elseif (WIN32) + list(APPEND SCREEN_SOURCES + ${DISPLAY_SRC_DIR}/gdi/Display.cpp + ${CANVAS_SRC_DIR}/gdi/WindowCanvas.cpp + ${CANVAS_SRC_DIR}/gdi/VirtualCanvas.cpp + ${CANVAS_SRC_DIR}/gdi/Font.cpp + ${WINDOW_SRC_DIR}/gdi/Window.cpp + ${WINDOW_SRC_DIR}/gdi/PaintWindow.cpp + ${WINDOW_SRC_DIR}/gdi/ContainerWindow.cpp + ${CONTROL_SRC_DIR}/gdi/LargeTextWindow.cpp + ${WINDOW_SRC_DIR}/gdi/SingleWindow.cpp + ${WINDOW_SRC_DIR}/gdi/TopWindow.cpp + ${CANVAS_SRC_DIR}/gdi/Pen.cpp + ${CANVAS_SRC_DIR}/gdi/Brush.cpp + ${CANVAS_SRC_DIR}/gdi/Bitmap.cpp + ${CANVAS_SRC_DIR}/gdi/GdiPlusBitmap.cpp + ${CANVAS_SRC_DIR}/gdi/ResourceBitmap.cpp + ${CANVAS_SRC_DIR}/gdi/RawBitmap.cpp + ${CANVAS_SRC_DIR}/gdi/Canvas.cpp + ${CANVAS_SRC_DIR}/gdi/BufferCanvas.cpp + ${CANVAS_SRC_DIR}/gdi/PaintCanvas.cpp + ) + set(GDI_CPPFLAGS -DUSE_GDI) + set(WINUSER_CPPFLAGS -DUSE_WINUSER) + set(GDI_LDLIBS -luser32 -lgdi32 -lmsimg32 -lgdiplus) + + # if (TARGET STREQUAL PC) + if (WIN32) + list(APPEND GDI_LDLIBS -Wl,-subsystem,windows) + endif() +endif() + +if (TARGET_IS_LINUX) + list(APPEND SCREEN_SOURCES + ${SRC}/ui/linux/GraphicsTTY.cpp) +endif() + +if (USE_MEMORY_CANVAS) + list(APPEND SCREEN_SOURCES + ${CANVAS_SRC_DIR}/custom/Cache.cpp + ${CANVAS_SRC_DIR}/memory/Bitmap.cpp + ${CANVAS_SRC_DIR}/memory/RawBitmap.cpp + ${CANVAS_SRC_DIR}/memory/VirtualCanvas.cpp + ${CANVAS_SRC_DIR}/memory/SubCanvas.cpp + ${CANVAS_SRC_DIR}/memory/Canvas.cpp + ) + set(MEMORY_CANVAS_CPPFLAGS -DUSE_MEMORY_CANVAS) +endif() + +set(SCREEN_CPPFLAGS_INTERNAL + ${FREETYPE_CPPFLAGS} + ${LIBPNG_CPPFLAGS} + ${LIBJPEG_CPPFLAGS} + ${LIBTIFF_CPPFLAGS} + ${COREGRAPHICS_CPPFLAGS} +) + +set(SCREEN_CPPFLAGS + ${LINUX_INPUT_CPPFLAGS} + ${LIBINPUT_CPPFLAGS} + ${SDL_CPPFLAGS} + ${GDI_CPPFLAGS} ${WINUSER_CPPFLAGS} + ${FREETYPE_FEATURE_CPPFLAGS} + ${APPKIT_CPPFLAGS} + ${UIKIT_CPPFLAGS} + ${MEMORY_CANVAS_CPPFLAGS} + ${OPENGL_CPPFLAGS} + ${WAYLAND_CPPFLAGS} + ${EGL_CPPFLAGS} + ${EGL_FEATURE_CPPFLAGS} + ${GLX_CPPFLAGS} + ${POLL_EVENT_CPPFLAGS} + ${CONSOLE_CPPFLAGS} ${FB_CPPFLAGS} ${VFB_CPPFLAGS} +) + +set(SCREEN_LDLIBS + ${SDL_LDLIBS} + ${GDI_LDLIBS} + ${OPENGL_LDLIBS} + ${FREETYPE_LDLIBS} + ${LIBPNG_LDLIBS} ${LIBJPEG_LDLIBS} + ${LIBTIFF_LDLIBS} + ${WAYLAND_LDLIBS} + ${EGL_LDLIBS} + ${GLX_LDLIBS} + ${FB_LDLIBS} + ${COREGRAPHICS_LDLIBS} + ${APPKIT_LDLIBS} + ${UIKIT_LDLIBS} +) + +## $(eval $(call link-library,screen,SCREEN)) + +list(APPEND SCREEN_LDADD + ${SDL_LDADD} + ${FB_LDADD} + ${FREETYPE_LDADD} + ${LIBPNG_LDADD} ${LIBJPEG_LDADD} +) + +############################################################################################################## +include(EventSource.cmake) +set(_SOURCES + ${SCREEN_SOURCES} + ${EVENT_SOURCES} +## ${SCREEN_CUSTOM_SOURCES} +) +set(SCREEN_HEADERS + ${CONTROL_SRC_DIR}/ProgressBar.hpp +# ?? ${CONTROL_SRC_DIR}/ScrollBar.hpp +# ?? ${CONTROL_SRC_DIR}/ScrollBar.cpp +# ?? ${CONTROL_SRC_DIR}/TerminalWindow.hpp +# ?? ${CONTROL_SRC_DIR}/TerminalWindow.cpp + ${CONTROL_SRC_DIR}/LargeTextWindow.hpp +# ?? ${CONTROL_SRC_DIR}/List.cpp +# ?? ${CONTROL_SRC_DIR}/List.hpp + + ${CANVAS_SRC_DIR}/AnyCanvas.hpp + ${CANVAS_SRC_DIR}/Bitmap.hpp + ${CANVAS_SRC_DIR}/Brush.hpp + ${CANVAS_SRC_DIR}/BufferCanvas.cpp + ${CANVAS_SRC_DIR}/BufferCanvas.hpp + ${CANVAS_SRC_DIR}/Color.cpp + ${CANVAS_SRC_DIR}/Color.hpp + ${CANVAS_SRC_DIR}/Font.hpp # neu 2021 + ${CANVAS_SRC_DIR}/Icon.cpp + ${CANVAS_SRC_DIR}/Icon.hpp + ${CANVAS_SRC_DIR}/Pen.hpp + ${CANVAS_SRC_DIR}/PortableColor.hpp + ${CANVAS_SRC_DIR}/Ramp.cpp + ${CANVAS_SRC_DIR}/Ramp.hpp + ${CANVAS_SRC_DIR}/RawBitmap.hpp ### 2021 + ${CANVAS_SRC_DIR}/SubCanvas.hpp ### 2021 + ${CANVAS_SRC_DIR}/Util.cpp + ${CANVAS_SRC_DIR}/Util.hpp + ${CANVAS_SRC_DIR}/VirtualCanvas.hpp ### 2021 + ${CANVAS_SRC_DIR}/WindowCanvas.hpp ### 2021 + + ### Window-Sources + ${WINDOW_SRC_DIR}/BufferWindow.cpp + ${WINDOW_SRC_DIR}/DoubleBufferWindow.cpp + ${WINDOW_SRC_DIR}/SingleWindow.cpp + ${WINDOW_SRC_DIR}/SolidContainerWindow.cpp + ${WINDOW_SRC_DIR}/Window.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake + + ../../build/libevent.mk + ../../build/screen.mk + ../../build/test.mk +) + + +####################################################################### +list(APPEND _SOURCES ${SCREEN_HEADERS}) + +# list(APPEND _SOURCES + # ${EVENT_SRC_DIR}/DelayedNotify.cpp + # ${EVENT_SRC_DIR}/Globals.cpp + # ${EVENT_SRC_DIR}/Idle.cpp + # ${EVENT_SRC_DIR}/Notify.cpp +# ) +# if(UNIX) + # list(APPEND _SOURCES + # ${EVENT_SRC_DIR}/poll/Timer.cpp + # ${EVENT_SRC_DIR}/poll/Loop.cpp + # ${EVENT_SRC_DIR}/poll/Queue.cpp + # ${EVENT_SRC_DIR}/poll/X11Queue.cpp + # ) +# elseif(WIN32) + # list(APPEND _SOURCES + # ${EVENT_SRC_DIR}/shared/Timer.cpp + # ${EVENT_SRC_DIR}/shared/TimerQueue.cpp + + # ${EVENT_SRC_DIR}/windows/Loop.cpp + # ${EVENT_SRC_DIR}/windows/Queue.cpp + # ) + + list(APPEND _SOURCES + ${CONTROL_SRC_DIR}/ScrollBar.cpp + ${CONTROL_SRC_DIR}/List.cpp + ) + list(APPEND _SOURCES + ${CONTROL_SRC_DIR}/TerminalWindow.cpp + ) +# endif() + # list(APPEND _SOURCES + # ${EVENT_SRC_DIR}/shared/Timer.cpp + # ) + + + diff --git a/src/ui/EventSource.cmake b/src/ui/EventSource.cmake new file mode 100644 index 00000000000..a5103bc1b15 --- /dev/null +++ b/src/ui/EventSource.cmake @@ -0,0 +1,94 @@ +set(EVENT_SRC_DIR ui/event) +####################################################################### + +set(EVENT_SOURCES + ${EVENT_SRC_DIR}/Globals.cpp + ${EVENT_SRC_DIR}/Idle.cpp + ${EVENT_SRC_DIR}/DelayedNotify.cpp + ${EVENT_SRC_DIR}/Notify.cpp +) + +if(USE_POLL_EVENT) + list(APPEND EVENT_SOURCES + ${EVENT_SRC_DIR}/poll/Timer.cpp + ${EVENT_SRC_DIR}/poll/Loop.cpp + ${EVENT_SRC_DIR}/poll/Queue.cpp +#### ${EVENT_SRC_DIR}/poll/X11Queue.cpp + ) +else() + list(APPEND EVENT_SOURCES + ${EVENT_SRC_DIR}/shared/Timer.cpp + ${EVENT_SRC_DIR}/shared/TimerQueue.cpp + ) +endif() + +if(ANDROID) # TARGET_IS_ANDROID + list(APPEND EVENT_SOURCES + ${EVENT_SRC_DIR}/android/Loop.cpp + ${EVENT_SRC_DIR}/android/Queue.cpp + ) +elseif(VFB) + set(VFB_CPPFLAGS "-DNON_INTERACTIVE") +elseif(USE_X11) + list(APPEND EVENT_SOURCES + ${EVENT_SRC_DIR}/poll/X11Queue.cpp + ) +elseif(USE_WAYLAND) + list(APPEND EVENT_SOURCES + ${EVENT_SRC_DIR}/poll/WaylandQueue.cpp + ) +elseif(USE_CONSOLE) + list(APPEND EVENT_SOURCES + ${EVENT_SRC_DIR}/poll/InputQueue.cpp) + set(CONSOLE_CPPFLAGS "-DUSE_CONSOLE") + + if(USE_LIBINPUT) + list(APPEND EVENT_SOURCES + ${EVENT_SRC_DIR}/poll/libinput/LibInputHandler.cpp + ) + if(ENABLE_UDEV) + list(APPEND EVENT_SOURCES + ${EVENT_SRC_DIR}/poll/libinput/UdevContext.cpp + ) + endif() + else() + list(APPEND EVENT_SOURCES + ${EVENT_SRC_DIR}/poll/linux/MergeMouse.cpp + ${EVENT_SRC_DIR}/poll/linux/Input.cpp + ) + endif() +elseif(ENABLE_SDL) + list(APPEND EVENT_SOURCES + ${EVENT_SRC_DIR}/sdl/Loop.cpp + ${EVENT_SRC_DIR}/sdl/Queue.cpp + ) +elseif(WIN32) # TARGET_IS_WINDOWS + list(APPEND EVENT_SOURCES + ${EVENT_SRC_DIR}/windows/Loop.cpp + ${EVENT_SRC_DIR}/windows/Queue.cpp + ) +endif() + +### ifeq ($(USE_LIBINPUT),y) +### $(eval $(call pkg-config-library,LIBINPUT,libinput)) +### EVENT_CPPFLAGS_INTERNAL += $(UDEV_CPPFLAGS) +### ifeq ($(LIBINPUT_MODVERSION),0.6.0) +### EVENT_CPPFLAGS_INTERNAL += -DLIBINPUT_LEGACY_API +### endif +### LIBINPUT_CPPFLAGS += -DUSE_LIBINPUT +### EVENT_LDLIBS += $(LIBINPUT_LDLIBS) $(UDEV_LDLIBS) +### endif +### +### EVENT_CPPFLAGS = \ +### $(LINUX_INPUT_CPPFLAGS) \ +### $(LIBINPUT_CPPFLAGS) \ +### $(SDL_CPPFLAGS) \ +### $(WINUSER_CPPFLAGS) \ +### $(OPENGL_CPPFLAGS) $(EGL_FEATURE_CPPFLAGS) $(GLX_CPPFLAGS) \ +### $(MEMORY_CANVAS_CPPFLAGS) \ +### $(POLL_EVENT_CPPFLAGS) \ +### $(CONSOLE_CPPFLAGS) $(FB_CPPFLAGS) $(VFB_CPPFLAGS) +### +### EVENT_CPPFLAGS_INTERNAL += $(EGL_CPPFLAGS) +### +### $(eval $(call link-library,libevent,EVENT)) diff --git a/src/ui/canvas/Font.hpp b/src/ui/canvas/Font.hpp index 83e7802fa37..294b8e64d41 100644 --- a/src/ui/canvas/Font.hpp +++ b/src/ui/canvas/Font.hpp @@ -4,7 +4,7 @@ #pragma once #include "ui/dim/Size.hpp" -#include "util/tstring_view.hxx" +#include #if defined(USE_APPKIT) || defined(USE_UIKIT) #import @@ -104,17 +104,17 @@ class Font { #endif [[gnu::pure]] - PixelSize TextSize(tstring_view text) const noexcept; + PixelSize TextSize(std::string_view text) const noexcept; #if defined(USE_FREETYPE) || defined(USE_APPKIT) || defined(USE_UIKIT) static constexpr std::size_t BufferSize(const PixelSize size) noexcept { return std::size_t(size.width) * std::size_t(size.height); } - void Render(tstring_view text, const PixelSize size, + void Render(std::string_view text, const PixelSize size, void *buffer) const noexcept; #elif defined(ANDROID) - std::unique_ptr TextTextureGL(tstring_view text) const noexcept; + std::unique_ptr TextTextureGL(std::string_view text) const noexcept; #elif defined(USE_GDI) HFONT Native() const noexcept { return font; diff --git a/src/ui/canvas/android/Font.cpp b/src/ui/canvas/android/Font.cpp index cf55d5d05c3..026cf169624 100644 --- a/src/ui/canvas/android/Font.cpp +++ b/src/ui/canvas/android/Font.cpp @@ -37,7 +37,7 @@ Font::Destroy() noexcept } PixelSize -Font::TextSize(tstring_view text) const noexcept +Font::TextSize(std::string_view text) const noexcept { if (text_util_object == nullptr || text.empty()) return {0, 0}; @@ -46,7 +46,7 @@ Font::TextSize(tstring_view text) const noexcept } std::unique_ptr -Font::TextTextureGL(tstring_view text) const noexcept +Font::TextTextureGL(std::string_view text) const noexcept { if (!text_util_object) return {}; diff --git a/src/ui/canvas/apple/Font.cpp b/src/ui/canvas/apple/Font.cpp index 5f68d6da994..af13b815b23 100644 --- a/src/ui/canvas/apple/Font.cpp +++ b/src/ui/canvas/apple/Font.cpp @@ -88,7 +88,7 @@ Font::Load(const FontDescription &d) } PixelSize -Font::TextSize(const tstring_view text) const noexcept +Font::TextSize(const std::string_view text) const noexcept { assert(nil != draw_attributes); @@ -106,7 +106,7 @@ Font::TextSize(const tstring_view text) const noexcept } void -Font::Render(tstring_view text, const PixelSize size, +Font::Render(std::string_view text, const PixelSize size, void *buffer) const noexcept { assert(nil != draw_attributes); diff --git a/src/ui/canvas/custom/Bitmap.cpp b/src/ui/canvas/custom/Bitmap.cpp index 5f202f41676..b9cb59bcadb 100644 --- a/src/ui/canvas/custom/Bitmap.cpp +++ b/src/ui/canvas/custom/Bitmap.cpp @@ -36,11 +36,11 @@ static UncompressedImage DecompressImageFile(Path path) { #ifdef USE_LIBTIFF - if (path.EndsWithIgnoreCase(_T(".tif")) || path.EndsWithIgnoreCase(_T(".tiff"))) + if (path.EndsWithIgnoreCase(".tif") || path.EndsWithIgnoreCase(".tiff")) return LoadTiff(path); #endif - if (path.EndsWithIgnoreCase(_T(".png"))) + if (path.EndsWithIgnoreCase(".png")) return LoadPNG(path); return LoadJPEGFile(path); diff --git a/src/ui/canvas/custom/Cache.cpp b/src/ui/canvas/custom/Cache.cpp index 04d0837a544..b0c43e2944a 100644 --- a/src/ui/canvas/custom/Cache.cpp +++ b/src/ui/canvas/custom/Cache.cpp @@ -6,7 +6,7 @@ #include "util/StaticCache.hxx" #include "util/StringCompare.hxx" #include "util/StringAPI.hxx" -#include "util/tstring_view.hxx" +#include #ifdef ENABLE_OPENGL #include "ui/canvas/opengl/Texture.hpp" @@ -15,10 +15,6 @@ #include "thread/Mutex.hxx" #endif -#ifdef UNICODE -#include "util/ConvertString.hpp" -#endif - #include #include @@ -169,11 +165,7 @@ TextCache::GetSize(const Font &font, std::string_view text) noexcept if (const PixelSize *cached = size_cache.Get(key)) return *cached; -#ifdef UNICODE - PixelSize size = font.TextSize(UTF8ToWideConverter(text)); -#else PixelSize size = font.TextSize(text); -#endif key.Allocate(); size_cache.Put(std::move(key), size); @@ -223,11 +215,7 @@ TextCache::Get(const Font &font, std::string_view text) noexcept /* render the text into a OpenGL texture */ #if defined(USE_FREETYPE) || defined(USE_APPKIT) || defined(USE_UIKIT) -#ifdef UNICODE - UTF8ToWideConverter text2(text); -#else std::string_view text2 = text; -#endif PixelSize size = font.TextSize(text2); size_t buffer_size = font.BufferSize(size); if (buffer_size == 0) diff --git a/src/ui/canvas/custom/GeoBitmap.cpp b/src/ui/canvas/custom/GeoBitmap.cpp index 05f26075da5..36a09cc2d03 100644 --- a/src/ui/canvas/custom/GeoBitmap.cpp +++ b/src/ui/canvas/custom/GeoBitmap.cpp @@ -22,8 +22,8 @@ GeoQuadrilateral Bitmap::LoadGeoFile([[maybe_unused]] Path path) { #ifdef USE_GEOTIFF - if (path.EndsWithIgnoreCase(_T(".tif")) || - path.EndsWithIgnoreCase(_T(".tiff"))) { + if (path.EndsWithIgnoreCase(".tif") || + path.EndsWithIgnoreCase(".tiff")) { auto result = LoadGeoTiff(path); if (!Load(std::move(result.first))) throw std::runtime_error("Failed to use geo image file"); diff --git a/src/ui/canvas/custom/LibJPEG.cpp b/src/ui/canvas/custom/LibJPEG.cpp index 2d1a46f7cb0..6d42096dbca 100644 --- a/src/ui/canvas/custom/LibJPEG.cpp +++ b/src/ui/canvas/custom/LibJPEG.cpp @@ -30,7 +30,7 @@ JpegErrorExit(j_common_ptr cinfo) UncompressedImage LoadJPEGFile(Path path) { - FILE *file = _tfopen(path.c_str(), _T("rb")); + FILE *file = _tfopen(path.c_str(), "rb"); if (file == nullptr) return UncompressedImage(); diff --git a/src/ui/canvas/custom/LibTiff.cpp b/src/ui/canvas/custom/LibTiff.cpp index b8b6adfc9c0..2952f8f331b 100644 --- a/src/ui/canvas/custom/LibTiff.cpp +++ b/src/ui/canvas/custom/LibTiff.cpp @@ -26,11 +26,7 @@ TiffOpen(Path path, const char *mode) XTIFFInitialize(); #endif -#ifdef _UNICODE - return TIFFOpenW(path.c_str(), mode); -#else return TIFFOpen(path.c_str(), mode); -#endif } class TiffLoader { diff --git a/src/ui/canvas/custom/MoreCanvas.cpp b/src/ui/canvas/custom/MoreCanvas.cpp index 00405b5266d..c53f2d92cc5 100644 --- a/src/ui/canvas/custom/MoreCanvas.cpp +++ b/src/ui/canvas/custom/MoreCanvas.cpp @@ -37,13 +37,10 @@ Canvas::DrawRaisedEdge(PixelRect &rc) noexcept } unsigned -Canvas::DrawFormattedText(const PixelRect r, const tstring_view text, +Canvas::DrawFormattedText(const PixelRect r, const std::string_view text, const unsigned format) noexcept { -#ifndef UNICODE assert(ValidateUTF8(text)); -#endif - if (font == nullptr) return 0; @@ -52,41 +49,41 @@ Canvas::DrawFormattedText(const PixelRect r, const tstring_view text, ? UINT_MAX : (r.GetHeight() + skip - 1) / skip; - TCHAR *const duplicated = new TCHAR[text.size() + 1], *p = duplicated; + char *const duplicated = new char[text.size() + 1], *p = duplicated; unsigned lines = 1; - for (TCHAR ch : text) { - if (ch == _T('\n')) { + for (char ch : text) { + if (ch == '\n') { /* explicit line break */ if (++lines > max_lines) break; - ch = _T('\0'); - } else if (ch == _T('\r')) + ch = '\0'; + } else if (ch == '\r') /* skip */ continue; else if ((unsigned)ch < 0x20) /* replace non-printable characters */ - ch = _T(' '); + ch = ' '; *p++ = ch; } - *p = _T('\0'); + *p = '\0'; const size_t len = p - duplicated; // simple wordbreak algorithm. looks for single spaces only, no tabs, // no grouping of multiple spaces - for (size_t i = 0; i < len; i += _tcslen(duplicated + i) + 1) { + for (size_t i = 0; i < len; i += strlen(duplicated + i) + 1) { PixelSize sz = CalcTextSize(duplicated + i); - TCHAR *prev_p = nullptr; + char *prev_p = nullptr; // remove words from behind till line fits or no more space is found while (sz.width > r.GetWidth() && - (p = StringFindLast(duplicated + i, _T(' '))) != nullptr) { + (p = StringFindLast(duplicated + i, ' ')) != nullptr) { if (prev_p) - *prev_p = _T(' '); - *p = _T('\0'); + *prev_p = ' '; + *p = '\0'; prev_p = p; sz = CalcTextSize(duplicated + i); } @@ -106,8 +103,8 @@ Canvas::DrawFormattedText(const PixelRect r, const tstring_view text, int y = (format & DT_VCENTER) && lines < max_lines ? (r.top + r.bottom - lines * skip) / 2 : r.top; - for (size_t i = 0; i < len; i += _tcslen(duplicated + i) + 1) { - if (duplicated[i] != _T('\0')) { + for (size_t i = 0; i < len; i += strlen(duplicated + i) + 1) { + if (duplicated[i] != '\0') { int x; if (format & (DT_RIGHT | DT_CENTER)) { PixelSize sz = CalcTextSize(duplicated + i); @@ -135,7 +132,7 @@ Canvas::DrawFormattedText(const PixelRect r, const tstring_view text, void Canvas::DrawOpaqueText(PixelPoint p, const PixelRect &rc, - tstring_view text) noexcept + std::string_view text) noexcept { DrawFilledRectangle(rc, background_color); DrawTransparentText(p, text); diff --git a/src/ui/canvas/freetype/Font.cpp b/src/ui/canvas/freetype/Font.cpp index 517e2e87034..4c85e84cfae 100644 --- a/src/ui/canvas/freetype/Font.cpp +++ b/src/ui/canvas/freetype/Font.cpp @@ -14,9 +14,7 @@ #include "thread/Mutex.hxx" #endif -#ifndef _UNICODE #include "util/UTF8.hpp" -#endif #if defined(__clang__) && defined(__arm__) /* work around warning: 'register' storage class specifier is @@ -77,19 +75,13 @@ FT_CEIL(FT_Long x) noexcept [[gnu::pure]] static unsigned -NextChar(tstring_view &s) noexcept +NextChar(std::string_view &s) noexcept { assert(!s.empty()); -#ifdef _UNICODE - const unsigned ch = s.front(); - s.remove_prefix(1); - return ch; -#else auto n = NextUTF8(s.data()); s.remove_prefix(n.second - s.data()); return n.first; -#endif } void @@ -211,11 +203,9 @@ Font::Destroy() noexcept } static void -ForEachChar(tstring_view text, std::invocable auto f) +ForEachChar(std::string_view text, std::invocable auto f) { -#ifndef _UNICODE assert(ValidateUTF8(text)); -#endif while (!text.empty()) { const unsigned ch = NextChar(text); @@ -271,7 +261,7 @@ ForEachGlyph(const FT_Face face, unsigned ascent_height, T &&text, } PixelSize -Font::TextSize(tstring_view text) const noexcept +Font::TextSize(std::string_view text) const noexcept { int maxx = 0; @@ -380,7 +370,7 @@ RenderGlyph(uint8_t *buffer, size_t width, size_t height, } void -Font::Render(tstring_view text, const PixelSize size, +Font::Render(std::string_view text, const PixelSize size, void *_buffer) const noexcept { uint8_t *buffer = (uint8_t *)_buffer; diff --git a/src/ui/canvas/gdi/Canvas.cpp b/src/ui/canvas/gdi/Canvas.cpp index 413b130af1f..53831f8f124 100644 --- a/src/ui/canvas/gdi/Canvas.cpp +++ b/src/ui/canvas/gdi/Canvas.cpp @@ -7,9 +7,31 @@ #include "Asset.hpp" /* for needclipping */ #include "AlphaBlend.hpp" #include "Math/Angle.hpp" +#include "util/UTF8.hpp" #include +static bool UTF8TextOut(HDC hdc, const PixelPoint &p, unsigned options, const RECT *r, + std::string_view _text, const int *lpDx) { + auto text = UTF8ToWide(_text); +#if 1 + return ::ExtTextOutW(hdc, p.x, p.y, options, r, text.c_str(), text.size(), + lpDx); +#else + unsigned format = DT_NOPREFIX | DT_WORDBREAK | DT_LEFT; + RECT rx = {p.x, p.y, 0, 0}; + int h = 0; + if (r) + rx = {r->left + p.x, r->top + p.y, r->right - r->left, r->bottom - r->top}; + + // calculate the rectangle... + h = ::DrawTextW(hdc, text.c_str(), text.size(), &rx, DT_CALCRECT); + // and paint... + h = ::DrawTextW(hdc, text.c_str(), text.size(), &rx, format); + return true; +#endif +} + void Canvas::DrawLine(int ax, int ay, int bx, int by) { @@ -87,12 +109,16 @@ Canvas::DrawArc(PixelPoint center, unsigned radius, } const PixelSize -Canvas::CalcTextSize(tstring_view text) const noexcept +Canvas::CalcTextSize(std::string_view _text) const noexcept { assert(IsDefined()); + // std::string_view text = UTF8ToWide(_text.data()); + auto text = UTF8ToWide(_text); + // std::wstring text = UTF8ToWide(_text.data()); + SIZE size; - ::GetTextExtentPoint(dc, text.data(), text.size(), &size); + ::GetTextExtentPointW(dc, text.c_str(), text.size(), &size); return PixelSize(size.cx, size.cy); } @@ -107,46 +133,43 @@ Canvas::GetFontHeight() const } void -Canvas::DrawText(PixelPoint p, tstring_view text) noexcept +Canvas::DrawText(PixelPoint p, std::string_view text) noexcept { assert(IsDefined()); - ::ExtTextOut(dc, p.x, p.y, 0, nullptr, text.data(), text.size(), nullptr); + UTF8TextOut(dc, p, 0, nullptr, text, nullptr); } void Canvas::DrawOpaqueText(PixelPoint p, const PixelRect &_rc, - tstring_view text) noexcept + std::string_view text) noexcept { assert(IsDefined()); RECT rc = _rc; - ::ExtTextOut(dc, p.x, p.y, ETO_OPAQUE, &rc, - text.data(), text.size(), nullptr); + UTF8TextOut(dc, p, ETO_OPAQUE, &rc, text,nullptr); } void Canvas::DrawClippedText(PixelPoint p, const PixelRect &_rc, - tstring_view text) noexcept + std::string_view text) noexcept { assert(IsDefined()); RECT rc = _rc; - ::ExtTextOut(dc, p.x, p.y, ETO_CLIPPED, &rc, - text.data(), text.size(), nullptr); + UTF8TextOut(dc, p, ETO_CLIPPED, &rc, text, nullptr); } void Canvas::DrawClippedText(PixelPoint p, unsigned width, - tstring_view text) noexcept + std::string_view text) noexcept { const PixelSize size = CalcTextSize(text); RECT rc; ::SetRect(&rc, p.x, p.y, p.x + std::min(width, size.width), p.y + size.height); - ::ExtTextOut(dc, p.x, p.y, ETO_CLIPPED, &rc, - text.data(), text.size(), nullptr); + UTF8TextOut(dc, p, ETO_CLIPPED, &rc, text,nullptr); } void @@ -324,3 +347,12 @@ Canvas::AlphaBlend(PixelPoint dest_position, PixelSize dest_size, } #endif + +unsigned +Canvas::DrawFormattedText(RECT rc, std::string_view _text, unsigned format) { + format |= DT_NOPREFIX | DT_WORDBREAK; + auto text = UTF8ToWide(_text); + + ::DrawTextW(dc, text.data(), text.size(), &rc, format); + return rc.bottom - rc.top; +} diff --git a/src/ui/canvas/gdi/Canvas.hpp b/src/ui/canvas/gdi/Canvas.hpp index ea16083c437..1a0e1a712ee 100644 --- a/src/ui/canvas/gdi/Canvas.hpp +++ b/src/ui/canvas/gdi/Canvas.hpp @@ -9,7 +9,7 @@ #include "ui/canvas/Pen.hpp" #include "ui/dim/Rect.hpp" #include "ui/dim/BulkPoint.hpp" -#include "util/tstring_view.hxx" +#include #include @@ -227,9 +227,10 @@ class Canvas { const RECT rc = _rc; /* this hack allows filling a rectangle with a solid color, - without the need to create a HBRUSH */ + * without the need to create a HBRUSH + * Here is no need to use UTF8TextOut - because all strings are empty */ ::SetBkColor(dc, color); - ::ExtTextOut(dc, rc.left, rc.top, ETO_OPAQUE, &rc, _T(""), 0, nullptr); + ::ExtTextOut(dc, rc.left, rc.top, ETO_OPAQUE, &rc, "", 0, nullptr); } void DrawFilledRectangle(const PixelRect &rc, const Color color) { @@ -358,37 +359,33 @@ class Canvas { } [[gnu::pure]] - const PixelSize CalcTextSize(tstring_view text) const noexcept; + const PixelSize CalcTextSize(std::string_view text) const noexcept; [[gnu::pure]] - unsigned CalcTextWidth(tstring_view text) const { + unsigned CalcTextWidth(std::string_view text) const { return CalcTextSize(text).width; } [[gnu::pure]] unsigned GetFontHeight() const; - void DrawText(PixelPoint p, tstring_view text) noexcept; + void DrawText(PixelPoint p, std::string_view text) noexcept; void DrawOpaqueText(PixelPoint p, const PixelRect &rc, - tstring_view text) noexcept; + std::string_view text) noexcept; void DrawClippedText(PixelPoint p, const PixelRect &rc, - tstring_view text) noexcept; + std::string_view text) noexcept; void DrawClippedText(PixelPoint p, unsigned width, - tstring_view text) noexcept; + std::string_view text) noexcept; /** * Render text, clip it within the bounds of this Canvas. */ - void TextAutoClipped(PixelPoint p, tstring_view t) noexcept { - DrawText(p, t); + void TextAutoClipped(PixelPoint p, std::string_view text) noexcept { + DrawText(p, text); } - unsigned DrawFormattedText(RECT rc, tstring_view text, unsigned format) { - format |= DT_NOPREFIX | DT_WORDBREAK; - ::DrawText(dc, text.data(), text.size(), &rc, format); - return rc.bottom - rc.top; - } + unsigned DrawFormattedText(RECT rc, std::string_view _text, unsigned format); void Copy(PixelPoint dest_position, PixelSize dest_size, HDC src, PixelPoint src_position, diff --git a/src/ui/canvas/gdi/Font.cpp b/src/ui/canvas/gdi/Font.cpp index f271e45153c..9ae6e499d09 100644 --- a/src/ui/canvas/gdi/Font.cpp +++ b/src/ui/canvas/gdi/Font.cpp @@ -31,7 +31,7 @@ Font::Load(const FontDescription &d) } PixelSize -Font::TextSize(tstring_view text) const noexcept +Font::TextSize(std::string_view text) const noexcept { AnyCanvas canvas; canvas.Select(*this); diff --git a/src/ui/canvas/gdi/GdiPlusBitmap.cpp b/src/ui/canvas/gdi/GdiPlusBitmap.cpp index 047772492f0..90d6d826f83 100644 --- a/src/ui/canvas/gdi/GdiPlusBitmap.cpp +++ b/src/ui/canvas/gdi/GdiPlusBitmap.cpp @@ -2,6 +2,7 @@ // Copyright The XCSoar Project #include "GdiPlusBitmap.hpp" +#include "util/UTF8.hpp" #if defined(_MSC_VER) # include @@ -9,6 +10,7 @@ using std::min; // to avoid the missing 'min' in the gdiplush headers using std::max; // to avoid the missing 'max' in the gdiplush headers #endif // _MSC_VER + #include #include #include @@ -33,16 +35,14 @@ GdiShutdown() //---------------------------------------------------------------------------- // can load: BMP, GIF, JPEG, PNG, TIFF, Exif, WMF, and EMF HBITMAP -GdiLoadImage(const TCHAR* filename) +GdiLoadImage(const char* filename) { HBITMAP result = nullptr; -#ifdef _UNICODE // TCHAR has to be WCHAR in GdiPlus - Gdiplus::Bitmap bitmap(filename, false); + Gdiplus::Bitmap bitmap(UTF8ToWide(filename).c_str(), false); if (bitmap.GetLastStatus() != Gdiplus::Ok) return nullptr; const Gdiplus::Color color = Gdiplus::Color::White; if (bitmap.GetHBITMAP(color, &result) != Gdiplus::Ok) return nullptr; -#endif // _UNICODE return result; } diff --git a/src/ui/canvas/gdi/GdiPlusBitmap.hpp b/src/ui/canvas/gdi/GdiPlusBitmap.hpp index a7d284cc5f5..6b83bbbb3b5 100644 --- a/src/ui/canvas/gdi/GdiPlusBitmap.hpp +++ b/src/ui/canvas/gdi/GdiPlusBitmap.hpp @@ -8,7 +8,7 @@ #include #include -HBITMAP GdiLoadImage(const TCHAR* filename); +HBITMAP GdiLoadImage(const char* filename); void GdiStartup(); void GdiShutdown(); #endif // _WIN32 && USE_GDI diff --git a/src/ui/canvas/gdi/ResourceBitmap.cpp b/src/ui/canvas/gdi/ResourceBitmap.cpp index d045577c769..bd7ee2de84a 100644 --- a/src/ui/canvas/gdi/ResourceBitmap.cpp +++ b/src/ui/canvas/gdi/ResourceBitmap.cpp @@ -20,7 +20,7 @@ Bitmap::Load(ResourceId id, [[maybe_unused]] Type type) { Reset(); - bitmap = ResourceLoader::LoadBitmap2(id); + bitmap = ResourceLoader::LoadResBitmap(id); return bitmap != nullptr; } diff --git a/src/ui/canvas/memory/Canvas.cpp b/src/ui/canvas/memory/Canvas.cpp index a4552183638..34e0f71d562 100644 --- a/src/ui/canvas/memory/Canvas.cpp +++ b/src/ui/canvas/memory/Canvas.cpp @@ -17,10 +17,6 @@ #include "util/UTF8.hpp" #endif -#ifdef UNICODE -#include "util/ConvertString.hpp" -#endif - #include #include #include @@ -200,14 +196,10 @@ Canvas::DrawArc(PixelPoint center, unsigned radius, } const PixelSize -Canvas::CalcTextSize(tstring_view text) const noexcept +Canvas::CalcTextSize(std::string_view text) const noexcept { -#ifdef UNICODE - const WideToUTF8Converter text2(text); -#else const std::string_view text2 = text; assert(ValidateUTF8(text)); -#endif PixelSize size = { 0, 0 }; @@ -223,18 +215,14 @@ Canvas::CalcTextSize(tstring_view text) const noexcept } static TextCache::Result -RenderText(const Font *font, tstring_view text) noexcept +RenderText(const Font *font, std::string_view text) noexcept { if (font == nullptr) return nullptr; assert(font->IsDefined()); -#ifdef UNICODE - return TextCache::Get(*font, WideToUTF8Converter(text)); -#else return TextCache::Get(*font, text); -#endif } template @@ -268,12 +256,9 @@ CopyTextRectangle(SDLRasterCanvas &canvas, int x, int y, } void -Canvas::DrawText(PixelPoint p, tstring_view text) noexcept +Canvas::DrawText(PixelPoint p, std::string_view text) noexcept { -#ifndef UNICODE assert(ValidateUTF8(text)); -#endif - auto s = RenderText(font, text); if (!s) return; @@ -285,11 +270,9 @@ Canvas::DrawText(PixelPoint p, tstring_view text) noexcept } void -Canvas::DrawTransparentText(PixelPoint p, tstring_view text) noexcept +Canvas::DrawTransparentText(PixelPoint p, std::string_view text) noexcept { -#ifndef UNICODE assert(ValidateUTF8(text)); -#endif auto s = RenderText(font, text); if (s.data == nullptr) @@ -303,7 +286,7 @@ Canvas::DrawTransparentText(PixelPoint p, tstring_view text) noexcept void Canvas::DrawClippedText(PixelPoint p, const PixelRect &rc, - tstring_view text) noexcept + std::string_view text) noexcept { // TODO: implement full clipping if (rc.right > p.x) @@ -312,11 +295,9 @@ Canvas::DrawClippedText(PixelPoint p, const PixelRect &rc, void Canvas::DrawClippedText(PixelPoint p, unsigned width, - tstring_view text) noexcept + std::string_view text) noexcept { -#ifndef UNICODE assert(ValidateUTF8(text)); -#endif auto s = RenderText(font, text); if (s.data == nullptr) diff --git a/src/ui/canvas/memory/Canvas.hpp b/src/ui/canvas/memory/Canvas.hpp index 1398d192a1b..07d761018ff 100644 --- a/src/ui/canvas/memory/Canvas.hpp +++ b/src/ui/canvas/memory/Canvas.hpp @@ -12,7 +12,7 @@ #include "PixelTraits.hpp" #include "Buffer.hpp" #include "ActivePixelTraits.hpp" -#include "util/tstring_view.hxx" +#include #include @@ -250,10 +250,10 @@ class Canvas { } [[gnu::pure]] - const PixelSize CalcTextSize(tstring_view text) const noexcept; + const PixelSize CalcTextSize(std::string_view text) const noexcept; [[gnu::pure]] - unsigned CalcTextWidth(tstring_view text) const noexcept { + unsigned CalcTextWidth(std::string_view text) const noexcept { return CalcTextSize(text).width; } @@ -262,22 +262,22 @@ class Canvas { return font != nullptr ? font->GetHeight() : 0; } - void DrawText(PixelPoint p, tstring_view text) noexcept; + void DrawText(PixelPoint p, std::string_view text) noexcept; - void DrawTransparentText(PixelPoint p, tstring_view text) noexcept; + void DrawTransparentText(PixelPoint p, std::string_view text) noexcept; void DrawOpaqueText(PixelPoint p, const PixelRect &rc, - tstring_view text) noexcept; + std::string_view text) noexcept; void DrawClippedText(PixelPoint p, const PixelRect &rc, - tstring_view text) noexcept; + std::string_view text) noexcept; void DrawClippedText(PixelPoint p, unsigned width, - tstring_view text) noexcept; + std::string_view text) noexcept; /** * Render text, clip it within the bounds of this Canvas. */ - void TextAutoClipped(PixelPoint p, tstring_view t) noexcept { + void TextAutoClipped(PixelPoint p, std::string_view t) noexcept { DrawText(p, t); } @@ -286,7 +286,7 @@ class Canvas { * * @return the resulting text height */ - unsigned DrawFormattedText(PixelRect r, tstring_view text, + unsigned DrawFormattedText(PixelRect r, std::string_view text, unsigned format) noexcept; void Copy(PixelPoint dest_position, PixelSize dest_size, diff --git a/src/ui/canvas/opengl/Canvas.cpp b/src/ui/canvas/opengl/Canvas.cpp index e206ce03bcc..22dca69ce18 100644 --- a/src/ui/canvas/opengl/Canvas.cpp +++ b/src/ui/canvas/opengl/Canvas.cpp @@ -25,10 +25,6 @@ #include #include -#ifdef UNICODE -#include "util/ConvertString.hpp" -#endif - #ifndef NDEBUG #include "util/UTF8.hpp" #endif @@ -77,8 +73,8 @@ Canvas::InvertRectangle(PixelRect r) noexcept glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); } -static tstring_view -ClipText(const Font &font, tstring_view text, +static std::string_view +ClipText(const Font &font, std::string_view text, int x, unsigned canvas_width) noexcept { if (text.empty() || x >= int(canvas_width)) @@ -539,14 +535,10 @@ Canvas::DrawFocusRectangle(PixelRect rc) noexcept } const PixelSize -Canvas::CalcTextSize(tstring_view text) const noexcept +Canvas::CalcTextSize(std::string_view text) const noexcept { -#ifdef UNICODE - const WideToUTF8Converter text2(text); -#else const std::string_view text2 = text; assert(ValidateUTF8(text)); -#endif PixelSize size = { 0, 0 }; @@ -572,14 +564,10 @@ PrepareColoredAlphaTexture(Color color) noexcept } void -Canvas::DrawText(PixelPoint p, tstring_view text) noexcept +Canvas::DrawText(PixelPoint p, std::string_view text) noexcept { -#ifdef UNICODE - const WideToUTF8Converter text2(text); -#else const std::string_view text2 = text; assert(ValidateUTF8(text)); -#endif assert(offset == OpenGL::translate); @@ -606,14 +594,10 @@ Canvas::DrawText(PixelPoint p, tstring_view text) noexcept } void -Canvas::DrawTransparentText(PixelPoint p, tstring_view text) noexcept +Canvas::DrawTransparentText(PixelPoint p, std::string_view text) noexcept { -#ifdef UNICODE - const WideToUTF8Converter text2(text); -#else const std::string_view text2 = text; assert(ValidateUTF8(text)); -#endif assert(offset == OpenGL::translate); @@ -638,14 +622,10 @@ Canvas::DrawTransparentText(PixelPoint p, tstring_view text) noexcept void Canvas::DrawClippedText(PixelPoint p, PixelSize size, - tstring_view text) noexcept + std::string_view text) noexcept { -#ifdef UNICODE - const WideToUTF8Converter text2(text); -#else const std::string_view text2 = text; assert(ValidateUTF8(text)); -#endif assert(offset == OpenGL::translate); diff --git a/src/ui/canvas/opengl/Canvas.hpp b/src/ui/canvas/opengl/Canvas.hpp index 5e4357000d8..c092073d297 100644 --- a/src/ui/canvas/opengl/Canvas.hpp +++ b/src/ui/canvas/opengl/Canvas.hpp @@ -274,10 +274,10 @@ class Canvas { void DrawFocusRectangle(PixelRect rc) noexcept; [[gnu::pure]] - const PixelSize CalcTextSize(tstring_view text) const noexcept; + const PixelSize CalcTextSize(std::string_view text) const noexcept; [[gnu::pure]] - unsigned CalcTextWidth(tstring_view text) const noexcept { + unsigned CalcTextWidth(std::string_view text) const noexcept { return CalcTextSize(text).width; } @@ -286,15 +286,15 @@ class Canvas { return font != nullptr ? font->GetHeight() : 0; } - void DrawText(PixelPoint p, tstring_view text) noexcept; + void DrawText(PixelPoint p, std::string_view text) noexcept; - void DrawTransparentText(PixelPoint p, tstring_view text) noexcept; + void DrawTransparentText(PixelPoint p, std::string_view text) noexcept; void DrawOpaqueText(PixelPoint p, const PixelRect &rc, - tstring_view text) noexcept; + std::string_view text) noexcept; void DrawClippedText(PixelPoint p, const PixelRect &rc, - tstring_view text) noexcept { + std::string_view text) noexcept { // XXX if (p.x < rc.right) @@ -302,17 +302,17 @@ class Canvas { } void DrawClippedText(PixelPoint p, PixelSize size, - tstring_view text) noexcept; + std::string_view text) noexcept; void DrawClippedText(PixelPoint p, unsigned width, - tstring_view text) noexcept { + std::string_view text) noexcept { DrawClippedText(p, {width, 16384u}, text); } /** * Render text, clip it within the bounds of this Canvas. */ - void TextAutoClipped(PixelPoint p, tstring_view t) noexcept { + void TextAutoClipped(PixelPoint p, std::string_view t) noexcept { if (p.x < (int)GetWidth() && p.y < (int)GetHeight()) DrawClippedText(p, {GetWidth() - p.x, GetHeight() - p.y}, t); } @@ -322,7 +322,7 @@ class Canvas { * * @return the resulting text height */ - unsigned DrawFormattedText(PixelRect r, tstring_view text, + unsigned DrawFormattedText(PixelRect r, std::string_view text, unsigned format) noexcept; /** diff --git a/src/ui/canvas/opengl/TopCanvas.cpp b/src/ui/canvas/opengl/TopCanvas.cpp index 1ab3d5ec89f..8533538cdbe 100644 --- a/src/ui/canvas/opengl/TopCanvas.cpp +++ b/src/ui/canvas/opengl/TopCanvas.cpp @@ -38,7 +38,14 @@ PixelSize TopCanvas::SetDisplayOrientation(DisplayOrientation orientation) noexcept { OpenGL::display_orientation = orientation; +#if defined (IS_OPENVARIO) + // Workaround: ask this one time .. and change it never + static const PixelSize _size(OpenGL::window_size.x, + OpenGL::window_size.y); + return SetupViewport(_size); +#else return SetupViewport({OpenGL::window_size.x, OpenGL::window_size.y}); +#endif } #endif diff --git a/src/ui/control/LargeTextWindow.hpp b/src/ui/control/LargeTextWindow.hpp index 52ff28922aa..d0d275f2512 100644 --- a/src/ui/control/LargeTextWindow.hpp +++ b/src/ui/control/LargeTextWindow.hpp @@ -7,7 +7,7 @@ #ifndef USE_WINUSER #include "Renderer/TextRenderer.hpp" -#include "util/tstring.hpp" +#include #endif #include @@ -36,7 +36,7 @@ class LargeTextWindow : public NativeWindow { #ifndef USE_WINUSER const Font *font = nullptr; - tstring value; + std::string value; /** * The first visible line. @@ -77,7 +77,7 @@ class LargeTextWindow : public NativeWindow { } #endif - void SetText(const TCHAR *text); + void SetText(const char *text); /** * Scroll the contents of a multi-line control by the specified diff --git a/src/ui/control/TerminalWindow.cpp b/src/ui/control/TerminalWindow.cpp index a5d6e849430..ae7d9f6217d 100644 --- a/src/ui/control/TerminalWindow.cpp +++ b/src/ui/control/TerminalWindow.cpp @@ -76,7 +76,7 @@ void TerminalWindow::OnCreate() { PaintWindow::OnCreate(); - cell_size = look.font.TextSize(_T("W")); + cell_size = look.font.TextSize("W"); cursor_x = 0; cursor_y = 0; data.Reset(); diff --git a/src/ui/control/TerminalWindow.hpp b/src/ui/control/TerminalWindow.hpp index 2bdae608bda..395033ead3f 100644 --- a/src/ui/control/TerminalWindow.hpp +++ b/src/ui/control/TerminalWindow.hpp @@ -17,7 +17,7 @@ class TerminalWindow : public PaintWindow { unsigned cursor_x, cursor_y; PixelSize cell_size; - AllocatedGrid data; + AllocatedGrid data; public: TerminalWindow(const TerminalLook &_look):look(_look) {} diff --git a/src/ui/control/custom/LargeTextWindow.cpp b/src/ui/control/custom/LargeTextWindow.cpp index 923b5056367..cacb461d6ca 100644 --- a/src/ui/control/custom/LargeTextWindow.cpp +++ b/src/ui/control/custom/LargeTextWindow.cpp @@ -25,9 +25,9 @@ LargeTextWindow::GetVisibleRows() const unsigned LargeTextWindow::GetRowCount() const { - const TCHAR *str = value.c_str(); + const char *str = value.c_str(); unsigned row_count = 1; - while ((str = StringFind(str, _T('\n'))) != nullptr) { + while ((str = StringFind(str, '\n')) != nullptr) { str++; row_count++; } @@ -179,7 +179,7 @@ LargeTextWindow::OnMouseDown([[maybe_unused]] PixelPoint p) noexcept } void -LargeTextWindow::SetText(const TCHAR *text) +LargeTextWindow::SetText(const char *text) { if (text != nullptr) value = text; diff --git a/src/ui/control/gdi/LargeTextWindow.cpp b/src/ui/control/gdi/LargeTextWindow.cpp index b37d9bd8094..bb7e828193a 100644 --- a/src/ui/control/gdi/LargeTextWindow.cpp +++ b/src/ui/control/gdi/LargeTextWindow.cpp @@ -17,31 +17,31 @@ LargeTextWindow::Create(ContainerWindow &parent, PixelRect rc, } void -LargeTextWindow::SetText(const TCHAR *text) +LargeTextWindow::SetText(const char *text) { // Replace \n by \r\r\n to enable usage of line-breaks in edit control - unsigned size = _tcslen(text); + unsigned size = strlen(text); - const std::unique_ptr allocation(new TCHAR[size * 3 + 1]); - TCHAR *buffer = allocation.get(); + const std::unique_ptr allocation(new char[size * 3 + 1]); + char *buffer = allocation.get(); - const TCHAR* p2 = text; - TCHAR* p3 = buffer; - for (; *p2 != _T('\0'); p2++) { - if (*p2 == _T('\n')) { - *p3 = _T('\r'); + const char* p2 = text; + char* p3 = buffer; + for (; *p2 != '\0'; p2++) { + if (*p2 == '\n') { + *p3 = '\r'; p3++; - *p3 = _T('\r'); + *p3 = '\r'; p3++; - *p3 = _T('\n'); - } else if (*p2 == _T('\r')) { + *p3 = '\n'; + } else if (*p2 == '\r') { continue; } else { *p3 = *p2; } p3++; } - *p3 = _T('\0'); + *p3 = '\0'; ::SetWindowText(hWnd, buffer); } diff --git a/src/ui/event/android/Loop.cpp b/src/ui/event/android/Loop.cpp index ba5271e8642..bd3619bab8c 100644 --- a/src/ui/event/android/Loop.cpp +++ b/src/ui/event/android/Loop.cpp @@ -38,7 +38,7 @@ EventLoop::Dispatch(const Event &event) if (event.type == Event::TIMER) { Timer *timer = (Timer *)event.ptr; timer->Invoke(); - } else if (event.type == Event::CALLBACK) { + } else if (event.type == Event::CALLBACK_) { event.callback(event.ptr); } else if (event.type != Event::NOP) top_window.OnEvent(event); diff --git a/src/ui/event/android/Queue.cpp b/src/ui/event/android/Queue.cpp index a053c909c05..99c3c8ed60b 100644 --- a/src/ui/event/android/Queue.cpp +++ b/src/ui/event/android/Queue.cpp @@ -99,7 +99,7 @@ static bool MatchCallback(const Event &event, void *ctx) noexcept { const Event *match = (const Event *)ctx; - return event.type == Event::CALLBACK && event.callback == match->callback && + return event.type == Event::CALLBACK_ && event.callback == match->callback && event.ptr == match->ptr; } diff --git a/src/ui/event/poll/InputQueue.hpp b/src/ui/event/poll/InputQueue.hpp index 9946f387984..4c215579e61 100644 --- a/src/ui/event/poll/InputQueue.hpp +++ b/src/ui/event/poll/InputQueue.hpp @@ -37,6 +37,8 @@ class InputEventQueue final { void SetScreenSize(PixelSize screen_size) noexcept { #ifdef USE_LIBINPUT libinput_handler.SetScreenSize(screen_size); + #elif defined(_WIN32) + // TODO(August2111): needs work? #else merge_mouse.SetScreenSize(screen_size); #endif @@ -44,13 +46,20 @@ class InputEventQueue final { #ifndef USE_LIBINPUT void SetDisplayOrientation(DisplayOrientation orientation) { +#if defined(_WIN32) + // TODO(August2111): needs work? +#else merge_mouse.SetDisplayOrientation(orientation); +#endif } #endif bool HasPointer() const noexcept { #ifdef USE_LIBINPUT return libinput_handler.HasPointer(); +#elif defined(_WIN32) + // TODO(August2111): needs work? + return false; #else return merge_mouse.HasPointer(); #endif @@ -69,6 +78,9 @@ class InputEventQueue final { PixelPoint GetMousePosition() const noexcept { #ifdef USE_LIBINPUT return PixelPoint(libinput_handler.GetX(), libinput_handler.GetY()); +#elif defined(_WIN32) + // TODO(August2111): needs work? + return PixelPoint(0, 0); #else return merge_mouse.GetPosition(); #endif diff --git a/src/ui/event/poll/Loop.cpp b/src/ui/event/poll/Loop.cpp index 06ea9ca0492..53d0db7099a 100644 --- a/src/ui/event/poll/Loop.cpp +++ b/src/ui/event/poll/Loop.cpp @@ -36,7 +36,7 @@ EventLoop::Get(Event &event) void EventLoop::Dispatch(const Event &event) { - if (event.type == Event::CALLBACK) { + if (event.type == Event::CALLBACK_) { event.callback(event.ptr); } else if (top_window != nullptr && event.type != Event::NOP) { #ifndef NON_INTERACTIVE diff --git a/src/ui/event/poll/Queue.cpp b/src/ui/event/poll/Queue.cpp index c2d6bfbd7fe..3e63786b1a2 100644 --- a/src/ui/event/poll/Queue.cpp +++ b/src/ui/event/poll/Queue.cpp @@ -164,7 +164,7 @@ static bool MatchCallback(const Event &event, void *ctx) noexcept { const Event *match = (const Event *)ctx; - return event.type == Event::CALLBACK && event.callback == match->callback && + return event.type == Event::CALLBACK_ && event.callback == match->callback && event.ptr == match->ptr; } diff --git a/src/ui/event/shared/Event.hpp b/src/ui/event/shared/Event.hpp index b3ec87cae33..8a9d4b387f2 100644 --- a/src/ui/event/shared/Event.hpp +++ b/src/ui/event/shared/Event.hpp @@ -19,7 +19,7 @@ struct Event { TIMER, #endif - CALLBACK, + CALLBACK_, KEY_DOWN, KEY_UP, @@ -111,7 +111,7 @@ struct Event { :type(_type), param(_param), ptr(_ptr) {} Event(Type _type, void *_ptr):type(_type), ptr(_ptr) {} Event(Callback _callback, void *_ptr) - :type(CALLBACK), ptr(_ptr), callback(_callback) {} + :type(CALLBACK_), ptr(_ptr), callback(_callback) {} Event(Type _type, PixelPoint _point) :type(_type), point(_point) {} diff --git a/src/ui/event/windows/Queue.cpp b/src/ui/event/windows/Queue.cpp index accc930f83d..7cfe7bbdff9 100644 --- a/src/ui/event/windows/Queue.cpp +++ b/src/ui/event/windows/Queue.cpp @@ -41,8 +41,22 @@ EventQueue::Wait(Event &event) /* check for WIN32 event */ - if (::PeekMessage(&event.msg, nullptr, 0, 0, PM_REMOVE)) + if (::PeekMessage(&event.msg, nullptr, 0, 0, PM_REMOVE)) { + #ifdef __AUGUST__ + /* TODO(August2111): + On Windows: if 'Restart' is selected a wrong (?) WM_QUIT is in the + event_loop - and closes the app immediately... ;-( + Bugfix/Workaround: With this handling the restart is OK + */ + static unsigned count = 0; + if (event.msg.message != WM_QUIT) + return true; + else + return (count++ & 1); +#else // __AUGUST__ return event.msg.message != WM_QUIT; +#endif // __AUGUST__ + } const DWORD n = 1; const LPHANDLE handles = &trigger; diff --git a/src/ui/window/ContainerWindow.cpp b/src/ui/window/ContainerWindow.cpp index 2cd17f51806..c8526999ca2 100644 --- a/src/ui/window/ContainerWindow.cpp +++ b/src/ui/window/ContainerWindow.cpp @@ -3,6 +3,8 @@ #include "ContainerWindow.hpp" +unsigned ContainerWindow::exit_value = 0; + void ContainerWindow::ScrollTo(const PixelRect &rc) noexcept { diff --git a/src/ui/window/ContainerWindow.hpp b/src/ui/window/ContainerWindow.hpp index abb04cdfd58..64a66cc3756 100644 --- a/src/ui/window/ContainerWindow.hpp +++ b/src/ui/window/ContainerWindow.hpp @@ -15,6 +15,25 @@ class Brush; class WindowReference; #endif +enum ExitValues { + EXIT_NORMAL = 100, // 20002); + EXIT_SYSTEM = 200, // 20002); + EXIT_REBOOT = 201, // 20002); + EXIT_SHUTDOWN = 202, // 20002); + +#ifdef IS_OPENVARIO + LAUNCH_SHELL = 203, + LAUNCH_SHELL_STOP = 204, + START_UPGRADE = 205, + LAUNCH_TOUCH_CALIBRATE = 206, + EXIT_BASE_MENU = 207, +#endif + EXIT_RESTART = 208, +#ifdef IS_OPENVARIO + EXIT_NEWSTART = 209, +#endif +}; + /** * A container for more #Window objects. It is also derived from * #PaintWindow, because you might want to paint a border between the @@ -62,6 +81,8 @@ class ContainerWindow : public PaintWindow { virtual void OnPaint([[maybe_unused]] Canvas &canvas) noexcept {} #endif +static unsigned exit_value; + public: #ifndef USE_WINUSER void AddChild(Window &child) noexcept; @@ -160,4 +181,11 @@ class ContainerWindow : public PaintWindow { * rectangle visible in the view port. */ virtual void ScrollTo(const PixelRect &rc) noexcept; + + static void SetExitValue(unsigned value) { + exit_value = value; + } + static unsigned GetExitValue(void) { + return exit_value; + } }; diff --git a/src/ui/window/PaintWindow.hpp b/src/ui/window/PaintWindow.hpp index 476d9feacfe..17c32cbee8c 100644 --- a/src/ui/window/PaintWindow.hpp +++ b/src/ui/window/PaintWindow.hpp @@ -29,19 +29,19 @@ class PaintWindow : public Window { Create(&parent, rc, style); } #else /* USE_WINUSER */ - void Create(ContainerWindow *parent, const TCHAR *cls, PixelRect rc, + void Create(ContainerWindow *parent, const char *cls, PixelRect rc, const WindowStyle style=WindowStyle()) noexcept { Window::Create(parent, cls, nullptr, rc, style); } - void Create(ContainerWindow &parent, const TCHAR *cls, PixelRect rc, + void Create(ContainerWindow &parent, const char *cls, PixelRect rc, const WindowStyle style=WindowStyle()) noexcept { Create(&parent, cls, rc, style); } void Create(ContainerWindow &parent, PixelRect rc, const WindowStyle style=WindowStyle()) noexcept { - Create(parent, _T("PaintWindow"), rc, style); + Create(parent, "PaintWindow", rc, style); } #endif /* USE_WINUSER */ diff --git a/src/ui/window/SingleWindow.hpp b/src/ui/window/SingleWindow.hpp index 26a68a4f850..ddb4208cadb 100644 --- a/src/ui/window/SingleWindow.hpp +++ b/src/ui/window/SingleWindow.hpp @@ -20,7 +20,7 @@ struct Event; */ class SingleWindow : public TopWindow { #ifdef USE_WINUSER - static constexpr const TCHAR *class_name = _T("XCSoarMain"); + static constexpr const char *class_name = "XCSoarMain"; #endif std::forward_list dialogs; @@ -38,7 +38,7 @@ class SingleWindow : public TopWindow { /** * Throws on error. */ - void Create(const TCHAR *text, PixelSize size, + void Create(const char *text, PixelSize size, TopWindowStyle style=TopWindowStyle()) { #ifdef USE_WINUSER TopWindow::Create(class_name, text, size, style); diff --git a/src/ui/window/TopWindow.hpp b/src/ui/window/TopWindow.hpp index 212c7a460df..0ee348ffd57 100644 --- a/src/ui/window/TopWindow.hpp +++ b/src/ui/window/TopWindow.hpp @@ -232,10 +232,10 @@ class TopWindow : public ContainerWindow { * Throws on error. */ #ifdef USE_WINUSER - void Create(const TCHAR *cls, const TCHAR *text, PixelSize size, + void Create(const char *cls, const char *text, PixelSize size, TopWindowStyle style=TopWindowStyle()); #else - void Create(const TCHAR *text, PixelSize size, + void Create(const char *text, PixelSize size, TopWindowStyle style=TopWindowStyle()); #endif @@ -244,7 +244,7 @@ class TopWindow : public ContainerWindow { /** * Throws on error. */ - void CreateNative(const TCHAR *text, PixelSize size, + void CreateNative(const char *text, PixelSize size, TopWindowStyle style); public: @@ -261,9 +261,9 @@ class TopWindow : public ContainerWindow { #if !defined(USE_WINUSER) && !defined(ENABLE_SDL) #if defined(ANDROID) || defined(USE_FB) || defined(USE_EGL) || defined(USE_GLX) || defined(USE_VFB) - void SetCaption(const TCHAR *) noexcept {} + void SetCaption(const char *) noexcept {} #else - void SetCaption(const TCHAR *caption) noexcept; + void SetCaption(const char *caption) noexcept; #endif #endif diff --git a/src/ui/window/Window.hpp b/src/ui/window/Window.hpp index 9ca5e6595f2..644c241c471 100644 --- a/src/ui/window/Window.hpp +++ b/src/ui/window/Window.hpp @@ -237,7 +237,7 @@ class Window { void Create(ContainerWindow *parent, const PixelRect rc, const WindowStyle window_style=WindowStyle()) noexcept; #else - void Create(ContainerWindow *parent, const TCHAR *cls, const TCHAR *text, + void Create(ContainerWindow *parent, const char *cls, const char *text, const PixelRect rc, const WindowStyle window_style=WindowStyle()) noexcept; diff --git a/src/ui/window/android/TopWindow.cpp b/src/ui/window/android/TopWindow.cpp index b17be61a411..4eaa362c456 100644 --- a/src/ui/window/android/TopWindow.cpp +++ b/src/ui/window/android/TopWindow.cpp @@ -200,7 +200,7 @@ TopWindow::OnEvent(const Event &event) case Event::NOP: case Event::TIMER: - case Event::CALLBACK: + case Event::CALLBACK_: break; case Event::KEY_DOWN: diff --git a/src/ui/window/custom/TopWindow.cpp b/src/ui/window/custom/TopWindow.cpp index f341a65af88..51c8b7c8030 100644 --- a/src/ui/window/custom/TopWindow.cpp +++ b/src/ui/window/custom/TopWindow.cpp @@ -30,6 +30,8 @@ #include "Screen/Layout.hpp" #endif +#include "LogFile.hpp" + namespace UI { TopWindow::~TopWindow() noexcept @@ -42,7 +44,7 @@ TopWindow::~TopWindow() noexcept } void -TopWindow::Create([[maybe_unused]] const TCHAR *text, PixelSize size, +TopWindow::Create([[maybe_unused]] const char *text, PixelSize size, TopWindowStyle style) { invalidated = true; @@ -84,6 +86,7 @@ TopWindow::SetDisplayOrientation(DisplayOrientation orientation) noexcept assert(screen != nullptr); Resize(screen->SetDisplayOrientation(orientation)); + LogFmt("TopWindow::SetDisplayOrientation ({})", (unsigned) orientation); } #endif diff --git a/src/ui/window/gdi/TopWindow.cpp b/src/ui/window/gdi/TopWindow.cpp index 3a95c7db627..f551436b662 100644 --- a/src/ui/window/gdi/TopWindow.cpp +++ b/src/ui/window/gdi/TopWindow.cpp @@ -10,7 +10,7 @@ namespace UI { void -TopWindow::Create(const TCHAR *cls, const TCHAR *text, PixelSize size, +TopWindow::Create(const char *cls, const char *text, PixelSize size, TopWindowStyle style) { hSavedFocus = nullptr; diff --git a/src/ui/window/gdi/Window.cpp b/src/ui/window/gdi/Window.cpp index eef6b6ff2ff..318d093cedc 100644 --- a/src/ui/window/gdi/Window.cpp +++ b/src/ui/window/gdi/Window.cpp @@ -12,7 +12,7 @@ #include void -Window::Create(ContainerWindow *parent, const TCHAR *cls, const TCHAR *text, +Window::Create(ContainerWindow *parent, const char *cls, const char *text, PixelRect rc, const WindowStyle window_style) noexcept { assert(IsScreenInitialized()); @@ -38,7 +38,7 @@ Window::Create(ContainerWindow *parent, const TCHAR *cls, const TCHAR *text, void Window::CreateMessageWindow() noexcept { - hWnd = ::CreateWindowEx(0, _T("PaintWindow"), nullptr, 0, 0, 0, 0, 0, + hWnd = ::CreateWindowEx(0, "PaintWindow", nullptr, 0, 0, 0, 0, 0, HWND_MESSAGE, nullptr, nullptr, this); assert(hWnd != nullptr); @@ -233,7 +233,7 @@ Window::OnMessage([[maybe_unused]] HWND _hWnd, UINT message, break; case WM_CHAR: - if (OnCharacter((TCHAR)wParam)) + if (OnCharacter((char)wParam)) /* true returned: message was handled */ return 0; diff --git a/src/ui/window/poll/TopWindow.cpp b/src/ui/window/poll/TopWindow.cpp index 376aa27dbff..b96ca20430a 100644 --- a/src/ui/window/poll/TopWindow.cpp +++ b/src/ui/window/poll/TopWindow.cpp @@ -28,7 +28,7 @@ TopWindow::OnEvent(const Event &event) Window *w; case Event::NOP: - case Event::CALLBACK: + case Event::CALLBACK_: break; case Event::CLOSE: diff --git a/src/ui/window/sdl/TopWindow.cpp b/src/ui/window/sdl/TopWindow.cpp index 3d8a018a61a..561cc22476d 100644 --- a/src/ui/window/sdl/TopWindow.cpp +++ b/src/ui/window/sdl/TopWindow.cpp @@ -7,10 +7,6 @@ #include "lib/fmt/RuntimeError.hxx" #include "util/UTF8.hpp" -#ifdef UNICODE -#include "util/ConvertString.hpp" -#endif - #include #include @@ -54,15 +50,10 @@ MakeSDLFlags([[maybe_unused]] bool full_screen, bool resizable) noexcept } void -TopWindow::CreateNative(const TCHAR *_text, PixelSize new_size, +TopWindow::CreateNative(const char *_text, PixelSize new_size, TopWindowStyle style) { -#ifdef UNICODE - const WideToUTF8Converter text(_text); -#else const char *text = _text; -#endif - const bool full_screen = style.GetFullScreen(); const bool resizable = style.GetResizable(); const Uint32 flags = MakeSDLFlags(full_screen, resizable); diff --git a/src/ui/window/wayland/TopWindow.cpp b/src/ui/window/wayland/TopWindow.cpp index ecd6977f977..e392e72acf5 100644 --- a/src/ui/window/wayland/TopWindow.cpp +++ b/src/ui/window/wayland/TopWindow.cpp @@ -87,7 +87,7 @@ static const struct xdg_toplevel_listener toplevel_listener = { }; void -TopWindow::CreateNative(const TCHAR *text, PixelSize size, +TopWindow::CreateNative(const char *text, PixelSize size, TopWindowStyle) { auto compositor = event_queue->GetCompositor(); diff --git a/src/ui/window/x11/TopWindow.cpp b/src/ui/window/x11/TopWindow.cpp index 735c983d337..bac2b06aba1 100644 --- a/src/ui/window/x11/TopWindow.cpp +++ b/src/ui/window/x11/TopWindow.cpp @@ -21,7 +21,7 @@ namespace UI { void -TopWindow::CreateNative(const TCHAR *text, PixelSize size, +TopWindow::CreateNative(const char *text, PixelSize size, TopWindowStyle style) { const auto x_display = display.GetXDisplay(); diff --git a/src/unix/tchar.h b/src/unix/tchar.h index 542823c6cde..1388aee00f8 100644 --- a/src/unix/tchar.h +++ b/src/unix/tchar.h @@ -5,12 +5,11 @@ #ifdef LIBCXX /* libc++ uses "_T" as template argument names; this conflicts with - the macro "_T()" defined below. To work around that problem, - include all relevant libc++ headers before defining _T() */ + the macro "" defined below. To work around that problem, + include all relevant libc++ headers before defining */ #include #endif -typedef char TCHAR; #define _stprintf sprintf #define _vstprintf vsprintf #define _vsntprintf vsnprintf @@ -18,20 +17,8 @@ typedef char TCHAR; #define _ftprintf fprintf #define _vftprintf vfprintf #define _fputts fputs -#define _tcsdup strdup -#define _tcscpy strcpy -#define _tcscmp strcmp -#define _tcslen strlen -#define _tcsclen strlen -#define _tcsstr strstr -#define _tcspbrk strpbrk -#define _tcscat strcat -#define _T(x) x #define _topen open #define _tfopen fopen #define _TEOF EOF #define _putts puts #define _stscanf sscanf - -#define _tcstol strtol -#define _tcstod strtod diff --git a/src/util/ASCII.hxx b/src/util/ASCII.hxx index 5db82db7d0b..780eec6c6c3 100644 --- a/src/util/ASCII.hxx +++ b/src/util/ASCII.hxx @@ -6,10 +6,6 @@ #include #include -#ifdef _UNICODE -#include "WASCII.hxx" -#endif - /** * Copy all ASCII characters to the destination string * (i.e. 0x01..0x7f), ignoring the others. In the worst case, the diff --git a/src/util/AllocatedGrid.hxx b/src/util/AllocatedGrid.hxx index d588a050ae7..a4329e03490 100644 --- a/src/util/AllocatedGrid.hxx +++ b/src/util/AllocatedGrid.hxx @@ -140,13 +140,14 @@ public: const unsigned delta_w = _width - width; const auto end = array.begin(); - for (auto in = array.begin() + (h - 1) * width, - out = array.begin() + (h - 1) * _width + width; - in > end; in -= width, out -= delta_w) { - out = std::move_backward(in, in + width, out); - std::fill(out - delta_w, out, fill); - } - + if (h > 0) { + for (auto in = array.begin() + (h - 1) * width, + out = array.begin() + (h - 1) * _width + width; + in > end; in -= width, out -= delta_w) { + out = std::move_backward(in, in + width, out); + std::fill(out - delta_w, out, fill); + } + } width = _width; } diff --git a/src/util/BindMethod.hxx b/src/util/BindMethod.hxx index 38996030b2f..942ce1b7ac5 100644 --- a/src/util/BindMethod.hxx +++ b/src/util/BindMethod.hxx @@ -6,6 +6,10 @@ #include #include +#ifdef _MSC_VER +# define NoExcept true +#endif // _MSCVER + /** * This object stores a function pointer wrapping a method, and a * reference to an instance of the method's class. It can be used to @@ -17,7 +21,9 @@ template class BoundMethod; template class BoundMethod { using function_pointer = R (*)(void *, Args...) noexcept(NoExcept); @@ -63,7 +69,11 @@ namespace BindMethodDetail { template struct SignatureHelper; -template +template struct SignatureHelper { /** * The class which contains the given method (signature). @@ -79,7 +89,11 @@ struct SignatureHelper { using function_pointer = R (*)(void *, Args...) noexcept(NoExcept); }; -template +template struct SignatureHelper { using plain_signature = R (Args...) noexcept(NoExcept); @@ -94,7 +108,10 @@ struct SignatureHelper { template struct WrapperGenerator; -template struct WrapperGenerator { static R Invoke(void *_instance, Args... args) noexcept(NoExcept) { @@ -103,7 +120,11 @@ struct WrapperGenerator { } }; -template +template struct WrapperGenerator { static R Invoke(void *, Args... args) noexcept(NoExcept) { return function(std::forward(args)...); diff --git a/src/util/ByteOrder.hxx b/src/util/ByteOrder.hxx index 78bcc21df4f..c66ae9782c0 100644 --- a/src/util/ByteOrder.hxx +++ b/src/util/ByteOrder.hxx @@ -4,6 +4,7 @@ #pragma once #include +#include #if defined(__i386__) || defined(__x86_64__) || defined(__ARMEL__) /* well-known little-endian */ @@ -81,6 +82,9 @@ ByteSwap16(uint16_t value) noexcept { #ifdef __GNUC__ return __builtin_bswap16(value); +#elif _MSC_VER >= 2000 // 1500 - VS 2008 + // TODO(August2111): isn't possible with constexpr + return _byteswap_ushort(value); #else return GenericByteSwap16(value); #endif @@ -91,6 +95,8 @@ ByteSwap32(uint32_t value) noexcept { #ifdef __GNUC__ return __builtin_bswap32(value); +#elif _MSC_VER >= 2000 // 1500 - VS 2008 + return (const uint32_t)_byteswap_ulong(value); #else return GenericByteSwap32(value); #endif @@ -101,6 +107,8 @@ ByteSwap64(uint64_t value) noexcept { #ifdef __GNUC__ return __builtin_bswap64(value); +#elif _MSC_VER >= 2000 // 1500 - VS 2008 + return _byteswap_uint64(value); #else return GenericByteSwap64(value); #endif diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt new file mode 100644 index 00000000000..843c4b2d174 --- /dev/null +++ b/src/util/CMakeLists.txt @@ -0,0 +1,63 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +include(CMakeSource.cmake) +# organize the files in subdirectories + + +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + list(APPEND SOURCE_FILES ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +# if(${3RDPARTY_DEPENDENCIES}) # ON) +## if(OFF) + # message(STATUS "add_dependencies(${TARGET_NAME} ${BOOST_LIB} ${ZLIB_LIB} ${CARES_LIB} ${CURL_LIB} ${PNG_LIB} ${SODIUM_LIB} ${LUA_LIB})") +# add_dependencies(${TARGET_NAME} ${BOOST_LIB} ${ZLIB_LIB} ${CARES_LIB} ${CURL_LIB} ${PNG_LIB} ${SODIUM_LIB} ${LUA_LIB} ) + # message(FATAL_ERROR Stop!) + +## else() +## endif() + +add_dependencies(${TARGET_NAME} ${3RDPARTY_TARGETS}) + +# add_dependencies(${TARGET_NAME} boost zlib c-ares curl png lua_3rd) + diff --git a/src/util/CMakeSource.cmake b/src/util/CMakeSource.cmake new file mode 100644 index 00000000000..279b3975451 --- /dev/null +++ b/src/util/CMakeSource.cmake @@ -0,0 +1,23 @@ +set(_SOURCES + util/ASCII.cxx + util/CRC16CCITT.cpp + util/EscapeBackslash.cpp + util/Exception.cxx + util/PrintException.cxx + util/StaticString.cxx + util/StringBuilder.cxx + util/StringCompare.cxx + util/StringStrip.cxx + util/StringUtil.cpp + util/TruncateString.cpp + util/UTF8.cpp + util/MD5.cpp # new with 6.8.14 + util/DecimalParser.cxx # new with 7.40 +) + +set(SCRIPT_FILES + CMakeSource.cmake +) + + + diff --git a/src/util/CRC8.hpp b/src/util/CRC8.hpp index 2d8c3cdf794..e7d92c20bfd 100644 --- a/src/util/CRC8.hpp +++ b/src/util/CRC8.hpp @@ -4,6 +4,7 @@ #pragma once #include +#include #include constexpr std::byte diff --git a/src/util/CharUtil.hxx b/src/util/CharUtil.hxx index 3f111b3ac42..19780fa6442 100644 --- a/src/util/CharUtil.hxx +++ b/src/util/CharUtil.hxx @@ -3,10 +3,6 @@ #pragma once -#ifdef _UNICODE -#include "WCharUtil.hxx" -#endif - constexpr bool IsASCII(const unsigned char ch) noexcept { diff --git a/src/util/Compiler.h b/src/util/Compiler.h index 2c9134af8ff..ad1d518a65b 100644 --- a/src/util/Compiler.h +++ b/src/util/Compiler.h @@ -2,6 +2,10 @@ // Copyright The XCSoar Project #pragma once +#ifdef _MSC_VER +# include "msvc/Compiler.h" +// sollte nie erreicht werden!!!! +#else // _MSC_VER #define GCC_MAKE_VERSION(major, minor, patchlevel) ((major) * 10000 + (minor) * 100 + patchlevel) @@ -13,6 +17,9 @@ #ifdef __clang__ # define CLANG_VERSION GCC_MAKE_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__) +# ifdef _WIN32 + typedef SSIZE_T ssize_t; +# endif #else # define CLANG_VERSION 0 #endif @@ -113,3 +120,4 @@ #else #define gcc_unreachable() #endif +#endif // _MSC_VER diff --git a/src/util/ConvertString.cpp b/src/util/ConvertString.cpp deleted file mode 100644 index f4f3c343c63..00000000000 --- a/src/util/ConvertString.cpp +++ /dev/null @@ -1,81 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -// Copyright The XCSoar Project - -#include "ConvertString.hpp" - -#ifdef _UNICODE -#include - -static BasicAllocatedString -ConvertToWide(const char *p, UINT codepage) noexcept -{ - assert(p != nullptr); - - int length = MultiByteToWideChar(codepage, 0, p, -1, nullptr, 0); - if (length <= 0) - return nullptr; - - wchar_t *buffer = new wchar_t[length]; - length = MultiByteToWideChar(codepage, 0, p, -1, buffer, length); - if (length <= 0) { - delete[] buffer; - return nullptr; - } - - return BasicAllocatedString::Donate(buffer); -} - -BasicAllocatedString -ConvertUTF8ToWide(const char *p) noexcept -{ - assert(p != nullptr); - - return ConvertToWide(p, CP_UTF8); -} - -BasicAllocatedString -ConvertACPToWide(const char *p) noexcept -{ - assert(p != nullptr); - - return ConvertToWide(p, CP_ACP); -} - -static AllocatedString -ConvertFromWide(const wchar_t *p, UINT codepage) noexcept -{ - assert(p != nullptr); - - int length = WideCharToMultiByte(codepage, 0, p, -1, nullptr, 0, - nullptr, nullptr); - if (length <= 0) - return nullptr; - - char *buffer = new char[length]; - length = WideCharToMultiByte(codepage, 0, p, -1, buffer, length, - nullptr, nullptr); - if (length <= 0) { - delete[] buffer; - return nullptr; - } - - return AllocatedString::Donate(buffer); -} - -AllocatedString -ConvertWideToUTF8(const wchar_t *p) noexcept -{ - assert(p != nullptr); - - return ConvertFromWide(p, CP_UTF8); -} - -AllocatedString -ConvertWideToACP(const wchar_t *p) noexcept -{ - assert(p != nullptr); - - return ConvertFromWide(p, CP_ACP); -} - -#endif diff --git a/src/util/ConvertString.hpp b/src/util/ConvertString.hpp deleted file mode 100644 index 7e4f30ec3f5..00000000000 --- a/src/util/ConvertString.hpp +++ /dev/null @@ -1,209 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -// Copyright The XCSoar Project - -#pragma once - -#include "UTF8.hpp" - -#ifdef _UNICODE -#include "AllocatedString.hxx" -#else -#include "StringPointer.hxx" -#endif - -#include - -#ifdef _UNICODE - -#include - -/** - * @return nullptr on error - */ -[[gnu::nonnull]] -BasicAllocatedString -ConvertUTF8ToWide(const char *p) noexcept; - -/** - * @return nullptr on error - */ -[[gnu::nonnull]] -BasicAllocatedString -ConvertACPToWide(const char *p) noexcept; - -/** - * @return nullptr on error - */ -[[gnu::nonnull]] -AllocatedString -ConvertWideToUTF8(const wchar_t *p) noexcept; - -/** - * @return nullptr on error - */ -[[gnu::nonnull]] -AllocatedString -ConvertWideToACP(const wchar_t *p) noexcept; - -#endif - -/** - * Convert a UTF-8 string to a TCHAR string. The source buffer passed - * to the constructor must be valid as long as this object is being - * used. - */ -class UTF8ToWideConverter { -#ifdef _UNICODE - typedef BasicAllocatedString Value; -#else - typedef StringPointer<> Value; -#endif - typedef typename Value::const_pointer const_pointer; - - Value value; - -public: -#ifdef _UNICODE - UTF8ToWideConverter(const char *_value) noexcept - :value(ConvertUTF8ToWide(_value)) {} -#else - UTF8ToWideConverter(const_pointer _value) noexcept - :value(_value) - { - assert(_value != nullptr); - } -#endif - - UTF8ToWideConverter(const UTF8ToWideConverter &other) = delete; - UTF8ToWideConverter &operator=(const UTF8ToWideConverter &other) = delete; - - [[gnu::pure]] - bool IsValid() const noexcept { -#ifdef _UNICODE - return value != nullptr; -#else - assert(value != nullptr); - - return ValidateUTF8(value.c_str()); -#endif - } - - const_pointer c_str() const noexcept { - assert(value != nullptr); - - return value.c_str(); - } - - operator const_pointer() const noexcept { - assert(value != nullptr); - - return value.c_str(); - } -}; - -/** - * Convert a TCHAR string to UTF-8. The source buffer passed to the - * constructor must be valid as long as this object is being used. - */ -class WideToUTF8Converter { -#ifdef _UNICODE - typedef AllocatedString Value; -#else - typedef StringPointer<> Value; -#endif - typedef typename Value::const_pointer const_pointer; - - Value value; - -public: -#ifdef _UNICODE - WideToUTF8Converter(const wchar_t *_value) noexcept - :value(ConvertWideToUTF8(_value)) {} -#else - WideToUTF8Converter(const_pointer _value) noexcept - :value(_value) - { - assert(_value != nullptr); - } -#endif - - WideToUTF8Converter(const WideToUTF8Converter &other) = delete; - WideToUTF8Converter &operator=(const WideToUTF8Converter &other) = delete; - - [[gnu::pure]] - bool IsValid() const noexcept { -#ifdef _UNICODE - return value != nullptr; -#else - assert(value != nullptr); - - return true; -#endif - } - - const_pointer c_str() const noexcept { - assert(value != nullptr); - - return value.c_str(); - } - - operator const_pointer() const noexcept { - assert(value != nullptr); - - return value.c_str(); - } -}; - -/** - * Convert a TCHAR string to ACP (Windows ANSI code page). The source - * buffer passed to the constructor must be valid as long as this - * object is being used. - */ -class WideToACPConverter { -#ifdef _UNICODE - typedef AllocatedString Value; -#else - typedef StringPointer<> Value; -#endif - typedef typename Value::const_pointer const_pointer; - - Value value; - -public: -#ifdef _UNICODE - WideToACPConverter(const wchar_t *_value) noexcept - :value(ConvertWideToACP(_value)) {} -#else - WideToACPConverter(const_pointer _value) noexcept - :value(_value) - { - assert(_value != nullptr); - } -#endif - - WideToACPConverter(const WideToACPConverter &other) = delete; - WideToACPConverter &operator=(const WideToACPConverter &other) = delete; - - [[gnu::pure]] - bool IsValid() const noexcept { -#ifdef _UNICODE - return value != nullptr; -#else - assert(value != nullptr); - - return true; -#endif - } - - const_pointer c_str() const noexcept { - assert(value != nullptr); - - return value.c_str(); - } - - operator const_pointer() const noexcept { - assert(value != nullptr); - - return value.c_str(); - } -}; diff --git a/src/util/DecimalParser.cxx b/src/util/DecimalParser.cxx index 72055802045..d4b3ba3979b 100644 --- a/src/util/DecimalParser.cxx +++ b/src/util/DecimalParser.cxx @@ -11,7 +11,12 @@ std::optional ParseDecimal(std::string_view src) noexcept { - const char *first = src.begin(), *const last = first + src.size(); +#if defined(__MSVC__) || defined(__clang__) + // MSVC cannot (change) the iterator to const char* automatically? + const char *first = src.data(), *const last = first + src.size(); +#else + const char *first = src.begin(), *const last = first + src.size(); +#endif if (first == last) return std::nullopt; diff --git a/src/util/DollarExpand.hpp b/src/util/DollarExpand.hpp index b74a4c9c87d..dd6101e0795 100644 --- a/src/util/DollarExpand.hpp +++ b/src/util/DollarExpand.hpp @@ -5,7 +5,7 @@ #include "StringAPI.hxx" #include "TruncateString.hpp" -#include "tstring_view.hxx" +#include #include #include @@ -18,20 +18,20 @@ * buffer is too small, then the output is truncated silently. */ void -DollarExpand(const TCHAR *src, std::span dest, - std::invocable auto lookup_function) noexcept +DollarExpand(const char *src, std::span dest, + std::invocable auto lookup_function) noexcept { while (true) { - auto dollar = StringFind(src, _T("$(")); + auto dollar = StringFind(src, "$("); if (dollar == nullptr) break; auto name_start = dollar + 2; - auto closing = StringFind(name_start, _T(')')); + auto closing = StringFind(name_start, ')'); if (closing == nullptr) break; - const tstring_view name(name_start, closing - name_start); + const std::string_view name(name_start, closing - name_start); const std::size_t prefix_size = dollar - src; if (prefix_size >= dest.size()) @@ -46,9 +46,9 @@ DollarExpand(const TCHAR *src, std::span dest, /* look up the name and copy the result to the destination buffer */ - const TCHAR *const expansion = lookup_function(name); + const char *const expansion = lookup_function(name); if (expansion != nullptr) { - const tstring_view ex{expansion}; + const std::string_view ex{expansion}; if (ex.size() >= dest.size()) break; diff --git a/src/util/EscapeBackslash.cpp b/src/util/EscapeBackslash.cpp index a6f435c0b15..d15ace2505e 100644 --- a/src/util/EscapeBackslash.cpp +++ b/src/util/EscapeBackslash.cpp @@ -6,14 +6,14 @@ #include #include -tstring_view::pointer -UnescapeBackslash(tstring_view old_string) noexcept +std::string_view::pointer +UnescapeBackslash(std::string_view old_string) noexcept { - TCHAR buffer[2048]; // Note - max size of any string we cope with here ! + char buffer[2048]; // Note - max size of any string we cope with here ! - tstring_view::size_type used = 0; + std::string_view::size_type used = 0; - for (tstring_view::size_type i = 0; i < old_string.size(); i++) { + for (std::string_view::size_type i = 0; i < old_string.size(); i++) { if (used < 2045) { if (old_string[i] == '\\') { if (old_string[i + 1] == 'r') { @@ -34,7 +34,7 @@ UnescapeBackslash(tstring_view old_string) noexcept } } - buffer[used++] = _T('\0'); + buffer[used++] = '\0'; - return _tcsdup(buffer); + return strdup(buffer); } diff --git a/src/util/EscapeBackslash.hpp b/src/util/EscapeBackslash.hpp index d9ee99bb6ee..7ed0310bdc1 100644 --- a/src/util/EscapeBackslash.hpp +++ b/src/util/EscapeBackslash.hpp @@ -3,7 +3,7 @@ #pragma once -#include "util/tstring_view.hxx" +#include /** * Parses the special characters (cr, lf, back slash) in the old_string and @@ -11,5 +11,5 @@ * @param old_string The old string with (or without) special characters * @return The new parsed string */ -tstring_view::pointer -UnescapeBackslash(tstring_view old_string) noexcept; +std::string_view::pointer +UnescapeBackslash(std::string_view old_string) noexcept; diff --git a/src/util/IterableSplitString.hxx b/src/util/IterableSplitString.hxx index 9349f76ea53..81f76c8c592 100644 --- a/src/util/IterableSplitString.hxx +++ b/src/util/IterableSplitString.hxx @@ -94,10 +94,4 @@ public: }; using IterableSplitString = BasicIterableSplitString; - -#ifdef _UNICODE -using WIterableSplitString = BasicIterableSplitString; -using TIterableSplitString = WIterableSplitString; -#else using TIterableSplitString = IterableSplitString; -#endif diff --git a/src/util/NumberParser.hpp b/src/util/NumberParser.hpp index 4dbdb0538b0..0b60513f5bc 100644 --- a/src/util/NumberParser.hpp +++ b/src/util/NumberParser.hpp @@ -7,10 +7,6 @@ #include #include -#ifdef _UNICODE -#include -#endif - static inline double ParseDouble(const char *p, char **endptr=nullptr) { @@ -19,40 +15,6 @@ ParseDouble(const char *p, char **endptr=nullptr) return (double)strtod(p, endptr); } -#ifdef _UNICODE -static inline double -ParseDouble(const wchar_t *p, wchar_t **endptr) -{ - assert(p != nullptr); - - return (double)wcstod(p, endptr); -} - -#ifdef _WIN32 -#include -#ifdef __MINGW64_VERSION_MAJOR -#if __MINGW64_VERSION_MAJOR == 3 && __MINGW64_VERSION_MINOR == 1 -#define BUGGY_WCSTOD -#endif -#endif -#endif - -static inline double -ParseDouble(const wchar_t *p) -{ - assert(p != nullptr); - -#ifdef BUGGY_WCSTOD - /* workaround for mingw64 3.1 bug to avoid nullptr dereference */ - wchar_t *dummy; - return ParseDouble(p, &dummy); -#else - return ParseDouble(p, nullptr); -#endif -} - -#endif - static inline unsigned ParseUnsigned(const char *p, char **endptr=nullptr, int base=10) { @@ -61,16 +23,6 @@ ParseUnsigned(const char *p, char **endptr=nullptr, int base=10) return (unsigned)strtoul(p, endptr, base); } -#ifdef _UNICODE -static inline unsigned -ParseUnsigned(const wchar_t *p, wchar_t **endptr=nullptr, int base=10) -{ - assert(p != nullptr); - - return (unsigned)wcstoul(p, endptr, base); -} -#endif - static inline int ParseInt(const char *p, char **endptr=nullptr, int base=10) { @@ -79,16 +31,6 @@ ParseInt(const char *p, char **endptr=nullptr, int base=10) return (int)strtol(p, endptr, base); } -#ifdef _UNICODE -static inline int -ParseInt(const wchar_t *p, wchar_t **endptr=nullptr, int base=10) -{ - assert(p != nullptr); - - return (int)wcstol(p, endptr, base); -} -#endif - static inline uint64_t ParseUint64(const char *p, char **endptr=nullptr, int base=10) { @@ -97,16 +39,6 @@ ParseUint64(const char *p, char **endptr=nullptr, int base=10) return strtoull(p, endptr, base); } -#ifdef _UNICODE -static inline uint64_t -ParseUint64(const wchar_t *p, wchar_t **endptr=nullptr, int base=10) -{ - assert(p != nullptr); - - return wcstoull(p, endptr, base); -} -#endif - static inline int64_t ParseInt64(const char *p, char **endptr=nullptr, int base=10) { @@ -115,12 +47,3 @@ ParseInt64(const char *p, char **endptr=nullptr, int base=10) return strtoll(p, endptr, base); } -#ifdef _UNICODE -static inline int64_t -ParseInt64(const wchar_t *p, wchar_t **endptr=nullptr, int base=10) -{ - assert(p != nullptr); - - return wcstoll(p, endptr, base); -} -#endif diff --git a/src/util/RadixTree.hpp b/src/util/RadixTree.hpp index 3f622476904..846d70bd2bb 100644 --- a/src/util/RadixTree.hpp +++ b/src/util/RadixTree.hpp @@ -5,7 +5,7 @@ #include "StaticString.hxx" #include "StringCompare.hxx" -#include "tstring.hpp" +#include #include #include @@ -16,7 +16,7 @@ #endif /** - * An associative container which maps TCHAR strings to arbitrary + * An associative container which maps char strings to arbitrary * objects. Each "key" may have multiple values. * * This class provides a sorted iterator, which is optimized for @@ -29,10 +29,10 @@ class RadixTree { template struct KeyVisitorAdapter { V &visitor; - const TCHAR *key; + const char *key; constexpr KeyVisitorAdapter(V &_visitor, - const TCHAR *_key) noexcept + const char *_key) noexcept :visitor(_visitor), key(_key) {} void operator()(const T &value) const { @@ -164,7 +164,7 @@ class RadixTree { Node *next_sibling = nullptr, *children = nullptr; LeafList leaves; - constexpr Node(const TCHAR *_label) noexcept + constexpr Node(const char *_label) noexcept :label(_label) {} Node(const Node &) = delete; @@ -180,9 +180,9 @@ class RadixTree { * StaticString, multiple chained Node objects are * created. */ - Node *CreateLeaf(const TCHAR *label, const T &value) const { + Node *CreateLeaf(const char *label, const T &value) const { Node *top = new Node(label), *bottom = top; - while (_tcslen(label) >= Node::label.capacity()) { + while (strlen(label) >= Node::label.capacity()) { /* label too long for the Node's StaticString, create another child Node */ @@ -209,8 +209,8 @@ class RadixTree { * match (even if the node's label is longer). */ [[gnu::pure]] - const TCHAR *MatchKey(const TCHAR *key) const noexcept { - const TCHAR *l = label.c_str(); + const char *MatchKey(const char *key) const noexcept { + const char *l = label.c_str(); while (!StringIsEmpty(key) && *key == *l) { ++key; @@ -231,8 +231,8 @@ class RadixTree { * Returns nullptr if there is a mismatch. */ [[gnu::pure]] - const TCHAR *MatchPrefix(const TCHAR *prefix) const noexcept { - const TCHAR *l = label.c_str(); + const char *MatchPrefix(const char *prefix) const noexcept { + const char *l = label.c_str(); while (!StringIsEmpty(prefix) && !StringIsEmpty(l)) { if (*l != *prefix) @@ -246,7 +246,7 @@ class RadixTree { } [[gnu::pure]] - T *Get(const TCHAR *key) noexcept { + T *Get(const char *key) noexcept { if (StringIsEmpty(key)) /* found */ return leaves.GetFirstPointer(); @@ -258,7 +258,7 @@ class RadixTree { } [[gnu::pure]] - const T *Get(const TCHAR *key) const noexcept { + const T *Get(const char *key) const noexcept { if (StringIsEmpty(key)) /* found */ return leaves.GetFirstPointer(); @@ -271,7 +271,7 @@ class RadixTree { template [[gnu::pure]] - T *GetIf(const TCHAR *key, const P &predicate) noexcept { + T *GetIf(const char *key, const P &predicate) noexcept { if (StringIsEmpty(key)) /* found */ return leaves.GetIf(predicate); @@ -284,7 +284,7 @@ class RadixTree { template [[gnu::pure]] - const T *GetIf(const TCHAR *key, + const T *GetIf(const char *key, const P &predicate) const noexcept { if (StringIsEmpty(key)) /* found */ @@ -297,18 +297,18 @@ class RadixTree { } [[gnu::pure]] - TCHAR *Suggest(const TCHAR *prefix, TCHAR *dest, + char *Suggest(const char *prefix, char *dest, size_t max_length) const noexcept { if (StringIsEmpty(prefix)) { /* exact match - return the first character of all child nodes */ - TCHAR *retval = dest, *end = dest + max_length - 1; + char *retval = dest, *end = dest + max_length - 1; for (const Node *node = children; node != nullptr && dest < end; node = node->next_sibling) *dest++ = node->label[0u]; - *dest = _T('\0'); + *dest = '\0'; return retval; } @@ -323,7 +323,7 @@ class RadixTree { /* return one character */ dest[0u] = m.node->label[(unsigned)(m.key - prefix)]; - dest[1] = _T('\0'); + dest[1] = '\0'; return dest; } @@ -373,7 +373,7 @@ class RadixTree { /** * Remove all values with the specified key. */ - void RemoveValues(const TCHAR *key) noexcept { + void RemoveValues(const char *key) noexcept { assert(key != nullptr); if (StringIsEmpty(key)) { @@ -392,7 +392,7 @@ class RadixTree { * * @return true if a value was found and removed */ - bool RemoveValue(const TCHAR *key, const T &value) noexcept { + bool RemoveValue(const char *key, const T &value) noexcept { assert(key != nullptr); if (StringIsEmpty(key)) { @@ -426,8 +426,8 @@ class RadixTree { * This overload is used by VisitAllPairs(). */ template - void VisitValues(const TCHAR *prefix, V &visitor) const { - tstring key(prefix); + void VisitValues(const char *prefix, V &visitor) const { + std::string key(prefix); key.append(label); const KeyVisitorAdapter adapter(visitor, key.c_str()); @@ -464,8 +464,8 @@ class RadixTree { * alphabetic order. This overload is used by VisitAllPairs(). */ template - void VisitAllChildren(const TCHAR *prefix, V &visitor) const { - tstring key(prefix); + void VisitAllChildren(const char *prefix, V &visitor) const { + std::string key(prefix); key.append(label); for (const Node *node = children; node != nullptr; @@ -481,7 +481,7 @@ class RadixTree { * is only matched on children's labels. */ template - void VisitChildren(const TCHAR *key, V &visitor) { + void VisitChildren(const char *key, V &visitor) { VisitSiblings(children, key, visitor); } @@ -491,7 +491,7 @@ class RadixTree { * children's labels. */ template - void VisitChildren(const TCHAR *key, V &visitor) const { + void VisitChildren(const char *key, V &visitor) const { VisitSiblings(const_cast(children), key, visitor); } @@ -500,8 +500,8 @@ class RadixTree { * key is matched on this node's label first. */ template - void Visit(const TCHAR *key, V &visitor) { - const TCHAR *match = MatchPrefix(key); + void Visit(const char *key, V &visitor) { + const char *match = MatchPrefix(key); if (match == nullptr) return; @@ -516,8 +516,8 @@ class RadixTree { * key is matched on this node's label first. */ template - void Visit(const TCHAR *key, V &visitor) const { - const TCHAR *match = MatchPrefix(key); + void Visit(const char *key, V &visitor) const { + const char *match = MatchPrefix(key); if (match == nullptr) return; @@ -533,7 +533,7 @@ class RadixTree { * is only matched on children's labels. */ template - void VisitPrefixChildren(const TCHAR *prefix, V &visitor) { + void VisitPrefixChildren(const char *prefix, V &visitor) { if (StringIsEmpty(prefix)) VisitAllChildren(visitor); else @@ -547,7 +547,7 @@ class RadixTree { * is only matched on children's labels. */ template - void VisitPrefixChildren(const TCHAR *prefix, V &visitor) const { + void VisitPrefixChildren(const char *prefix, V &visitor) const { if (StringIsEmpty(prefix)) VisitAllChildren(visitor); else @@ -562,8 +562,8 @@ class RadixTree { * prefix is matched on this node's label first. */ template - void VisitPrefix(const TCHAR *prefix, V &visitor) { - const TCHAR *match = MatchPrefix(prefix); + void VisitPrefix(const char *prefix, V &visitor) { + const char *match = MatchPrefix(prefix); if (match == nullptr) return; @@ -581,8 +581,8 @@ class RadixTree { * prefix is matched on this node's label first. */ template - void VisitPrefix(const TCHAR *prefix, V &visitor) const { - const TCHAR *match = MatchPrefix(prefix); + void VisitPrefix(const char *prefix, V &visitor) const { + const char *match = MatchPrefix(prefix); if (match == nullptr) return; @@ -596,14 +596,14 @@ class RadixTree { struct Match { Node *node; - const TCHAR *key; + const char *key; constexpr Match(Node *_node, - const TCHAR *_key) noexcept + const char *_key) noexcept :node(_node), key(_key) {} [[gnu::pure]] - bool IsFullMatch(const TCHAR *key) const noexcept { + bool IsFullMatch(const char *key) const noexcept { return this->key != key && this->key >= key + node->label.length(); } }; @@ -615,10 +615,10 @@ class RadixTree { * of the key which was not used yet. */ [[gnu::pure]] - struct Match FindChild(const TCHAR *key) const noexcept { + struct Match FindChild(const char *key) const noexcept { Node *node = children, *prev = nullptr; while (node != nullptr) { - const TCHAR *label = node->label.c_str(); + const char *label = node->label.c_str(); if (key[0u] < label[0u]) return Match(prev, key); else if (key[0u] == label[0u]) @@ -635,7 +635,7 @@ class RadixTree { * Adds a new value relative to this node, possibly creating a * new node and/or splitting an existing node. */ - void Add(const TCHAR *key, const T &value) { + void Add(const char *key, const T &value) { assert(key != nullptr); if (StringIsEmpty(key)) { @@ -708,7 +708,7 @@ class RadixTree { Node root; public: - constexpr RadixTree() noexcept:root(_T("")) {} + constexpr RadixTree() noexcept:root("") {} /** * Gets a value for the specified key. Returns the parameter @@ -716,7 +716,7 @@ class RadixTree { * multiple values, any one is returned. */ [[gnu::pure]] - T &Get(const TCHAR *key, T &default_value) noexcept { + T &Get(const char *key, T &default_value) noexcept { T *value = root.get(key); return value != nullptr ? *value @@ -729,7 +729,7 @@ class RadixTree { * multiple values, any one is returned. */ [[gnu::pure]] - const T &Get(const TCHAR *key, const T &default_value) const noexcept { + const T &Get(const char *key, const T &default_value) const noexcept { const T *value = root.Get(key); return value != nullptr ? *value @@ -738,7 +738,7 @@ class RadixTree { template [[gnu::pure]] - T &GetIf(const TCHAR *key, T &default_value, const P &predicate) noexcept { + T &GetIf(const char *key, T &default_value, const P &predicate) noexcept { const T *value = root.GetIf(key, predicate); return value != nullptr ? *value @@ -747,7 +747,7 @@ class RadixTree { template [[gnu::pure]] - const T &GetIf(const TCHAR *key, const T &default_value, + const T &GetIf(const char *key, const T &default_value, const P &predicate) const noexcept { const T *value = root.GetIf(key, predicate); return value != nullptr @@ -769,7 +769,7 @@ class RadixTree { * occur in the tree */ [[gnu::pure]] - TCHAR *Suggest(const TCHAR *prefix, TCHAR *dest, + char *Suggest(const char *prefix, char *dest, size_t max_length) const noexcept { return root.Suggest(prefix, dest, max_length); } @@ -782,14 +782,14 @@ class RadixTree { * Add a new value with the specified key. Multiple values can * exist for one key. */ - void Add(const TCHAR *key, const T &value) { + void Add(const char *key, const T &value) { root.Add(key, value); } /** * Remove all values with the specified key. */ - void Remove(const TCHAR *key) noexcept { + void Remove(const char *key) noexcept { assert(key != nullptr); root.RemoveValues(key); @@ -800,7 +800,7 @@ class RadixTree { * * @return true if a value was found and removed */ - bool Remove(const TCHAR *key, const T &value) noexcept { + bool Remove(const char *key, const T &value) noexcept { assert(key != nullptr); return root.RemoveValue(key, value); @@ -829,15 +829,15 @@ class RadixTree { */ template void VisitAllPairs(V &visitor) const { - root.VisitValues(_T(""), visitor); - root.VisitAllChildren(_T(""), visitor); + root.VisitValues("", visitor); + root.VisitAllChildren("", visitor); } /** * Visit all values with the specified key. */ template - void Visit(const TCHAR *key, V &visitor) { + void Visit(const char *key, V &visitor) { root.Visit(key, visitor); } @@ -845,7 +845,7 @@ class RadixTree { * Visit all values with the specified key. */ template - void Visit(const TCHAR *key, V &visitor) const { + void Visit(const char *key, V &visitor) const { root.Visit(key, visitor); } @@ -854,7 +854,7 @@ class RadixTree { * order. */ template - void VisitPrefix(const TCHAR *prefix, V &visitor) { + void VisitPrefix(const char *prefix, V &visitor) { root.VisitPrefix(prefix, visitor); } @@ -863,7 +863,7 @@ class RadixTree { * order. */ template - void VisitPrefix(const TCHAR *prefix, V &visitor) const { + void VisitPrefix(const char *prefix, V &visitor) const { root.VisitPrefix(prefix, visitor); } diff --git a/src/util/StaticString.cxx b/src/util/StaticString.cxx index 03fa5edb01f..c670185c5bd 100644 --- a/src/util/StaticString.cxx +++ b/src/util/StaticString.cxx @@ -3,10 +3,6 @@ #include "StaticString.hxx" -#ifdef _UNICODE -#include -#endif - bool CopyUTF8(char *dest, size_t dest_size, const char *src) noexcept { @@ -18,13 +14,3 @@ CopyUTF8(char *dest, size_t dest_size, const char *src) noexcept return true; } -#ifdef _UNICODE - -bool -CopyUTF8(wchar_t *dest, size_t dest_size, const char *src) noexcept -{ - int result = MultiByteToWideChar(CP_UTF8, 0, src, -1, dest, dest_size); - return result > 0; -} - -#endif diff --git a/src/util/StaticString.hxx b/src/util/StaticString.hxx index 371fa32f7ba..07e4ff83d08 100644 --- a/src/util/StaticString.hxx +++ b/src/util/StaticString.hxx @@ -7,6 +7,7 @@ #include "StringAPI.hxx" #include "StringUtil.hpp" #include "StringFormat.hpp" +#include "StringCompare.hxx" #include "UTF8.hpp" #include "ASCII.hxx" @@ -14,18 +15,9 @@ #include #include -#ifdef _UNICODE -#include -#endif - bool CopyUTF8(char *dest, size_t dest_size, const char *src) noexcept; -#ifdef _UNICODE -bool -CopyUTF8(wchar_t *dest, size_t dest_size, const char *src) noexcept; -#endif - /** * A string with a maximum size known at compile time. */ @@ -79,13 +71,6 @@ public: *end = SENTINEL; } -#ifdef _UNICODE - void SetASCII(std::wstring_view src) noexcept { - pointer end = ::CopyASCII(data(), capacity() - 1, src); - *end = SENTINEL; - } -#endif - /** * Eliminate all non-ASCII characters. */ @@ -283,7 +268,7 @@ public: * This is the char-based sister of the StaticString class. */ template -class NarrowString: public StaticStringBase +class StaticString: public StaticStringBase { typedef StaticStringBase Base; @@ -304,35 +289,3 @@ public: } }; -#ifdef _UNICODE - -/** - * A string with a maximum size known at compile time. - * This is the TCHAR-based sister of the NarrowString class. - */ -template -class StaticString: public StaticStringBase -{ - typedef StaticStringBase Base; - -public: - using typename Base::value_type; - using typename Base::reference; - using typename Base::pointer; - using typename Base::const_pointer; - using typename Base::const_iterator; - using typename Base::size_type; - - using Base::Base; - using Base::operator=; - using Base::operator+=; - - void CropIncompleteUTF8() noexcept { - /* this is a wchar_t string, it's not multi-byte, - therefore we have no incomplete sequences */ - } -}; - -#else -#define StaticString NarrowString -#endif diff --git a/src/util/StringAPI.hxx b/src/util/StringAPI.hxx index a38185d1f12..4c0025dd590 100644 --- a/src/util/StringAPI.hxx +++ b/src/util/StringAPI.hxx @@ -5,10 +5,6 @@ #include -#ifdef _UNICODE -#include "WStringAPI.hxx" -#endif - [[gnu::pure]] [[gnu::nonnull]] static inline size_t StringLength(const char *p) noexcept diff --git a/src/util/StringBuilder.cxx b/src/util/StringBuilder.cxx index 6264084208a..5737a368d0e 100644 --- a/src/util/StringBuilder.cxx +++ b/src/util/StringBuilder.cxx @@ -6,10 +6,6 @@ #include -#ifdef _UNICODE -#include -#endif - #include #include @@ -49,6 +45,3 @@ BasicStringBuilder::Format(const_pointer fmt, ...) Extend(n); } -#ifdef _UNICODE -template class BasicStringBuilder; -#endif diff --git a/src/util/StringCompare.hxx b/src/util/StringCompare.hxx index 579752187cf..8d7525ad0ee 100644 --- a/src/util/StringCompare.hxx +++ b/src/util/StringCompare.hxx @@ -5,10 +5,6 @@ #include "StringAPI.hxx" -#ifdef _UNICODE -#include "WStringCompare.hxx" -#endif - #include [[gnu::pure]] [[gnu::nonnull]] @@ -18,6 +14,8 @@ StringIsEmpty(const char *string) noexcept return *string == 0; } +#if 0 // ambiguous with StringAPI.hpp->StringIsEqual(const char *a, const char *b) +// TODO(August2111) - at the end this should be the used function [[gnu::pure]] static inline bool StringIsEqual(std::string_view a, std::string_view b) noexcept @@ -25,6 +23,7 @@ StringIsEqual(std::string_view a, std::string_view b) noexcept return a.size() == b.size() && StringIsEqual(a.data(), b.data(), b.size()); } +#endif [[gnu::pure]] static inline bool diff --git a/src/util/StringFormat.hpp b/src/util/StringFormat.hpp index ac26587a977..73dea28ceac 100644 --- a/src/util/StringFormat.hpp +++ b/src/util/StringFormat.hpp @@ -3,10 +3,6 @@ #pragma once -#ifdef _UNICODE -#include "WStringFormat.hpp" -#endif - #include template diff --git a/src/util/StringStrip.hxx b/src/util/StringStrip.hxx index 5032858e5bd..11c229822f4 100644 --- a/src/util/StringStrip.hxx +++ b/src/util/StringStrip.hxx @@ -6,10 +6,6 @@ #include #include -#ifdef _UNICODE -#include "WStringStrip.hxx" -#endif - /** * Skips whitespace at the beginning of the string, and returns the * first non-whitespace character. If the string has no diff --git a/src/util/StringUtil.hpp b/src/util/StringUtil.hpp index eb5354e44ba..1120dd99459 100644 --- a/src/util/StringUtil.hpp +++ b/src/util/StringUtil.hpp @@ -6,10 +6,6 @@ #include #include -#ifdef _UNICODE -#include "WStringUtil.hpp" -#endif - /** * Copy a string. If the buffer is too small, then the string is * truncated. This is a safer version of strncpy(). diff --git a/src/util/TruncateString.cpp b/src/util/TruncateString.cpp index aa80cbcb45c..7803ee0079d 100644 --- a/src/util/TruncateString.cpp +++ b/src/util/TruncateString.cpp @@ -20,45 +20,17 @@ CopyTruncateString(char *dest, size_t dest_size, const char *src) size_t copy = std::min(src_length, dest_size - 1); auto *p = std::copy_n(src, copy, dest); - *p = _T('\0'); + *p = '\0'; return CropIncompleteUTF8(dest); } -#ifdef _UNICODE - -TCHAR * -CopyTruncateString(TCHAR *dest, size_t dest_size, const TCHAR *src) -{ - assert(dest != nullptr); - assert(dest_size > 0); - assert(src != nullptr); - - size_t src_length = StringLength(src); - size_t copy = std::min(src_length, dest_size - 1); - - auto *p = std::copy_n(src, copy, dest); - *p = _T('\0'); - return p; -} - -#endif - -TCHAR * -CopyTruncateString(TCHAR *dest, size_t dest_size, - const TCHAR *src, size_t truncate) +char * +CopyTruncateString(char *dest, size_t dest_size, + const char *src, size_t truncate) { assert(dest != nullptr); assert(dest_size > 0); assert(src != nullptr); -#ifdef _UNICODE - size_t src_length = StringLength(src); - size_t copy = std::min({src_length, truncate, dest_size - 1}); - - auto *p = std::copy_n(src, copy, dest); - *p = _T('\0'); - return p; -#else return CopyTruncateStringUTF8({dest, dest_size}, src, truncate); -#endif } diff --git a/src/util/TruncateString.hpp b/src/util/TruncateString.hpp index 1a8102bf7b9..d0bf527d333 100644 --- a/src/util/TruncateString.hpp +++ b/src/util/TruncateString.hpp @@ -16,12 +16,6 @@ */ char * CopyTruncateString(char *dest, size_t dest_size, const char *src); - -#ifdef _UNICODE -TCHAR * -CopyTruncateString(TCHAR *dest, size_t dest_size, const TCHAR *src); -#endif - /** * Copy a string to a buffer, truncating it if the buffer is not large * enough. At most #truncate characters will be copied. No partial @@ -33,6 +27,6 @@ CopyTruncateString(TCHAR *dest, size_t dest_size, const TCHAR *src); * copy * @return a pointer to the end of the destination string */ -TCHAR * -CopyTruncateString(TCHAR *dest, size_t dest_size, - const TCHAR *src, size_t truncate); +char * +CopyTruncateString(char *dest, size_t dest_size, + const char *src, size_t truncate); diff --git a/src/util/UTF8.cpp b/src/util/UTF8.cpp index 00ab25a1de2..a05c13322d3 100644 --- a/src/util/UTF8.cpp +++ b/src/util/UTF8.cpp @@ -4,6 +4,7 @@ #include "UTF8.hpp" #include "CharUtil.hxx" #include "Compiler.h" +#include "LogFile.hpp" #include @@ -658,3 +659,17 @@ NextUTF8(const char *p) noexcept gcc_unreachable(); } } + +#ifdef _WIN32 +#include + +std::wstring +UTF8ToWide(const std::string_view s) +{ + int length = MultiByteToWideChar(CP_UTF8, 0, s.data(), s.size() + 1, nullptr, 0); + std::wstring w(length + 1, L'\0'); + MultiByteToWideChar(CP_UTF8, 0, s.data(), s.size() + 1, w.data(), length); + return w; +} + +#endif diff --git a/src/util/UTF8.hpp b/src/util/UTF8.hpp index 4fa9f033beb..4525ec1418f 100644 --- a/src/util/UTF8.hpp +++ b/src/util/UTF8.hpp @@ -5,7 +5,7 @@ #include #include -#include +#include #include constexpr std::string_view utf8_byte_order_mark{"\xef\xbb\xbf"}; @@ -136,13 +136,23 @@ CopyTruncateStringUTF8(std::span dest, const char *src, std::size_t truncate) noexcept; /** - * Decode the next UNICODE character. + * Decode the next UTF-8 character. * * @param p a null-terminated valid UTF-8 string - * @return a pair containing the next UNICODE character code and a + * @return a pair containing the next UTF-8(?) character code and a * pointer to the first byte of the following character or 0 if * already at the end of the string */ [[gnu::pure]] [[gnu::nonnull]] std::pair NextUTF8(const char *p) noexcept; + +#ifdef _WIN32 +// #include +#include +#include + +std::wstring +UTF8ToWide(const std::string_view s); + +#endif diff --git a/src/util/WASCII.cxx b/src/util/WASCII.cxx deleted file mode 100644 index 05ae8db8288..00000000000 --- a/src/util/WASCII.cxx +++ /dev/null @@ -1,84 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -// author: Max Kellermann - -#include "WASCII.hxx" -#include "WCharUtil.hxx" - -#include - -template -static D * -TemplateCopyASCII(D *dest, std::size_t dest_size, - std::basic_string_view src) noexcept -{ - const auto dest_end = dest + dest_size; - for (const auto ch : src) { - if (!IsASCII(ch)) - continue; - - if (dest == dest_end) - break; - - *dest++ = ch; - } - - return dest; -} - -void -CopyASCII(wchar_t *dest, const wchar_t *src) noexcept -{ - do { - if (IsASCII(*src)) - *dest++ = *src; - } while (*src++ != L'\0'); -} - -wchar_t * -CopyASCII(wchar_t *dest, std::size_t dest_size, - std::wstring_view src) noexcept -{ - return TemplateCopyASCII(dest, dest_size, src); -} - -void -CopyASCII(wchar_t *dest, const char *src) noexcept -{ - do { - if (IsASCII(*src)) - *dest++ = (wchar_t)*src; - } while (*src++ != '\0'); -} - -wchar_t * -CopyASCII(wchar_t *dest, std::size_t dest_size, - std::string_view src) noexcept -{ - return TemplateCopyASCII(dest, dest_size, src); -} - -char * -CopyASCII(char *dest, std::size_t dest_size, - std::wstring_view src) noexcept -{ - return TemplateCopyASCII(dest, dest_size, src); -} - -char * -CopyASCIIUpper(char *dest, std::size_t dest_size, - std::wstring_view src) noexcept -{ - const auto dest_end = dest + dest_size; - for (auto t : src) { - if (!IsASCII(t)) - continue; - - if (dest == dest_end) - break; - - char ch = (char)t; - *dest++ = ToUpperASCII(ch); - } - - return dest; -} diff --git a/src/util/WASCII.hxx b/src/util/WASCII.hxx deleted file mode 100644 index 9d93cceba93..00000000000 --- a/src/util/WASCII.hxx +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -// author: Max Kellermann - -#pragma once - -#include -#include - -#include - -[[gnu::nonnull]] -void -CopyASCII(wchar_t *dest, const wchar_t *src) noexcept; - -[[gnu::nonnull]] -wchar_t * -CopyASCII(wchar_t *dest, std::size_t dest_size, - std::wstring_view src) noexcept; - -[[gnu::nonnull]] -void -CopyASCII(wchar_t *dest, const char *src) noexcept; - -[[gnu::nonnull]] -wchar_t * -CopyASCII(wchar_t *dest, std::size_t dest_size, - std::string_view src) noexcept; - -[[gnu::nonnull]] -char * -CopyASCII(char *dest, std::size_t dest_size, - std::wstring_view src) noexcept; - -[[gnu::nonnull]] -char * -CopyASCIIUpper(char *dest, std::size_t dest_size, - std::wstring_view src) noexcept; diff --git a/src/util/WCharUtil.hxx b/src/util/WCharUtil.hxx deleted file mode 100644 index 4117be8626a..00000000000 --- a/src/util/WCharUtil.hxx +++ /dev/null @@ -1,120 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -// author: Max Kellermann - -#pragma once - -#include - -constexpr bool -IsASCII(const wchar_t ch) noexcept -{ - return (ch & ~0x7f) == 0; -} - -constexpr bool -IsWhitespaceOrNull(const wchar_t ch) noexcept -{ - return (unsigned)ch <= 0x20; -} - -constexpr bool -IsWhitespaceNotNull(const wchar_t ch) noexcept -{ - return ch > 0 && ch <= 0x20; -} - -/** - * Is the given character whitespace? This calls the faster one of - * IsWhitespaceOrNull() or IsWhitespaceNotNull(). Use this if you - * want the fastest implementation, and you don't care if a null byte - * matches. - */ -constexpr bool -IsWhitespaceFast(const wchar_t ch) noexcept -{ - return IsWhitespaceOrNull(ch); -} - -/** - * Is this a non-printable ASCII character? Returns false for - * non-ASCII characters. - * - * Note that this is not the opposide of IsNonPrintableASCII(). - */ -constexpr bool -IsPrintableASCII(wchar_t ch) noexcept -{ - return IsASCII(ch) && ch >= 0x20; -} - -/** - * Is this a non-printable character? Returns false for non-ASCII - * characters. - * - * Note that this is not the opposide of IsPrintableASCII() - */ -constexpr bool -IsNonPrintableASCII(wchar_t ch) noexcept -{ - return (unsigned)ch < 0x20; -} - -constexpr bool -IsDigitASCII(wchar_t ch) noexcept -{ - return ch >= '0' && ch <= '9'; -} - -constexpr bool -IsUpperAlphaASCII(wchar_t ch) noexcept -{ - return ch >= 'A' && ch <= 'Z'; -} - -constexpr bool -IsLowerAlphaASCII(wchar_t ch) noexcept -{ - return ch >= 'a' && ch <= 'z'; -} - -constexpr bool -IsAlphaASCII(wchar_t ch) noexcept -{ - return IsUpperAlphaASCII(ch) || IsLowerAlphaASCII(ch); -} - -constexpr bool -IsAlphaNumericASCII(wchar_t ch) noexcept -{ - return IsAlphaASCII(ch) || IsDigitASCII(ch); -} - -constexpr bool -IsLowerAlphaNumericASCII(wchar_t ch) noexcept -{ - return IsLowerAlphaASCII(ch) || IsDigitASCII(ch); -} - -/** - * Convert the specified ASCII character (0x00..0x7f) to upper case. - * Unlike toupper(), it ignores the system locale. - */ -constexpr wchar_t -ToUpperASCII(wchar_t ch) noexcept -{ - return ch >= 'a' && ch <= 'z' - ? (ch - ('a' - 'A')) - : ch; -} - -/** - * Convert the specified ASCII character (0x00..0x7f) to lower case. - * Unlike tolower(), it ignores the system locale. - */ -constexpr wchar_t -ToLowerASCII(wchar_t ch) noexcept -{ - return ch >= 'A' && ch <= 'Z' - ? (ch + ('a' - 'A')) - : ch; -} diff --git a/src/util/WStringAPI.hxx b/src/util/WStringAPI.hxx deleted file mode 100644 index ec79d014321..00000000000 --- a/src/util/WStringAPI.hxx +++ /dev/null @@ -1,184 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -// author: Max Kellermann - -#pragma once - -#include - -[[gnu::pure]] [[gnu::nonnull]] -static inline size_t -StringLength(const wchar_t *p) noexcept -{ - return wcslen(p); -} - -[[gnu::pure]] [[gnu::nonnull]] -static inline const wchar_t * -StringFind(const wchar_t *haystack, const wchar_t *needle) noexcept -{ - return wcsstr(haystack, needle); -} - -[[gnu::pure]] [[gnu::nonnull]] -static inline const wchar_t * -StringFind(const wchar_t *haystack, wchar_t needle, size_t size) noexcept -{ - return std::wmemchr(haystack, needle, size); -} - -[[gnu::pure]] [[gnu::nonnull]] -static inline wchar_t * -StringFind(wchar_t *haystack, wchar_t needle, size_t size) noexcept -{ - return std::wmemchr(haystack, needle, size); -} - -[[gnu::pure]] [[gnu::nonnull]] -static inline const wchar_t * -StringFind(const wchar_t *haystack, wchar_t needle) noexcept -{ - return wcschr(haystack, needle); -} - -[[gnu::pure]] [[gnu::nonnull]] -static inline wchar_t * -StringFind(wchar_t *haystack, wchar_t needle) noexcept -{ - return wcschr(haystack, needle); -} - -[[gnu::pure]] [[gnu::nonnull]] -static inline const wchar_t * -StringFindLast(const wchar_t *haystack, wchar_t needle) noexcept -{ - return wcsrchr(haystack, needle); -} - -[[gnu::pure]] [[gnu::nonnull]] -static inline wchar_t * -StringFindLast(wchar_t *haystack, wchar_t needle) noexcept -{ - return wcsrchr(haystack, needle); -} - -[[gnu::pure]] [[gnu::nonnull]] -static inline const wchar_t * -StringFindLast(const wchar_t *haystack, wchar_t needle, size_t size) noexcept -{ - /* there's no wmemrchr() unfortunately */ - const auto *p = haystack + size; - while (p > haystack) { - --p; - if (*p == needle) - return p; - } - - return nullptr; -} - -[[gnu::pure]] [[gnu::nonnull]] -static inline const wchar_t * -StringFindAny(const wchar_t *haystack, const wchar_t *accept) noexcept -{ - return wcspbrk(haystack, accept); -} - -[[gnu::nonnull]] -static inline void -UnsafeCopyString(wchar_t *dest, const wchar_t *src) noexcept -{ - wcscpy(dest, src); -} - -[[gnu::returns_nonnull]] [[gnu::nonnull]] -static inline wchar_t * -UnsafeCopyStringP(wchar_t *dest, const wchar_t *src) noexcept -{ -#if defined(_WIN32) || defined(__OpenBSD__) || defined(__NetBSD__) - /* emulate wcpcpy() */ - UnsafeCopyString(dest, src); - return dest + StringLength(dest); -#elif defined(__sun) && defined (__SVR4) - return std::wcpcpy(dest, src); -#else - return wcpcpy(dest, src); -#endif -} - -[[gnu::pure]] [[gnu::nonnull]] -static inline int -StringCompare(const wchar_t *a, const wchar_t *b) noexcept -{ - return wcscmp(a, b); -} - -[[gnu::pure]] [[gnu::nonnull]] -static inline int -StringCompare(const wchar_t *a, const wchar_t *b, size_t n) noexcept -{ - return wcsncmp(a, b, n); -} - -/** - * Checks whether str1 and str2 are equal. - * @param str1 String 1 - * @param str2 String 2 - * @return True if equal, False otherwise - */ -[[gnu::pure]] [[gnu::nonnull]] -static inline bool -StringIsEqual(const wchar_t *str1, const wchar_t *str2) noexcept -{ - return StringCompare(str1, str2) == 0; -} - -/** - * Checks whether #a and #b are equal. - */ -[[gnu::pure]] [[gnu::nonnull]] -static inline bool -StringIsEqual(const wchar_t *a, const wchar_t *b, size_t length) noexcept -{ - return wcsncmp(a, b, length) == 0; -} - -[[gnu::pure]] [[gnu::nonnull]] -static inline bool -StringIsEqualIgnoreCase(const wchar_t *a, const wchar_t *b) noexcept -{ -#ifdef _WIN32 - return _wcsicmp(a, b) == 0; -#else - return wcscasecmp(a, b) == 0; -#endif -} - -[[gnu::pure]] [[gnu::nonnull]] -static inline bool -StringIsEqualIgnoreCase(const wchar_t *a, const wchar_t *b, - size_t size) noexcept -{ -#ifdef _WIN32 - return _wcsnicmp(a, b, size) == 0; -#else - return wcsncasecmp(a, b, size) == 0; -#endif -} - -[[gnu::pure]] [[gnu::nonnull]] -static inline int -StringCollate(const wchar_t *a, const wchar_t *b) noexcept -{ - return wcscoll(a, b); -} - -[[gnu::malloc]] [[gnu::returns_nonnull]] [[gnu::nonnull]] -static inline wchar_t * -DuplicateString(const wchar_t *p) noexcept -{ -#if defined(__sun) && defined (__SVR4) - return std::wcsdup(p); -#else - return wcsdup(p); -#endif -} diff --git a/src/util/WStringCompare.cxx b/src/util/WStringCompare.cxx deleted file mode 100644 index 4d715d8100a..00000000000 --- a/src/util/WStringCompare.cxx +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -// author: Max Kellermann - -#include "WStringCompare.hxx" - -#include - -bool -StringEndsWith(const wchar_t *haystack, const wchar_t *needle) noexcept -{ - const size_t haystack_length = StringLength(haystack); - const size_t needle_length = StringLength(needle); - - return haystack_length >= needle_length && - StringIsEqual(haystack + haystack_length - needle_length, needle); -} - -bool -StringEndsWithIgnoreCase(const wchar_t *haystack, - const wchar_t *needle) noexcept -{ - const size_t haystack_length = StringLength(haystack); - const size_t needle_length = StringLength(needle); - - return haystack_length >= needle_length && - StringIsEqualIgnoreCase(haystack + haystack_length - needle_length, - needle); -} - -const wchar_t * -FindStringSuffix(const wchar_t *p, const wchar_t *suffix) noexcept -{ - const size_t p_length = StringLength(p); - const size_t suffix_length = StringLength(suffix); - - if (p_length < suffix_length) - return nullptr; - - const auto *q = p + p_length - suffix_length; - return memcmp(q, suffix, suffix_length * sizeof(*suffix)) == 0 - ? q - : nullptr; -} diff --git a/src/util/WStringCompare.hxx b/src/util/WStringCompare.hxx deleted file mode 100644 index cbc32e64859..00000000000 --- a/src/util/WStringCompare.hxx +++ /dev/null @@ -1,94 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -// author: Max Kellermann - -#pragma once - -#include "WStringAPI.hxx" - -#include -#include - -[[gnu::pure]] [[gnu::nonnull]] -static inline bool -StringIsEmpty(const wchar_t *string) noexcept -{ - return *string == 0; -} - -[[gnu::pure]] -static inline bool -StringIsEqual(std::wstring_view a, std::wstring_view b) noexcept -{ - return a.size() == b.size() && - StringIsEqual(a.data(), b.data(), b.size()); -} - -[[gnu::pure]] -static inline bool -StringIsEqualIgnoreCase(std::wstring_view a, std::wstring_view b) noexcept -{ - return a.size() == b.size() && - StringIsEqualIgnoreCase(a.data(), b.data(), b.size()); -} - -[[gnu::pure]] [[gnu::nonnull]] -static inline bool -StringStartsWith(const wchar_t *haystack, std::wstring_view needle) noexcept -{ - return StringIsEqual(haystack, needle.data(), needle.size()); -} - -[[gnu::pure]] [[gnu::nonnull]] -bool -StringEndsWith(const wchar_t *haystack, const wchar_t *needle) noexcept; - -[[gnu::pure]] [[gnu::nonnull]] -bool -StringEndsWithIgnoreCase(const wchar_t *haystack, - const wchar_t *needle) noexcept; - -/** - * Returns the portion of the string after a prefix. If the string - * does not begin with the specified prefix, this function returns - * nullptr. - */ -[[gnu::pure]] [[gnu::nonnull]] -static inline const wchar_t * -StringAfterPrefix(const wchar_t *haystack, std::wstring_view needle) noexcept -{ - return StringStartsWith(haystack, needle) - ? haystack + needle.size() - : nullptr; -} - -[[gnu::pure]] [[gnu::nonnull]] -static inline bool -StringStartsWithIgnoreCase(const wchar_t *haystack, - std::wstring_view needle) noexcept -{ - return StringIsEqualIgnoreCase(haystack, needle.data(), needle.size()); -} - -/** - * Returns the portion of the string after a prefix. If the string - * does not begin with the specified prefix, this function returns - * nullptr. - * This function is case-independent. - */ -[[gnu::pure]] [[gnu::nonnull]] -static inline const wchar_t * -StringAfterPrefixIgnoreCase(const wchar_t *haystack, - std::wstring_view needle) noexcept -{ - return StringStartsWithIgnoreCase(haystack, needle) - ? haystack + needle.size() - : nullptr; -} - -/** - * Check if the given string ends with the specified suffix. If yes, - * returns the position of the suffix, and nullptr otherwise. - */ -[[gnu::pure]] [[gnu::nonnull]] -const wchar_t * -FindStringSuffix(const wchar_t *p, const wchar_t *suffix) noexcept; diff --git a/src/util/WStringFormat.hpp b/src/util/WStringFormat.hpp deleted file mode 100644 index 673ce9e6b82..00000000000 --- a/src/util/WStringFormat.hpp +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -// author: Max Kellermann - -#pragma once - -#include - -#ifdef _WIN32 -#include -#endif - -template -static inline int -StringFormat(wchar_t *buffer, size_t size, const wchar_t *fmt, - Args&&... args) noexcept -{ - /* unlike snprintf(), _sntprintf() does not guarantee that the - destination buffer is terminated */ - -#ifdef _WIN32 - /* usually, it would be enough to clear the last byte in the output - buffer after the _sntprintf() call, but unfortunately WINE 1.4.1 - has a bug that applies the wrong limit in the overflow branch - (confuses number of characters with number of bytes), therefore - we must clear the whole buffer and pass an even number of - characters; this terminates the string at half the buffer size, - but is better than exposing undefined bytes */ - size &= ~decltype(size)(sizeof(wchar_t) - 1); - memset(buffer, 0, size * sizeof(wchar_t)); - --size; -#endif - - return _snwprintf(buffer, size, fmt, args...); -} - -template -static inline int -StringFormatUnsafe(wchar_t *buffer, const wchar_t *fmt, - Args&&... args) noexcept -{ - /* work around a problem in mingw-w64/libstdc++: libstdc++ defines - __USE_MINGW_ANSI_STDIO=1 and forces mingw to expose the - POSIX-compatible stdio functions instead of the - Microsoft-compatible ones, but those have a major problem for us: - "%s" denotes a "narrow" string, not a "wide" string, and we'd - need to use "%ls"; this workaround explicitly selects the - Microsoft-compatible implementation */ - return _swprintf(buffer, fmt, args...); -} diff --git a/src/util/WStringStrip.cxx b/src/util/WStringStrip.cxx deleted file mode 100644 index 63769709eb1..00000000000 --- a/src/util/WStringStrip.cxx +++ /dev/null @@ -1,88 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -// author: Max Kellermann - -#include "WStringStrip.hxx" -#include "WStringAPI.hxx" -#include "WCharUtil.hxx" - -#include -#include - -const wchar_t * -StripLeft(const wchar_t *p) noexcept -{ - while (IsWhitespaceNotNull(*p)) - ++p; - - return p; -} - -const wchar_t * -StripLeft(const wchar_t *p, const wchar_t *end) noexcept -{ - while (p < end && IsWhitespaceOrNull(*p)) - ++p; - - return p; -} - -std::wstring_view -StripLeft(const std::wstring_view s) noexcept -{ - auto i = std::find_if_not(s.begin(), s.end(), - [](auto ch){ return IsWhitespaceOrNull(ch); }); - - return { - i, - s.end(), - }; -} - -const wchar_t * -StripRight(const wchar_t *p, const wchar_t *end) noexcept -{ - while (end > p && IsWhitespaceOrNull(end[-1])) - --end; - - return end; -} - -size_t -StripRight(const wchar_t *p, size_t length) noexcept -{ - while (length > 0 && IsWhitespaceOrNull(p[length - 1])) - --length; - - return length; -} - -void -StripRight(wchar_t *p) noexcept -{ - size_t old_length = StringLength(p); - size_t new_length = StripRight(p, old_length); - p[new_length] = 0; -} - -std::wstring_view -StripRight(std::wstring_view s) noexcept -{ - auto i = std::find_if_not(s.rbegin(), s.rend(), - [](auto ch){ return IsWhitespaceOrNull(ch); }); - - return s.substr(0, std::distance(i, s.rend())); -} - -wchar_t * -Strip(wchar_t *p) noexcept -{ - p = StripLeft(p); - StripRight(p); - return p; -} - -std::wstring_view -Strip(std::wstring_view s) noexcept -{ - return StripRight(StripLeft(s)); -} diff --git a/src/util/WStringStrip.hxx b/src/util/WStringStrip.hxx deleted file mode 100644 index c0216e82d55..00000000000 --- a/src/util/WStringStrip.hxx +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -// author: Max Kellermann - -#pragma once - -#include - -#include - -/** - * Skips whitespace at the beginning of the string, and returns the - * first non-whitespace character. If the string has no - * non-whitespace characters, then a pointer to the NULL terminator is - * returned. - */ -[[gnu::pure]] [[gnu::returns_nonnull]] [[gnu::nonnull]] -const wchar_t * -StripLeft(const wchar_t *p) noexcept; - -[[gnu::pure]] [[gnu::returns_nonnull]] [[gnu::nonnull]] -static inline wchar_t * -StripLeft(wchar_t *p) noexcept -{ - return const_cast(StripLeft((const wchar_t *)p)); -} - -/** - * Skips whitespace at the beginning of the string, and returns the - * first non-whitespace character or the end pointer. - */ -[[gnu::pure]] [[gnu::returns_nonnull]] [[gnu::nonnull]] -const wchar_t * -StripLeft(const wchar_t *p, const wchar_t *end) noexcept; - -[[gnu::pure]] -std::wstring_view -StripLeft(std::wstring_view s) noexcept; - -/** - * Determine the string's end as if it was stripped on the right side. - */ -[[gnu::pure]] [[gnu::returns_nonnull]] [[gnu::nonnull]] -const wchar_t * -StripRight(const wchar_t *p, const wchar_t *end) noexcept; - -/** - * Determine the string's end as if it was stripped on the right side. - */ -[[gnu::pure]] [[gnu::returns_nonnull]] [[gnu::nonnull]] -static inline wchar_t * -StripRight(wchar_t *p, wchar_t *end) noexcept -{ - return const_cast(StripRight((const wchar_t *)p, - (const wchar_t *)end)); -} - -/** - * Determine the string's length as if it was stripped on the right - * side. - */ -[[gnu::pure]] [[gnu::nonnull]] -size_t -StripRight(const wchar_t *p, size_t length) noexcept; - -/** - * Strip trailing whitespace by null-terminating the string. - */ -[[gnu::nonnull]] -void -StripRight(wchar_t *p) noexcept; - -[[gnu::pure]] -std::wstring_view -StripRight(std::wstring_view s) noexcept; - -/** - * Skip whitespace at the beginning and terminate the string after the - * last non-whitespace character. - */ -[[gnu::returns_nonnull]] [[gnu::nonnull]] -wchar_t * -Strip(wchar_t *p) noexcept; - -[[gnu::pure]] -std::wstring_view -Strip(std::wstring_view s) noexcept; diff --git a/src/util/WStringUtil.cpp b/src/util/WStringUtil.cpp deleted file mode 100644 index 61809c11a54..00000000000 --- a/src/util/WStringUtil.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -// Copyright The XCSoar Project - -#include "WStringUtil.hpp" -#include "WCharUtil.hxx" -#include "Compiler.h" - -#include - -wchar_t * -CopyString(wchar_t *gcc_restrict dest, size_t dest_size, - std::wstring_view src) noexcept -{ - if (src.size() >= dest_size) - src = src.substr(0, dest_size -1); - - wchar_t *p = std::copy(src.begin(), src.end(), dest); - *p = L'\0'; - return p; -} - -wchar_t * -NormalizeSearchString(wchar_t *gcc_restrict dest, - std::wstring_view src) noexcept -{ - wchar_t *retval = dest; - - for (const auto ch : src) - if (IsAlphaNumericASCII(ch)) - *dest++ = ToUpperASCII(ch); - - *dest = L'\0'; - - return retval; -} diff --git a/src/util/WStringUtil.hpp b/src/util/WStringUtil.hpp deleted file mode 100644 index 39bf43fc591..00000000000 --- a/src/util/WStringUtil.hpp +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -// Copyright The XCSoar Project - -#pragma once - -#include - -#include - -/** - * Copy a string. If the buffer is too small, then the string is - * truncated. This is a safer version of strncpy(). - * - * @param dest_size the size of the destination buffer (including the - * null terminator) - * @return a pointer to the null terminator - */ -[[gnu::nonnull]] -wchar_t * -CopyString(wchar_t *dest, size_t dest_size, std::wstring_view src) noexcept; - -[[gnu::nonnull]] -wchar_t * -NormalizeSearchString(wchar_t *dest, std::wstring_view src) noexcept; diff --git a/src/util/msvc/Compiler.h b/src/util/msvc/Compiler.h new file mode 100644 index 00000000000..cb1fcd01786 --- /dev/null +++ b/src/util/msvc/Compiler.h @@ -0,0 +1,107 @@ +/* +Copyright_License { + + XCSoar Glide Computer - http://www.xcsoar.org/ + Copyright (C) 2000-2021 The XCSoar Project + A detailed list of copyright holders can be found in the file "AUTHORS". + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +} +*/ + +#pragma once + +#include +#include "corecrt_math_defines.h" +#include + +#define STRING2(x) #x +#define STRING(x) STRING2(x) + +#define CLANG_OR_GCC_VERSION(x, y) 0 +#define GCC_CHECK_VERSION(x, y) 0 +// #define GCC_OLDER_THAN(x, y) 1 // This isn't a (new!) GCC +#define CLANG_CHECK_VERSION(x, y) 0 + +#define DT_UNDERLINE 0 // gibt es in WinUser.h nicht! + +#define __attribute__(x) +// #define __attribute__(x) __declspec(x) + +#define gcc_const +// not used: #define gcc_deprecated +// not used: #define gcc_may_alias +#define gcc_malloc +#define gcc_noreturn [[noreturn]] // C17++ +#if 0 +// Unfortunately the PACKED structures definition are differently completely +// in MSVC yoe have to work with #pragma, on gcc/clang the definition of this +// is on the end of the structue, maybe this: +// https://stackoverflow.com/questions/1537964/visual-c-equivalent-of-gccs-attribute-packed +#ifdef _MSC_VER +#define PACKED_STRUCT(name) \ + __pragma(pack(push, 1)) struct name __pragma(pack(pop)) +#elif defined(__GNUC__) +#define PACKED_STRUCT(name) struct __attribute__((packed)) name +#endif +#else +#define gcc_packed +#endif + + +#define gcc_printf(a,b) // TODO(August2111): _Printf_format_string_ p +#define gcc_pure // TODO(August2111): is used! +// not used: #define gcc_sentinel // aug: sentinel +#define gcc_unused [[maybe_unused]] // C17++ // aug: unused??? +// not used: #define gcc_warn_unused_result // aug: warn_unused_result + +// not used: #define gcc_nonnull(...) // __assume(__VA_ARGS__ != nullptr) +#define gcc_nonnull_all // __assume(!nullptr) +// not used: #define gcc_returns_nonnull // returns_nonnull + +#define gcc_likely(x) (x) +// aug: __builtin_expect (!!(x), 1) +#define gcc_unlikely(x) (x) +// aug: __builtin_expect (!!(x), 0) + +// not used: #define gcc_aligned(n) // aug: aligned(n) + +// not used: #define gcc_visibility_hidden // aug: visibility("hidden") +// not used: #define gcc_visibility_default // aug: visibility("default") + +#define gcc_always_inline +// inline // wird dann mehrfach verwendet... // aug: always_inline + + +// unuse deprecated functions: +#define strdup(a) _strdup(a) +#define wcsdup(a) _wcsdup(a) + +typedef SSIZE_T ssize_t; + +#define gcc_hot + // not used: #define gcc_cold +#define gcc_flatten +#define gcc_fallthrough [[fallthrough]] // C17++ +#define gcc_restrict + +#ifndef __has_feature + // define dummy macro for non-clang compilers + #define __has_feature(x) 0 +#endif + +#define gcc_unused_field [[maybe_unused]] // C17++ + +#define gcc_unreachable() __assume(0) // GCC: __builtin_unreachable() diff --git a/src/util/tstring.hpp b/src/util/tstring.hpp deleted file mode 100644 index 450ebd5d5b2..00000000000 --- a/src/util/tstring.hpp +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -// Copyright The XCSoar Project - -#pragma once - -#include - -#ifdef _UNICODE -using tstring = std::wstring; -#else -using tstring = std::string; -#endif diff --git a/src/util/tstring_view.hxx b/src/util/tstring_view.hxx deleted file mode 100644 index 4ab300776da..00000000000 --- a/src/util/tstring_view.hxx +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -// author: Max Kellermann - -#pragma once - -#include - -#ifdef _UNICODE -using tstring_view = std::wstring_view; -#else -using tstring_view = std::string_view; -#endif diff --git a/src/zzip/CMakeLists.txt b/src/zzip/CMakeLists.txt new file mode 100644 index 00000000000..9908ea2a2b4 --- /dev/null +++ b/src/zzip/CMakeLists.txt @@ -0,0 +1,65 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + + include(CMakeSource.cmake) + +# organize the files in subdirectories + +if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows" AND WIN32 AND MINGW AND NOT CLANG) + find_program(MINGW_APP NAMES mingw32-make REQUIRED) +endif() + +set(SOURCE_FILES ) +foreach(source_file ${_SOURCES}) + list(APPEND SOURCE_FILES ${source_file}) + string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) + get_filename_component(src_path ${source_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Source\\${src_path}" FILES ${source_file}) + # message(STATUS "### ${src_path} --- ${source_file}") +endforeach() + +if(NOT HEADER_FILES) # STREQUAL "" +file(GLOB_RECURSE HEADER_FILES_TEMP "${CMAKE_CURRENT_SOURCE_DIR}/*.h*") # ;../*.hxx;../*.h +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES_TEMP}" ) +set(HEADER_FILES) +foreach(header_file ${HEADER_FILES_TEMP}) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" header_file ${header_file}) + list(APPEND HEADER_FILES ${header_file}) + get_filename_component(src_path ${header_file} DIRECTORY) + if (src_path) + string(REPLACE "/" "\\" src_path ${src_path}) + endif() + source_group("Header\\${src_path}" FILES ${header_file}) + ## message(STATUS "### ### ${src_path} --- ${header_file}" ) +endforeach() +# message(FATAL_ERROR "### ### Header-Liste --- ${HEADER_FILES}" ) +endif() + +if(WIN32) +# this has to be defined in zzip-Project, not here (but without MSVC!) + add_compile_definitions(ZZIP_1_H) # definition of uint32_t and Co.! + add_compile_definitions(WIN32) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${TARGET_NAME} ${XCSOAR_LIB_TYPE} + ${SOURCE_FILES} + ${HEADER_FILES} + ${SCRIPT_FILES} +) + +# zlib before zzip??? +add_dependencies(${TARGET_NAME} util) + +# message(FATAL_ERROR "Stop!") +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Libs) + +add_dependencies(${TARGET_NAME} util) diff --git a/src/zzip/CMakeSource.cmake b/src/zzip/CMakeSource.cmake new file mode 100644 index 00000000000..ebf8c4460c9 --- /dev/null +++ b/src/zzip/CMakeSource.cmake @@ -0,0 +1,34 @@ +set(ZZIP_DIR ${CMAKE_CURRENT_SOURCE_DIR}) #/zzip) +set(_SOURCES + ${ZZIP_DIR}/fetch.c + ${ZZIP_DIR}/file.c + ${ZZIP_DIR}/plugin.c + ${ZZIP_DIR}/stat.c + ${ZZIP_DIR}/zip.c +) + +set(HEADER_FILES + # zzip/autoconf.h + ${ZZIP_DIR}/conf.h + ${ZZIP_DIR}/fetch.h + ${ZZIP_DIR}/file.h + ${ZZIP_DIR}/format.h + ${ZZIP_DIR}/info.h + ${ZZIP_DIR}/lib.h + ${ZZIP_DIR}/plugin.h + ${ZZIP_DIR}/stdint.h + ${ZZIP_DIR}/types.h + ${ZZIP_DIR}/util.h + ${ZZIP_DIR}/zzip.h + ${ZZIP_DIR}/zzip32.h + ${ZZIP_DIR}/_config.h + ${ZZIP_DIR}/_msvc.h # only for windows host + ${ZZIP_DIR}/__debug.h + ${ZZIP_DIR}/__hints.h + ${ZZIP_DIR}/__mmap.h +) +set(SCRIPT_FILES + ${ZZIP_DIR}/CMakeLists.txt + ${ZZIP_DIR}/CMakeSource.cmake +) + diff --git a/src/zzip/_msvc.h b/src/zzip/_msvc.h new file mode 100644 index 00000000000..e7a98062052 --- /dev/null +++ b/src/zzip/_msvc.h @@ -0,0 +1,275 @@ +#ifndef _ZZIP__MSVC_H +#define _ZZIP__MSVC_H 1 +// TODO(August2111): +// speziell angefertigte Datei für das MSVC-Build (fehlte im zzip-Ordner!) +// mit den defines für VS (müsste es aber im Internet geben! + +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +typedef unsigned long long uint64_t; + +/* zzip/_config.h. Generated automatically at end of configure. */ +/* config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define if building universal (internal helper macro) */ +/* #undef AC_APPLE_UNIVERSAL_BUILD */ + +/* Define if pointers to integers require aligned access */ +/* #undef HAVE_ALIGNED_ACCESS_REQUIRED */ + +/* Define to 1 if you have the header file. */ +#if !defined(__APPLE__) && !defined(WIN32) +#ifndef ZZIP_HAVE_BYTESWAP_H +#define ZZIP_HAVE_BYTESWAP_H 1 +#endif +#endif + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_DIRECT_H */ + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#ifndef ZZIP_HAVE_DIRENT_H +#define ZZIP_HAVE_DIRENT_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef ZZIP_HAVE_DLFCN_H +#define ZZIP_HAVE_DLFCN_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef ZZIP_HAVE_FNMATCH_H +#define ZZIP_HAVE_FNMATCH_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef ZZIP_HAVE_INTTYPES_H +#define ZZIP_HAVE_INTTYPES_H 1 +#endif + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_IO_H */ + +/* Define to 1 if you have the header file. */ +#ifndef ZZIP_HAVE_MEMORY_H +#define ZZIP_HAVE_MEMORY_H 1 +#endif + +/* Define to 1 if you have the header file, and it defines `DIR'. */ +/* #undef HAVE_NDIR_H */ + +/* Define to 1 if you have the header file. */ +#ifndef ZZIP_HAVE_STDINT_H +#define ZZIP_HAVE_STDINT_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef ZZIP_HAVE_STDLIB_H +#define ZZIP_HAVE_STDLIB_H 1 +#endif + +/* Define to 1 if you have the `strcasecmp' function. */ +#ifndef ZZIP_HAVE_STRCASECMP +#define ZZIP_HAVE_STRCASECMP 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef ZZIP_HAVE_STRINGS_H +#define ZZIP_HAVE_STRINGS_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef ZZIP_HAVE_STRING_H +#define ZZIP_HAVE_STRING_H 1 +#endif + +/* Define to 1 if you have the `strndup' function. */ +#ifndef ZZIP_HAVE_STRNDUP +#define ZZIP_HAVE_STRNDUP 1 +#endif + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_SYS_DIR_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_INT_TYPES_H */ + +/* Define to 1 if you have the header file. */ +#ifndef ZZIP_HAVE_SYS_MMAN_H +#define ZZIP_HAVE_SYS_MMAN_H 1 +#endif + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_SYS_NDIR_H */ + +/* Define to 1 if you have the header file. */ +#ifndef ZZIP_HAVE_SYS_PARAM_H +// #define ZZIP_HAVE_SYS_PARAM_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef ZZIP_HAVE_SYS_STAT_H +#define ZZIP_HAVE_SYS_STAT_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef ZZIP_HAVE_SYS_TYPES_H +#define ZZIP_HAVE_SYS_TYPES_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef ZZIP_HAVE_UNISTD_H +// #define ZZIP_HAVE_UNISTD_H 1 +#endif + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_WINBASE_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_WINDOWS_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_WINNT_H */ + +/* Define to 1 if you have the header file. */ +#ifndef ZZIP_HAVE_ZLIB_H +#define ZZIP_HAVE_ZLIB_H 1 +#endif + +/* whether the system defaults to 32bit off_t but can do 64bit when requested + */ +/* #undef LARGEFILE_SENSITIVE */ + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#ifndef ZZIP_LT_OBJDIR +#define ZZIP_LT_OBJDIR ".libs/" +#endif + +/* Name of package */ +#ifndef ZZIP_PACKAGE +#define ZZIP_PACKAGE "zziplib" +#endif + +/* Define to the address where bug reports for this package should be sent. */ +#ifndef ZZIP_PACKAGE_BUGREPORT +#define ZZIP_PACKAGE_BUGREPORT "" +#endif + +/* Define to the full name of this package. */ +#ifndef ZZIP_PACKAGE_NAME +#define ZZIP_PACKAGE_NAME "" +#endif + +/* Define to the full name and version of this package. */ +#ifndef ZZIP_PACKAGE_STRING +#define ZZIP_PACKAGE_STRING "" +#endif + +/* Define to the one symbol short name of this package. */ +#ifndef ZZIP_PACKAGE_TARNAME +#define ZZIP_PACKAGE_TARNAME "" +#endif + +/* Define to the home page for this package. */ +#ifndef ZZIP_PACKAGE_URL +#define ZZIP_PACKAGE_URL "" +#endif + +/* Define to the version of this package. */ +#ifndef ZZIP_PACKAGE_VERSION +#define ZZIP_PACKAGE_VERSION "" +#endif + +/* The number of bytes in type int */ +#ifndef ZZIP_SIZEOF_INT +#define ZZIP_SIZEOF_INT 4 +#endif + +/* The number of bytes in type long */ +#ifndef ZZIP_SIZEOF_LONG +#define ZZIP_SIZEOF_LONG 8 +#endif + +/* The number of bytes in type short */ +#ifndef ZZIP_SIZEOF_SHORT +#define ZZIP_SIZEOF_SHORT 2 +#endif + +/* Define to 1 if you have the ANSI C header files. */ +#ifndef ZZIP_STDC_HEADERS +#define ZZIP_STDC_HEADERS 1 +#endif + +/* Version number of package */ +#ifndef ZZIP_VERSION +#define ZZIP_VERSION "0.13.62" +#endif + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +/* # undef WORDS_BIGENDIAN */ +# endif +#endif + +/* Number of bits in a file offset, on hosts where this is settable. */ +/* #undef _FILE_OFFSET_BITS */ + +/* Define for large files, on AIX-style hosts. */ +/* #undef _LARGE_FILES */ + +/* Define to `long long' if does not define. */ +#ifndef ZZIP___int64 +#define ZZIP___int64 int64_t +#endif + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +/* #undef inline */ +#endif + +/* Define to `_zzip_off_t' if does not define. */ +#ifndef _zzip_off64_t +#define _zzip_off64_t _zzip_off_t +#endif + +/* Define to `long int' if does not define. */ +/* #undef off_t */ + +/* Define to equivalent of C99 restrict keyword, or to nothing if this is not + supported. Do not define if restrict is supported directly. */ +#ifndef _zzip_restrict +// #define _zzip_restrict __restrict__ +#endif + +/* Define to `unsigned int' if does not define. */ +/* #undef size_t */ + +/* Define to `int' if does not define. */ +#ifndef ZZIP_ssize_t +#ifndef HAVE_POSIX +/* we need "int" here because the standard C functions read() and + write() must fit into the zzip_plugin_io struct */ +#define ZZIP_ssize_t int +#endif +#endif + +#include "stdint.h" + +/* once: _ZZIP__CONFIG_H */ +#endif diff --git a/src/zzip/zzip-1.h b/src/zzip/zzip-1.h new file mode 100644 index 00000000000..022b2900e84 --- /dev/null +++ b/src/zzip/zzip-1.h @@ -0,0 +1,276 @@ +#pragma once +// TODO(August2111): +// speziell angefertigte Datei für das MSVC-Build (fehlte im zzip-Ordner!) +// mit den defines für VS (müsste es aber im Internet geben! + +#if 1 +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +typedef unsigned long long uint64_t; +#else +#include "stdint.h" +#endif + +/* zzip/_config.h. Generated automatically at end of configure. */ +/* config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define if building universal (internal helper macro) */ +/* #undef AC_APPLE_UNIVERSAL_BUILD */ + +/* Define if pointers to integers require aligned access */ +/* #undef HAVE_ALIGNED_ACCESS_REQUIRED */ + +/* Define to 1 if you have the header file. */ +#if !defined(__APPLE__) && !defined(WIN32) +#ifndef ZZIP_HAVE_BYTESWAP_H +#define ZZIP_HAVE_BYTESWAP_H 1 +#endif +#endif + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_DIRECT_H */ + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#ifndef ZZIP_HAVE_DIRENT_H +#define ZZIP_HAVE_DIRENT_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef ZZIP_HAVE_DLFCN_H +#define ZZIP_HAVE_DLFCN_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef ZZIP_HAVE_FNMATCH_H +#define ZZIP_HAVE_FNMATCH_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef ZZIP_HAVE_INTTYPES_H +#define ZZIP_HAVE_INTTYPES_H 1 +#endif + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_IO_H */ + +/* Define to 1 if you have the header file. */ +#ifndef ZZIP_HAVE_MEMORY_H +#define ZZIP_HAVE_MEMORY_H 1 +#endif + +/* Define to 1 if you have the header file, and it defines `DIR'. */ +/* #undef HAVE_NDIR_H */ + +/* Define to 1 if you have the header file. */ +#ifndef ZZIP_HAVE_STDINT_H +#define ZZIP_HAVE_STDINT_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef ZZIP_HAVE_STDLIB_H +#define ZZIP_HAVE_STDLIB_H 1 +#endif + +/* Define to 1 if you have the `strcasecmp' function. */ +#ifndef ZZIP_HAVE_STRCASECMP +#define ZZIP_HAVE_STRCASECMP 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef ZZIP_HAVE_STRINGS_H +#define ZZIP_HAVE_STRINGS_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef ZZIP_HAVE_STRING_H +#define ZZIP_HAVE_STRING_H 1 +#endif + +/* Define to 1 if you have the `strndup' function. */ +#ifndef ZZIP_HAVE_STRNDUP +#define ZZIP_HAVE_STRNDUP 1 +#endif + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_SYS_DIR_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_INT_TYPES_H */ + +/* Define to 1 if you have the header file. */ +#ifndef ZZIP_HAVE_SYS_MMAN_H +#define ZZIP_HAVE_SYS_MMAN_H 1 +#endif + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_SYS_NDIR_H */ + +/* Define to 1 if you have the header file. */ +#ifndef ZZIP_HAVE_SYS_PARAM_H +// #define ZZIP_HAVE_SYS_PARAM_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef ZZIP_HAVE_SYS_STAT_H +#define ZZIP_HAVE_SYS_STAT_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef ZZIP_HAVE_SYS_TYPES_H +#define ZZIP_HAVE_SYS_TYPES_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef ZZIP_HAVE_UNISTD_H + #define ZZIP_HAVE_UNISTD_H 1 +#endif + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_WINBASE_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_WINDOWS_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_WINNT_H */ + +/* Define to 1 if you have the header file. */ +#ifndef ZZIP_HAVE_ZLIB_H +#define ZZIP_HAVE_ZLIB_H 1 +#endif + +/* whether the system defaults to 32bit off_t but can do 64bit when requested + */ +/* #undef LARGEFILE_SENSITIVE */ + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#ifndef ZZIP_LT_OBJDIR +#define ZZIP_LT_OBJDIR ".libs/" +#endif + +/* Name of package */ +#ifndef ZZIP_PACKAGE +#define ZZIP_PACKAGE "zziplib" +#endif + +/* Define to the address where bug reports for this package should be sent. */ +#ifndef ZZIP_PACKAGE_BUGREPORT +#define ZZIP_PACKAGE_BUGREPORT "" +#endif + +/* Define to the full name of this package. */ +#ifndef ZZIP_PACKAGE_NAME +#define ZZIP_PACKAGE_NAME "" +#endif + +/* Define to the full name and version of this package. */ +#ifndef ZZIP_PACKAGE_STRING +#define ZZIP_PACKAGE_STRING "" +#endif + +/* Define to the one symbol short name of this package. */ +#ifndef ZZIP_PACKAGE_TARNAME +#define ZZIP_PACKAGE_TARNAME "" +#endif + +/* Define to the home page for this package. */ +#ifndef ZZIP_PACKAGE_URL +#define ZZIP_PACKAGE_URL "" +#endif + +/* Define to the version of this package. */ +#ifndef ZZIP_PACKAGE_VERSION +#define ZZIP_PACKAGE_VERSION "" +#endif + +/* The number of bytes in type int */ +#ifndef ZZIP_SIZEOF_INT +#define ZZIP_SIZEOF_INT 4 +#endif + +/* The number of bytes in type long */ +#ifndef ZZIP_SIZEOF_LONG +#define ZZIP_SIZEOF_LONG 8 +#endif + +/* The number of bytes in type short */ +#ifndef ZZIP_SIZEOF_SHORT +#define ZZIP_SIZEOF_SHORT 2 +#endif + +/* Define to 1 if you have the ANSI C header files. */ +#ifndef ZZIP_STDC_HEADERS +#define ZZIP_STDC_HEADERS 1 +#endif + +/* Version number of package */ +#ifndef ZZIP_VERSION +#define ZZIP_VERSION "0.13.62" +#endif + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +/* # undef WORDS_BIGENDIAN */ +# endif +#endif + +/* Number of bits in a file offset, on hosts where this is settable. */ +/* #undef _FILE_OFFSET_BITS */ + +/* Define for large files, on AIX-style hosts. */ +/* #undef _LARGE_FILES */ + +/* Define to `long long' if does not define. */ +#ifndef ZZIP___int64 +#define ZZIP___int64 int64_t +#endif + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +/* #undef inline */ +#endif + +/* Define to `_zzip_off_t' if does not define. */ +#ifndef _zzip_off64_t +#define _zzip_off64_t _zzip_off_t +#endif + +/* Define to `long int' if does not define. */ +/* #undef off_t */ + +/* Define to equivalent of C99 restrict keyword, or to nothing if this is not + supported. Do not define if restrict is supported directly. */ +#ifndef _zzip_restrict +// #define _zzip_restrict __restrict__ +#endif + +/* Define to `unsigned int' if does not define. */ +/* #undef size_t */ + +/* Define to `int' if does not define. */ +#ifndef ZZIP_ssize_t +#ifndef HAVE_POSIX +/* we need "int" here because the standard C functions read() and + write() must fit into the zzip_plugin_io struct */ +#define ZZIP_ssize_t int +#endif +#endif + +/* once: _ZZIP__CONFIG_H */ + diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 00000000000..50a9a72a85f --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,35 @@ +cmake_minimum_required(VERSION 3.15) +message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +file(GLOB_RECURSE TEST_LIST *.cpp) + +foreach(lib ${XCSOAR_LINK_LIBRARIES}) + message(STATUS "### Add-Library to test: ${lib} ") + +endforeach() +# message(FATAL_ERROR "### Stop !!!!") +foreach(source_file ${TEST_LIST}) +# string(REPLACE "${TARGET_NAME}/" "" source_file ${source_file}) +# list(APPEND SOURCE_FILES ${source_file}) + + add_compile_definitions("__STDC_VERSION__= 199901L") # ? + get_filename_component(test ${source_file} NAME_WE) + get_filename_component(test_path ${source_file} DIRECTORY) + + add_executable(${test} ${source_file} + ${test_path}/tap.c ) +# set_target_properties(${test} PROPERTIES FOLDER _Test) +# set_target_properties(${test} PROPERTIES EXCLUDE_FROM_ALL TRUE) + set_target_properties(${test} PROPERTIES + FOLDER _Test + EXCLUDE_FROM_ALL TRUE + ) + + target_link_libraries(${test} PUBLIC ${XCSOAR_LINK_LIBRARIES}) + + add_dependencies(${test} util libXCSoar) # Dialogs Math) + +# message(STATUS "### ${test_path} --- ${test}") +endforeach() diff --git a/test/data/wp_parser/MBG08.xcm b/test/data/wp_parser/MBG08.xcm index 101d6d59dcd..634e545e08f 100644 Binary files a/test/data/wp_parser/MBG08.xcm and b/test/data/wp_parser/MBG08.xcm differ diff --git a/test/src/AddChecksum.cpp b/test/src/AddChecksum.cpp index 4df3bb79ce7..1584533d0e2 100644 --- a/test/src/AddChecksum.cpp +++ b/test/src/AddChecksum.cpp @@ -26,7 +26,12 @@ int main() } printf("%.*s*%02x\n", (int)(end - buffer), buffer, +#if defined(__APPLE__) && (!defined(TARGET_OS_IPHONE) || !TARGET_OS_IPHONE) + // MacOS workaround + NMEAChecksum(start)); +#else // MacOS NMEAChecksum({start, end})); +#endif // MacOS } return 0; diff --git a/test/src/AnalyseFlight.cpp b/test/src/AnalyseFlight.cpp index 032ff0e0577..0467bb7be13 100644 --- a/test/src/AnalyseFlight.cpp +++ b/test/src/AnalyseFlight.cpp @@ -176,7 +176,7 @@ WriteEventAttributes(const BrokenDateTime &time, o = boost::json::value_from(location).as_object(); if (time.IsPlausible()) { - NarrowString<64> buffer; + StaticString<64> buffer; FormatISO8601(buffer.buffer(), time); o.emplace("time", buffer.c_str()); } diff --git a/test/src/CMakeLists.txt b/test/src/CMakeLists.txt new file mode 100644 index 00000000000..e0da6010f8a --- /dev/null +++ b/test/src/CMakeLists.txt @@ -0,0 +1,66 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + + get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE) + +# file(GLOB_RECURSE TEST_LIST *.cpp) +set(SRC_DIR ${PROJECTGROUP_SOURCE_DIR}/test/src) +include(CMakeSource.cmake) + +### foreach(lib ${XCSOAR_LINK_LIBRARIES}) +### message(STATUS "### Add-Library to test: ${lib} ") +### endforeach() +### message(FATAL_ERROR "### Stop !!!!") + +foreach(source_file ${TEST_LIST}) + message(STATUS "+++ Add Test-Project to test: ${source_file} ") + + add_compile_definitions("__STDC_VERSION__= 199901L") # ? + get_filename_component(test ${source_file} NAME_WE) + get_filename_component(test_path ${source_file} DIRECTORY) + + list(APPEND source_file ${SRC_DIR}/DebugPort.cpp) + list(APPEND source_file ${PROJECTGROUP_SOURCE_DIR}/src/Operation/ConsoleOperationEnvironment.cpp) + add_executable(${test} ${source_file} + ${test_path}/tap.c + ${SCRIPT_FILES} + ) + set_target_properties(${test} PROPERTIES + FOLDER _ConsoleTest + EXCLUDE_FROM_ALL TRUE + ) + target_link_libraries(${test} PUBLIC ${XCSOAR_LINK_LIBRARIES}) + + add_dependencies(${test} util libOpenSoar) + +# message(STATUS "### ${test_path} --- ${test}") +endforeach() + +foreach(source_file ${GUI_TEST_LIST}) + message(STATUS "+++ Add (Gui-)Test-Project to test: ${source_file} ") + + add_compile_definitions("__STDC_VERSION__= 199901L") # ? + get_filename_component(test ${source_file} NAME_WE) + get_filename_component(test_path ${source_file} DIRECTORY) + + list(APPEND source_file ${SRC_DIR}/DebugPort.cpp) + list(APPEND source_file ${PROJECTGROUP_SOURCE_DIR}/src/Operation/ConsoleOperationEnvironment.cpp) + list(APPEND source_file ${SRC_DIR}/Fonts.cpp) + add_executable(${test} ${source_file} + ${test_path}/tap.c + ${SCRIPT_FILES} + ) + set_target_properties(${test} PROPERTIES + FOLDER _GuiTest + EXCLUDE_FROM_ALL TRUE + ) + if(MSVC) + target_link_options(${test} PUBLIC "/SUBSYSTEM:WINDOWS") + endif() + target_link_libraries(${test} PUBLIC ${XCSOAR_LINK_LIBRARIES}) + + add_dependencies(${test} util libOpenSoar) + +endforeach() diff --git a/test/src/CMakeSource.cmake b/test/src/CMakeSource.cmake new file mode 100644 index 00000000000..79a25626c29 --- /dev/null +++ b/test/src/CMakeSource.cmake @@ -0,0 +1,308 @@ +set(TEST_LIST + +# ${SRC_DIR}/AddChecksum.cpp +# ${SRC_DIR}/AirspacePrinting.cpp +# ${SRC_DIR}/AnalyseFlight.cpp +# ${SRC_DIR}/AppendGRecord.cpp +# ${SRC_DIR}/ArcApprox.cpp +# ${SRC_DIR}/BenchmarkFAITriangleSector.cpp +# ${SRC_DIR}/BenchmarkProjection.cpp +# ${SRC_DIR}/CAI302Tool.cpp +# ${SRC_DIR}/ConsoleJobRunner.cpp +# ${SRC_DIR}/ContestPrinting.cpp +# ${SRC_DIR}/DebugDisplay.cpp +# ${SRC_DIR}/DebugPort.cpp +# ${SRC_DIR}/DebugReplay.cpp +# ${SRC_DIR}/DebugReplayIGC.cpp +# ${SRC_DIR}/DebugReplayNMEA.cpp +# ${SRC_DIR}/DownloadFile.cpp +# ${SRC_DIR}/DumpFlarmNet.cpp +# ${SRC_DIR}/DumpHexColor.cpp +# ${SRC_DIR}/DumpTaskFile.cpp +# ${SRC_DIR}/DumpTextInflate.cpp +# ${SRC_DIR}/DumpVario.cpp +# ${SRC_DIR}/EmulateDevice.cpp +# ${SRC_DIR}/EnumeratePorts.cpp +# ${SRC_DIR}/FakeAsset.cpp +# ${SRC_DIR}/FakeDialogs.cpp +# ${SRC_DIR}/FakeGeoid.cpp +# ${SRC_DIR}/FakeHelpDialog.cpp +# ${SRC_DIR}/FakeLanguage.cpp +# ${SRC_DIR}/FakeListPicker.cpp +# ${SRC_DIR}/FakeLogFile.cpp +# ${SRC_DIR}/FakeMessage.cpp +# ${SRC_DIR}/FakeNMEALogger.cpp +# ${SRC_DIR}/FakeProfile.cpp +# ${SRC_DIR}/FakeTerrain.cpp +# ${SRC_DIR}/FeedFlyNetData.cpp +# ${SRC_DIR}/FeedNMEA.cpp +# ${SRC_DIR}/FeedVega.cpp +# ${SRC_DIR}/FixGRecord.cpp +# ${SRC_DIR}/FlightPath.cpp +# ${SRC_DIR}/FlightPhaseDetector.cpp +# ${SRC_DIR}/FlightPhaseJSON.cpp +# ${SRC_DIR}/FlightTable.cpp +# ${SRC_DIR}/Fonts.cpp +# ${SRC_DIR}/IGC2NMEA.cpp +# ${SRC_DIR}/KeyCodeDumper.cpp +# ${SRC_DIR}/LoadImage.cpp +# ${SRC_DIR}/LoadTerrain.cpp +# ${SRC_DIR}/LoadTopography.cpp +# ${SRC_DIR}/LogPort.cpp +# ${SRC_DIR}/NearestWaypoints.cpp +# ${SRC_DIR}/PlayTone.cpp +# ${SRC_DIR}/PlayVario.cpp +# ${SRC_DIR}/Printing.cpp +# ${SRC_DIR}/ReadGRecord.cpp +# ${SRC_DIR}/ReadMO.cpp +# ${SRC_DIR}/ReadPort.cpp +# ${SRC_DIR}/ReadProfileInt.cpp +# ${SRC_DIR}/ReadProfileString.cpp +${SRC_DIR}/RunAirspaceParser.cpp +${SRC_DIR}/RunAirspaceWarningDialog.cpp +${SRC_DIR}/RunAnalysis.cpp +${SRC_DIR}/RunAngleEntry.cpp +${SRC_DIR}/RunCanvas.cpp +${SRC_DIR}/RunChartRenderer.cpp +${SRC_DIR}/RunCirclingWind.cpp +${SRC_DIR}/RunContestAnalysis.cpp +${SRC_DIR}/RunDeclare.cpp +${SRC_DIR}/RunDeviceDriver.cpp +${SRC_DIR}/RunDownloadFlight.cpp +${SRC_DIR}/RunDownloadToFile.cpp +${SRC_DIR}/RunEnableNMEA.cpp +${SRC_DIR}/RunExternalWind.cpp +${SRC_DIR}/RunFAITriangleSectorRenderer.cpp +${SRC_DIR}/RunFinalGlideBarRenderer.cpp +${SRC_DIR}/RunFlarmUtils.cpp +${SRC_DIR}/RunFlightList.cpp +${SRC_DIR}/RunFlightListRenderer.cpp +${SRC_DIR}/RunFlightLogger.cpp +${SRC_DIR}/RunFlightParser.cpp +${SRC_DIR}/RunFlyingComputer.cpp +${SRC_DIR}/RunGeoPointEntry.cpp +${SRC_DIR}/RunHeightMatrix.cpp +${SRC_DIR}/RunHorizonRenderer.cpp +${SRC_DIR}/RunIGCWriter.cpp +${SRC_DIR}/RunInputParser.cpp +${SRC_DIR}/RunJobDialog.cpp +${SRC_DIR}/RunKalmanFilter1d.cpp +${SRC_DIR}/RunLX1600Utils.cpp +${SRC_DIR}/RunListControl.cpp +${SRC_DIR}/RunLiveTrack24.cpp +${SRC_DIR}/RunLua.cpp +${SRC_DIR}/RunMD5.cpp +${SRC_DIR}/RunMapWindow.cpp +${SRC_DIR}/RunNOAADownloader.cpp +${SRC_DIR}/RunNumberEntry.cpp +${SRC_DIR}/RunPortHandler.cpp +${SRC_DIR}/RunProfileListDialog.cpp +${SRC_DIR}/RunProgressWindow.cpp +${SRC_DIR}/RunRenderOZ.cpp +${SRC_DIR}/RunRepositoryParser.cpp +${SRC_DIR}/RunSHA256.cpp +${SRC_DIR}/RunSkyLinesTracking.cpp +${SRC_DIR}/RunTask.cpp +${SRC_DIR}/RunTaskEditorDialog.cpp +${SRC_DIR}/RunTerminal.cpp +${SRC_DIR}/RunTextEntry.cpp +${SRC_DIR}/RunTextWriter.cpp +${SRC_DIR}/RunTimeEntry.cpp +${SRC_DIR}/RunTrace.cpp +${SRC_DIR}/RunVegaSettings.cpp +${SRC_DIR}/RunWPASupplicant.cpp +${SRC_DIR}/RunWaveComputer.cpp +${SRC_DIR}/RunWaypointParser.cpp +${SRC_DIR}/RunWindArrowRenderer.cpp +${SRC_DIR}/RunWindComputer.cpp +${SRC_DIR}/RunWindEKF.cpp +${SRC_DIR}/RunWindZigZag.cpp +${SRC_DIR}/RunXMLParser.cpp + +${SRC_DIR}/RunWeGlideClient.cpp +${SRC_DIR}/TestAATPoint.cpp +${SRC_DIR}/TestARange.cpp +${SRC_DIR}/TestAirspaceParser.cpp +${SRC_DIR}/TestAllocatedGrid.cpp +${SRC_DIR}/TestAngle.cpp +${SRC_DIR}/TestByteSizeFormatter.cpp +${SRC_DIR}/TestCRC8.cpp +${SRC_DIR}/TestCRC16.cpp +${SRC_DIR}/TestCSVLine.cpp +${SRC_DIR}/TestClimbAvCalc.cpp +${SRC_DIR}/TestColorRamp.cpp +${SRC_DIR}/TestDateTime.cpp +${SRC_DIR}/TestDiffFilter.cpp +${SRC_DIR}/TestDriver.cpp +${SRC_DIR}/TestEarth.cpp +${SRC_DIR}/TestFileUtil.cpp +${SRC_DIR}/TestFlarmNet.cpp +${SRC_DIR}/TestFlatGeoPoint.cpp +${SRC_DIR}/TestFlatLine.cpp +${SRC_DIR}/TestFlatPoint.cpp +${SRC_DIR}/TestGRecord.cpp +${SRC_DIR}/TestGeoBounds.cpp +${SRC_DIR}/TestGeoClip.cpp +${SRC_DIR}/TestGeoPoint.cpp +${SRC_DIR}/TestGeoPointFormatter.cpp +${SRC_DIR}/TestGlidePolar.cpp +${SRC_DIR}/TestHexColorFormatter.cpp +${SRC_DIR}/TestHexString.cpp +${SRC_DIR}/TestIGCFilenameFormatter.cpp +${SRC_DIR}/TestIGCParser.cpp +${SRC_DIR}/TestLXNToIGC.cpp +${SRC_DIR}/TestLeastSquares.cpp +${SRC_DIR}/TestLine2D.cpp +${SRC_DIR}/TestLogger.cpp +${SRC_DIR}/TestMETARParser.cpp +${SRC_DIR}/TestMacCready.cpp +${SRC_DIR}/TestMath.cpp +${SRC_DIR}/TestMathTables.cpp +${SRC_DIR}/TestNotify.cpp +${SRC_DIR}/TestOrderedTask.cpp +${SRC_DIR}/TestOverwritingRingBuffer.cpp +${SRC_DIR}/TestPlanes.cpp +${SRC_DIR}/TestPolars.cpp +${SRC_DIR}/TestProfile.cpp +${SRC_DIR}/TestProjection.cpp +${SRC_DIR}/TestQuadrilateral.cpp +${SRC_DIR}/TestRadixTree.cpp +${SRC_DIR}/TestRoughTime.cpp +${SRC_DIR}/TestStrings.cpp +${SRC_DIR}/TestSunEphemeris.cpp +${SRC_DIR}/TestTaskPoint.cpp +${SRC_DIR}/TestTaskSave.cpp +${SRC_DIR}/TestTaskWaypoint.cpp +${SRC_DIR}/TestTeamCode.cpp +${SRC_DIR}/TestThermalBand.cpp +${SRC_DIR}/TestThermalBase.cpp +${SRC_DIR}/TestTimeFormatter.cpp +${SRC_DIR}/TestTrace.cpp +${SRC_DIR}/TestUTF8.cpp +${SRC_DIR}/TestUTM.cpp +${SRC_DIR}/TestUnits.cpp +${SRC_DIR}/TestUnitsFormatter.cpp +${SRC_DIR}/TestValidity.cpp +${SRC_DIR}/TestWaypointReader.cpp +${SRC_DIR}/TestWaypoints.cpp +${SRC_DIR}/TestWrapClock.cpp +${SRC_DIR}/TestZeroFinder.cpp +${SRC_DIR}/TestPolylineDecoder.cpp # add 7.38 +# ${SRC_DIR}/VerifyGRecord.cpp +# ${SRC_DIR}/ViewImage.cpp +# ${SRC_DIR}/WriteTextFile.cpp +# ${SRC_DIR}/harness_aircraft.cpp +# ${SRC_DIR}/harness_airspace.cpp +# ${SRC_DIR}/harness_flight.cpp +# ${SRC_DIR}/harness_task.cpp +# ${SRC_DIR}/harness_task2.cpp +# ${SRC_DIR}/harness_waypoints.cpp +# ${SRC_DIR}/lxn2igc.cpp +# ${SRC_DIR}/test_aat.cpp +# ${SRC_DIR}/test_acfilter.cpp +# ${SRC_DIR}/test_airspace.cpp +# ${SRC_DIR}/test_automc.cpp +# ${SRC_DIR}/test_bestcruisetrack.cpp +# ${SRC_DIR}/test_cruiseefficiency.cpp +# ${SRC_DIR}/test_debug.cpp +# ${SRC_DIR}/test_effectivemc.cpp +# ${SRC_DIR}/test_fixed.cpp +# ${SRC_DIR}/test_flight.cpp +# ${SRC_DIR}/test_highterrain.cpp +# ${SRC_DIR}/test_mc.cpp +# ${SRC_DIR}/test_modes.cpp +# ${SRC_DIR}/test_pressure.cpp +# ${SRC_DIR}/test_randomtask.cpp +# ${SRC_DIR}/test_reach.cpp +# ${SRC_DIR}/test_replay_olc.cpp +# ${SRC_DIR}/test_replay_retrospective.cpp +# ${SRC_DIR}/test_replay_task.cpp +# ${SRC_DIR}/test_route.cpp +# ${SRC_DIR}/test_task.cpp +# ${SRC_DIR}/test_troute.cpp +# ${SRC_DIR}/test_vopt.cpp +) + +set(TEST_LIST + ${SRC_DIR}/UploadFile.cpp + ${SRC_DIR}/RunWeGlideClient.cpp + ${SRC_DIR}/DownloadFile.cpp + ${SRC_DIR}/TestDriver.cpp + ${SRC_DIR}/test_fixed.cpp + ${SRC_DIR}/TestWaypoints.cpp + ${SRC_DIR}/test_pressure.cpp + ${SRC_DIR}/test_task.cpp + ${SRC_DIR}/TestOverwritingRingBuffer.cpp + ${SRC_DIR}/TestDateTime.cpp + ${SRC_DIR}/TestRoughTime.cpp + ${SRC_DIR}/TestWrapClock.cpp + ${SRC_DIR}/TestPolylineDecoder.cpp + ${SRC_DIR}/TestTransponderCode.cpp + ${SRC_DIR}/TestMath.cpp + ${SRC_DIR}/TestMathTables.cpp + ${SRC_DIR}/TestAngle.cpp + ${SRC_DIR}/TestARange.cpp + ${SRC_DIR}/TestGrahamScan.cpp + ${SRC_DIR}/TestUnits.cpp + ${SRC_DIR}/TestEarth.cpp + ${SRC_DIR}/TestSunEphemeris.cpp + ${SRC_DIR}/TestValidity.cpp + ${SRC_DIR}/TestUTM.cpp + ${SRC_DIR}/TestAllocatedGrid.cpp + ${SRC_DIR}/TestRadixTree.cpp + ${SRC_DIR}/TestGeoBounds.cpp + ${SRC_DIR}/TestGeoClip.cpp + ${SRC_DIR}/TestLogger.cpp + ${SRC_DIR}/TestGRecord.cpp + ${SRC_DIR}/TestClimbAvCalc.cpp + ${SRC_DIR}/TestWaypointReader.cpp + ${SRC_DIR}/TestThermalBase.cpp + ${SRC_DIR}/TestFlarmNet.cpp + ${SRC_DIR}/TestColorRamp.cpp + ${SRC_DIR}/TestGeoPoint.cpp + ${SRC_DIR}/TestDiffFilter.cpp + ${SRC_DIR}/TestFileUtil.cpp + ${SRC_DIR}/TestPolars.cpp + ${SRC_DIR}/TestCSVLine.cpp + ${SRC_DIR}/TestGlidePolar.cpp + ${SRC_DIR}/test_replay_task.cpp + ${SRC_DIR}/TestProjection.cpp + ${SRC_DIR}/TestFlatPoint.cpp + ${SRC_DIR}/TestFlatLine.cpp + ${SRC_DIR}/TestFlatGeoPoint.cpp + ${SRC_DIR}/TestMacCready.cpp + ${SRC_DIR}/TestOrderedTask.cpp + ${SRC_DIR}/TestAATPoint.cpp + ${SRC_DIR}/TestPlanes.cpp + ${SRC_DIR}/TestTaskPoint.cpp + ${SRC_DIR}/TestTaskWaypoint.cpp + ${SRC_DIR}/TestTeamCode.cpp + ${SRC_DIR}/TestZeroFinder.cpp + ${SRC_DIR}/TestAirspaceParser.cpp + ${SRC_DIR}/TestMETARParser.cpp + ${SRC_DIR}/TestIGCParser.cpp + ${SRC_DIR}/TestStrings.cpp + ${SRC_DIR}/TestUTF8.cpp + ${SRC_DIR}/TestCRC16.cpp + ${SRC_DIR}/TestCRC8.cpp + ${SRC_DIR}/TestUnitsFormatter.cpp + ${SRC_DIR}/TestGeoPointFormatter.cpp + ${SRC_DIR}/TestHexColorFormatter.cpp + ${SRC_DIR}/TestByteSizeFormatter.cpp + ${SRC_DIR}/TestTimeFormatter.cpp + ${SRC_DIR}/TestIGCFilenameFormatter.cpp + ${SRC_DIR}/TestNMEAFormatter.cpp + ${SRC_DIR}/TestLXNToIGC.cpp + ${SRC_DIR}/TestLeastSquares.cpp + ${SRC_DIR}/TestHexString.cpp + ${SRC_DIR}/TestThermalBand.cpp +) + +set(GUI_TEST_LIST + ${SRC_DIR}/RunWindArrowRenderer.cpp + ${SRC_DIR}/DebugDisplay.cpp +) + +set(SCRIPT_FILES + CMakeSource.cmake +) \ No newline at end of file diff --git a/test/src/ContestPrinting.cpp b/test/src/ContestPrinting.cpp index 0e3b9a8dce0..34b4d544803 100644 --- a/test/src/ContestPrinting.cpp +++ b/test/src/ContestPrinting.cpp @@ -14,7 +14,7 @@ PrintHelper::contestmanager_print(const ContestManager &man, const Trace &trace_triangle, const Trace &trace_sprint) { - Directory::Create(Path(_T("output/results"))); + Directory::Create(Path("output/results")); { std::ofstream fs("output/results/res-olc-trace.txt"); diff --git a/test/src/DebugPort.cpp b/test/src/DebugPort.cpp index f9a5c72ae34..00178059507 100644 --- a/test/src/DebugPort.cpp +++ b/test/src/DebugPort.cpp @@ -19,39 +19,39 @@ ParsePortArgs(Args &args) config.path = args.ExpectNextT().c_str(); #ifndef NDEBUG - if (config.path.equals(_T("dump"))) { + if (config.path.equals("dump")) { config = ParsePortArgs(args); config.dump_port = true; return config; } #endif - if (config.path.equals(_T("k6bt"))) { + if (config.path.equals("k6bt")) { config = ParsePortArgs(args); config.k6bt = true; return config; } - if (config.path.equals(_T("pty"))) { + if (config.path.equals("pty")) { config.port_type = DeviceConfig::PortType::PTY; config.path = args.ExpectNextT().c_str(); return config; } - if (config.path.equals(_T("tcp"))) { + if (config.path.equals("tcp")) { config.port_type = DeviceConfig::PortType::TCP_LISTENER; config.tcp_port = atoi(args.ExpectNext()); return config; } - if (config.path.equals(_T("tcp_client"))) { + if (config.path.equals("tcp_client")) { config.port_type = DeviceConfig::PortType::TCP_CLIENT; config.ip_address = args.ExpectNextT().c_str(); config.tcp_port = atoi(args.ExpectNext()); return config; } - if (config.path.equals(_T("udp"))) { + if (config.path.equals("udp")) { config.port_type = DeviceConfig::PortType::UDP_LISTENER; config.tcp_port = atoi(args.ExpectNext()); return config; diff --git a/test/src/DebugReplayNMEA.cpp b/test/src/DebugReplayNMEA.cpp index 4d330369f0c..6b8e25ddcfe 100644 --- a/test/src/DebugReplayNMEA.cpp +++ b/test/src/DebugReplayNMEA.cpp @@ -23,11 +23,11 @@ DebugReplayNMEA::DebugReplayNMEA(FileLineReaderA *_reader, } DebugReplay* -DebugReplayNMEA::Create(Path input_file, const tstring &driver_name) +DebugReplayNMEA::Create(Path input_file, const std::string &driver_name) { const struct DeviceRegister *driver = FindDriverByName(driver_name.c_str()); if (driver == NULL) { - _ftprintf(stderr, _T("No such driver: %s\n"), driver_name.c_str()); + _ftprintf(stderr, "No such driver: %s\n", driver_name.c_str()); return nullptr; } diff --git a/test/src/DebugReplayNMEA.hpp b/test/src/DebugReplayNMEA.hpp index 7790835b6df..7e4eb7ae9a3 100644 --- a/test/src/DebugReplayNMEA.hpp +++ b/test/src/DebugReplayNMEA.hpp @@ -27,5 +27,5 @@ class DebugReplayNMEA : public DebugReplayFile { public: virtual bool Next(); - static DebugReplay *Create(Path input_file, const tstring &driver_name); + static DebugReplay *Create(Path input_file, const std::string &driver_name); }; diff --git a/test/src/DownloadFile.cpp b/test/src/DownloadFile.cpp index 11f1ddaf043..7036b37ee8b 100644 --- a/test/src/DownloadFile.cpp +++ b/test/src/DownloadFile.cpp @@ -59,7 +59,7 @@ class MyResponseHandler final : public CurlResponseHandler { static void Download(CurlGlobal &curl, const char *url, Path path) { - FILE *file = path != nullptr ? _tfopen(path.c_str(), _T("wb")) : nullptr; + FILE *file = path != nullptr ? _tfopen(path.c_str(), "wb") : nullptr; MyResponseHandler handler(file); CurlRequest request(curl, url, handler); diff --git a/test/src/DumpFlarmNet.cpp b/test/src/DumpFlarmNet.cpp index a0562be4aa7..7a66b2c5f53 100644 --- a/test/src/DumpFlarmNet.cpp +++ b/test/src/DumpFlarmNet.cpp @@ -19,7 +19,7 @@ int main(int argc, char **argv) for (auto i = database.begin(), end = database.end(); i != end; ++i) { const FlarmNetRecord &record = i->second; - _tprintf(_T("%s\t%s\t%s\t%s\n"), + _tprintf("%s\t%s\t%s\t%s\n", record.id.c_str(), record.pilot.c_str(), record.registration.c_str(), record.callsign.c_str()); } diff --git a/test/src/DumpTaskFile.cpp b/test/src/DumpTaskFile.cpp index 126a21bb4c9..8ce4fb07312 100644 --- a/test/src/DumpTaskFile.cpp +++ b/test/src/DumpTaskFile.cpp @@ -46,7 +46,7 @@ try { }); } else { for (const auto &i : file->GetList()) - _tprintf(_T("task: %s\n"), i.c_str()); + _tprintf("task: %s\n", i.c_str()); } return EXIT_SUCCESS; diff --git a/test/src/DumpVario.cpp b/test/src/DumpVario.cpp index 8b0065ef81c..96952277fef 100644 --- a/test/src/DumpVario.cpp +++ b/test/src/DumpVario.cpp @@ -8,7 +8,11 @@ #include #include -#include +#if defined(_WIN32) +# include +#else +# include +#endif int main(int argc, char **argv) diff --git a/test/src/FLARMEmulator.cpp b/test/src/FLARMEmulator.cpp index 249240adc2c..140cab47074 100644 --- a/test/src/FLARMEmulator.cpp +++ b/test/src/FLARMEmulator.cpp @@ -21,7 +21,7 @@ FLARMEmulator::PFLAC_S(NMEAInputLine &line) noexcept const auto name = line.ReadView(); const auto value = line.Rest(); - NarrowString<256> value_buffer; + StaticString<256> value_buffer; value_buffer.SetASCII(value); settings[std::string{name}] = value_buffer; diff --git a/test/src/FakeDialogs.cpp b/test/src/FakeDialogs.cpp index 7057545ad88..3c174c1b4cd 100644 --- a/test/src/FakeDialogs.cpp +++ b/test/src/FakeDialogs.cpp @@ -5,17 +5,17 @@ #include "Dialogs/DataField.hpp" int -ShowMessageBox([[maybe_unused]] const TCHAR *lpText, - [[maybe_unused]] const TCHAR *lpCaption, +ShowMessageBox([[maybe_unused]] const char *lpText, + [[maybe_unused]] const char *lpCaption, [[maybe_unused]] unsigned uType) noexcept { return -1; } bool -EditDataFieldDialog([[maybe_unused]] const TCHAR *caption, +EditDataFieldDialog([[maybe_unused]] const char *caption, [[maybe_unused]] DataField &df, - [[maybe_unused]] const TCHAR *help_text) + [[maybe_unused]] const char *help_text) { return false; } diff --git a/test/src/FakeHelpDialog.cpp b/test/src/FakeHelpDialog.cpp index 6a34d34ae2b..ac6a369dcfb 100644 --- a/test/src/FakeHelpDialog.cpp +++ b/test/src/FakeHelpDialog.cpp @@ -4,6 +4,6 @@ #include "Dialogs/HelpDialog.hpp" void -HelpDialog([[maybe_unused]] const TCHAR *caption, [[maybe_unused]] const TCHAR *text) +HelpDialog([[maybe_unused]] const char *caption, [[maybe_unused]] const char *text) { } diff --git a/test/src/FakeLanguage.cpp b/test/src/FakeLanguage.cpp index a653ad454cf..85752e6c825 100644 --- a/test/src/FakeLanguage.cpp +++ b/test/src/FakeLanguage.cpp @@ -5,8 +5,8 @@ #ifndef USE_LIBINTL -const TCHAR * -gettext(const TCHAR *text) +const char * +gettext(const char *text) { return text; } diff --git a/test/src/FakeListPicker.cpp b/test/src/FakeListPicker.cpp index fb32ef7c818..f92c84c26f8 100644 --- a/test/src/FakeListPicker.cpp +++ b/test/src/FakeListPicker.cpp @@ -4,9 +4,9 @@ #include "Dialogs/ComboPicker.hpp" bool -ComboPicker([[maybe_unused]] const TCHAR *caption, +ComboPicker([[maybe_unused]] const char *caption, [[maybe_unused]] DataField &df, - [[maybe_unused]] const TCHAR *help_text) + [[maybe_unused]] const char *help_text) { return false; } diff --git a/test/src/FakeLogFile.cpp b/test/src/FakeLogFile.cpp index b2e6508ba61..4eef768f0af 100644 --- a/test/src/FakeLogFile.cpp +++ b/test/src/FakeLogFile.cpp @@ -41,22 +41,6 @@ LogFormat(const char *fmt, ...) noexcept fputc('\n', stderr); } -#ifdef _UNICODE - -void -LogFormat(const wchar_t *fmt, ...) noexcept -{ - va_list ap; - - va_start(ap, fmt); - vfwprintf(stderr, fmt, ap); - va_end(ap); - - fputc('\n', stderr); -} - -#endif - void LogError(std::exception_ptr e) noexcept { diff --git a/test/src/FakeMessage.cpp b/test/src/FakeMessage.cpp index a6487e3c30c..6e2ba616485 100644 --- a/test/src/FakeMessage.cpp +++ b/test/src/FakeMessage.cpp @@ -6,8 +6,8 @@ #include void -Message::AddMessage(const TCHAR *text, - [[maybe_unused]] const TCHAR *data) noexcept +Message::AddMessage(const char *text, + [[maybe_unused]] const char *data) noexcept { - _ftprintf(stderr, _T("%s\n"), text); + _ftprintf(stderr, "%s\n", text); } diff --git a/test/src/FakeProfile.cpp b/test/src/FakeProfile.cpp index 511ab77e9bd..6346ee51d38 100644 --- a/test/src/FakeProfile.cpp +++ b/test/src/FakeProfile.cpp @@ -24,9 +24,9 @@ Profile::Get([[maybe_unused]] std::string_view key, bool Profile::Get([[maybe_unused]] std::string_view key, - std::span value) noexcept + std::span value) noexcept { - value[0] = _T('\0'); + value[0] = '\0'; return false; } diff --git a/test/src/FeedFlyNetData.cpp b/test/src/FeedFlyNetData.cpp index b8438a05f7a..5b568363fff 100644 --- a/test/src/FeedFlyNetData.cpp +++ b/test/src/FeedFlyNetData.cpp @@ -48,7 +48,7 @@ try { unsigned battery_level = 11; while (true) { if (pressure_clock.CheckUpdate(std::chrono::milliseconds(48))) { - NarrowString<16> sentence; + StaticString<16> sentence; const auto elapsed = ToFloatSeconds(start_clock.Elapsed()); auto vario = sin(elapsed / 3) * cos(elapsed / 10) * @@ -66,7 +66,7 @@ try { } if (battery_clock.CheckUpdate(std::chrono::seconds(11))) { - NarrowString<16> sentence; + StaticString<16> sentence; sentence = "_BAT "; if (battery_level <= 10) diff --git a/test/src/FlightPhaseJSON.cpp b/test/src/FlightPhaseJSON.cpp index 1b6c421ae09..603e724182f 100644 --- a/test/src/FlightPhaseJSON.cpp +++ b/test/src/FlightPhaseJSON.cpp @@ -42,7 +42,7 @@ static boost::json::object WritePhase(Phase &phase) noexcept { boost::json::object object; - NarrowString<64> buffer; + StaticString<64> buffer; FormatISO8601(buffer.buffer(), phase.start_datetime); object.emplace("start_time", buffer.c_str()); diff --git a/test/src/FlightTable.cpp b/test/src/FlightTable.cpp index 3f622f441b1..bdabef310b3 100644 --- a/test/src/FlightTable.cpp +++ b/test/src/FlightTable.cpp @@ -23,7 +23,7 @@ class FlightCheck { unsigned slow_count, fast_count; public: - FlightCheck(const TCHAR *_name) + FlightCheck(const char *_name) :name(_name), year(0), month(0), day(0), previous_valid(false), takeoff_valid(false), @@ -36,7 +36,7 @@ class FlightCheck { } void print_flight() { - _tprintf(_T("%s,%04u-%02u-%02u,%02u:%02u,%02u:%02u\n"), name.c_str(), + _tprintf("%s,%04u-%02u-%02u,%02u:%02u,%02u:%02u\n", name.c_str(), year, month, day, takeoff.time.hour, takeoff.time.minute, landing.time.hour, landing.time.minute); @@ -140,7 +140,7 @@ IGCFileVisitor::Visit(Path path, Path filename) int main([[maybe_unused]] int argc, [[maybe_unused]] char **argv) try { IGCFileVisitor visitor; - Directory::VisitSpecificFiles(Path(_T(".")), _T("*.igc"), visitor); + Directory::VisitSpecificFiles(Path("."), "*.igc", visitor); return 0; } catch (...) { PrintException(std::current_exception()); diff --git a/test/src/IGC2NMEA.cpp b/test/src/IGC2NMEA.cpp index c9eea2d7d5c..217aad1ddf1 100644 --- a/test/src/IGC2NMEA.cpp +++ b/test/src/IGC2NMEA.cpp @@ -18,7 +18,7 @@ GenerateNMEA(BufferedOutputStream &os, { char gprmc_buffer[100]; FormatGPRMC(gprmc_buffer, sizeof(gprmc_buffer), basic); - NarrowString<256> gprmc("$"); + StaticString<256> gprmc("$"); gprmc.append(gprmc_buffer); AppendNMEAChecksum(gprmc.buffer()); os.Write(gprmc); @@ -26,7 +26,7 @@ GenerateNMEA(BufferedOutputStream &os, char gpgga_buffer[100]; FormatGPGGA(gpgga_buffer, sizeof(gpgga_buffer), basic); - NarrowString<256> gpgga("$"); + StaticString<256> gpgga("$"); gpgga.append(gpgga_buffer); AppendNMEAChecksum(gpgga.buffer()); os.Write(gpgga); @@ -34,7 +34,7 @@ GenerateNMEA(BufferedOutputStream &os, char pgrmz_buffer[100]; FormatPGRMZ(pgrmz_buffer, sizeof(pgrmz_buffer), basic); - NarrowString<256> pgrmz("$"); + StaticString<256> pgrmz("$"); pgrmz.append(pgrmz_buffer); AppendNMEAChecksum(pgrmz.buffer()); os.Write(pgrmz); diff --git a/test/src/KeyCodeDumper.cpp b/test/src/KeyCodeDumper.cpp index ba3692f5c45..d055f5fd130 100644 --- a/test/src/KeyCodeDumper.cpp +++ b/test/src/KeyCodeDumper.cpp @@ -83,12 +83,12 @@ class KeyCodeDumper : public PaintWindow { canvas.SetBackgroundTransparent(); canvas.Select(normal_font); - unsigned text_height = canvas.CalcTextSize(_T("W")).height; + unsigned text_height = canvas.CalcTextSize("W").height; for (int i = num_events - 1, y = 4; i >= 0; --i, y += text_height) { const struct key_event &event = events[i]; - TCHAR buffer[64]; - _stprintf(buffer, _T("key %s = 0x%x"), - event.down ? _T("down") : _T("up"), event.code); + char buffer[64]; + _stprintf(buffer, "key %s = 0x%x", + event.down ? "down" : "up", event.code); canvas.DrawText({4, y}, buffer); } } @@ -102,7 +102,7 @@ class TestWindow final : public UI::SingleWindow { using UI::SingleWindow::SingleWindow; void Create(PixelSize size) { - SingleWindow::Create(_T("KeyCodeDumper"), size); + SingleWindow::Create("KeyCodeDumper", size); PixelRect rc = GetClientRect(); @@ -114,7 +114,7 @@ class TestWindow final : public UI::SingleWindow { button_rc.top = (rc.top + rc.bottom + 1) / 2; close_button.Create(*this, *button_look, - _T("Close"), button_rc, + "Close", button_rc, WindowStyle(), [this](){ Close(); }); diff --git a/test/src/LoadImage.cpp b/test/src/LoadImage.cpp index 91137a29cda..efb9d5db794 100644 --- a/test/src/LoadImage.cpp +++ b/test/src/LoadImage.cpp @@ -28,7 +28,7 @@ ParseCommandLine(Args &args) path = args.ExpectNextPath(); #ifdef USE_GDI - TCHAR *endptr; + char *endptr; unsigned _id = ParseUnsigned(path.c_str(), &endptr); if (StringIsEmpty(endptr)) id = ResourceId(_id); diff --git a/test/src/Main.hpp b/test/src/Main.hpp index 13c98104dab..e0c754932ed 100644 --- a/test/src/Main.hpp +++ b/test/src/Main.hpp @@ -162,7 +162,7 @@ class TestMainWindow : public UI::SingleWindow { SingleWindow::OnCreate(); #ifdef ENABLE_CLOSE_BUTTON - close_button.Create(*this, *button_look, _T("Close"), + close_button.Create(*this, *button_look, "Close", GetCloseButtonRect(GetClientRect()), WindowStyle(), [this](){ Close(); }); @@ -287,7 +287,7 @@ WinMain([[maybe_unused]] HINSTANCE hInstance, [[maybe_unused]] HINSTANCE hPrevIn #ifdef ENABLE_MAIN_WINDOW main_window = new TestMainWindow(screen_init.GetDisplay()); - main_window->Create(_T("Test"), window_size); + main_window->Create("Test", window_size); main_window->Show(); #endif diff --git a/test/src/NearestWaypoints.cpp b/test/src/NearestWaypoints.cpp index cd38cac89a4..26a182b5e44 100644 --- a/test/src/NearestWaypoints.cpp +++ b/test/src/NearestWaypoints.cpp @@ -94,7 +94,7 @@ PrintWaypoint(const Waypoint *waypoint) if (!waypoint) printf("\n"); else - _ftprintf(stdout, _T("%f %f %.0f %s\n"), + _ftprintf(stdout, "%f %f %.0f %s\n", (double)waypoint->location.latitude.Degrees(), (double)waypoint->location.longitude.Degrees(), (double)waypoint->GetElevationOrZero(), diff --git a/test/src/Printing.cpp b/test/src/Printing.cpp index 913a7311156..771282e1980 100644 --- a/test/src/Printing.cpp +++ b/test/src/Printing.cpp @@ -5,14 +5,13 @@ #include "Trace/Trace.hpp" #include "system/FileUtil.hpp" #include "Waypoint/Waypoint.hpp" -#include "util/ConvertString.hpp" #include std::ostream & operator<<(std::ostream &f, Path path) { - f << WideToUTF8Converter(path.c_str()); + f << path.c_str(); return f; } @@ -81,7 +80,7 @@ void PrintHelper::trace_print([[maybe_unused]] const Trace& trace, [[maybe_unused]] const GeoPoint &loc) { - Directory::Create(Path(_T("output/results"))); + Directory::Create(Path("output/results")); std::ofstream fs("output/results/res-trace.txt"); for (auto it = trace.begin(); it != trace.end(); ++it) diff --git a/test/src/RunAirspaceWarningDialog.cpp b/test/src/RunAirspaceWarningDialog.cpp index 440b7fc2c26..7385660dd2e 100644 --- a/test/src/RunAirspaceWarningDialog.cpp +++ b/test/src/RunAirspaceWarningDialog.cpp @@ -27,7 +27,7 @@ #include #include -void VisitDataFiles([[maybe_unused]] const TCHAR* filter, +void VisitDataFiles([[maybe_unused]] const char* filter, [[maybe_unused]] File::Visitor &visitor) {} InterfaceBlackboard CommonInterface::Private::blackboard; @@ -42,7 +42,7 @@ dlgAirspaceDetails([[maybe_unused]] ConstAirspacePtr the_airspace, void ActionInterface::SetActiveFrequency([[maybe_unused]] const RadioFrequency freq, - [[maybe_unused]] const TCHAR * freq_name, + [[maybe_unused]] const char * freq_name, [[maybe_unused]] bool to_devices) noexcept { } diff --git a/test/src/RunAnalysis.cpp b/test/src/RunAnalysis.cpp index 8f101c84987..f2637bef6a0 100644 --- a/test/src/RunAnalysis.cpp +++ b/test/src/RunAnalysis.cpp @@ -173,7 +173,7 @@ Main(UI::Display &display) delete replay; UI::SingleWindow main_window{display}; - main_window.Create(_T("RunAnalysis"), + main_window.Create("RunAnalysis", {640, 480}); dlgAnalysisShowModal(main_window, *look, blackboard, glide_computer, diff --git a/test/src/RunAngleEntry.cpp b/test/src/RunAngleEntry.cpp index b440af79d74..4f9a7c2916f 100644 --- a/test/src/RunAngleEntry.cpp +++ b/test/src/RunAngleEntry.cpp @@ -14,7 +14,7 @@ static void Main([[maybe_unused]] TestMainWindow &main_window) { Angle value = Angle::Zero(); - if (!AngleEntryDialog(_T("The caption"), value)) + if (!AngleEntryDialog("The caption", value)) return; printf("%ld\n", lround(value.Degrees())); diff --git a/test/src/RunCanvas.cpp b/test/src/RunCanvas.cpp index eda60b497e0..efac95efbd0 100644 --- a/test/src/RunCanvas.cpp +++ b/test/src/RunCanvas.cpp @@ -42,7 +42,7 @@ class TestWindow final : public UI::SingleWindow { using UI::SingleWindow::SingleWindow; void Create(PixelSize size) { - SingleWindow::Create(_T("RunCanvas"), size); + SingleWindow::Create("RunCanvas", size); PixelRect rc = GetClientRect(); @@ -54,7 +54,7 @@ class TestWindow final : public UI::SingleWindow { button_rc.left += 5; button_rc.right = button_rc.left + 65; - buffer_button.Create(*this, *button_look, _T("Buffer"), button_rc, + buffer_button.Create(*this, *button_look, "Buffer", button_rc, WindowStyle(), [this](){ buffered = !buffered; @@ -70,7 +70,7 @@ class TestWindow final : public UI::SingleWindow { button_rc.right = rc.right - 5; button_rc.left = button_rc.right - 65; - close_button.Create(*this, *button_look, _T("Close"), button_rc, + close_button.Create(*this, *button_look, "Close", button_rc, WindowStyle(), [this](){ Close(); }); } @@ -98,14 +98,14 @@ class TestWindow final : public UI::SingleWindow { { width * 5, 3000 }, }; - const TCHAR *label; + const char *label; switch (page) { case 0: canvas.DrawSegment(center, std::min(width, height) / 3, Angle::Zero(), Angle::Degrees(90), false); - label = _T("segment 0-90 horizon=false"); + label = "segment 0-90 horizon=false"; break; case 1: @@ -113,13 +113,13 @@ class TestWindow final : public UI::SingleWindow { std::min(width, height) / 3, Angle::Degrees(45), Angle::Degrees(180), true); - label = _T("segment 45-180 horizon=true"); + label = "segment 45-180 horizon=true"; break; case 2: canvas.DrawCircle(center, std::min(width, height) / 3); - label = _T("circle"); + label = "circle"; break; case 3: @@ -132,20 +132,20 @@ class TestWindow final : public UI::SingleWindow { button_renderer.DrawButton(canvas, rc, page == 4 ? ButtonState::PRESSED : ButtonState::ENABLED); label = page == 4 - ? _T("button down=true") : _T("button down=false"); + ? "button down=true" : "button down=false"; } break; case 5: canvas.Select(red_brush); canvas.DrawPolygon(p1, 3); - label = _T("big polygon"); + label = "big polygon"; break; case 6: canvas.Select(red_brush); canvas.DrawPolygon(p2, 3); - label = _T("huge polygon"); + label = "huge polygon"; break; default: @@ -158,7 +158,7 @@ class TestWindow final : public UI::SingleWindow { canvas.DrawText({5, 5}, label); #ifndef ENABLE_OPENGL canvas.DrawText({5, 25}, - buffered ? _T("buffered") : _T("not buffered")); + buffered ? "buffered" : "not buffered"); #endif } diff --git a/test/src/RunChartRenderer.cpp b/test/src/RunChartRenderer.cpp index 315afede39a..20a75de470b 100644 --- a/test/src/RunChartRenderer.cpp +++ b/test/src/RunChartRenderer.cpp @@ -12,9 +12,9 @@ #include "util/Macros.hpp" #include "Renderer/ChartRenderer.hpp" -static const TCHAR *const chart_names[] = { - _T("Line"), - _T("Line2"), +static const char *const chart_names[] = { + "Line", + "Line2", }; class ChartWindow : public PaintWindow { @@ -51,8 +51,8 @@ void ChartWindow::DrawChart(ChartRenderer &renderer) { if (chart == 1) { - renderer.SetXLabel(_T("VVV"),_T("m/s")); - renderer.SetYLabel(_T("AAA"),_T("m/s")); + renderer.SetXLabel("VVV","m/s"); + renderer.SetYLabel("AAA","m/s"); } renderer.Begin(); @@ -84,7 +84,7 @@ ChartWindow::DrawChart(ChartRenderer &renderer) renderer.DrawYGrid(20, 20, ChartRenderer::UnitFormat::NUMERIC); - renderer.DrawLabel({50, 50}, _T("hello")); + renderer.DrawLabel({50, 50}, "hello"); } renderer.Finish(); @@ -104,7 +104,7 @@ class TestWindow : public UI::SingleWindow, } void Create(const DialogLook &look, PixelSize size) { - SingleWindow::Create(_T("RunChartRenderer"), size); + SingleWindow::Create("RunChartRenderer", size); const PixelRect rc = GetClientRect(); @@ -127,7 +127,7 @@ class TestWindow : public UI::SingleWindow, PixelRect button_rc = rc; button_rc.right = list_rc.right; button_rc.top = button_rc.bottom - 30; - close_button.Create(*this, *button_look, _T("Close"), button_rc, + close_button.Create(*this, *button_look, "Close", button_rc, WindowStyle(), [this](){ Close(); }); diff --git a/test/src/RunCirclingWind.cpp b/test/src/RunCirclingWind.cpp index 76f4e931bf2..fbb863150fa 100644 --- a/test/src/RunCirclingWind.cpp +++ b/test/src/RunCirclingWind.cpp @@ -43,10 +43,10 @@ int main(int argc, char **argv) CirclingWind::Result result = circling_wind.NewSample(replay->Basic(), replay->Calculated()); if (result.quality > 0) { - TCHAR time_buffer[32]; + char time_buffer[32]; FormatTime(time_buffer, replay->Basic().time); - _tprintf(_T("%s %d %d %g\n"), + _tprintf("%s %d %d %g\n", time_buffer, result.quality, (int)result.wind.bearing.Degrees(), (double)result.wind.norm); diff --git a/test/src/RunDateEntry.cpp b/test/src/RunDateEntry.cpp index 8a777749f3f..b5b717ae204 100644 --- a/test/src/RunDateEntry.cpp +++ b/test/src/RunDateEntry.cpp @@ -14,7 +14,7 @@ static void Main([[maybe_unused]] TestMainWindow &main_window) { auto value = BrokenDate::TodayUTC(); - if (!DateEntryDialog(_T("The caption"), value, true)) + if (!DateEntryDialog("The caption", value, true)) return; if (value.IsPlausible()) diff --git a/test/src/RunDeclare.cpp b/test/src/RunDeclare.cpp index 793fa91696f..6798788da63 100644 --- a/test/src/RunDeclare.cpp +++ b/test/src/RunDeclare.cpp @@ -33,13 +33,13 @@ PrintMoreUsage() const struct DeviceRegister *driver; for (unsigned i = 0; (driver = GetDriverByIndex(i)) != NULL; ++i) if (driver->HasPassThrough()) - _ftprintf(stderr, _T("\t%s\n"), driver->name); + _ftprintf(stderr, "\t%s\n", driver->name); fputs("Where DRIVER is one of:\n", stderr); for (unsigned i = 0; (driver = GetDriverByIndex(i)) != NULL; ++i) if (driver->CanDeclare()) - _ftprintf(stderr, _T("\t%s\n"), driver->name); + _ftprintf(stderr, "\t%s\n", driver->name); } bool @@ -71,7 +71,7 @@ NMEAParser::TimeHasAdvanced([[maybe_unused]] TimeStamp this_time, } static Waypoint -MakeWaypoint(const TCHAR *name, int altitude, +MakeWaypoint(const char *name, int altitude, double longitude, double latitude) { Waypoint wp(GeoPoint(Angle::Degrees(longitude), @@ -86,8 +86,8 @@ int main(int argc, char **argv) try { Args args(argc, argv, "[--through DRIVER0] DRIVER PORT BAUD"); - tstring _through_name; - const TCHAR *through_name = NULL; + std::string _through_name; + const char *through_name = NULL; const char *a; while ((a = args.PeekNext()) != NULL && *a == '-') { @@ -99,8 +99,8 @@ try { args.UsageError(); } - tstring _driver_name = args.ExpectNextT(); - const TCHAR *driver_name = _driver_name.c_str(); + std::string _driver_name = args.ExpectNextT(); + const char *driver_name = _driver_name.c_str(); DebugPort debug_port(args); args.ExpectEnd(); @@ -117,19 +117,19 @@ try { } LoggerSettings logger_settings; - logger_settings.pilot_name = _T("Foo Bar"); + logger_settings.pilot_name = "Foo Bar"; Plane plane; - plane.registration = _T("D-3003"); - plane.competition_id = _T("33"); - plane.type = _T("Cirrus"); + plane.registration = "D-3003"; + plane.competition_id = "33"; + plane.type = "Cirrus"; Declaration declaration(logger_settings, plane, NULL); - declaration.Append(MakeWaypoint(_T("Bergneustadt"), 488, + declaration.Append(MakeWaypoint("Bergneustadt", 488, 7.7061111111111114, 51.051944444444445)); - declaration.Append(MakeWaypoint(_T("Foo"), 488, 8, 52)); - declaration.Append(MakeWaypoint(_T("Bar"), 488, 7.5, 50)); - declaration.Append(MakeWaypoint(_T("Bergneustadt"), 488, + declaration.Append(MakeWaypoint("Foo", 488, 8, 52)); + declaration.Append(MakeWaypoint("Bar", 488, 7.5, 50)); + declaration.Append(MakeWaypoint("Bergneustadt", 488, 7.7061111111111114, 51.051944444444445)); Device *through_device = NULL; @@ -137,12 +137,12 @@ try { const struct DeviceRegister *through_driver = FindDriverByName(through_name); if (through_driver == NULL) { - _ftprintf(stderr, _T("No such driver: %s\n"), through_name); + _ftprintf(stderr, "No such driver: %s\n", through_name); return EXIT_FAILURE; } if (!through_driver->HasPassThrough()) { - _ftprintf(stderr, _T("Not a pass-through driver: %s\n"), through_name); + _ftprintf(stderr, "Not a pass-through driver: %s\n", through_name); return EXIT_FAILURE; } @@ -154,12 +154,12 @@ try { const struct DeviceRegister *driver = FindDriverByName(driver_name); if (driver == NULL) { - _ftprintf(stderr, _T("No such driver: %s\n"), driver_name); + _ftprintf(stderr, "No such driver: %s\n", driver_name); return EXIT_FAILURE; } if (!driver->CanDeclare()) { - _ftprintf(stderr, _T("Not a logger driver: %s\n"), driver_name); + _ftprintf(stderr, "Not a logger driver: %s\n", driver_name); return EXIT_FAILURE; } @@ -168,7 +168,7 @@ try { assert(device != NULL); if (through_device != NULL && !through_device->EnablePassThrough(env)) { - _ftprintf(stderr, _T("Failed to enable pass-through mode: %s\n"), + _ftprintf(stderr, "Failed to enable pass-through mode: %s\n", through_name); return EXIT_FAILURE; } diff --git a/test/src/RunDeviceDriver.cpp b/test/src/RunDeviceDriver.cpp index 289aa1d4b17..642feec1756 100644 --- a/test/src/RunDeviceDriver.cpp +++ b/test/src/RunDeviceDriver.cpp @@ -11,7 +11,6 @@ #include "Engine/Waypoint/Waypoints.hpp" #include "Input/InputEvents.hpp" #include "system/Args.hpp" -#include "util/ConvertString.hpp" #include "util/StringStrip.hxx" #include @@ -160,24 +159,23 @@ Dump(const NMEAInfo &basic) int main(int argc, char **argv) { - NarrowString<1024> usage; + StaticString<1024> usage; usage = "DRIVER\n\n" "Where DRIVER is one of:"; { const DeviceRegister *driver; for (unsigned i = 0; (driver = GetDriverByIndex(i)) != nullptr; ++i) { - WideToUTF8Converter driver_name(driver->name); - usage.AppendFormat("\n\t%s", (const char *)driver_name); + usage.AppendFormat("\n\t%s", driver->name); } } Args args(argc, argv, usage); - tstring driver_name = args.ExpectNextT(); + std::string driver_name = args.ExpectNextT(); args.ExpectEnd(); driver = FindDriverByName(driver_name.c_str()); if (driver == nullptr) { - _ftprintf(stderr, _T("No such driver: %s\n"), driver_name.c_str()); + _ftprintf(stderr, "No such driver: %s\n", driver_name.c_str()); return 1; } diff --git a/test/src/RunDownloadFlight.cpp b/test/src/RunDownloadFlight.cpp index c1b7792a96f..734419f5d4a 100644 --- a/test/src/RunDownloadFlight.cpp +++ b/test/src/RunDownloadFlight.cpp @@ -16,7 +16,6 @@ #include "io/async/GlobalAsioThread.hpp" #include "io/async/AsioThread.hpp" #include "io/NullDataHandler.hpp" -#include "util/ConvertString.hpp" #include "util/PrintException.hxx" #include @@ -63,21 +62,20 @@ PrintFlightList(const RecordedFlightList &flight_list) int main(int argc, char **argv) try { - NarrowString<1024> usage; + StaticString<1024> usage; usage = "DRIVER PORT BAUD FILE.igc [FLIGHT NR]\n\n" "Where DRIVER is one of:"; { const DeviceRegister *driver; for (unsigned i = 0; (driver = GetDriverByIndex(i)) != NULL; ++i) { if (driver->IsLogger()) { - WideToUTF8Converter driver_name(driver->name); - usage.AppendFormat("\n\t%s", (const char *)driver_name); + usage.AppendFormat("\n\t%s", driver->name); } } } Args args(argc, argv, usage); - tstring driver_name = args.ExpectNextT(); + std::string driver_name = args.ExpectNextT(); DebugPort debug_port(args); const auto path = args.ExpectNextPath(); diff --git a/test/src/RunEnableNMEA.cpp b/test/src/RunEnableNMEA.cpp index fe011b2b986..3808ede03b9 100644 --- a/test/src/RunEnableNMEA.cpp +++ b/test/src/RunEnableNMEA.cpp @@ -26,7 +26,7 @@ PrintMoreUsage() const struct DeviceRegister *driver; for (unsigned i = 0; (driver = GetDriverByIndex(i)) != NULL; ++i) - _ftprintf(stderr, _T("\t%s\n"), driver->name); + _ftprintf(stderr, "\t%s\n", driver->name); } bool @@ -63,8 +63,8 @@ int main(int argc, char **argv) try { Args args(argc, argv, "DRIVER PORT BAUD"); - tstring _driver_name = args.ExpectNextT(); - const TCHAR *driver_name = _driver_name.c_str(); + std::string _driver_name = args.ExpectNextT(); + const char *driver_name = _driver_name.c_str(); DebugPort debug_port(args); args.ExpectEnd(); @@ -75,7 +75,7 @@ try { const struct DeviceRegister *driver = FindDriverByName(driver_name); if (driver == NULL) { - _ftprintf(stderr, _T("No such driver: %s\n"), driver_name); + _ftprintf(stderr, "No such driver: %s\n", driver_name); return EXIT_FAILURE; } diff --git a/test/src/RunExternalWind.cpp b/test/src/RunExternalWind.cpp index 062c56dbf9a..dfb1bf3879e 100644 --- a/test/src/RunExternalWind.cpp +++ b/test/src/RunExternalWind.cpp @@ -27,10 +27,10 @@ int main(int argc, char **argv) if (basic.external_wind_available.Modified(last_available)) { last_available = basic.external_wind_available; - TCHAR time_buffer[32]; + char time_buffer[32]; FormatTime(time_buffer, basic.time); - _tprintf(_T("%s %d %g\n"), + _tprintf("%s %d %g\n", time_buffer, (int)basic.external_wind.bearing.Degrees(), (double)basic.external_wind.norm); diff --git a/test/src/RunFlarmUtils.cpp b/test/src/RunFlarmUtils.cpp index 105abacf69c..7d22f6431c0 100644 --- a/test/src/RunFlarmUtils.cpp +++ b/test/src/RunFlarmUtils.cpp @@ -11,7 +11,6 @@ #include "Device/Config.hpp" #include "system/Args.hpp" #include "util/StringStrip.hxx" -#include "util/ConvertString.hpp" #include "util/PrintException.hxx" #include "Operation/ConsoleOperationEnvironment.hpp" #include "io/async/GlobalAsioThread.hpp" @@ -24,9 +23,9 @@ static void ChangePilot(FlarmDevice &flarm, OperationEnvironment &env) { while (true) { - TCHAR old_pilot_name[64]; + char old_pilot_name[64]; if (flarm.GetPilot(old_pilot_name, 64, env)) - _tprintf(_T("Old pilot name: \"%s\"\n"), old_pilot_name); + _tprintf("Old pilot name: \"%s\"\n", old_pilot_name); fprintf(stdout, "Please enter the new pilot name:\n"); fprintf(stdout, "> "); @@ -40,8 +39,7 @@ ChangePilot(FlarmDevice &flarm, OperationEnvironment &env) StripRight(pilot_name); fprintf(stdout, "Setting pilot name to \"%s\" ...\n", pilot_name); - const UTF8ToWideConverter value(pilot_name); - if (flarm.SetPilot(value, env)) + if (flarm.SetPilot(pilot_name, env)) fprintf(stdout, "Pilot name set to \"%s\"\n", pilot_name); else fprintf(stdout, "Operation failed!\n"); @@ -54,9 +52,9 @@ static void ChangeCoPilot(FlarmDevice &flarm, OperationEnvironment &env) { while (true) { - TCHAR old_copilot_name[64]; + char old_copilot_name[64]; if (flarm.GetCoPilot(old_copilot_name, 64, env)) - _tprintf(_T("Old copilot name: \"%s\"\n"), old_copilot_name); + _tprintf("Old copilot name: \"%s\"\n", old_copilot_name); fprintf(stdout, "Please enter the new copilot name:\n"); fprintf(stdout, "> "); @@ -70,8 +68,7 @@ ChangeCoPilot(FlarmDevice &flarm, OperationEnvironment &env) StripRight(copilot_name); fprintf(stdout, "Setting copilot name to \"%s\" ...\n", copilot_name); - const UTF8ToWideConverter value(copilot_name); - if (flarm.SetCoPilot(value, env)) + if (flarm.SetCoPilot(copilot_name, env)) fprintf(stdout, "CoPilot name set to \"%s\"\n", copilot_name); else fprintf(stdout, "Operation failed!\n"); @@ -84,9 +81,9 @@ static void ChangePlaneType(FlarmDevice &flarm, OperationEnvironment &env) { while (true) { - TCHAR old_plane_type[64]; + char old_plane_type[64]; if (flarm.GetPlaneType(old_plane_type, 64, env)) - _tprintf(_T("Old plane type: \"%s\"\n"), old_plane_type); + _tprintf("Old plane type: \"%s\"\n", old_plane_type); fprintf(stdout, "Please enter the new plane type:\n"); fprintf(stdout, "> "); @@ -100,8 +97,7 @@ ChangePlaneType(FlarmDevice &flarm, OperationEnvironment &env) StripRight(plane_type); fprintf(stdout, "Setting plane type to \"%s\" ...\n", plane_type); - const UTF8ToWideConverter value(plane_type); - if (flarm.SetPlaneType(value, env)) + if (flarm.SetPlaneType(plane_type, env)) fprintf(stdout, "Plane type set to \"%s\"\n", plane_type); else fprintf(stdout, "Operation failed!\n"); @@ -114,9 +110,9 @@ static void ChangeRegistration(FlarmDevice &flarm, OperationEnvironment &env) { while (true) { - TCHAR old_registration[64]; + char old_registration[64]; if (flarm.GetPlaneRegistration(old_registration, 64, env)) - _tprintf(_T("Old plane registratio: \"%s\"\n"), old_registration); + _tprintf("Old plane registratio: \"%s\"\n", old_registration); fprintf(stdout, "Please enter the new plane registration:\n"); fprintf(stdout, "> "); @@ -130,8 +126,7 @@ ChangeRegistration(FlarmDevice &flarm, OperationEnvironment &env) StripRight(registration); fprintf(stdout, "Setting plane registration to \"%s\" ...\n", registration); - const UTF8ToWideConverter value(registration); - if (flarm.SetPlaneRegistration(value, env)) + if (flarm.SetPlaneRegistration(registration, env)) fprintf(stdout, "Plane registration set to \"%s\"\n", registration); else fprintf(stdout, "Operation failed!\n"); @@ -144,9 +139,9 @@ static void ChangeCompetitionId(FlarmDevice &flarm, OperationEnvironment &env) { while (true) { - TCHAR old_id[64]; + char old_id[64]; if (flarm.GetCompetitionId(old_id, 64, env)) - _tprintf(_T("Old competition id: \"%s\"\n"), old_id); + _tprintf("Old competition id: \"%s\"\n", old_id); fprintf(stdout, "Please enter the new competition id:\n"); fprintf(stdout, "> "); @@ -160,8 +155,7 @@ ChangeCompetitionId(FlarmDevice &flarm, OperationEnvironment &env) StripRight(id); fprintf(stdout, "Setting competition id to \"%s\" ...\n", id); - const UTF8ToWideConverter value(id); - if (flarm.SetCompetitionId(value, env)) + if (flarm.SetCompetitionId(id, env)) fprintf(stdout, "competition id set to \"%s\"\n", id); else fprintf(stdout, "Operation failed!\n"); @@ -174,9 +168,9 @@ static void ChangeCompetitionClass(FlarmDevice &flarm, OperationEnvironment &env) { while (true) { - TCHAR old_comp_class[64]; + char old_comp_class[64]; if (flarm.GetCompetitionClass(old_comp_class, 64, env)) - _tprintf(_T("Old competition class: \"%s\"\n"), old_comp_class); + _tprintf("Old competition class: \"%s\"\n", old_comp_class); fprintf(stdout, "Please enter the new competition class:\n"); fprintf(stdout, "> "); @@ -190,8 +184,7 @@ ChangeCompetitionClass(FlarmDevice &flarm, OperationEnvironment &env) StripRight(comp_class); fprintf(stdout, "Setting competition class to \"%s\" ...\n", comp_class); - const UTF8ToWideConverter value(comp_class); - if (flarm.SetCompetitionClass(value, env)) + if (flarm.SetCompetitionClass(comp_class, env)) fprintf(stdout, "Competition class set to \"%s\"\n", comp_class); else fprintf(stdout, "Operation failed!\n"); diff --git a/test/src/RunFlightList.cpp b/test/src/RunFlightList.cpp index 0e6ef7fb959..a7e2993a448 100644 --- a/test/src/RunFlightList.cpp +++ b/test/src/RunFlightList.cpp @@ -17,7 +17,6 @@ #include "io/async/GlobalAsioThread.hpp" #include "io/async/AsioThread.hpp" #include "io/NullDataHandler.hpp" -#include "util/ConvertString.hpp" #include "util/PrintException.hxx" #include @@ -57,21 +56,20 @@ NMEAParser::TimeHasAdvanced([[maybe_unused]] TimeStamp this_time, int main(int argc, char **argv) try { - NarrowString<1024> usage; + StaticString<1024> usage; usage = "DRIVER PORT BAUD\n\n" "Where DRIVER is one of:"; { const DeviceRegister *driver; for (unsigned i = 0; (driver = GetDriverByIndex(i)) != NULL; ++i) { if (driver->IsLogger()) { - WideToUTF8Converter driver_name(driver->name); - usage.AppendFormat("\n\t%s", (const char *)driver_name); + usage.AppendFormat("\n\t%s", driver->name); } } } Args args(argc, argv, usage); - tstring driver_name = args.ExpectNextT(); + std::string driver_name = args.ExpectNextT(); DebugPort debug_port(args); args.ExpectEnd(); diff --git a/test/src/RunFlightListRenderer.cpp b/test/src/RunFlightListRenderer.cpp index 761bdff6c09..a85886aaccc 100644 --- a/test/src/RunFlightListRenderer.cpp +++ b/test/src/RunFlightListRenderer.cpp @@ -45,13 +45,13 @@ class MainWindow final : public UI::SingleWindow using UI::SingleWindow::SingleWindow; void Create(PixelSize size) { - SingleWindow::Create(_T("Test"), size); + SingleWindow::Create("Test", size); WindowStyle style; style.Disable(); const PixelRect rc = GetClientRect(); - close_button.Create(*this, *button_look, _T("Close"), GetButtonRect(rc), + close_button.Create(*this, *button_look, "Close", GetButtonRect(rc), WindowStyle(), [this](){ Close(); }); test_window.Create(*this, rc, style); diff --git a/test/src/RunFlyingComputer.cpp b/test/src/RunFlyingComputer.cpp index fd856dd5156..790b5d00d59 100644 --- a/test/src/RunFlyingComputer.cpp +++ b/test/src/RunFlyingComputer.cpp @@ -10,12 +10,12 @@ #include static void -LogEvent(const TCHAR *event, TimeStamp time, const GeoPoint &location) noexcept +LogEvent(const char *event, TimeStamp time, const GeoPoint &location) noexcept { - TCHAR time_buffer[32]; + char time_buffer[32]; FormatTime(time_buffer, time); - _tprintf(_T("%s %s %s\n"), time_buffer, + _tprintf("%s %s %s\n", time_buffer, FormatGeoPoint(location, CoordinateFormat::DDMMSS).c_str(), event); } @@ -35,11 +35,11 @@ int main(int argc, char **argv) const FlyingState &flight = replay->Calculated().flight; if (flight.flying && !last_flying) - LogEvent(_T("take-off"), flight.takeoff_time, flight.takeoff_location); + LogEvent("take-off", flight.takeoff_time, flight.takeoff_location); else if (!flight.flying && last_flying) - LogEvent(_T("landing"), flight.landing_time, flight.landing_location); + LogEvent("landing", flight.landing_time, flight.landing_location); else if (flight.release_time.IsDefined() && !last_released) - LogEvent(_T("release"), flight.release_time, flight.release_location); + LogEvent("release", flight.release_time, flight.release_location); last_flying = flight.flying; last_released = flight.release_time.IsDefined(); @@ -47,7 +47,7 @@ int main(int argc, char **argv) const FlyingState &flight = replay->Calculated().flight; if (flight.far_distance >= 0) - _tprintf(_T("far %u km at %s\n"), unsigned(flight.far_distance / 1000), + _tprintf("far %u km at %s\n", unsigned(flight.far_distance / 1000), FormatGeoPoint(flight.far_location, CoordinateFormat::DDMMSS).c_str()); diff --git a/test/src/RunGeoPointEntry.cpp b/test/src/RunGeoPointEntry.cpp index 3153434d5fd..5ced25e8f13 100644 --- a/test/src/RunGeoPointEntry.cpp +++ b/test/src/RunGeoPointEntry.cpp @@ -20,11 +20,11 @@ Main([[maybe_unused]] TestMainWindow &main_window) GeoPoint value = GeoPoint(Angle::Degrees(7.7061111111111114), Angle::Degrees(51.051944444444445)); - if (!GeoPointEntryDialog(_T("The caption"), value, format, true)) + if (!GeoPointEntryDialog("The caption", value, format, true)) return; if (value.IsValid()) - _tprintf(_T("%s\n"), + _tprintf("%s\n", FormatGeoPoint(value, CoordinateFormat::DDMMSS).c_str()); else printf("invalid\n"); diff --git a/test/src/RunIGCWriter.cpp b/test/src/RunIGCWriter.cpp index 0e9d06a34fd..7be87562c39 100644 --- a/test/src/RunIGCWriter.cpp +++ b/test/src/RunIGCWriter.cpp @@ -23,12 +23,12 @@ int main(int argc, char **argv) if (!replay->Next()) return 0; - const TCHAR *driver_name = _T("Unknown"); + const char *driver_name = "Unknown"; IGCWriter writer(output_file); - writer.WriteHeader(replay->Basic().date_time_utc, _T("Manfred Mustermann"), _T("Manuela Mustermann"), - _T("Ventus"), _T("D-1234"), - _T("MM"), "FOO", driver_name, true); + writer.WriteHeader(replay->Basic().date_time_utc, "Manfred Mustermann", "Manuela Mustermann", + "Ventus", "D-1234", + "MM", "FOO", driver_name, true); GPSClock log_clock; while (replay->Next()) diff --git a/test/src/RunInputParser.cpp b/test/src/RunInputParser.cpp index b69dc9bd8f9..a6326cad085 100644 --- a/test/src/RunInputParser.cpp +++ b/test/src/RunInputParser.cpp @@ -13,10 +13,10 @@ #include pt2Event -InputEvents::findEvent(tstring_view name) noexcept +InputEvents::findEvent(std::string_view name) noexcept { union { - const TCHAR *in; + const char *in; pt2Event out; } u; @@ -25,13 +25,13 @@ InputEvents::findEvent(tstring_view name) noexcept } int -InputEvents::findGCE([[maybe_unused]] const TCHAR *data) +InputEvents::findGCE([[maybe_unused]] const char *data) { return -1; } int -InputEvents::findNE([[maybe_unused]] const TCHAR *data) +InputEvents::findNE([[maybe_unused]] const char *data) { return -1; } @@ -39,8 +39,8 @@ InputEvents::findNE([[maybe_unused]] const TCHAR *data) static void Dump(InputConfig::Event &event, unsigned id) { - _tprintf(_T(" Event[%u]: '%s' misc='%s'\n"), id, - (const TCHAR *)event.event, event.misc); + _tprintf(" Event[%u]: '%s' misc='%s'\n", id, + (const char *)event.event, event.misc); } int main(int argc, char **argv) @@ -59,7 +59,7 @@ try { } for (unsigned mode = 0; mode < config.modes.size(); ++mode) { - _tprintf(_T("Mode '%s'\n"), config.modes[mode].c_str()); + _tprintf("Mode '%s'\n", config.modes[mode].c_str()); for (unsigned key = 0; key < InputConfig::MAX_KEY; ++key) { unsigned event = config.Key2Event[mode][key]; @@ -78,7 +78,7 @@ try { for (unsigned i = 0; i < Menu::MAX_ITEMS; ++i) { const MenuItem &mi = config.menus[mode][i]; if (mi.IsDefined()) { - _tprintf(_T(" Menu[%u] = '%s'\n"), i, mi.label); + _tprintf(" Menu[%u] = '%s'\n", i, mi.label); unsigned event = mi.event; assert(event < InputConfig::MAX_EVENTS); do { diff --git a/test/src/RunJobDialog.cpp b/test/src/RunJobDialog.cpp index 9fa90a20d47..a9a06be7634 100644 --- a/test/src/RunJobDialog.cpp +++ b/test/src/RunJobDialog.cpp @@ -12,7 +12,7 @@ class TestJob : public Job { public: virtual void Run(OperationEnvironment &env) { - env.SetText(_T("Working...")); + env.SetText("Working..."); env.SetProgressRange(30); for (unsigned i = 0; i < 30 && !env.IsCancelled(); ++i) { env.SetProgressPosition(i); @@ -25,5 +25,5 @@ static void Main(TestMainWindow &main_window) { TestJob job; - JobDialog(main_window, *dialog_look, _T("RunJobDialog"), job); + JobDialog(main_window, *dialog_look, "RunJobDialog", job); } diff --git a/test/src/RunListControl.cpp b/test/src/RunListControl.cpp index 0dfc63bd335..d7bb9fa5d36 100644 --- a/test/src/RunListControl.cpp +++ b/test/src/RunListControl.cpp @@ -12,8 +12,8 @@ static void PaintItemCallback(Canvas &canvas, const PixelRect rc, unsigned idx) { - TCHAR text[32]; - _stprintf(text, _T("%u"), idx); + char text[32]; + _stprintf(text, "%u", idx); canvas.DrawText(rc.WithPadding(2).GetTopLeft(), text); } @@ -21,7 +21,7 @@ static void Main(TestMainWindow &main_window) { WndForm form(*dialog_look); - form.Create(main_window, _T("RunListControl")); + form.Create(main_window, "RunListControl"); ContainerWindow &client_area = form.GetClientAreaWindow(); PixelRect list_rc = client_area.GetClientRect(); diff --git a/test/src/RunLiveTrack24.cpp b/test/src/RunLiveTrack24.cpp index fc51bccd9ef..cf759f86f15 100644 --- a/test/src/RunLiveTrack24.cpp +++ b/test/src/RunLiveTrack24.cpp @@ -30,14 +30,14 @@ TestTracking(int argc, char *argv[], LiveTrack24::Client &client) bool has_user_id; UserID user_id; - tstring username, password; + std::string username, password; if (args.IsEmpty()) { - username = _T(""); - password = _T(""); + username = ""; + password = ""; has_user_id = false; } else { username = args.ExpectNextT(); - password = args.IsEmpty() ? _T("") : args.ExpectNextT(); + password = args.IsEmpty() ? "" : args.ExpectNextT(); user_id = co_await client.GetUserID(username.c_str(), password.c_str()); has_user_id = (user_id != 0); @@ -51,7 +51,7 @@ TestTracking(int argc, char *argv[], LiveTrack24::Client &client) printf("Starting tracking ... "); co_await client.StartTracking(session, username.c_str(), password.c_str(), 10, - VehicleType::GLIDER, _T("Hornet")); + VehicleType::GLIDER, "Hornet"); printf("done\n"); BrokenDate now = BrokenDate::TodayUTC(); @@ -90,7 +90,7 @@ try { Instance instance; Client client{*Net::curl}; - client.SetServer(_T("www.livetrack24.com")); + client.SetServer("www.livetrack24.com"); instance.Run(TestTracking(argc, argv, client)); return EXIT_SUCCESS; } catch (...) { diff --git a/test/src/RunNOAADownloader.cpp b/test/src/RunNOAADownloader.cpp index e122fc3ef52..bd57ad0df77 100644 --- a/test/src/RunNOAADownloader.cpp +++ b/test/src/RunNOAADownloader.cpp @@ -40,41 +40,41 @@ DisplayParsedMETAR(const NOAAStore::Item &station) printf("Parsed Data:\n"); if (parsed.name_available) - _tprintf(_T("Name: %s\n"), parsed.name.c_str()); + _tprintf("Name: %s\n", parsed.name.c_str()); if (parsed.location_available) - _tprintf(_T("Location: %s\n"), + _tprintf("Location: %s\n", FormatGeoPoint(parsed.location, CoordinateFormat::DDMMSS).c_str()); if (parsed.qnh_available) { - TCHAR buffer[256]; + char buffer[256]; FormatUserPressure(parsed.qnh, buffer); - _tprintf(_T("QNH: %s\n"), buffer); + _tprintf("QNH: %s\n", buffer); } if (parsed.wind_available) { - TCHAR buffer[256]; + char buffer[256]; FormatUserWindSpeed(parsed.wind.norm, buffer); - _tprintf(_T("Wind: %.0f" DEG " %s\n"), + _tprintf("Wind: %.0f" DEG " %s\n", (double)parsed.wind.bearing.Degrees(), buffer); } if (parsed.temperatures_available) { - TCHAR buffer[256]; + char buffer[256]; FormatUserTemperature(parsed.temperature, buffer); - _tprintf(_T("Temperature: %s\n"), buffer); + _tprintf("Temperature: %s\n", buffer); FormatUserTemperature(parsed.dew_point, buffer); - _tprintf(_T("Dew point: %s\n"), buffer); + _tprintf("Dew point: %s\n", buffer); } if (parsed.visibility_available) { - TCHAR buffer[256]; + char buffer[256]; if (parsed.visibility >= 9999) - _tcscpy(buffer, _T("unlimited")); + strcpy(buffer, "unlimited"); else { FormatUserDistanceSmart(parsed.visibility, buffer); } - _tprintf(_T("Visibility: %s\n"), buffer); + _tprintf("Visibility: %s\n", buffer); } printf("\n"); @@ -99,10 +99,10 @@ DisplayMETAR(const NOAAStore::Item &station) (unsigned)metar.last_update.second); if (!metar.content.empty()) - _tprintf(_T("%s\n\n"), metar.content.c_str()); + _tprintf("%s\n\n", metar.content.c_str()); if (!metar.decoded.empty()) - _tprintf(_T("%s\n\n"), metar.decoded.c_str()); + _tprintf("%s\n\n", metar.decoded.c_str()); DisplayParsedMETAR(station); } @@ -126,7 +126,7 @@ DisplayTAF(const NOAAStore::Item &station) (unsigned)taf.last_update.second); if (!taf.content.empty()) - _tprintf(_T("%s\n\n"), taf.content.c_str()); + _tprintf("%s\n\n", taf.content.c_str()); } int diff --git a/test/src/RunNumberEntry.cpp b/test/src/RunNumberEntry.cpp index 67be01ed20c..b570f94c5bd 100644 --- a/test/src/RunNumberEntry.cpp +++ b/test/src/RunNumberEntry.cpp @@ -13,6 +13,6 @@ static void Main([[maybe_unused]] TestMainWindow &main_window) { unsigned value; - if (NumberEntryDialog(_T("The caption"), value, 6)) + if (NumberEntryDialog("The caption", value, 6)) printf("%u\n", value); } diff --git a/test/src/RunProfileListDialog.cpp b/test/src/RunProfileListDialog.cpp index 5fb16b7b135..3c88cd09120 100644 --- a/test/src/RunProfileListDialog.cpp +++ b/test/src/RunProfileListDialog.cpp @@ -10,9 +10,9 @@ #include "Dialogs/DataField.hpp" bool -EditDataFieldDialog([[maybe_unused]] const TCHAR *caption, +EditDataFieldDialog([[maybe_unused]] const char *caption, [[maybe_unused]] DataField &df, - [[maybe_unused]] const TCHAR *help_text) + [[maybe_unused]] const char *help_text) { return false; } diff --git a/test/src/RunProgressWindow.cpp b/test/src/RunProgressWindow.cpp index 7e0a1ba2d77..76f3b2b009f 100644 --- a/test/src/RunProgressWindow.cpp +++ b/test/src/RunProgressWindow.cpp @@ -11,7 +11,7 @@ static void Main(TestMainWindow &main_window) { ProgressWindow progress(main_window); - progress.SetMessage(_T("Testing...")); + progress.SetMessage("Testing..."); progress.SetRange(0, 1024); progress.SetValue(768); diff --git a/test/src/RunRenderOZ.cpp b/test/src/RunRenderOZ.cpp index c81d06c7bf6..c5e5b5e6238 100644 --- a/test/src/RunRenderOZ.cpp +++ b/test/src/RunRenderOZ.cpp @@ -29,19 +29,19 @@ enum { NUM_OZ_TYPES = 12, }; -static const TCHAR *const oz_type_names[NUM_OZ_TYPES] = { - _T("Line"), - _T("Cylinder"), - _T("MAT Cylinder"), - _T("Sector"), - _T("FAI Sector"), - _T("DAeC Keyhole"), - _T("BGA Fixed Course"), - _T("BGA Enhanced Option"), - _T("BGA Start"), - _T("Annular sector"), - _T("Symmetric quadrant"), - _T("Custom Keyhole"), +static const char *const oz_type_names[NUM_OZ_TYPES] = { + "Line", + "Cylinder", + "MAT Cylinder", + "Sector", + "FAI Sector", + "DAeC Keyhole", + "BGA Fixed Course", + "BGA Enhanced Option", + "BGA Start", + "Annular sector", + "Symmetric quadrant", + "Custom Keyhole", }; static GeoPoint location(Angle::Degrees(7.7061111111111114), @@ -188,7 +188,7 @@ class TestWindow : public UI::SingleWindow, } void Create(const DialogLook &look, PixelSize size) { - SingleWindow::Create(_T("RunRenderOZ"), size); + SingleWindow::Create("RunRenderOZ", size); const PixelRect rc = GetClientRect(); @@ -211,7 +211,7 @@ class TestWindow : public UI::SingleWindow, PixelRect button_rc = rc; button_rc.right = (rc.left + rc.right) / 2; button_rc.top = button_rc.bottom - 30; - close_button.Create(*this, *button_look, _T("Close"), button_rc, + close_button.Create(*this, *button_look, "Close", button_rc, WindowStyle(), [this](){ Close(); }); diff --git a/test/src/RunTaskEditorDialog.cpp b/test/src/RunTaskEditorDialog.cpp index e01901c555e..c2ce4202371 100644 --- a/test/src/RunTaskEditorDialog.cpp +++ b/test/src/RunTaskEditorDialog.cpp @@ -65,7 +65,7 @@ LoadFiles() static void CreateDefaultTask(TaskManager &task_manager, const Waypoints &way_points) { - const TCHAR start_name[] = _T("Bergneustadt"); + const char start_name[] = "Bergneustadt"; task_manager.set_factory(OrderedTask::FactoryType::MIXED); AbstractTaskFactory &factory = task_manager.GetFactory(); @@ -83,7 +83,7 @@ CreateDefaultTask(TaskManager &task_manager, const Waypoints &way_points) fprintf(stderr, "No start waypoint\n"); } - wp = way_points.lookup_name(_T("Uslar")); + wp = way_points.lookup_name("Uslar"); if (wp != NULL) { tp = factory.createIntermediate(AbstractTaskFactory::AST_CYLINDER, *wp); if (!factory.append(tp, false)) { @@ -93,7 +93,7 @@ CreateDefaultTask(TaskManager &task_manager, const Waypoints &way_points) fprintf(stderr, "No turn point\n"); } - wp = way_points.lookup_name(_T("Suhl Goldlaut")); + wp = way_points.lookup_name("Suhl Goldlaut"); if (wp != NULL) { tp = factory.createIntermediate(AbstractTaskFactory::AST_CYLINDER, *wp); if (!factory.append(tp, false)) { @@ -131,7 +131,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, CreateDefaultTask(task_manager, way_points); SingleWindow main_window; - main_window.set(_T("STATIC"), _T("RunTaskEditorDialog"), + main_window.set("STATIC", "RunTaskEditorDialog", 0, 0, 640, 480); main_window.Show(); diff --git a/test/src/RunTerminal.cpp b/test/src/RunTerminal.cpp index f104238db8d..48ca1da4b81 100644 --- a/test/src/RunTerminal.cpp +++ b/test/src/RunTerminal.cpp @@ -19,7 +19,7 @@ class TestWindow : public UI::SingleWindow { :UI::SingleWindow(display), terminal(look) {} void Create(PixelSize size) { - SingleWindow::Create(_T("RunTerminal"), size); + SingleWindow::Create("RunTerminal", size); PixelRect rc = GetClientRect(); diff --git a/test/src/RunTextEntry.cpp b/test/src/RunTextEntry.cpp index 8aa8ae59dd7..6fd4fcc2787 100644 --- a/test/src/RunTextEntry.cpp +++ b/test/src/RunTextEntry.cpp @@ -13,6 +13,6 @@ static void Main([[maybe_unused]] TestMainWindow &main_window) { - TCHAR text[64] = _T(""); - TextEntryDialog(text, ARRAY_SIZE(text), _T("The caption")); + char text[64] = ""; + TextEntryDialog(text, ARRAY_SIZE(text), "The caption"); } diff --git a/test/src/RunTimeEntry.cpp b/test/src/RunTimeEntry.cpp index 3d08070430a..56e95a6bc7c 100644 --- a/test/src/RunTimeEntry.cpp +++ b/test/src/RunTimeEntry.cpp @@ -15,7 +15,7 @@ Main([[maybe_unused]] TestMainWindow &main_window) { RoughTime value = RoughTime::Invalid(); const RoughTimeDelta time_zone = RoughTimeDelta::FromMinutes(0); - if (!TimeEntryDialog(_T("The caption"), value, time_zone, true)) + if (!TimeEntryDialog("The caption", value, time_zone, true)) return; if (value.IsValid()) diff --git a/test/src/RunWaveComputer.cpp b/test/src/RunWaveComputer.cpp index 862fda4f701..455fc7e53f0 100644 --- a/test/src/RunWaveComputer.cpp +++ b/test/src/RunWaveComputer.cpp @@ -39,13 +39,13 @@ int main(int argc, char **argv) delete replay; for (const auto &w : result.waves) { - TCHAR time_buffer[32]; + char time_buffer[32]; if (w.time.IsDefined()) FormatTime(time_buffer, w.time); else - _tcscpy(time_buffer, _T("?")); + strcpy(time_buffer, "?"); - _tprintf(_T("wave: t=%s location=%f,%f a=%f,%f b=%f,%f location=%s normal=%f\n"), + _tprintf("wave: t=%s location=%f,%f a=%f,%f b=%f,%f location=%s normal=%f\n", time_buffer, (double)w.location.longitude.Degrees(), (double)w.location.latitude.Degrees(), diff --git a/test/src/RunWaypointParser.cpp b/test/src/RunWaypointParser.cpp index 5dde0434b3a..550ca10438e 100644 --- a/test/src/RunWaypointParser.cpp +++ b/test/src/RunWaypointParser.cpp @@ -27,16 +27,16 @@ try { way_points.Optimise(); printf("Size %d\n", way_points.size()); - way_points.VisitNamePrefix(_T(""), [](const auto &p){ + way_points.VisitNamePrefix("", [](const auto &p){ const auto &wp = *p; - _ftprintf(stdout, _T("%s, %f, %f, "), wp.name.c_str(), + _ftprintf(stdout, "%s, %f, %f, ", wp.name.c_str(), wp.location.latitude.Degrees(), wp.location.longitude.Degrees()); if (wp.has_elevation) - _ftprintf(stdout, _T("%.0fm\n"), wp.elevation); + _ftprintf(stdout, "%.0fm\n", wp.elevation); else - _ftprintf(stdout, _T("?\n")); + _ftprintf(stdout, "?\n"); }); return EXIT_SUCCESS; diff --git a/test/src/RunWindArrowRenderer.cpp b/test/src/RunWindArrowRenderer.cpp index c3a8e2b11aa..ac56292bd2b 100644 --- a/test/src/RunWindArrowRenderer.cpp +++ b/test/src/RunWindArrowRenderer.cpp @@ -40,8 +40,9 @@ class WindWindow : public PaintWindow canvas.SelectBlackPen(); canvas.SelectHollowBrush(); canvas.DrawCircle(pt, 2); + Brush brush; - renderer.Draw(canvas, Angle::Zero(), wind, pt, rc, WindArrowStyle::ARROW_HEAD); + renderer.Draw(canvas, Angle::Zero(), wind, pt, rc, WindArrowStyle::ARROW_HEAD, brush); } }; diff --git a/test/src/RunWindComputer.cpp b/test/src/RunWindComputer.cpp index 01d6fa33361..7704f87cd08 100644 --- a/test/src/RunWindComputer.cpp +++ b/test/src/RunWindComputer.cpp @@ -52,10 +52,10 @@ int main(int argc, char **argv) replay->SetCalculated()); if (calculated.estimated_wind_available.Modified(last)) { - TCHAR time_buffer[32]; + char time_buffer[32]; FormatTime(time_buffer, replay->Basic().time); - _tprintf(_T("%s %d %g\n"), + _tprintf("%s %d %g\n", time_buffer, (int)calculated.estimated_wind.bearing.Degrees(), (double)calculated.estimated_wind.norm); } diff --git a/test/src/RunWindEKF.cpp b/test/src/RunWindEKF.cpp index e05a6e65995..e6f3d279804 100644 --- a/test/src/RunWindEKF.cpp +++ b/test/src/RunWindEKF.cpp @@ -40,10 +40,10 @@ int main(int argc, char **argv) WindEKFGlue::Result result = wind_ekf.Update(data, replay->Calculated()); if (result.quality > 0) { - TCHAR time_buffer[32]; + char time_buffer[32]; FormatTime(time_buffer, data.time); - _tprintf(_T("%s %d %g %g %g %d\n"), time_buffer, + _tprintf("%s %d %g %g %g %d\n", time_buffer, (int)result.wind.bearing.Degrees(), (double)result.wind.norm, (double)data.ground_speed, diff --git a/test/src/TaskInfo.cpp b/test/src/TaskInfo.cpp index a0883ab493f..f6b7815e567 100644 --- a/test/src/TaskInfo.cpp +++ b/test/src/TaskInfo.cpp @@ -61,7 +61,7 @@ try { if (task != NULL) { Print(*task); } else { - _ftprintf(stderr, _T("Failed to load %s\n"), path.c_str()); + _ftprintf(stderr, "Failed to load %s\n", path.c_str()); result = EXIT_FAILURE; } diff --git a/test/src/TaskPrinting.cpp b/test/src/TaskPrinting.cpp index 897bfdf68ae..fd5d46e336a 100644 --- a/test/src/TaskPrinting.cpp +++ b/test/src/TaskPrinting.cpp @@ -219,7 +219,7 @@ void PrintHelper::abstracttask_print(const AbstractTask &task, [[maybe_unused]] const AircraftState &state) { - Directory::Create(Path(_T("output/results"))); + Directory::Create(Path("output/results")); std::ofstream fs("output/results/res-stats-all.txt"); const auto &stats = task.GetStats(); diff --git a/test/src/TestAirspaceParser.cpp b/test/src/TestAirspaceParser.cpp index 0de66a3d1c1..20cc634e8aa 100644 --- a/test/src/TestAirspaceParser.cpp +++ b/test/src/TestAirspaceParser.cpp @@ -18,7 +18,7 @@ struct AirspaceClassTestCouple { - const TCHAR* name; + const char* name; AirspaceClass asclass; }; @@ -44,34 +44,34 @@ static void TestOpenAir() { Airspaces airspaces; - if (!ParseFile(Path(_T("test/data/airspace/openair.txt")), airspaces)) { + if (!ParseFile(Path("test/data/airspace/openair.txt"), airspaces)) { skip(3, 0, "Failed to parse input file"); return; } static constexpr AirspaceClassTestCouple classes[] = { - { _T("Class-R-Test"), RESTRICT }, - { _T("Class-Q-Test"), DANGER }, - { _T("Class-P-Test"), PROHIBITED }, - { _T("Class-CTR-Test"), CTR }, - { _T("Class-A-Test"), CLASSA }, - { _T("Class-B-Test"), CLASSB }, - { _T("Class-C-Test"), CLASSC }, - { _T("Class-D-Test"), CLASSD }, - { _T("Class-GP-Test"), NOGLIDER }, - { _T("Class-W-Test"), WAVE }, - { _T("Class-E-Test"), CLASSE }, - { _T("Class-F-Test"), CLASSF }, - { _T("Class-TMZ-Test"), TMZ }, - { _T("Class-G-Test"), CLASSG }, - { _T("Class-RMZ-Test"), RMZ }, + { "Class-R-Test", RESTRICT }, + { "Class-Q-Test", DANGER }, + { "Class-P-Test", PROHIBITED }, + { "Class-CTR-Test", CTR }, + { "Class-A-Test", CLASSA }, + { "Class-B-Test", CLASSB }, + { "Class-C-Test", CLASSC }, + { "Class-D-Test", CLASSD }, + { "Class-GP-Test", NOGLIDER }, + { "Class-W-Test", WAVE }, + { "Class-E-Test", CLASSE }, + { "Class-F-Test", CLASSF }, + { "Class-TMZ-Test", TMZ }, + { "Class-G-Test", CLASSG }, + { "Class-RMZ-Test", RMZ }, }; ok1(airspaces.GetSize() == 26); for (const auto &as_ : airspaces.QueryAll()) { const AbstractAirspace &airspace = as_.GetAirspace(); - if (StringIsEqual(_T("Circle-Test"), airspace.GetName())) { + if (StringIsEqual("Circle-Test", airspace.GetName())) { if (!ok1(airspace.GetShape() == AbstractAirspace::Shape::CIRCLE)) continue; @@ -79,7 +79,7 @@ TestOpenAir() ok1(equals(circle.GetRadius(), Units::ToSysUnit(5, Unit::NAUTICAL_MILES))); ok1(equals(circle.GetReferenceLocation(), Angle::Degrees(1.091667), Angle::Degrees(0.091667))); - } else if (StringIsEqual(_T("Arc-Test"), airspace.GetName())) { + } else if (StringIsEqual("Arc-Test", airspace.GetName())) { if (!ok1(airspace.GetShape() == AbstractAirspace::Shape::POLYGON)) continue; @@ -87,7 +87,7 @@ TestOpenAir() const SearchPointVector &points = polygon.GetPoints(); ok1(points.size() == 33); - } else if (StringIsEqual(_T("Polygon-Test"), airspace.GetName())) { + } else if (StringIsEqual("Polygon-Test", airspace.GetName())) { if (!ok1(airspace.GetShape() == AbstractAirspace::Shape::POLYGON)) continue; @@ -112,37 +112,37 @@ TestOpenAir() ok1(equals(points[4].GetLocation(), Angle::DMS(1, 30, 30), Angle::DMS(1, 30, 30, true))); - } else if (StringIsEqual(_T("Radio-Test 1 (AR with MHz)"), airspace.GetName())) { + } else if (StringIsEqual("Radio-Test 1 (AR with MHz)", airspace.GetName())) { ok1(airspace.GetRadioFrequency() == RadioFrequency::FromMegaKiloHertz(130, 125)); - } else if (StringIsEqual(_T("Radio-Test 2 (AF without MHz)"), airspace.GetName())) { + } else if (StringIsEqual("Radio-Test 2 (AF without MHz)", airspace.GetName())) { ok1(airspace.GetRadioFrequency() == RadioFrequency::FromMegaKiloHertz(130, 125)); - } else if (StringIsEqual(_T("Height-Test-1"), airspace.GetName())) { + } else if (StringIsEqual("Height-Test-1", airspace.GetName())) { ok1(airspace.GetBase().IsTerrain()); ok1(airspace.GetTop().reference == AltitudeReference::MSL); ok1(equals(airspace.GetTop().altitude, Units::ToSysUnit(2000, Unit::FEET))); - } else if (StringIsEqual(_T("Height-Test-2"), airspace.GetName())) { + } else if (StringIsEqual("Height-Test-2", airspace.GetName())) { ok1(airspace.GetBase().reference == AltitudeReference::MSL); ok1(equals(airspace.GetBase().altitude, 0)); ok1(airspace.GetTop().reference == AltitudeReference::STD); ok1(equals(airspace.GetTop().flight_level, 65)); - } else if (StringIsEqual(_T("Height-Test-3"), airspace.GetName())) { + } else if (StringIsEqual("Height-Test-3", airspace.GetName())) { ok1(airspace.GetBase().reference == AltitudeReference::AGL); ok1(equals(airspace.GetBase().altitude_above_terrain, Units::ToSysUnit(100, Unit::FEET))); ok1(airspace.GetTop().reference == AltitudeReference::MSL); ok1(airspace.GetTop().altitude > Units::ToSysUnit(30000, Unit::FEET)); - } else if (StringIsEqual(_T("Height-Test-4"), airspace.GetName())) { + } else if (StringIsEqual("Height-Test-4", airspace.GetName())) { ok1(airspace.GetBase().reference == AltitudeReference::MSL); ok1(equals(airspace.GetBase().altitude, 100)); ok1(airspace.GetTop().reference == AltitudeReference::MSL); ok1(airspace.GetTop().altitude > Units::ToSysUnit(30000, Unit::FEET)); - } else if (StringIsEqual(_T("Height-Test-5"), airspace.GetName())) { + } else if (StringIsEqual("Height-Test-5", airspace.GetName())) { ok1(airspace.GetBase().reference == AltitudeReference::AGL); ok1(equals(airspace.GetBase().altitude, 100)); ok1(airspace.GetTop().reference == AltitudeReference::MSL); ok1(equals(airspace.GetTop().altitude, 450)); - } else if (StringIsEqual(_T("Height-Test-6"), airspace.GetName())) { + } else if (StringIsEqual("Height-Test-6", airspace.GetName())) { ok1(airspace.GetBase().reference == AltitudeReference::AGL); ok1(equals(airspace.GetBase().altitude_above_terrain, Units::ToSysUnit(50, Unit::FEET))); @@ -160,34 +160,34 @@ static void TestTNP() { Airspaces airspaces; - if (!ParseFile(Path(_T("test/data/airspace/tnp.sua")), airspaces)) { + if (!ParseFile(Path("test/data/airspace/tnp.sua"), airspaces)) { skip(3, 0, "Failed to parse input file"); return; } static constexpr AirspaceClassTestCouple classes[] = { - { _T("Class-R-Test"), RESTRICT }, - { _T("Class-Q-Test"), DANGER }, - { _T("Class-P-Test"), PROHIBITED }, - { _T("Class-CTR-Test"), CTR }, - { _T("Class-A-Test"), CLASSA }, - { _T("Class-B-Test"), CLASSB }, - { _T("Class-C-Test"), CLASSC }, - { _T("Class-D-Test"), CLASSD }, - { _T("Class-W-Test"), WAVE }, - { _T("Class-E-Test"), CLASSE }, - { _T("Class-F-Test"), CLASSF }, - { _T("Class-TMZ-Test"), TMZ }, - { _T("Class-G-Test"), CLASSG }, - { _T("Class-CLASS-C-Test"), CLASSC }, - { _T("Class-MATZ-Test"), MATZ }, + { "Class-R-Test", RESTRICT }, + { "Class-Q-Test", DANGER }, + { "Class-P-Test", PROHIBITED }, + { "Class-CTR-Test", CTR }, + { "Class-A-Test", CLASSA }, + { "Class-B-Test", CLASSB }, + { "Class-C-Test", CLASSC }, + { "Class-D-Test", CLASSD }, + { "Class-W-Test", WAVE }, + { "Class-E-Test", CLASSE }, + { "Class-F-Test", CLASSF }, + { "Class-TMZ-Test", TMZ }, + { "Class-G-Test", CLASSG }, + { "Class-CLASS-C-Test", CLASSC }, + { "Class-MATZ-Test", MATZ }, }; ok1(airspaces.GetSize() == 24); for (const auto &as_ : airspaces.QueryAll()) { const AbstractAirspace &airspace = as_.GetAirspace(); - if (StringIsEqual(_T("Circle-Test"), airspace.GetName())) { + if (StringIsEqual("Circle-Test", airspace.GetName())) { if (!ok1(airspace.GetShape() == AbstractAirspace::Shape::CIRCLE)) continue; @@ -195,7 +195,7 @@ TestTNP() ok1(equals(circle.GetRadius(), Units::ToSysUnit(5, Unit::NAUTICAL_MILES))); ok1(equals(circle.GetReferenceLocation(), Angle::Degrees(1.091667), Angle::Degrees(0.091667))); - } else if (StringIsEqual(_T("Polygon-Test"), airspace.GetName())) { + } else if (StringIsEqual("Polygon-Test", airspace.GetName())) { if (!ok1(airspace.GetShape() == AbstractAirspace::Shape::POLYGON)) continue; @@ -220,35 +220,35 @@ TestTNP() ok1(equals(points[4].GetLocation(), Angle::DMS(1, 30, 30), Angle::DMS(1, 30, 30, true))); - } else if (StringIsEqual(_T("Radio-Test"), airspace.GetName())) { + } else if (StringIsEqual("Radio-Test", airspace.GetName())) { ok1(airspace.GetRadioFrequency() == RadioFrequency::FromMegaKiloHertz(130, 125)); - } else if (StringIsEqual(_T("Height-Test-1"), airspace.GetName())) { + } else if (StringIsEqual("Height-Test-1", airspace.GetName())) { ok1(airspace.GetBase().IsTerrain()); ok1(airspace.GetTop().reference == AltitudeReference::MSL); ok1(equals(airspace.GetTop().altitude, Units::ToSysUnit(2000, Unit::FEET))); - } else if (StringIsEqual(_T("Height-Test-2"), airspace.GetName())) { + } else if (StringIsEqual("Height-Test-2", airspace.GetName())) { ok1(airspace.GetBase().reference == AltitudeReference::MSL); ok1(equals(airspace.GetBase().altitude, 0)); ok1(airspace.GetTop().reference == AltitudeReference::STD); ok1(equals(airspace.GetTop().flight_level, 65)); - } else if (StringIsEqual(_T("Height-Test-3"), airspace.GetName())) { + } else if (StringIsEqual("Height-Test-3", airspace.GetName())) { ok1(airspace.GetBase().reference == AltitudeReference::AGL); ok1(equals(airspace.GetBase().altitude_above_terrain, Units::ToSysUnit(100, Unit::FEET))); ok1(airspace.GetTop().reference == AltitudeReference::MSL); ok1(airspace.GetTop().altitude > Units::ToSysUnit(30000, Unit::FEET)); - } else if (StringIsEqual(_T("Height-Test-4"), airspace.GetName())) { + } else if (StringIsEqual("Height-Test-4", airspace.GetName())) { ok1(airspace.GetBase().reference == AltitudeReference::MSL); ok1(equals(airspace.GetBase().altitude, 100)); ok1(airspace.GetTop().reference == AltitudeReference::MSL); ok1(airspace.GetTop().altitude > Units::ToSysUnit(30000, Unit::FEET)); - } else if (StringIsEqual(_T("Height-Test-5"), airspace.GetName())) { + } else if (StringIsEqual("Height-Test-5", airspace.GetName())) { ok1(airspace.GetBase().reference == AltitudeReference::AGL); ok1(equals(airspace.GetBase().altitude, 100)); ok1(airspace.GetTop().reference == AltitudeReference::MSL); ok1(equals(airspace.GetTop().altitude, 450)); - } else if (StringIsEqual(_T("Height-Test-6"), airspace.GetName())) { + } else if (StringIsEqual("Height-Test-6", airspace.GetName())) { ok1(airspace.GetBase().reference == AltitudeReference::AGL); ok1(equals(airspace.GetBase().altitude_above_terrain, Units::ToSysUnit(50, Unit::FEET))); @@ -266,7 +266,7 @@ static void TestOpenAirExtended() { Airspaces airspaces; - if (!ParseFile(Path(_T("test/data/airspace/openair_extended.txt")), airspaces)) { + if (!ParseFile(Path("test/data/airspace/openair_extended.txt"), airspaces)) { skip(3, 0, "Failed to parse input file"); return; } @@ -275,10 +275,10 @@ TestOpenAirExtended() for (const auto &as_ : airspaces.QueryAll()) { const AbstractAirspace &airspace = as_.GetAirspace(); - if (StringIsEqual(_T("Type-TMA-Test"), airspace.GetName())) { - ok1(StringIsEqual(_T("TMA"), airspace.GetType())); - } else if (StringIsEqual(_T("Type-GLIDING_SECTOR-Test"), airspace.GetName())) { - ok1(StringIsEqual(_T("GLIDING_SECTOR"), airspace.GetType())); + if (StringIsEqual("Type-TMA-Test", airspace.GetName())) { + ok1(StringIsEqual("TMA", airspace.GetType())); + } else if (StringIsEqual("Type-GLIDING_SECTOR-Test", airspace.GetName())) { + ok1(StringIsEqual("GLIDING_SECTOR", airspace.GetType())); } } } diff --git a/test/src/TestByteSizeFormatter.cpp b/test/src/TestByteSizeFormatter.cpp index dad3f2cfa89..d8b3c5c2485 100644 --- a/test/src/TestByteSizeFormatter.cpp +++ b/test/src/TestByteSizeFormatter.cpp @@ -10,107 +10,107 @@ int main() { plan_tests(31); - TCHAR buffer[256]; + char buffer[256]; FormatByteSize(buffer, ARRAY_SIZE(buffer), 0); - ok1(StringIsEqual(buffer, _T("0 B"))); + ok1(StringIsEqual(buffer, "0 B")); FormatByteSize(buffer, ARRAY_SIZE(buffer), 1); - ok1(StringIsEqual(buffer, _T("1 B"))); + ok1(StringIsEqual(buffer, "1 B")); FormatByteSize(buffer, ARRAY_SIZE(buffer), 9); - ok1(StringIsEqual(buffer, _T("9 B"))); + ok1(StringIsEqual(buffer, "9 B")); FormatByteSize(buffer, ARRAY_SIZE(buffer), 10); - ok1(StringIsEqual(buffer, _T("10 B"))); + ok1(StringIsEqual(buffer, "10 B")); FormatByteSize(buffer, ARRAY_SIZE(buffer), 345); - ok1(StringIsEqual(buffer, _T("345 B"))); + ok1(StringIsEqual(buffer, "345 B")); FormatByteSize(buffer, ARRAY_SIZE(buffer), 1 * 1024); - ok1(StringIsEqual(buffer, _T("1.00 KB"))); + ok1(StringIsEqual(buffer, "1.00 KB")); FormatByteSize(buffer, ARRAY_SIZE(buffer), 1 * 1024 + 512); - ok1(StringIsEqual(buffer, _T("1.50 KB"))); + ok1(StringIsEqual(buffer, "1.50 KB")); FormatByteSize(buffer, ARRAY_SIZE(buffer), 9 * 1024); - ok1(StringIsEqual(buffer, _T("9.00 KB"))); + ok1(StringIsEqual(buffer, "9.00 KB")); FormatByteSize(buffer, ARRAY_SIZE(buffer), 10 * 1024); - ok1(StringIsEqual(buffer, _T("10.0 KB"))); + ok1(StringIsEqual(buffer, "10.0 KB")); FormatByteSize(buffer, ARRAY_SIZE(buffer), 345 * 1024); - ok1(StringIsEqual(buffer, _T("345 KB"))); + ok1(StringIsEqual(buffer, "345 KB")); FormatByteSize(buffer, ARRAY_SIZE(buffer), 1 * 1024 * 1024); - ok1(StringIsEqual(buffer, _T("1.00 MB"))); + ok1(StringIsEqual(buffer, "1.00 MB")); FormatByteSize(buffer, ARRAY_SIZE(buffer), 1 * 1024 * 1024 + 512 * 1024); - ok1(StringIsEqual(buffer, _T("1.50 MB"))); + ok1(StringIsEqual(buffer, "1.50 MB")); FormatByteSize(buffer, ARRAY_SIZE(buffer), 9 * 1024 * 1024); - ok1(StringIsEqual(buffer, _T("9.00 MB"))); + ok1(StringIsEqual(buffer, "9.00 MB")); FormatByteSize(buffer, ARRAY_SIZE(buffer), 10 * 1024 * 1024); - ok1(StringIsEqual(buffer, _T("10.0 MB"))); + ok1(StringIsEqual(buffer, "10.0 MB")); FormatByteSize(buffer, ARRAY_SIZE(buffer), 345 * 1024 * 1024); - ok1(StringIsEqual(buffer, _T("345 MB"))); + ok1(StringIsEqual(buffer, "345 MB")); FormatByteSize(buffer, ARRAY_SIZE(buffer), 1 * 1024 * 1024 * 1024); - ok1(StringIsEqual(buffer, _T("1.00 GB"))); + ok1(StringIsEqual(buffer, "1.00 GB")); FormatByteSize(buffer, ARRAY_SIZE(buffer), 0, true); - ok1(StringIsEqual(buffer, _T("0B"))); + ok1(StringIsEqual(buffer, "0B")); FormatByteSize(buffer, ARRAY_SIZE(buffer), 1, true); - ok1(StringIsEqual(buffer, _T("1B"))); + ok1(StringIsEqual(buffer, "1B")); FormatByteSize(buffer, ARRAY_SIZE(buffer), 10, true); - ok1(StringIsEqual(buffer, _T("10B"))); + ok1(StringIsEqual(buffer, "10B")); FormatByteSize(buffer, ARRAY_SIZE(buffer), 345, true); - ok1(StringIsEqual(buffer, _T("345B"))); + ok1(StringIsEqual(buffer, "345B")); FormatByteSize(buffer, ARRAY_SIZE(buffer), 1 * 1024, true); - ok1(StringIsEqual(buffer, _T("1.0K"))); + ok1(StringIsEqual(buffer, "1.0K")); FormatByteSize(buffer, ARRAY_SIZE(buffer), 1 * 1024 + 512, true); - ok1(StringIsEqual(buffer, _T("1.5K"))); + ok1(StringIsEqual(buffer, "1.5K")); FormatByteSize(buffer, ARRAY_SIZE(buffer), 9 * 1024, true); - ok1(StringIsEqual(buffer, _T("9.0K"))); + ok1(StringIsEqual(buffer, "9.0K")); FormatByteSize(buffer, ARRAY_SIZE(buffer), 10 * 1024, true); - ok1(StringIsEqual(buffer, _T("10.0K"))); + ok1(StringIsEqual(buffer, "10.0K")); FormatByteSize(buffer, ARRAY_SIZE(buffer), 345 * 1024, true); - ok1(StringIsEqual(buffer, _T("345K"))); + ok1(StringIsEqual(buffer, "345K")); FormatByteSize(buffer, ARRAY_SIZE(buffer), 1 * 1024 * 1024, true); - ok1(StringIsEqual(buffer, _T("1.0M"))); + ok1(StringIsEqual(buffer, "1.0M")); FormatByteSize(buffer, ARRAY_SIZE(buffer), 1 * 1024 * 1024 + 512 * 1024, true); - ok1(StringIsEqual(buffer, _T("1.5M"))); + ok1(StringIsEqual(buffer, "1.5M")); FormatByteSize(buffer, ARRAY_SIZE(buffer), 9 * 1024 * 1024, true); - ok1(StringIsEqual(buffer, _T("9.0M"))); + ok1(StringIsEqual(buffer, "9.0M")); FormatByteSize(buffer, ARRAY_SIZE(buffer), 10 * 1024 * 1024, true); - ok1(StringIsEqual(buffer, _T("10.0M"))); + ok1(StringIsEqual(buffer, "10.0M")); FormatByteSize(buffer, ARRAY_SIZE(buffer), 345 * 1024 * 1024, true); - ok1(StringIsEqual(buffer, _T("345M"))); + ok1(StringIsEqual(buffer, "345M")); FormatByteSize(buffer, ARRAY_SIZE(buffer), 1 * 1024 * 1024 * 1024, true); - ok1(StringIsEqual(buffer, _T("1.0G"))); + ok1(StringIsEqual(buffer, "1.0G")); return exit_status(); diff --git a/test/src/TestDriver.cpp b/test/src/TestDriver.cpp index ca71252d7d6..018a12b9ddb 100644 --- a/test/src/TestDriver.cpp +++ b/test/src/TestDriver.cpp @@ -23,6 +23,7 @@ #include "Device/Driver/ILEC.hpp" #include "Device/Driver/IMI.hpp" #include "Device/Driver/OpenVario.hpp" +#include "Device/Driver/Larus.hpp" #include "Device/Driver/PosiGraph.hpp" #include "Device/Driver/Vaulter.hpp" #include "Device/Driver/Vega.hpp" @@ -49,8 +50,12 @@ #include "Units/System.hpp" #include "io/NullDataHandler.hpp" -#include +#include "FLARM/List.hpp" +#include +#ifdef _DEBUG +# include +#endif static const DeviceConfig dummy_config = DeviceConfig(); /* @@ -166,25 +171,25 @@ TestFLARM() FlarmId id = FlarmId::Parse("DDA85C", NULL); - FlarmTraffic *traffic = nmea_info.flarm.traffic.FindTraffic(id); - if (ok1(traffic != NULL)) { - ok1(traffic->valid); - ok1(traffic->alarm_level == FlarmTraffic::AlarmType::NONE); - ok1(equals(traffic->relative_north, 100)); - ok1(equals(traffic->relative_east, -150)); - ok1(equals(traffic->relative_altitude, 10)); - ok1(equals(traffic->track, 123)); - ok1(traffic->track_received); - ok1(equals(traffic->turn_rate, 13)); - ok1(traffic->turn_rate_received); - ok1(equals(traffic->speed, 24)); - ok1(traffic->speed_received); - ok1(equals(traffic->climb_rate, 1.4)); - ok1(traffic->climb_rate_received); - ok1(traffic->type == FlarmTraffic::AircraftType::TOW_PLANE); - ok1(!traffic->stealth); + FlarmTraffic *traffic1 = nmea_info.flarm.traffic.FindTraffic(id); + if (ok1(traffic1 != NULL)) { + ok1(traffic1->valid); + ok1(traffic1->alarm_level == FlarmTraffic::AlarmType::NONE); + ok1(equals(traffic1->relative_north, 100)); + ok1(equals(traffic1->relative_east, -150)); + ok1(equals(traffic1->relative_altitude, 10)); + ok1(equals(traffic1->track, 123)); + ok1(traffic1->track_received); + ok1(equals(traffic1->turn_rate, 13)); + ok1(traffic1->turn_rate_received); + ok1(equals(traffic1->speed, 24)); + ok1(traffic1->speed_received); + ok1(equals(traffic1->climb_rate, 1.4)); + ok1(traffic1->climb_rate_received); + ok1(traffic1->type == FlarmTraffic::AircraftType::TOW_PLANE); + ok1(!traffic1->stealth); } else { - skip(16, 0, "traffic == NULL"); + skip(16, 0, "traffic1 == NULL"); } ok1(parser.ParseLine("$PFLAA,2,20,10,24,2,DEADFF,,,,,1*46", @@ -192,21 +197,21 @@ TestFLARM() ok1(nmea_info.flarm.traffic.GetActiveTrafficCount() == 2); id = FlarmId::Parse("DEADFF", NULL); - traffic = nmea_info.flarm.traffic.FindTraffic(id); - if (ok1(traffic != NULL)) { - ok1(traffic->valid); - ok1(traffic->alarm_level == FlarmTraffic::AlarmType::IMPORTANT); - ok1(equals(traffic->relative_north, 20)); - ok1(equals(traffic->relative_east, 10)); - ok1(equals(traffic->relative_altitude, 24)); - ok1(!traffic->track_received); - ok1(!traffic->turn_rate_received); - ok1(!traffic->speed_received); - ok1(!traffic->climb_rate_received); - ok1(traffic->type == FlarmTraffic::AircraftType::GLIDER); - ok1(traffic->stealth); + FlarmTraffic *traffic2 = nmea_info.flarm.traffic.FindTraffic(id); + if (ok1(traffic2 != NULL)) { + ok1(traffic2->valid); + ok1(traffic2->alarm_level == FlarmTraffic::AlarmType::IMPORTANT); + ok1(equals(traffic2->relative_north, 20)); + ok1(equals(traffic2->relative_east, 10)); + ok1(equals(traffic2->relative_altitude, 24)); + ok1(!traffic2->track_received); + ok1(!traffic2->turn_rate_received); + ok1(!traffic2->speed_received); + ok1(!traffic2->climb_rate_received); + ok1(traffic2->type == FlarmTraffic::AircraftType::GLIDER); + ok1(traffic2->stealth); } else { - skip(12, 0, "traffic == NULL"); + skip(12, 0, "traffic2 == NULL"); } ok1(parser.ParseLine("$PFLAA,0,1206,574,21,2,DDAED5,196,,32,1.0,C*62", @@ -214,25 +219,44 @@ TestFLARM() ok1(nmea_info.flarm.traffic.GetActiveTrafficCount() == 3); id = FlarmId::Parse("DDAED5", NULL); - traffic = nmea_info.flarm.traffic.FindTraffic(id); - if (ok1(traffic != NULL)) { - ok1(traffic->valid); - ok1(traffic->alarm_level == FlarmTraffic::AlarmType::NONE); - ok1(equals(traffic->relative_north, 1206)); - ok1(equals(traffic->relative_east, 574)); - ok1(equals(traffic->relative_altitude, 21)); - ok1(equals(traffic->track, 196)); - ok1(traffic->track_received); - ok1(!traffic->turn_rate_received); - ok1(equals(traffic->speed, 32)); - ok1(traffic->speed_received); - ok1(equals(traffic->climb_rate, 1.0)); - ok1(traffic->climb_rate_received); - ok1(traffic->type == FlarmTraffic::AircraftType::AIRSHIP); - ok1(!traffic->stealth); + FlarmTraffic *traffic3 = nmea_info.flarm.traffic.FindTraffic(id); + if (ok1(traffic3 != NULL)) { + ok1(traffic3->valid); + ok1(traffic3->alarm_level == FlarmTraffic::AlarmType::NONE); + ok1(equals(traffic3->relative_north, 1206)); + ok1(equals(traffic3->relative_east, 574)); + ok1(equals(traffic3->relative_altitude, 21)); + ok1(equals(traffic3->track, 196)); + ok1(traffic3->track_received); + ok1(!traffic3->turn_rate_received); + ok1(equals(traffic3->speed, 32)); + ok1(traffic3->speed_received); + ok1(equals(traffic3->climb_rate, 1.0)); + ok1(traffic3->climb_rate_received); + ok1(traffic3->type == FlarmTraffic::AircraftType::AIRSHIP); + ok1(!traffic3->stealth); + +#ifdef _DEBUG + std::cout << nmea_info.flarm.traffic.TrafficIndex(traffic1) << std::endl; + std::cout << nmea_info.flarm.traffic.TrafficIndex(traffic2) << std::endl; + std::cout << nmea_info.flarm.traffic.TrafficIndex(traffic3) << std::endl; + + std::cout << traffic1->distance << std::endl; + std::cout << nmea_info.flarm.traffic.NextTraffic(traffic1)->distance << std::endl; + std::cout << nmea_info.flarm.traffic.NextTraffic(traffic2)->distance << std::endl; + std::cout << nmea_info.flarm.traffic.NextTraffic(traffic3) << std::endl; +#endif + + ok1(equals(nmea_info.flarm.traffic.TrafficIndex(traffic1), 0)); + ok1(equals(nmea_info.flarm.traffic.TrafficIndex(traffic2), 1)); + ok1(equals(nmea_info.flarm.traffic.TrafficIndex(traffic3), 2)); } else { - skip(15, 0, "traffic == NULL"); + skip(15, 0, "traffic3 == NULL"); } + +#ifdef __MSVC__ + exit(1); +#endif } static void @@ -1219,6 +1243,63 @@ TestOpenVario() delete device; } +static void +TestLarus() +{ + NullPort null; + Device *device = larus_driver.CreateOnPort(dummy_config, null); + ok1(device != NULL); + + NMEAInfo nmea_info; + nmea_info.Reset(); + nmea_info.clock = TimeStamp{FloatDuration{1}}; + + // $PLARA attitude + ok1(device->ParseNMEA("$PLARA,42.1,5.6,335.5*78", nmea_info)); + ok1(nmea_info.attitude.bank_angle_available); + ok1(equals(nmea_info.attitude.bank_angle, 42.1)); + ok1(nmea_info.attitude.pitch_angle_available); + ok1(equals(nmea_info.attitude.pitch_angle, 5.6)); + ok1(nmea_info.attitude.heading_available); + ok1(equals(nmea_info.attitude.heading, 335.5)); + + // $PLARB battery voltage + ok1(device->ParseNMEA("$PLARB,13.00*4D", nmea_info)); + ok1(nmea_info.voltage_available); + ok1(equals(nmea_info.voltage, 13.0)); + + // $PLARV tek vario, av_vario, baro height and speed (tas) + ok1(device->ParseNMEA("$PLARV,1.90,1.96,1284,94*5D", nmea_info)); + ok1(nmea_info.total_energy_vario_available); + ok1(equals(nmea_info.total_energy_vario, 1.9)); + ok1(nmea_info.pressure_altitude_available); + ok1(equals(nmea_info.pressure_altitude, 1284.0)); + ok1(nmea_info.airspeed_available); + ok1(equals(nmea_info.true_airspeed, Units::ToSysUnit(94, Unit::KILOMETER_PER_HOUR))); + + // $PLARW wind + ok1(device->ParseNMEA("$PLARW,73,23,A,A*5D", nmea_info)); + ok1(nmea_info.external_wind_available); + ok1(equals(nmea_info.external_wind.bearing, 73.0)); + ok1(equals(nmea_info.external_wind.norm, Units::ToSysUnit(23, Unit::KILOMETER_PER_HOUR))); + + // $PLARS water ballast, bugs, mc, qnh + ok1(device->ParseNMEA("$PLARS,L,BAL,0.331*5C", nmea_info)); + ok1(nmea_info.settings.ballast_fraction_available); + ok1(equals(nmea_info.settings.ballast_fraction, 0.331)); + ok1(device->ParseNMEA("$PLARS,L,BUGS,8*07", nmea_info)); + ok1(nmea_info.settings.bugs_available); + ok1(equals(nmea_info.settings.bugs, 0.92)); + ok1(device->ParseNMEA("$PLARS,L,MC,1.8*15", nmea_info)); + ok1(nmea_info.settings.mac_cready_available); + ok1(equals(nmea_info.settings.mac_cready, 1.8)); + ok1(device->ParseNMEA("$PLARS,L,QNH,1015.0*70", nmea_info)); + ok1(nmea_info.settings.qnh_available); + ok1(equals(nmea_info.settings.qnh.GetHectoPascal(), 1015)); + + delete device; +} + static void TestWesterboer() { @@ -1543,17 +1624,17 @@ TestDeclare(const struct DeviceRegister &driver) ok1(device != NULL); LoggerSettings logger_settings; - logger_settings.pilot_name = _T("Foo Bar"); + logger_settings.pilot_name = "Foo Bar"; Plane plane; - plane.registration = _T("D-3003"); - plane.competition_id = _T("33"); - plane.type = _T("Cirrus"); + plane.registration = "D-3003"; + plane.competition_id = "33"; + plane.type = "Cirrus"; Declaration declaration(logger_settings, plane, NULL); const GeoPoint gp(Angle::Degrees(7.7061111111111114), Angle::Degrees(51.051944444444445)); Waypoint wp(gp); - wp.name = _T("Foo"); + wp.name = "Foo"; wp.elevation = 123; wp.has_elevation = true; declaration.Append(wp); @@ -1622,7 +1703,8 @@ TestFlightList(const struct DeviceRegister &driver) int main() { - plan_tests(843); +#if 1 + plan_tests(880); TestGeneric(); TestTasman(); @@ -1642,6 +1724,10 @@ int main() TestLXV7(); TestILEC(); TestOpenVario(); +#endif + // plan_tests(13); + TestLarus(); +#if 1 TestVega(); TestWesterboer(); TestZander(); @@ -1668,6 +1754,7 @@ int main() TestFlightList(cai302_driver); TestFlightList(lx_driver); TestFlightList(imi_driver); +#endif return exit_status(); } diff --git a/test/src/TestFileUtil.cpp b/test/src/TestFileUtil.cpp index f45e48ef94a..5a9e1700d6b 100644 --- a/test/src/TestFileUtil.cpp +++ b/test/src/TestFileUtil.cpp @@ -17,13 +17,13 @@ class TestingFileVisitor: public File::Visitor void Visit([[maybe_unused]] Path path, Path filename) { - if (filename == Path(_T("a.txt"))) { + if (filename == Path("a.txt")) { ok(true, "a.txt"); - } else if (filename == Path(_T("b.txt"))) { + } else if (filename == Path("b.txt")) { ok(true, "b.txt"); - } else if (filename == Path(_T("c.tx"))) { + } else if (filename == Path("c.tx")) { ok(!filtered, "c.tx"); - } else if (filename == Path(_T("d.txt"))) { + } else if (filename == Path("d.txt")) { ok(recursive, "d.txt"); } else { ok(false, "unexpected file"); @@ -35,25 +35,25 @@ int main() { plan_tests(17); - ok1(Directory::Exists(Path(_T("test/data/file_visitor_test")))); - ok1(File::Exists(Path(_T("test/data/file_visitor_test/a.txt")))); - ok1(File::Exists(Path(_T("test/data/file_visitor_test/b.txt")))); - ok1(File::Exists(Path(_T("test/data/file_visitor_test/c.tx")))); - ok1(File::Exists(Path(_T("test/data/file_visitor_test/subfolder/d.txt")))); + ok1(Directory::Exists(Path("test/data/file_visitor_test"))); + ok1(File::Exists(Path("test/data/file_visitor_test/a.txt"))); + ok1(File::Exists(Path("test/data/file_visitor_test/b.txt"))); + ok1(File::Exists(Path("test/data/file_visitor_test/c.tx"))); + ok1(File::Exists(Path("test/data/file_visitor_test/subfolder/d.txt"))); TestingFileVisitor fv1(false, false); - Directory::VisitFiles(Path(_T("test/data/file_visitor_test")), fv1, false); + Directory::VisitFiles(Path("test/data/file_visitor_test"), fv1, false); TestingFileVisitor fv2(true, false); - Directory::VisitFiles(Path(_T("test/data/file_visitor_test")), fv2, true); + Directory::VisitFiles(Path("test/data/file_visitor_test"), fv2, true); TestingFileVisitor fv3(false, true); - Directory::VisitSpecificFiles(Path(_T("test/data/file_visitor_test")), - _T("*.txt"), fv3, false); + Directory::VisitSpecificFiles(Path("test/data/file_visitor_test"), + "*.txt", fv3, false); TestingFileVisitor fv4(true, true); - Directory::VisitSpecificFiles(Path(_T("test/data/file_visitor_test")), - _T("*.txt"), fv4, true); + Directory::VisitSpecificFiles(Path("test/data/file_visitor_test"), + "*.txt", fv4, true); return exit_status(); } diff --git a/test/src/TestFlarmNet.cpp b/test/src/TestFlarmNet.cpp index dc1e37a7318..b2853c09202 100644 --- a/test/src/TestFlarmNet.cpp +++ b/test/src/TestFlarmNet.cpp @@ -13,7 +13,7 @@ int main() plan_tests(15); FlarmNetDatabase db; - int count = FlarmNetReader::LoadFile(Path(_T("test/data/flarmnet/data.fln")), + int count = FlarmNetReader::LoadFile(Path("test/data/flarmnet/data.fln"), db); ok1(count == 6); @@ -22,30 +22,30 @@ int main() const FlarmNetRecord *record = db.FindRecordById(id); ok1(record != NULL); - ok1(StringIsEqual(record->id, _T("DDA85C"))); - ok1(StringIsEqual(record->pilot, _T("Tobias Bieniek"))); - ok1(StringIsEqual(record->airfield, _T("AACHEN"))); - ok1(StringIsEqual(record->plane_type, _T("Hornet"))); - ok1(StringIsEqual(record->registration, _T("D-4449"))); - ok1(StringIsEqual(record->callsign, _T("TH"))); - ok1(StringIsEqual(record->frequency, _T("130.625"))); + ok1(StringIsEqual(record->id, "DDA85C")); + ok1(StringIsEqual(record->pilot, "Tobias Bieniek")); + ok1(StringIsEqual(record->airfield, "AACHEN")); + ok1(StringIsEqual(record->plane_type, "Hornet")); + ok1(StringIsEqual(record->registration, "D-4449")); + ok1(StringIsEqual(record->callsign, "TH")); + ok1(StringIsEqual(record->frequency, "130.625")); const FlarmNetRecord *array[3]; - ok1(db.FindRecordsByCallSign(_T("TH"), array, 3) == 2); + ok1(db.FindRecordsByCallSign("TH", array, 3) == 2); bool found4449 = false, found5799 = false; for (unsigned i = 0; i < 2; i++) { record = array[i]; - if (StringIsEqual(record->registration, _T("D-4449"))) + if (StringIsEqual(record->registration, "D-4449")) found4449 = true; - if (StringIsEqual(record->registration, _T("D-5799"))) + if (StringIsEqual(record->registration, "D-5799")) found5799 = true; } ok1(found4449); ok1(found5799); FlarmId ids[3]; - ok1(db.FindIdsByCallSign(_T("TH"), ids, 3) == 2); + ok1(db.FindIdsByCallSign("TH", ids, 3) == 2); id = FlarmId::Parse("DDA85C", NULL); FlarmId id2 = FlarmId::Parse("DDA896", NULL); diff --git a/test/src/TestGRecord.cpp b/test/src/TestGRecord.cpp index 8b0f5a44e62..de5e8702de3 100644 --- a/test/src/TestGRecord.cpp +++ b/test/src/TestGRecord.cpp @@ -10,7 +10,7 @@ #include static void -CheckGRecord(const TCHAR *path) +CheckGRecord(const char *path) { GRecord grecord; grecord.Initialize(); @@ -22,10 +22,10 @@ int main() try { plan_tests(4); - CheckGRecord(_T("test/data/grecord64a.igc")); - CheckGRecord(_T("test/data/grecord64b.igc")); - CheckGRecord(_T("test/data/grecord65a.igc")); - CheckGRecord(_T("test/data/grecord65b.igc")); + CheckGRecord("test/data/grecord64a.igc"); + CheckGRecord("test/data/grecord64b.igc"); + CheckGRecord("test/data/grecord65a.igc"); + CheckGRecord("test/data/grecord65b.igc"); return exit_status(); } catch (...) { diff --git a/test/src/TestGeoPointFormatter.cpp b/test/src/TestGeoPointFormatter.cpp index 8760dfbe5cf..667013a63f8 100644 --- a/test/src/TestGeoPointFormatter.cpp +++ b/test/src/TestGeoPointFormatter.cpp @@ -7,13 +7,13 @@ #include "TestUtil.hpp" static bool -StringIsEqualWildcard(const TCHAR *string1, const TCHAR *string2, - TCHAR wildcard = _T('*')) +StringIsEqualWildcard(const char *string1, const char *string2, + char wildcard = '*') { while (*string1 == *string2 || *string1 == wildcard || *string2 == wildcard) { - if (*string1 == _T('\0') && *string2 == _T('\0')) + if (*string1 == '\0' && *string2 == '\0') return true; string1++; @@ -26,7 +26,7 @@ int main() { plan_tests(14); - TCHAR buffer[256]; + char buffer[256]; GeoPoint location1(Angle::Degrees(8.466322), Angle::Degrees(49.487153)); @@ -36,67 +36,67 @@ int main() // Test DD.ddddd FormatGeoPoint(location1, buffer, ARRAY_SIZE(buffer), CoordinateFormat::DD_DDDDD); - ok1(StringIsEqual(buffer, _T("49.48715° N 008.46632° E"))); + ok1(StringIsEqual(buffer, "49.48715° N 008.46632° E")); FormatGeoPoint(location2, buffer, ARRAY_SIZE(buffer), CoordinateFormat::DD_DDDDD); - ok1(StringIsEqual(buffer, _T("32.65333° S 070.01167° W"))); + ok1(StringIsEqual(buffer, "32.65333° S 070.01167° W")); // Test DDMM.mmm FormatGeoPoint(location1, buffer, ARRAY_SIZE(buffer), CoordinateFormat::DDMM_MMM); - ok1(StringIsEqual(buffer, _T("49°29.229' N 008°27.979' E"))); + ok1(StringIsEqual(buffer, "49°29.229' N 008°27.979' E")); FormatGeoPoint(location2, buffer, ARRAY_SIZE(buffer), CoordinateFormat::DDMM_MMM); - ok1(StringIsEqual(buffer, _T("32°39.200' S 070°00.700' W"))); + ok1(StringIsEqual(buffer, "32°39.200' S 070°00.700' W")); // Test DDMMSS FormatGeoPoint(location1, buffer, ARRAY_SIZE(buffer), CoordinateFormat::DDMMSS); - ok1(StringIsEqual(buffer, _T("49°29'14\" N 008°27'59\" E"))); + ok1(StringIsEqual(buffer, "49°29'14\" N 008°27'59\" E")); FormatGeoPoint(location2, buffer, ARRAY_SIZE(buffer), CoordinateFormat::DDMMSS); - ok1(StringIsEqual(buffer, _T("32°39'12\" S 070°00'42\" W"))); + ok1(StringIsEqual(buffer, "32°39'12\" S 070°00'42\" W")); // Test DDMMSS.s FormatGeoPoint(location1, buffer, ARRAY_SIZE(buffer), CoordinateFormat::DDMMSS_S); - ok1(StringIsEqual(buffer, _T("49°29'13.8\" N 008°27'58.8\" E"))); + ok1(StringIsEqual(buffer, "49°29'13.8\" N 008°27'58.8\" E")); FormatGeoPoint(location2, buffer, ARRAY_SIZE(buffer), CoordinateFormat::DDMMSS_S); - ok1(StringIsEqual(buffer, _T("32°39'12.0\" S 070°00'42.0\" W"))); + ok1(StringIsEqual(buffer, "32°39'12.0\" S 070°00'42.0\" W")); // Test UTM FormatGeoPoint(location1, buffer, ARRAY_SIZE(buffer), CoordinateFormat::UTM); - ok1(StringIsEqualWildcard(buffer, _T("32U 4613** 5481***"))); + ok1(StringIsEqualWildcard(buffer, "32U 4613** 5481***")); FormatGeoPoint(location2, buffer, ARRAY_SIZE(buffer), CoordinateFormat::UTM); - ok1(StringIsEqualWildcard(buffer, _T("19H 4051** 6386***"))); + ok1(StringIsEqualWildcard(buffer, "19H 4051** 6386***")); // Test separator FormatGeoPoint(location1, buffer, ARRAY_SIZE(buffer), - CoordinateFormat::DDMMSS, _T('\n')); - ok1(StringIsEqual(buffer, _T("49°29'14\" N\n008°27'59\" E"))); + CoordinateFormat::DDMMSS, '\n'); + ok1(StringIsEqual(buffer, "49°29'14\" N\n008°27'59\" E")); FormatGeoPoint(location2, buffer, ARRAY_SIZE(buffer), - CoordinateFormat::DDMMSS, _T('\n')); - ok1(StringIsEqual(buffer, _T("32°39'12\" S\n070°00'42\" W"))); + CoordinateFormat::DDMMSS, '\n'); + ok1(StringIsEqual(buffer, "32°39'12\" S\n070°00'42\" W")); FormatGeoPoint(location1, buffer, ARRAY_SIZE(buffer), - CoordinateFormat::UTM, _T('\n')); - ok1(StringIsEqualWildcard(buffer, _T("32U\n4613**\n5481***"))); + CoordinateFormat::UTM, '\n'); + ok1(StringIsEqualWildcard(buffer, "32U\n4613**\n5481***")); FormatGeoPoint(location2, buffer, ARRAY_SIZE(buffer), - CoordinateFormat::UTM, _T('\n')); - ok1(StringIsEqualWildcard(buffer, _T("19H\n4051**\n6386***"))); + CoordinateFormat::UTM, '\n'); + ok1(StringIsEqualWildcard(buffer, "19H\n4051**\n6386***")); return exit_status(); diff --git a/test/src/TestIGCFilenameFormatter.cpp b/test/src/TestIGCFilenameFormatter.cpp index 6422a607a5b..ea818fd2f86 100644 --- a/test/src/TestIGCFilenameFormatter.cpp +++ b/test/src/TestIGCFilenameFormatter.cpp @@ -9,47 +9,47 @@ static void TestShort() { - TCHAR buffer[256]; + char buffer[256]; - FormatIGCFilename(buffer, BrokenDate(2012, 2, 10), _T('T'), _T("ABC"), 1); - ok1(StringIsEqual(buffer, _T("22ATABC1.igc"))); + FormatIGCFilename(buffer, BrokenDate(2012, 2, 10), 'T', "ABC", 1); + ok1(StringIsEqual(buffer, "22ATABC1.igc")); - FormatIGCFilename(buffer, BrokenDate(2010, 1, 1), _T('X'), _T("234"), 15); - ok1(StringIsEqual(buffer, _T("011X234F.igc"))); + FormatIGCFilename(buffer, BrokenDate(2010, 1, 1), 'X', "234", 15); + ok1(StringIsEqual(buffer, "011X234F.igc")); - FormatIGCFilename(buffer, BrokenDate(2009, 12, 1), _T('X'), _T("234"), 35); - ok1(StringIsEqual(buffer, _T("9C1X234Z.igc"))); + FormatIGCFilename(buffer, BrokenDate(2009, 12, 1), 'X', "234", 35); + ok1(StringIsEqual(buffer, "9C1X234Z.igc")); } static void TestLong() { - TCHAR buffer[256]; + char buffer[256]; FormatIGCFilenameLong(buffer, BrokenDate(2012, 2, 10), - _T("XYZ"), _T("ABC"), 1); - ok1(StringIsEqual(buffer, _T("2012-02-10-XYZ-ABC-01.igc"))); + "XYZ", "ABC", 1); + ok1(StringIsEqual(buffer, "2012-02-10-XYZ-ABC-01.igc")); FormatIGCFilenameLong(buffer, BrokenDate(2010, 1, 1), - _T("BLA"), _T("234"), 15); - ok1(StringIsEqual(buffer, _T("2010-01-01-BLA-234-15.igc"))); + "BLA", "234", 15); + ok1(StringIsEqual(buffer, "2010-01-01-BLA-234-15.igc")); FormatIGCFilenameLong(buffer, BrokenDate(2009, 12, 1), - _T("S45"), _T("234"), 35); - ok1(StringIsEqual(buffer, _T("2009-12-01-S45-234-35.igc"))); + "S45", "234", 35); + ok1(StringIsEqual(buffer, "2009-12-01-S45-234-35.igc")); } static void TestChar() { - TCHAR buffer[256]; + char buffer[256]; FormatIGCFilename(buffer, BrokenDate(2012, 2, 10), 'T', "ABC", 1); - ok1(StringIsEqual(buffer, _T("22ATABC1.igc"))); + ok1(StringIsEqual(buffer, "22ATABC1.igc")); FormatIGCFilenameLong(buffer, BrokenDate(2012, 2, 10), "XYZ", "ABC", 1); - ok1(StringIsEqual(buffer, _T("2012-02-10-XYZ-ABC-01.igc"))); + ok1(StringIsEqual(buffer, "2012-02-10-XYZ-ABC-01.igc")); } int main() diff --git a/test/src/TestLogger.cpp b/test/src/TestLogger.cpp index 42332cd6b2f..5d80a6bf491 100644 --- a/test/src/TestLogger.cpp +++ b/test/src/TestLogger.cpp @@ -91,12 +91,12 @@ Run(IGCWriter &writer) i.ProvidePressureAltitude(490); i.ProvideBaroAltitudeTrue(400); - writer.WriteHeader(i.date_time_utc, _T("Pilot Name"), _T("CoPilot Name"), _T("ASK-21"), - _T("D-1234"), _T("34"), "FOO", _T("bar"), false); + writer.WriteHeader(i.date_time_utc, "Pilot Name", "CoPilot Name", "ASK-21", + "D-1234", "34", "FOO", "bar", false); writer.StartDeclaration(i.date_time_utc, 3); - writer.AddDeclaration(home, _T("Bergneustadt")); - writer.AddDeclaration(tp, _T("Suhl")); - writer.AddDeclaration(home, _T("Bergneustadt")); + writer.AddDeclaration(home, "Bergneustadt"); + writer.AddDeclaration(tp, "Suhl"); + writer.AddDeclaration(home, "Bergneustadt"); writer.EndDeclaration(); writer.LogEmptyFRecord(i.date_time_utc); @@ -106,7 +106,7 @@ Run(IGCWriter &writer) i.date_time_utc.second += 5; writer.LogEvent(i, "my_event"); i.date_time_utc.second += 5; - writer.LoggerNote(_T("my_note")); + writer.LoggerNote("my_note"); int satellites[GPSState::MAXSATELLITES]; for (unsigned i = 0; i < GPSState::MAXSATELLITES; ++i) @@ -139,7 +139,7 @@ int main() try { plan_tests(51); - const Path path(_T("output/test/test.igc")); + const Path path("output/test/test.igc"); File::Delete(path); Run(path); diff --git a/test/src/TestMETARParser.cpp b/test/src/TestMETARParser.cpp index 7493fff9237..c71b9ce9ab6 100644 --- a/test/src/TestMETARParser.cpp +++ b/test/src/TestMETARParser.cpp @@ -18,12 +18,12 @@ main() { ParsedMETAR parsed; - metar.content = _T("EDDL 231050Z 31007MPS 9999 FEW020 SCT130 23/18 Q1015 NOSIG"); - metar.decoded = _T(""); + metar.content = "EDDL 231050Z 31007MPS 9999 FEW020 SCT130 23/18 Q1015 NOSIG"; + metar.decoded = ""; if (!ok1(METARParser::Parse(metar, parsed))) return exit_status(); - ok1(parsed.icao_code == _T("EDDL")); + ok1(parsed.icao_code == "EDDL"); ok1(parsed.day_of_month == 23); ok1(parsed.hour == 10); ok1(parsed.minute == 50); @@ -42,13 +42,13 @@ main() } { ParsedMETAR parsed; - metar.content = _T("METAR KTTN 051853Z 04011KT 1/2SM VCTS SN FZFG BKN003 OVC010 M02/M02 A3006 RMK AO2 TSB40 SLP176 P0002 T10171017="); - metar.decoded = _T("Pudahuel, Chile (SCEL) 33-23S 070-47W 476M\r\n" - "Nov 04, 2011 - 07:50 PM EDT / 2011.11.04 2350 UTC\r\n"); + metar.content = "METAR KTTN 051853Z 04011KT 1/2SM VCTS SN FZFG BKN003 OVC010 M02/M02 A3006 RMK AO2 TSB40 SLP176 P0002 T10171017="; + metar.decoded = "Pudahuel, Chile (SCEL) 33-23S 070-47W 476M\r\n" + "Nov 04, 2011 - 07:50 PM EDT / 2011.11.04 2350 UTC\r\n"; if (!ok1(METARParser::Parse(metar, parsed))) return exit_status(); - ok1(parsed.icao_code == _T("KTTN")); + ok1(parsed.icao_code == "KTTN"); ok1(parsed.day_of_month == 5); ok1(parsed.hour == 18); ok1(parsed.minute == 53); @@ -68,13 +68,13 @@ main() } { ParsedMETAR parsed; - metar.content = _T("METAR EDJA 231950Z VRB01KT CAVOK 21/17 Q1017="); - metar.decoded = _T("Duesseldorf, Germany (EDDL) 51-18N 006-46E 41M\r\n" - "Nov 04, 2011 - 07:50 PM EDT / 2011.11.04 2350 UTC\r\n"); + metar.content = "METAR EDJA 231950Z VRB01KT CAVOK 21/17 Q1017="; + metar.decoded = "Duesseldorf, Germany (EDDL) 51-18N 006-46E 41M\r\n" + "Nov 04, 2011 - 07:50 PM EDT / 2011.11.04 2350 UTC\r\n"; if (!ok1(METARParser::Parse(metar, parsed))) return exit_status(); - ok1(parsed.icao_code == _T("EDJA")); + ok1(parsed.icao_code == "EDJA"); ok1(parsed.day_of_month == 23); ok1(parsed.hour == 19); ok1(parsed.minute == 50); diff --git a/test/src/TestPlanes.cpp b/test/src/TestPlanes.cpp index b729e215dcf..eabe299967c 100644 --- a/test/src/TestPlanes.cpp +++ b/test/src/TestPlanes.cpp @@ -18,13 +18,13 @@ static void TestReader() { Plane plane; - PlaneGlue::ReadFile(plane, Path(_T("test/data/D-4449.xcp"))); + PlaneGlue::ReadFile(plane, Path("test/data/D-4449.xcp")); - ok1(plane.registration == _T("D-4449")); - ok1(plane.competition_id == _T("TH")); - ok1(plane.type == _T("Hornet")); + ok1(plane.registration == "D-4449"); + ok1(plane.competition_id == "TH"); + ok1(plane.type == "Hornet"); ok1(plane.handicap == 100); - ok1(plane.polar_name == _T("Hornet")); + ok1(plane.polar_name == "Hornet"); ok1(equals(plane.polar_shape[0].v, Units::ToSysUnit(80, Unit::KILOMETER_PER_HOUR))); ok1(equals(plane.polar_shape[1].v, @@ -44,7 +44,7 @@ TestReader() ok1(equals(plane.weglide_glider_type, 261)); plane = Plane(); - PlaneGlue::ReadFile(plane, Path(_T("test/data/D-4449dry.xcp"))); + PlaneGlue::ReadFile(plane, Path("test/data/D-4449dry.xcp")); ok1(equals(plane.empty_mass, 212)); } @@ -52,11 +52,11 @@ static void TestWriter() { Plane plane; - plane.registration = _T("D-4449"); - plane.competition_id = _T("TH"); - plane.type = _T("Hornet"); + plane.registration = "D-4449"; + plane.competition_id = "TH"; + plane.type = "Hornet"; plane.handicap = 100; - plane.polar_name = _T("Hornet"); + plane.polar_name = "Hornet"; plane.polar_shape[0].v = Units::ToSysUnit(80, Unit::KILOMETER_PER_HOUR); plane.polar_shape[1].v = Units::ToSysUnit(120, Unit::KILOMETER_PER_HOUR); plane.polar_shape[2].v = Units::ToSysUnit(160, Unit::KILOMETER_PER_HOUR); @@ -72,9 +72,9 @@ TestWriter() plane.wing_area = 9.8; plane.weglide_glider_type = 160; - PlaneGlue::WriteFile(plane, Path(_T("output/D-4449.xcp"))); + PlaneGlue::WriteFile(plane, Path("output/D-4449.xcp")); - FileLineReaderA reader(Path(_T("output/D-4449.xcp"))); + FileLineReaderA reader(Path("output/D-4449.xcp")); unsigned count = 0; bool found1 = false, found2 = false, found3 = false, found4 = false; diff --git a/test/src/TestPolars.cpp b/test/src/TestPolars.cpp index c42e2995cca..c5fc1fb29ef 100644 --- a/test/src/TestPolars.cpp +++ b/test/src/TestPolars.cpp @@ -11,7 +11,6 @@ #include "Polar/Parser.hpp" #include "Polar/PolarFileGlue.hpp" #include "Polar/PolarStore.hpp" -#include "util/ConvertString.hpp" #include "util/Macros.hpp" #include "util/PrintException.hxx" #include "util/StringAPI.hxx" @@ -59,7 +58,7 @@ TestFileImport() { // Test LoadFromFile() PolarInfo polar; - PolarGlue::LoadFromFile(polar, Path(_T("test/data/test.plr"))); + PolarGlue::LoadFromFile(polar, Path("test/data/test.plr")); ok1(equals(polar.shape.reference_mass, 318)); ok1(equals(polar.max_ballast, 100)); ok1(equals(polar.shape[0].v, 22.2222222)); @@ -76,14 +75,12 @@ TestBuiltInPolars() { for (const auto &i : PolarStore::GetAll()) { PolarInfo polar = i.ToPolarInfo(); - - WideToUTF8Converter narrow(i.name); - ok(polar.IsValid(), narrow); + ok(polar.IsValid(), i.name); } } struct PerformanceItem { - const TCHAR* name; + const char* name; bool check_best_LD; double best_LD; bool check_best_LD_speed; @@ -96,23 +93,23 @@ struct PerformanceItem { static const PerformanceItem performanceData[] = { /* 206 Hornet */ - { _T("206 Hornet"), true, 38, true, 103, true, 0.6, true, 74 }, + { "206 Hornet", true, 38, true, 103, true, 0.6, true, 74 }, /* Discus */ - { _T("Discus"), true, 43, false, 0, true, 0.59, false, 0 }, + { "Discus", true, 43, false, 0, true, 0.59, false, 0 }, /* G-103 TWIN II (PIL)*/ - { _T("G 103 Twin 2"), true, 38.5, true, 95, true, 0.64, true, 80 }, + { "G 103 Twin 2", true, 38.5, true, 95, true, 0.64, true, 80 }, /* H-201 Std. Libelle */ - { _T("H-201 Std Libelle"), true, 38, true, 90, true, 0.6, true, 75 }, + { "H-201 Std Libelle", true, 38, true, 90, true, 0.6, true, 75 }, /* Ka6 CR */ - { _T("Ka 6CR"), true, 30, true, 85, true, 0.65, true, 72 }, + { "Ka 6CR", true, 30, true, 85, true, 0.65, true, 72 }, /* K8 */ - { _T("Ka 8"), true, 25, true, 75, false, 0, true, 62 }, + { "Ka 8", true, 25, true, 75, false, 0, true, 62 }, /* LS-4 */ - { _T("LS-4"), true, 40.5, false, 0, true, 0.60, false, 0 }, + { "LS-4", true, 40.5, false, 0, true, 0.60, false, 0 }, /* Std. Cirrus */ - { _T("Std Cirrus"), true, 38.5, false, 0, true, 0.6, false, 0 }, + { "Std Cirrus", true, 38.5, false, 0, true, 0.6, false, 0 }, /* LS-1f */ - { _T("LS-1f"), true, 38.2, false, 0, true, 0.64, false, 0 }, + { "LS-1f", true, 38.2, false, 0, true, 0.64, false, 0 }, }; static bool @@ -125,7 +122,7 @@ ValuePlausible(double ref, double used, double threshold = 0.05) [[gnu::pure]] static auto -GetPolarByName(const TCHAR *name) noexcept +GetPolarByName(const char *name) noexcept { for (const auto &i : PolarStore::GetAll()) if (StringIsEqual(i.name, name)) @@ -138,9 +135,8 @@ static void TestBuiltInPolarsPlausibility() { for(unsigned i = 0; i < ARRAY_SIZE(performanceData); i++) { - const TCHAR *si = performanceData[i].name; - WideToUTF8Converter polarName(si); - const auto polar = GetPolarByName(si); + const char *polarName = performanceData[i].name; + const auto polar = GetPolarByName(polarName); PolarCoefficients pc = polar.CalculateCoefficients(); ok(pc.IsValid(), polarName); diff --git a/test/src/TestProfile.cpp b/test/src/TestProfile.cpp index 25112d66580..75355a107be 100644 --- a/test/src/TestProfile.cpp +++ b/test/src/TestProfile.cpp @@ -69,9 +69,9 @@ TestWriter() Profile::Set("key1", 4); Profile::Set("key2", "value2"); - Profile::SaveFile(Path(_T("output/TestProfileWriter.prf"))); + Profile::SaveFile(Path("output/TestProfileWriter.prf")); - FileLineReaderA reader(Path(_T("output/TestProfileWriter.prf"))); + FileLineReaderA reader(Path("output/TestProfileWriter.prf")); unsigned count = 0; bool found1 = false, found2 = false; @@ -95,7 +95,7 @@ static void TestReader() { Profile::Clear(); - Profile::LoadFile(Path(_T("test/data/TestProfileReader.prf"))); + Profile::LoadFile(Path("test/data/TestProfileReader.prf")); { int value; @@ -108,7 +108,7 @@ TestReader() StaticString<32> value; ok1(Profile::Exists("key2")); ok1(Profile::Get("key2", value)); - ok1(value == _T("value")); + ok1(value == "value"); } { diff --git a/test/src/TestRadixTree.cpp b/test/src/TestRadixTree.cpp index 373efed278d..f9f59c5a548 100644 --- a/test/src/TestRadixTree.cpp +++ b/test/src/TestRadixTree.cpp @@ -28,7 +28,7 @@ all_sum(const RadixTree &rt) } static int -prefix_sum(const RadixTree &rt, const TCHAR *prefix) +prefix_sum(const RadixTree &rt, const char *prefix) { Sum sum; rt.VisitPrefix(prefix, sum); @@ -37,9 +37,9 @@ prefix_sum(const RadixTree &rt, const TCHAR *prefix) template struct AscendingKeyVisitor { - tstring last; + std::string last; - void operator()(const TCHAR *key, [[maybe_unused]] const T &value) { + void operator()(const char *key, [[maybe_unused]] const T &value) { ok1(last.compare(key) <= 0); last = key; } @@ -57,136 +57,136 @@ int main() { plan_tests(86); - TCHAR buffer[64], *suggest; + char buffer[64], *suggest; RadixTree irt; - irt.Add(_T("foo"), 42); + irt.Add("foo", 42); ok1(all_sum(irt) == 42); - ok1(prefix_sum(irt, _T("")) == 42); - ok1(prefix_sum(irt, _T("f")) == 42); - ok1(prefix_sum(irt, _T("fo")) == 42); - ok1(prefix_sum(irt, _T("foo")) == 42); - ok1(prefix_sum(irt, _T("foobar")) == 0); + ok1(prefix_sum(irt, "") == 42); + ok1(prefix_sum(irt, "f") == 42); + ok1(prefix_sum(irt, "fo") == 42); + ok1(prefix_sum(irt, "foo") == 42); + ok1(prefix_sum(irt, "foobar") == 0); - irt.Add(_T("foa"), 0); + irt.Add("foa", 0); ok1(all_sum(irt) == 42); check_ascending_keys(irt); - suggest = irt.Suggest(_T("xyz"), buffer, 64); + suggest = irt.Suggest("xyz", buffer, 64); ok1(suggest == NULL); - suggest = irt.Suggest(_T(""), buffer, 64); + suggest = irt.Suggest("", buffer, 64); ok1(suggest != NULL); - ok1(StringIsEqual(suggest, _T("f"))); + ok1(StringIsEqual(suggest, "f")); - suggest = irt.Suggest(_T("f"), buffer, 64); + suggest = irt.Suggest("f", buffer, 64); ok1(suggest != NULL); - ok1(StringIsEqual(suggest, _T("o"))); + ok1(StringIsEqual(suggest, "o")); - suggest = irt.Suggest(_T("foo"), buffer, 64); + suggest = irt.Suggest("foo", buffer, 64); ok1(suggest != NULL); - ok1(StringIsEqual(suggest, _T(""))); + ok1(StringIsEqual(suggest, "")); - irt.Add(_T("bar"), 1); + irt.Add("bar", 1); ok1(all_sum(irt) == 43); - ok1(prefix_sum(irt, _T("")) == 43); - ok1(prefix_sum(irt, _T("f")) == 42); + ok1(prefix_sum(irt, "") == 43); + ok1(prefix_sum(irt, "f") == 42); - suggest = irt.Suggest(_T(""), buffer, 64); + suggest = irt.Suggest("", buffer, 64); ok1(suggest != NULL); - ok1(StringIsEqual(suggest, _T("bf"))); + ok1(StringIsEqual(suggest, "bf")); - suggest = irt.Suggest(_T("ba"), buffer, 64); + suggest = irt.Suggest("ba", buffer, 64); ok1(suggest != NULL); - ok1(StringIsEqual(suggest, _T("r"))); + ok1(StringIsEqual(suggest, "r")); - irt.Add(_T("foo"), 2); + irt.Add("foo", 2); ok1(all_sum(irt) == 45); - ok1(prefix_sum(irt, _T("")) == 45); - ok1(prefix_sum(irt, _T("f")) == 44); - ok1(prefix_sum(irt, _T("fo")) == 44); - ok1(prefix_sum(irt, _T("foo")) == 44); - ok1(prefix_sum(irt, _T("foobar")) == 0); - - ok1(irt.Get(_T("foo"), 0) == 42 || irt.Get(_T("foo"), 0) == 2); - ok1(irt.GetIf(_T("foo"), 0, [](auto i){ return i == 42; }) == 42); - ok1(irt.GetIf(_T("foo"), 0, [](auto i){ return i == 2; }) == 2); - ok1(irt.GetIf(_T("foo"), 0, [](auto i){ return i == 22; }) == 0); - - suggest = irt.Suggest(_T("foo"), buffer, 64); + ok1(prefix_sum(irt, "") == 45); + ok1(prefix_sum(irt, "f") == 44); + ok1(prefix_sum(irt, "fo") == 44); + ok1(prefix_sum(irt, "foo") == 44); + ok1(prefix_sum(irt, "foobar") == 0); + + ok1(irt.Get("foo", 0) == 42 || irt.Get("foo", 0) == 2); + ok1(irt.GetIf("foo", 0, [](auto i){ return i == 42; }) == 42); + ok1(irt.GetIf("foo", 0, [](auto i){ return i == 2; }) == 2); + ok1(irt.GetIf("foo", 0, [](auto i){ return i == 22; }) == 0); + + suggest = irt.Suggest("foo", buffer, 64); ok1(suggest != NULL); - ok1(StringIsEqual(suggest, _T(""))); + ok1(StringIsEqual(suggest, "")); - irt.Add(_T("baz"), 3); + irt.Add("baz", 3); ok1(all_sum(irt) == 48); - ok1(prefix_sum(irt, _T("b")) == 4); - ok1(prefix_sum(irt, _T("ba")) == 4); - ok1(prefix_sum(irt, _T("bar")) == 1); - ok1(prefix_sum(irt, _T("baz")) == 3); + ok1(prefix_sum(irt, "b") == 4); + ok1(prefix_sum(irt, "ba") == 4); + ok1(prefix_sum(irt, "bar") == 1); + ok1(prefix_sum(irt, "baz") == 3); - suggest = irt.Suggest(_T(""), buffer, 64); + suggest = irt.Suggest("", buffer, 64); ok1(suggest != NULL); - ok1(StringIsEqual(suggest, _T("bf"))); + ok1(StringIsEqual(suggest, "bf")); - suggest = irt.Suggest(_T("ba"), buffer, 64); + suggest = irt.Suggest("ba", buffer, 64); ok1(suggest != NULL); - ok1(StringIsEqual(suggest, _T("rz"))); + ok1(StringIsEqual(suggest, "rz")); - irt.Add(_T("foobar"), 4); + irt.Add("foobar", 4); ok1(all_sum(irt) == 52); - ok1(prefix_sum(irt, _T("f")) == 48); - ok1(prefix_sum(irt, _T("fo")) == 48); - ok1(prefix_sum(irt, _T("foo")) == 48); - ok1(prefix_sum(irt, _T("foobar")) == 4); + ok1(prefix_sum(irt, "f") == 48); + ok1(prefix_sum(irt, "fo") == 48); + ok1(prefix_sum(irt, "foo") == 48); + ok1(prefix_sum(irt, "foobar") == 4); - suggest = irt.Suggest(_T("foo"), buffer, 64); + suggest = irt.Suggest("foo", buffer, 64); ok1(suggest != NULL); - ok1(StringIsEqual(suggest, _T("b"))); + ok1(StringIsEqual(suggest, "b")); - irt.Add(_T("fo"), 5); + irt.Add("fo", 5); ok1(all_sum(irt) == 57); - ok1(prefix_sum(irt, _T("f")) == 53); - ok1(prefix_sum(irt, _T("fo")) == 53); - ok1(prefix_sum(irt, _T("foo")) == 48); - ok1(prefix_sum(irt, _T("foobar")) == 4); + ok1(prefix_sum(irt, "f") == 53); + ok1(prefix_sum(irt, "fo") == 53); + ok1(prefix_sum(irt, "foo") == 48); + ok1(prefix_sum(irt, "foobar") == 4); - irt.Add(_T("fooz"), 6); + irt.Add("fooz", 6); ok1(all_sum(irt) == 63); - ok1(prefix_sum(irt, _T("f")) == 59); - ok1(prefix_sum(irt, _T("fo")) == 59); - ok1(prefix_sum(irt, _T("foo")) == 54); + ok1(prefix_sum(irt, "f") == 59); + ok1(prefix_sum(irt, "fo") == 59); + ok1(prefix_sum(irt, "foo") == 54); - suggest = irt.Suggest(_T("foo"), buffer, 64); + suggest = irt.Suggest("foo", buffer, 64); ok1(suggest != NULL); - ok1(StringIsEqual(suggest, _T("bz"))); + ok1(StringIsEqual(suggest, "bz")); - irt.Add(_T("fooy"), 7); + irt.Add("fooy", 7); ok1(all_sum(irt) == 70); - ok1(prefix_sum(irt, _T("f")) == 66); - ok1(prefix_sum(irt, _T("fo")) == 66); - ok1(prefix_sum(irt, _T("foo")) == 61); + ok1(prefix_sum(irt, "f") == 66); + ok1(prefix_sum(irt, "fo") == 66); + ok1(prefix_sum(irt, "foo") == 61); - suggest = irt.Suggest(_T("foo"), buffer, 64); + suggest = irt.Suggest("foo", buffer, 64); ok1(suggest != NULL); - ok1(StringIsEqual(suggest, _T("byz"))); + ok1(StringIsEqual(suggest, "byz")); - irt.Add(_T("foo"), 8); + irt.Add("foo", 8); ok1(all_sum(irt) == 78); - ok1(prefix_sum(irt, _T("foo")) == 69); + ok1(prefix_sum(irt, "foo") == 69); - irt.Remove(_T("foo"), 42); + irt.Remove("foo", 42); ok1(all_sum(irt) == 36); - ok1(prefix_sum(irt, _T("foo")) == 27); + ok1(prefix_sum(irt, "foo") == 27); - irt.Remove(_T("foo")); + irt.Remove("foo"); ok1(all_sum(irt) == 26); - ok1(prefix_sum(irt, _T("")) == 26); - ok1(prefix_sum(irt, _T("foo")) == 17); + ok1(prefix_sum(irt, "") == 26); + ok1(prefix_sum(irt, "foo") == 17); - irt.Add(_T(""), 9); + irt.Add("", 9); ok1(all_sum(irt) == 35); - ok1(prefix_sum(irt, _T("")) == 35); - ok1(prefix_sum(irt, _T("foo")) == 17); + ok1(prefix_sum(irt, "") == 35); + ok1(prefix_sum(irt, "foo") == 17); check_ascending_keys(irt); diff --git a/test/src/TestStrings.cpp b/test/src/TestStrings.cpp index be4f94055b6..a3a7383c841 100644 --- a/test/src/TestStrings.cpp +++ b/test/src/TestStrings.cpp @@ -24,37 +24,37 @@ int main() ok1(StringIsEqual("This is a funny test case!", "This is a funny test case!")); - ok1(StringIsEqual(_T(""), _T(""))); - ok1(!StringIsEqual(_T("a"), _T(""))); - ok1(!StringIsEqual(_T(""), _T("a"))); - ok1(StringIsEqual(_T("aaa"), _T("aaa"))); - ok1(!StringIsEqual(_T("aaa"), _T("a"))); - ok1(!StringIsEqual(_T("aaa"), _T("bbb"))); - ok1(!StringIsEqual(_T("bbb"), _T("aaa"))); + ok1(StringIsEqual("", "")); + ok1(!StringIsEqual("a", "")); + ok1(!StringIsEqual("", "a")); + ok1(StringIsEqual("aaa", "aaa")); + ok1(!StringIsEqual("aaa", "a")); + ok1(!StringIsEqual("aaa", "bbb")); + ok1(!StringIsEqual("bbb", "aaa")); - ok1(StringIsEqual(_T("This is a funny test case!"), - _T("This is a funny test case!"))); + ok1(StringIsEqual("This is a funny test case!", + "This is a funny test case!")); // Test StringStartsWith() - ok1(StringStartsWith(_T(""), _T(""))); - ok1(StringStartsWith(_T("a"), _T(""))); - ok1(!StringStartsWith(_T(""), _T("a"))); - ok1(StringStartsWith(_T("aaa"), _T("aaa"))); - ok1(StringStartsWith(_T("aaa"), _T("a"))); - ok1(!StringStartsWith(_T("bbb"), _T("aaa"))); + ok1(StringStartsWith("", "")); + ok1(StringStartsWith("a", "")); + ok1(!StringStartsWith("", "a")); + ok1(StringStartsWith("aaa", "aaa")); + ok1(StringStartsWith("aaa", "a")); + ok1(!StringStartsWith("bbb", "aaa")); // Test StringAfterPrefix() - ok1(StringIsEqual(StringAfterPrefix(_T(""), _T("")), _T(""))); - ok1(StringIsEqual(StringAfterPrefix(_T("a"), _T("")), _T("a"))); - ok1(StringAfterPrefix(_T(""), _T("a")) == NULL); - ok1(StringIsEqual(StringAfterPrefix(_T("aaa"), _T("aaa")), _T(""))); - ok1(StringIsEqual(StringAfterPrefix(_T("aaa"), _T("a")), _T("aa"))); - ok1(StringAfterPrefix(_T("bbb"), _T("aaa")) == NULL); - ok1(StringIsEqual(StringAfterPrefix(_T("This is a funny test case!"), - _T("This is")), - _T(" a funny test case!"))); + ok1(StringIsEqual(StringAfterPrefix("", ""), "")); + ok1(StringIsEqual(StringAfterPrefix("a", ""), "a")); + ok1(StringAfterPrefix("", "a") == NULL); + ok1(StringIsEqual(StringAfterPrefix("aaa", "aaa"), "")); + ok1(StringIsEqual(StringAfterPrefix("aaa", "a"), "aa")); + ok1(StringAfterPrefix("bbb", "aaa") == NULL); + ok1(StringIsEqual(StringAfterPrefix("This is a funny test case!", + "This is"), + " a funny test case!")); return exit_status(); } diff --git a/test/src/TestTaskSave.cpp b/test/src/TestTaskSave.cpp index 7fff071746a..bf8b15b1296 100644 --- a/test/src/TestTaskSave.cpp +++ b/test/src/TestTaskSave.cpp @@ -15,7 +15,7 @@ static TaskBehaviour task_behaviour; static OrderedTaskSettings ordered_task_settings; -static constexpr Path task_path{_T("output/results/Test-Task.tsk")}; +static constexpr Path task_path{"output/results/Test-Task.tsk"}; static constexpr GeoPoint MakeGeoPoint(double longitude, double latitude) noexcept @@ -24,7 +24,7 @@ MakeGeoPoint(double longitude, double latitude) noexcept } static Waypoint -MakeWaypoint(Waypoint wp, double altitude, tstring name, unsigned id) noexcept +MakeWaypoint(Waypoint wp, double altitude, std::string name, unsigned id) noexcept { wp.name = name; wp.id = id; @@ -34,7 +34,7 @@ MakeWaypoint(Waypoint wp, double altitude, tstring name, unsigned id) noexcept } static Waypoint -MakeWaypoint(double longitude, double latitude, double altitude, tstring name, unsigned id) noexcept +MakeWaypoint(double longitude, double latitude, double altitude, std::string name, unsigned id) noexcept { return MakeWaypoint(Waypoint(MakeGeoPoint(longitude, latitude)), altitude, name, id); } @@ -46,9 +46,9 @@ MakeWaypointPtr(Args&&... args) noexcept return WaypointPtr(new Waypoint(MakeWaypoint(std::forward(args)...))); } -static const auto wp1_str = _T("wp-01"); -static const auto wp2_str = _T("wp-02"); -static const auto wp3_str = _T("wp-03"); +static const auto wp1_str = "wp-01"; +static const auto wp2_str = "wp-02"; +static const auto wp3_str = "wp-03"; static const auto wp1 = MakeWaypointPtr(0, 45, 50, wp1_str, 100); static const auto wp2 = MakeWaypointPtr(0, 45.3, 50, wp2_str, 102); @@ -97,7 +97,7 @@ TestAll() int main() { - Directory::Create(Path{_T("output/results")}); + Directory::Create(Path{"output/results"}); plan_tests(10); task_behaviour.SetDefaults(); diff --git a/test/src/TestTaskWaypoint.cpp b/test/src/TestTaskWaypoint.cpp index d9fda957a17..5016bb1a550 100644 --- a/test/src/TestTaskWaypoint.cpp +++ b/test/src/TestTaskWaypoint.cpp @@ -33,14 +33,14 @@ TaskWaypointTest::Run() { GeoPoint gp(Angle::Degrees(20), Angle::Degrees(50)); Waypoint wp(gp); - wp.name = _T("Test"); + wp.name = "Test"; wp.elevation = 42; wp.has_elevation = true; DummyTaskWaypoint tw(TaskPointType::AST, WaypointPtr(new Waypoint(wp))); const Waypoint &wp2 = tw.GetWaypoint(); - ok1(wp2.name == _T("Test")); + ok1(wp2.name == "Test"); ok1(equals(tw.GetBaseElevation(), 42)); ok1(wp2.has_elevation); ok1(equals(tw.GetBaseElevation(), wp2.elevation)); diff --git a/test/src/TestTeamCode.cpp b/test/src/TestTeamCode.cpp index d69ef4edd0b..129c81852c2 100644 --- a/test/src/TestTeamCode.cpp +++ b/test/src/TestTeamCode.cpp @@ -14,22 +14,22 @@ int main() tc.Update(Angle::Degrees(90), 5000); - ok1(StringIsEqual(tc.GetCode(), _T("901E"))); + ok1(StringIsEqual(tc.GetCode(), "901E")); ok1(iround(tc.GetBearing().Degrees()) == 90); ok1(equals(tc.GetRange(), 5000)); tc.Update(Angle::Degrees(359), 25000); - ok1(StringIsEqual(tc.GetCode(), _T("ZW6Y"))); + ok1(StringIsEqual(tc.GetCode(), "ZW6Y")); ok1(iround(tc.GetBearing().Degrees()) == 359); ok1(equals(tc.GetRange(), 25000)); tc.Update(Angle::Degrees(180), 800000); - ok1(StringIsEqual(tc.GetCode(), _T("I0668"))); + ok1(StringIsEqual(tc.GetCode(), "I0668")); ok1(iround(tc.GetBearing().Degrees()) == 180); ok1(equals(tc.GetRange(), 800000)); tc.Update(Angle::Degrees(270), 100); - ok1(StringIsEqual(tc.GetCode(), _T("R01"))); + ok1(StringIsEqual(tc.GetCode(), "R01")); ok1(iround(tc.GetBearing().Degrees()) == 270); ok1(equals(tc.GetRange(), 100)); diff --git a/test/src/TestTimeFormatter.cpp b/test/src/TestTimeFormatter.cpp index 035ba3bb021..70267bcbea2 100644 --- a/test/src/TestTimeFormatter.cpp +++ b/test/src/TestTimeFormatter.cpp @@ -9,118 +9,118 @@ static void TestFormat() { - TCHAR buffer[256]; + char buffer[256]; FormatTime(buffer, FloatDuration{}); - ok1(StringIsEqual(buffer, _T("00:00:00"))); + ok1(StringIsEqual(buffer, "00:00:00")); FormatTime(buffer, std::chrono::seconds{1}); - ok1(StringIsEqual(buffer, _T("00:00:01"))); + ok1(StringIsEqual(buffer, "00:00:01")); FormatTime(buffer, std::chrono::seconds{59}); - ok1(StringIsEqual(buffer, _T("00:00:59"))); + ok1(StringIsEqual(buffer, "00:00:59")); FormatTime(buffer, std::chrono::seconds{60}); - ok1(StringIsEqual(buffer, _T("00:01:00"))); + ok1(StringIsEqual(buffer, "00:01:00")); FormatTime(buffer, std::chrono::seconds{60 * 5}); - ok1(StringIsEqual(buffer, _T("00:05:00"))); + ok1(StringIsEqual(buffer, "00:05:00")); FormatTime(buffer, std::chrono::seconds{60 * 59}); - ok1(StringIsEqual(buffer, _T("00:59:00"))); + ok1(StringIsEqual(buffer, "00:59:00")); FormatTime(buffer, std::chrono::seconds{60 * 60}); - ok1(StringIsEqual(buffer, _T("01:00:00"))); + ok1(StringIsEqual(buffer, "01:00:00")); FormatTime(buffer, std::chrono::seconds{60 * 60 * 3 + 60 * 25}); - ok1(StringIsEqual(buffer, _T("03:25:00"))); + ok1(StringIsEqual(buffer, "03:25:00")); FormatTime(buffer, std::chrono::seconds{60 * 60 * 19 + 60 * 47 + 43}); - ok1(StringIsEqual(buffer, _T("19:47:43"))); + ok1(StringIsEqual(buffer, "19:47:43")); FormatTime(buffer, std::chrono::seconds{-(60 * 59)}); - ok1(StringIsEqual(buffer, _T("-00:59:00"))); + ok1(StringIsEqual(buffer, "-00:59:00")); FormatTime(buffer, std::chrono::seconds{-(60 * 60 * 19 + 60 * 47 + 43)}); - ok1(StringIsEqual(buffer, _T("-19:47:43"))); + ok1(StringIsEqual(buffer, "-19:47:43")); } static void TestFormatLong() { - TCHAR buffer[256]; + char buffer[256]; FormatTimeLong(buffer, {}); - ok1(StringIsEqual(buffer, _T("00:00:00.000"))); + ok1(StringIsEqual(buffer, "00:00:00.000")); FormatTimeLong(buffer, FloatDuration{1.123}); - ok1(StringIsEqual(buffer, _T("00:00:01.123"))); + ok1(StringIsEqual(buffer, "00:00:01.123")); FormatTimeLong(buffer, std::chrono::seconds{59}); - ok1(StringIsEqual(buffer, _T("00:00:59.000"))); + ok1(StringIsEqual(buffer, "00:00:59.000")); FormatTimeLong(buffer, FloatDuration{60.001}); - ok1(StringIsEqual(buffer, _T("00:01:00.001"))); + ok1(StringIsEqual(buffer, "00:01:00.001")); FormatTimeLong(buffer, std::chrono::seconds{60 * 5}); - ok1(StringIsEqual(buffer, _T("00:05:00.000"))); + ok1(StringIsEqual(buffer, "00:05:00.000")); FormatTimeLong(buffer, std::chrono::seconds{60 * 59}); - ok1(StringIsEqual(buffer, _T("00:59:00.000"))); + ok1(StringIsEqual(buffer, "00:59:00.000")); FormatTimeLong(buffer, std::chrono::seconds{60 * 60}); - ok1(StringIsEqual(buffer, _T("01:00:00.000"))); + ok1(StringIsEqual(buffer, "01:00:00.000")); FormatTimeLong(buffer, std::chrono::seconds{60 * 60 * 3 + 60 * 25}); - ok1(StringIsEqual(buffer, _T("03:25:00.000"))); + ok1(StringIsEqual(buffer, "03:25:00.000")); FormatTimeLong(buffer, FloatDuration{60 * 60 * 19 + 60 * 47 + 43.765}); - ok1(StringIsEqual(buffer, _T("19:47:43.765"))); + ok1(StringIsEqual(buffer, "19:47:43.765")); FormatTimeLong(buffer, std::chrono::seconds{-(60 * 59)}); - ok1(StringIsEqual(buffer, _T("-00:59:00.000"))); + ok1(StringIsEqual(buffer, "-00:59:00.000")); FormatTimeLong(buffer, FloatDuration{-(60 * 60 * 19 + 60 * 47 + 43.765)}); - ok1(StringIsEqual(buffer, _T("-19:47:43.765"))); + ok1(StringIsEqual(buffer, "-19:47:43.765")); } static void TestHHMM() { - TCHAR buffer[256]; + char buffer[256]; FormatSignedTimeHHMM(buffer, {}); - ok1(StringIsEqual(buffer, _T("00:00"))); + ok1(StringIsEqual(buffer, "00:00")); FormatSignedTimeHHMM(buffer, std::chrono::seconds{1}); - ok1(StringIsEqual(buffer, _T("00:00"))); + ok1(StringIsEqual(buffer, "00:00")); FormatSignedTimeHHMM(buffer, std::chrono::seconds{59}); - ok1(StringIsEqual(buffer, _T("00:00"))); + ok1(StringIsEqual(buffer, "00:00")); FormatSignedTimeHHMM(buffer, std::chrono::seconds{60}); - ok1(StringIsEqual(buffer, _T("00:01"))); + ok1(StringIsEqual(buffer, "00:01")); FormatSignedTimeHHMM(buffer, std::chrono::seconds{60 * 5}); - ok1(StringIsEqual(buffer, _T("00:05"))); + ok1(StringIsEqual(buffer, "00:05")); FormatSignedTimeHHMM(buffer, std::chrono::seconds{60 * 59}); - ok1(StringIsEqual(buffer, _T("00:59"))); + ok1(StringIsEqual(buffer, "00:59")); FormatSignedTimeHHMM(buffer, std::chrono::seconds{60 * 60}); - ok1(StringIsEqual(buffer, _T("01:00"))); + ok1(StringIsEqual(buffer, "01:00")); FormatSignedTimeHHMM(buffer, std::chrono::seconds{60 * 60 * 3 + 60 * 25}); - ok1(StringIsEqual(buffer, _T("03:25"))); + ok1(StringIsEqual(buffer, "03:25")); FormatSignedTimeHHMM(buffer, std::chrono::seconds{60 * 60 * 19 + 60 * 47}); - ok1(StringIsEqual(buffer, _T("19:47"))); + ok1(StringIsEqual(buffer, "19:47")); FormatSignedTimeHHMM(buffer, std::chrono::seconds{-(60 * 59)}); - ok1(StringIsEqual(buffer, _T("-00:59"))); + ok1(StringIsEqual(buffer, "-00:59")); FormatSignedTimeHHMM(buffer, std::chrono::seconds{-(60 * 60 * 19 + 60 * 47)}); - ok1(StringIsEqual(buffer, _T("-19:47"))); + ok1(StringIsEqual(buffer, "-19:47")); } #include @@ -128,59 +128,59 @@ TestHHMM() static void TestTwoLines() { - TCHAR buffer[256], buffer2[256]; + char buffer[256], buffer2[256]; FormatTimeTwoLines(buffer, buffer2, {}); - ok1(StringIsEqual(buffer, _T("00'00"))); - ok1(StringIsEqual(buffer2, _T(""))); + ok1(StringIsEqual(buffer, "00'00")); + ok1(StringIsEqual(buffer2, "")); FormatTimeTwoLines(buffer, buffer2, std::chrono::seconds{1}); - ok1(StringIsEqual(buffer, _T("00'01"))); - ok1(StringIsEqual(buffer2, _T(""))); + ok1(StringIsEqual(buffer, "00'01")); + ok1(StringIsEqual(buffer2, "")); FormatTimeTwoLines(buffer, buffer2, std::chrono::seconds{59}); - ok1(StringIsEqual(buffer, _T("00'59"))); - ok1(StringIsEqual(buffer2, _T(""))); + ok1(StringIsEqual(buffer, "00'59")); + ok1(StringIsEqual(buffer2, "")); FormatTimeTwoLines(buffer, buffer2, std::chrono::seconds{60}); - ok1(StringIsEqual(buffer, _T("01'00"))); - ok1(StringIsEqual(buffer2, _T(""))); + ok1(StringIsEqual(buffer, "01'00")); + ok1(StringIsEqual(buffer2, "")); FormatTimeTwoLines(buffer, buffer2, std::chrono::seconds{60 * 5}); - ok1(StringIsEqual(buffer, _T("05'00"))); - ok1(StringIsEqual(buffer2, _T(""))); + ok1(StringIsEqual(buffer, "05'00")); + ok1(StringIsEqual(buffer2, "")); FormatTimeTwoLines(buffer, buffer2, std::chrono::seconds{60 * 59}); - ok1(StringIsEqual(buffer, _T("59'00"))); - ok1(StringIsEqual(buffer2, _T(""))); + ok1(StringIsEqual(buffer, "59'00")); + ok1(StringIsEqual(buffer2, "")); FormatTimeTwoLines(buffer, buffer2, std::chrono::seconds{60 * 60}); - ok1(StringIsEqual(buffer, _T("01:00"))); - ok1(StringIsEqual(buffer2, _T("00"))); + ok1(StringIsEqual(buffer, "01:00")); + ok1(StringIsEqual(buffer2, "00")); FormatTimeTwoLines(buffer, buffer2, std::chrono::seconds{60 * 60 * 3 + 60 * 25 + 13}); - ok1(StringIsEqual(buffer, _T("03:25"))); - ok1(StringIsEqual(buffer2, _T("13"))); + ok1(StringIsEqual(buffer, "03:25")); + ok1(StringIsEqual(buffer2, "13")); FormatTimeTwoLines(buffer, buffer2, std::chrono::seconds{60 * 60 * 19 + 60 * 47 + 28}); - ok1(StringIsEqual(buffer, _T("19:47"))); - ok1(StringIsEqual(buffer2, _T("28"))); + ok1(StringIsEqual(buffer, "19:47")); + ok1(StringIsEqual(buffer2, "28")); FormatTimeTwoLines(buffer, buffer2, std::chrono::seconds{-(60 * 59)}); - ok1(StringIsEqual(buffer, _T("-59'00"))); - ok1(StringIsEqual(buffer2, _T(""))); + ok1(StringIsEqual(buffer, "-59'00")); + ok1(StringIsEqual(buffer2, "")); FormatTimeTwoLines(buffer, buffer2, std::chrono::seconds{-(60 * 60 * 19 + 60 * 47 + 28)}); - ok1(StringIsEqual(buffer, _T("-19:47"))); - ok1(StringIsEqual(buffer2, _T("28"))); + ok1(StringIsEqual(buffer, "-19:47")); + ok1(StringIsEqual(buffer2, "28")); } static void -TestSmart(int _time, const TCHAR *expected_output1, - const TCHAR *expected_output2, const TCHAR *expected_output3, - const TCHAR *expected_output4, const TCHAR *separator = _T(" ")) +TestSmart(int _time, const char *expected_output1, + const char *expected_output2, const char *expected_output3, + const char *expected_output4, const char *separator = " ") { - TCHAR buffer[256]; + char buffer[256]; const auto time = std::chrono::seconds{_time}; @@ -200,39 +200,39 @@ TestSmart(int _time, const TCHAR *expected_output1, static void TestSmart() { - TestSmart(0, _T("0 sec"), _T("0 sec"), _T("0 sec"), _T("0 sec")); - TestSmart(1, _T("1 sec"), _T("1 sec"), _T("1 sec"), _T("1 sec")); - TestSmart(59, _T("59 sec"), _T("59 sec"), _T("59 sec"), _T("59 sec")); - TestSmart(60, _T("1 min"), _T("1 min"), _T("1 min"), _T("1 min")); + TestSmart(0, "0 sec", "0 sec", "0 sec", "0 sec"); + TestSmart(1, "1 sec", "1 sec", "1 sec", "1 sec"); + TestSmart(59, "59 sec", "59 sec", "59 sec", "59 sec"); + TestSmart(60, "1 min", "1 min", "1 min", "1 min"); - TestSmart(60 + 59, _T("1 min"), _T("1 min 59 sec"), _T("1 min 59 sec"), - _T("1 min 59 sec")); + TestSmart(60 + 59, "1 min", "1 min 59 sec", "1 min 59 sec", + "1 min 59 sec"); - TestSmart(60 * 5 + 34, _T("5 min"), _T("5 min 34 sec"), _T("5 min 34 sec"), - _T("5 min 34 sec")); + TestSmart(60 * 5 + 34, "5 min", "5 min 34 sec", "5 min 34 sec", + "5 min 34 sec"); - TestSmart(60 * 59, _T("59 min"), _T("59 min"), _T("59 min"), _T("59 min")); - TestSmart(60 * 60, _T("1 h"), _T("1 h"), _T("1 h"), _T("1 h")); + TestSmart(60 * 59, "59 min", "59 min", "59 min", "59 min"); + TestSmart(60 * 60, "1 h", "1 h", "1 h", "1 h"); - TestSmart(60 * 60 * 3 + 60 * 25, _T("3 h"), _T("3 h 25 min"), - _T("3 h 25 min"), _T("3 h 25 min")); + TestSmart(60 * 60 * 3 + 60 * 25, "3 h", "3 h 25 min", + "3 h 25 min", "3 h 25 min"); - TestSmart(60 * 60 * 19 + 60 * 47, _T("19 h"), _T("19 h 47 min"), - _T("19 h 47 min"), _T("19 h 47 min")); + TestSmart(60 * 60 * 19 + 60 * 47, "19 h", "19 h 47 min", + "19 h 47 min", "19 h 47 min"); - TestSmart(60 * 60 * 19 + 47, _T("19 h"), _T("19 h"), - _T("19 h 0 min 47 sec"), _T("19 h 0 min 47 sec")); + TestSmart(60 * 60 * 19 + 47, "19 h", "19 h", + "19 h 0 min 47 sec", "19 h 0 min 47 sec"); - TestSmart(60 * 60 * 19 + 60 * 47 + 5, _T("19 h"), _T("19 h 47 min"), - _T("19 h 47 min 5 sec"), _T("19 h 47 min 5 sec")); + TestSmart(60 * 60 * 19 + 60 * 47 + 5, "19 h", "19 h 47 min", + "19 h 47 min 5 sec", "19 h 47 min 5 sec"); - TestSmart(60 * 60 * 24 * 3 + 60 * 60 * 19 + 60 * 47 + 5, _T("3 days"), - _T("3 days 19 h"), _T("3 days 19 h 47 min"), - _T("3 days 19 h 47 min 5 sec")); + TestSmart(60 * 60 * 24 * 3 + 60 * 60 * 19 + 60 * 47 + 5, "3 days", + "3 days 19 h", "3 days 19 h 47 min", + "3 days 19 h 47 min 5 sec"); - TestSmart(-(60 * 60 * 24 * 3 + 60 * 60 * 19 + 60 * 47 + 5), _T("-3 days"), - _T("-3 days 19 h"), _T("-3 days 19 h 47 min"), - _T("-3 days 19 h 47 min 5 sec")); + TestSmart(-(60 * 60 * 24 * 3 + 60 * 60 * 19 + 60 * 47 + 5), "-3 days", + "-3 days 19 h", "-3 days 19 h 47 min", + "-3 days 19 h 47 min 5 sec"); } int main() diff --git a/test/src/TestTrace.cpp b/test/src/TestTrace.cpp index 7168d5bb84d..e7849bcbfc6 100644 --- a/test/src/TestTrace.cpp +++ b/test/src/TestTrace.cpp @@ -78,7 +78,7 @@ try { if (argc > 1) { n = atoi(argv[1]); } - TestTrace(Path(_T("test/data/09kc3ov3.igc")), n); + TestTrace(Path("test/data/09kc3ov3.igc"), n); } else { assert(argc >= 3); unsigned n = atoi(argv[2]); diff --git a/test/src/TestTransponderCode.cpp b/test/src/TestTransponderCode.cpp index 8a3f8db5014..2771fb3d264 100644 --- a/test/src/TestTransponderCode.cpp +++ b/test/src/TestTransponderCode.cpp @@ -13,28 +13,28 @@ int main() { plan_tests(13); - ok1(TransponderCode::Parse(_T("7000")).IsDefined()); + ok1(TransponderCode::Parse("7000").IsDefined()); ok1(TransponderCode{07000}.IsDefined()); ok1(equals(TransponderCode().GetCode(), 0)); - ok1(!TransponderCode::Parse(_T("7797")).IsDefined()); + ok1(!TransponderCode::Parse("7797").IsDefined()); ok1(!TransponderCode{7797}.IsDefined()); ok1(!TransponderCode::Null().IsDefined()); - ok1(!TransponderCode::Parse(_T("20000")).IsDefined()); + ok1(!TransponderCode::Parse("20000").IsDefined()); ok1(!TransponderCode{20000}.IsDefined()); TransponderCode code{04567}; ok1(code.IsDefined()); - TCHAR buf[12]; + char buf[12]; ok1(StringIsEqual(code.Format(buf, std::size(buf)), - _T("4567"))); + "4567")); code.Clear(); ok1(!code.IsDefined()); ok1(code.Format(buf, std::size(buf)) == nullptr); - code = TransponderCode::Parse(_T("4567")); + code = TransponderCode::Parse("4567"); ok1(code.IsDefined()); return exit_status(); diff --git a/test/src/TestUTF8.cpp b/test/src/TestUTF8.cpp index 81b304495b1..b7d0d2fb6d7 100644 --- a/test/src/TestUTF8.cpp +++ b/test/src/TestUTF8.cpp @@ -89,8 +89,6 @@ MyValidateUTF8(const char *p) } } -#ifndef _UNICODE - static constexpr struct { const char *src; size_t truncate, dest_size; @@ -125,7 +123,6 @@ TestTruncateString() } } -#endif int main() { @@ -134,9 +131,7 @@ int main() 2 * ARRAY_SIZE(length) + 4 * ARRAY_SIZE(crop) + ARRAY_SIZE(latin1_chars) + -#ifndef _UNICODE ARRAY_SIZE(truncate_string_tests) + -#endif 9 + 27); for (auto i : valid) { @@ -170,9 +165,7 @@ int main() ok1(end == buffer + strlen(buffer)); } -#ifndef _UNICODE TestTruncateString(); -#endif { const char *p = "foo\xe7\x9b\xae"; diff --git a/test/src/TestUnitsFormatter.cpp b/test/src/TestUnitsFormatter.cpp index 1b4a93ee826..ee1314c92ad 100644 --- a/test/src/TestUnitsFormatter.cpp +++ b/test/src/TestUnitsFormatter.cpp @@ -12,205 +12,205 @@ static void TestAltitude() { - TCHAR buffer[256]; + char buffer[256]; // Test FormatAltitude() FormatAltitude(buffer, 1234, Unit::METER); - ok1(StringIsEqual(buffer, _T("1234 m"))); + ok1(StringIsEqual(buffer, "1234 m")); FormatAltitude(buffer, Units::ToSysUnit(1234, Unit::FEET), Unit::FEET); - ok1(StringIsEqual(buffer, _T("1234 ft"))); + ok1(StringIsEqual(buffer, "1234 ft")); FormatAltitude(buffer, -1234, Unit::METER); - ok1(StringIsEqual(buffer, _T("-1234 m"))); + ok1(StringIsEqual(buffer, "-1234 m")); FormatAltitude(buffer, Units::ToSysUnit(-1234, Unit::FEET), Unit::FEET); - ok1(StringIsEqual(buffer, _T("-1234 ft"))); + ok1(StringIsEqual(buffer, "-1234 ft")); FormatAltitude(buffer, 1234, Unit::METER, false); - ok1(StringIsEqual(buffer, _T("1234"))); + ok1(StringIsEqual(buffer, "1234")); FormatAltitude(buffer, -1234, Unit::METER, false); - ok1(StringIsEqual(buffer, _T("-1234"))); + ok1(StringIsEqual(buffer, "-1234")); } static void TestRelativeAltitude() { - TCHAR buffer[256]; + char buffer[256]; // Test FormatRelativeAltitude() FormatRelativeAltitude(buffer, 1234, Unit::METER); - ok1(StringIsEqual(buffer, _T("+1234 m"))); + ok1(StringIsEqual(buffer, "+1234 m")); FormatRelativeAltitude(buffer, Units::ToSysUnit(1234, Unit::FEET), Unit::FEET); - ok1(StringIsEqual(buffer, _T("+1234 ft"))); + ok1(StringIsEqual(buffer, "+1234 ft")); FormatRelativeAltitude(buffer, -1234, Unit::METER); - ok1(StringIsEqual(buffer, _T("-1234 m"))); + ok1(StringIsEqual(buffer, "-1234 m")); FormatRelativeAltitude(buffer, Units::ToSysUnit(-1234, Unit::FEET), Unit::FEET); - ok1(StringIsEqual(buffer, _T("-1234 ft"))); + ok1(StringIsEqual(buffer, "-1234 ft")); FormatRelativeAltitude(buffer, 1234, Unit::METER, false); - ok1(StringIsEqual(buffer, _T("+1234"))); + ok1(StringIsEqual(buffer, "+1234")); FormatRelativeAltitude(buffer, -1234, Unit::METER, false); - ok1(StringIsEqual(buffer, _T("-1234"))); + ok1(StringIsEqual(buffer, "-1234")); } static void TestDistance() { - TCHAR buffer[256]; + char buffer[256]; // Test FormatDistance() FormatDistance(buffer, 123.4, Unit::METER); - ok1(StringIsEqual(buffer, _T("123 m"))); + ok1(StringIsEqual(buffer, "123 m")); FormatDistance(buffer, 123.4, Unit::METER, false); - ok1(StringIsEqual(buffer, _T("123"))); + ok1(StringIsEqual(buffer, "123")); FormatDistance(buffer, 123.4, Unit::METER, true, 1); - ok1(StringIsEqual(buffer, _T("123.4 m"))); + ok1(StringIsEqual(buffer, "123.4 m")); FormatDistance(buffer, 123.4, Unit::METER, false, 1); - ok1(StringIsEqual(buffer, _T("123.4"))); + ok1(StringIsEqual(buffer, "123.4")); FormatDistance(buffer, 123.4, Unit::METER, true, 2); - ok1(StringIsEqual(buffer, _T("123.40 m"))); + ok1(StringIsEqual(buffer, "123.40 m")); FormatDistance(buffer, 123.4, Unit::METER, false, 2); - ok1(StringIsEqual(buffer, _T("123.40"))); + ok1(StringIsEqual(buffer, "123.40")); FormatDistance(buffer, Units::ToSysUnit(123.4, Unit::KILOMETER), Unit::KILOMETER); - ok1(StringIsEqual(buffer, _T("123 km"))); + ok1(StringIsEqual(buffer, "123 km")); FormatDistance(buffer, Units::ToSysUnit(123.4, Unit::KILOMETER), Unit::KILOMETER, false); - ok1(StringIsEqual(buffer, _T("123"))); + ok1(StringIsEqual(buffer, "123")); FormatDistance(buffer, Units::ToSysUnit(123.4, Unit::KILOMETER), Unit::KILOMETER, true, 1); - ok1(StringIsEqual(buffer, _T("123.4 km"))); + ok1(StringIsEqual(buffer, "123.4 km")); FormatDistance(buffer, Units::ToSysUnit(123.4, Unit::KILOMETER), Unit::KILOMETER, false, 1); - ok1(StringIsEqual(buffer, _T("123.4"))); + ok1(StringIsEqual(buffer, "123.4")); FormatDistance(buffer, Units::ToSysUnit(123.4, Unit::NAUTICAL_MILES), Unit::NAUTICAL_MILES); - ok1(StringIsEqual(buffer, _T("123 NM"))); + ok1(StringIsEqual(buffer, "123 NM")); FormatDistance(buffer, Units::ToSysUnit(123.4, Unit::NAUTICAL_MILES), Unit::NAUTICAL_MILES, false); - ok1(StringIsEqual(buffer, _T("123"))); + ok1(StringIsEqual(buffer, "123")); FormatDistance(buffer, Units::ToSysUnit(123.4, Unit::NAUTICAL_MILES), Unit::NAUTICAL_MILES, true, 1); - ok1(StringIsEqual(buffer, _T("123.4 NM"))); + ok1(StringIsEqual(buffer, "123.4 NM")); FormatDistance(buffer, Units::ToSysUnit(123.4, Unit::NAUTICAL_MILES), Unit::NAUTICAL_MILES, false, 1); - ok1(StringIsEqual(buffer, _T("123.4"))); + ok1(StringIsEqual(buffer, "123.4")); FormatDistance(buffer, Units::ToSysUnit(123.4, Unit::STATUTE_MILES), Unit::STATUTE_MILES); - ok1(StringIsEqual(buffer, _T("123 mi"))); + ok1(StringIsEqual(buffer, "123 mi")); FormatDistance(buffer, Units::ToSysUnit(123.4, Unit::STATUTE_MILES), Unit::STATUTE_MILES, false); - ok1(StringIsEqual(buffer, _T("123"))); + ok1(StringIsEqual(buffer, "123")); FormatDistance(buffer, Units::ToSysUnit(123.4, Unit::STATUTE_MILES), Unit::STATUTE_MILES, true, 1); - ok1(StringIsEqual(buffer, _T("123.4 mi"))); + ok1(StringIsEqual(buffer, "123.4 mi")); FormatDistance(buffer, Units::ToSysUnit(123.4, Unit::STATUTE_MILES), Unit::STATUTE_MILES, false, 1); - ok1(StringIsEqual(buffer, _T("123.4"))); + ok1(StringIsEqual(buffer, "123.4")); } static void TestSmallDistance() { - TCHAR buffer[256]; + char buffer[256]; // Test FormatSmallDistance() FormatSmallDistance(buffer, 123.4, Unit::METER); - ok1(StringIsEqual(buffer, _T("123 m"))); + ok1(StringIsEqual(buffer, "123 m")); FormatSmallDistance(buffer, 123.4, Unit::METER, false); - ok1(StringIsEqual(buffer, _T("123"))); + ok1(StringIsEqual(buffer, "123")); FormatSmallDistance(buffer, 123.4, Unit::METER, true, 1); - ok1(StringIsEqual(buffer, _T("123.4 m"))); + ok1(StringIsEqual(buffer, "123.4 m")); FormatSmallDistance(buffer, 123.4, Unit::METER, false, 1); - ok1(StringIsEqual(buffer, _T("123.4"))); + ok1(StringIsEqual(buffer, "123.4")); FormatSmallDistance(buffer, 123.4, Unit::METER, true, 2); - ok1(StringIsEqual(buffer, _T("123.40 m"))); + ok1(StringIsEqual(buffer, "123.40 m")); FormatSmallDistance(buffer, 123.4, Unit::METER, false, 2); - ok1(StringIsEqual(buffer, _T("123.40"))); + ok1(StringIsEqual(buffer, "123.40")); FormatSmallDistance(buffer, 123.4, Unit::KILOMETER); - ok1(StringIsEqual(buffer, _T("123 m"))); + ok1(StringIsEqual(buffer, "123 m")); FormatSmallDistance(buffer, 123.4, Unit::KILOMETER, false); - ok1(StringIsEqual(buffer, _T("123"))); + ok1(StringIsEqual(buffer, "123")); FormatSmallDistance(buffer, 123.4, Unit::KILOMETER, true, 1); - ok1(StringIsEqual(buffer, _T("123.4 m"))); + ok1(StringIsEqual(buffer, "123.4 m")); FormatSmallDistance(buffer, 123.4, Unit::KILOMETER, false, 1); - ok1(StringIsEqual(buffer, _T("123.4"))); + ok1(StringIsEqual(buffer, "123.4")); FormatSmallDistance(buffer, Units::ToSysUnit(123.4, Unit::FEET), Unit::NAUTICAL_MILES); - ok1(StringIsEqual(buffer, _T("123 ft"))); + ok1(StringIsEqual(buffer, "123 ft")); FormatSmallDistance(buffer, Units::ToSysUnit(123.4, Unit::FEET), Unit::NAUTICAL_MILES, false); - ok1(StringIsEqual(buffer, _T("123"))); + ok1(StringIsEqual(buffer, "123")); FormatSmallDistance(buffer, Units::ToSysUnit(123.4, Unit::FEET), Unit::NAUTICAL_MILES, true, 1); - ok1(StringIsEqual(buffer, _T("123.4 ft"))); + ok1(StringIsEqual(buffer, "123.4 ft")); FormatSmallDistance(buffer, Units::ToSysUnit(123.4, Unit::FEET), Unit::NAUTICAL_MILES, false, 1); - ok1(StringIsEqual(buffer, _T("123.4"))); + ok1(StringIsEqual(buffer, "123.4")); FormatSmallDistance(buffer, Units::ToSysUnit(123.4, Unit::FEET), Unit::STATUTE_MILES); - ok1(StringIsEqual(buffer, _T("123 ft"))); + ok1(StringIsEqual(buffer, "123 ft")); FormatSmallDistance(buffer, Units::ToSysUnit(123.4, Unit::FEET), Unit::STATUTE_MILES, false); - ok1(StringIsEqual(buffer, _T("123"))); + ok1(StringIsEqual(buffer, "123")); FormatSmallDistance(buffer, Units::ToSysUnit(123.4, Unit::FEET), Unit::STATUTE_MILES, true, 1); - ok1(StringIsEqual(buffer, _T("123.4 ft"))); + ok1(StringIsEqual(buffer, "123.4 ft")); FormatSmallDistance(buffer, Units::ToSysUnit(123.4, Unit::FEET), Unit::STATUTE_MILES, false, 1); - ok1(StringIsEqual(buffer, _T("123.4"))); + ok1(StringIsEqual(buffer, "123.4")); } static void TestDistanceSmart(double value, Unit unit, Unit expected_unit, - const TCHAR *expected_output_with_unit, - const TCHAR *expected_output_without_unit, + const char *expected_output_with_unit, + const char *expected_output_without_unit, double small_unit_threshold = 2500, double precision_threshold = 100) { - TCHAR buffer[256]; + char buffer[256]; ok1(FormatDistanceSmart(buffer, value, unit, true, small_unit_threshold, precision_threshold) == expected_unit); @@ -227,277 +227,277 @@ TestDistanceSmart() // Test FormatDistanceSmart() // Test Meter - TestDistanceSmart(0.1234, Unit::METER, Unit::METER, _T("0.12 m"), - _T("0.12")); + TestDistanceSmart(0.1234, Unit::METER, Unit::METER, "0.12 m", + "0.12"); - TestDistanceSmart(1.234, Unit::METER, Unit::METER, _T("1.23 m"), - _T("1.23")); + TestDistanceSmart(1.234, Unit::METER, Unit::METER, "1.23 m", + "1.23"); - TestDistanceSmart(12.34, Unit::METER, Unit::METER, _T("12.3 m"), - _T("12.3")); + TestDistanceSmart(12.34, Unit::METER, Unit::METER, "12.3 m", + "12.3"); - TestDistanceSmart(123.4, Unit::METER, Unit::METER, _T("123 m"), - _T("123")); + TestDistanceSmart(123.4, Unit::METER, Unit::METER, "123 m", + "123"); - TestDistanceSmart(1234, Unit::METER, Unit::METER, _T("1234 m"), - _T("1234")); + TestDistanceSmart(1234, Unit::METER, Unit::METER, "1234 m", + "1234"); - TestDistanceSmart(12345, Unit::METER, Unit::METER, _T("12345 m"), - _T("12345")); + TestDistanceSmart(12345, Unit::METER, Unit::METER, "12345 m", + "12345"); - TestDistanceSmart(123456, Unit::METER, Unit::METER, _T("123456 m"), - _T("123456")); + TestDistanceSmart(123456, Unit::METER, Unit::METER, "123456 m", + "123456"); // Test Kilometer TestDistanceSmart(Units::ToSysUnit(0.1234, Unit::KILOMETER), - Unit::KILOMETER, Unit::METER, _T("123 m"), _T("123")); + Unit::KILOMETER, Unit::METER, "123 m", "123"); TestDistanceSmart(Units::ToSysUnit(1.234, Unit::KILOMETER), - Unit::KILOMETER, Unit::METER, _T("1234 m"), _T("1234")); + Unit::KILOMETER, Unit::METER, "1234 m", "1234"); TestDistanceSmart(Units::ToSysUnit(2.345, Unit::KILOMETER), - Unit::KILOMETER, Unit::METER, _T("2345 m"), _T("2345")); + Unit::KILOMETER, Unit::METER, "2345 m", "2345"); TestDistanceSmart(Units::ToSysUnit(2.634, Unit::KILOMETER), - Unit::KILOMETER, Unit::KILOMETER, _T("2.63 km"), - _T("2.63")); + Unit::KILOMETER, Unit::KILOMETER, "2.63 km", + "2.63"); TestDistanceSmart(Units::ToSysUnit(12.34, Unit::KILOMETER), - Unit::KILOMETER, Unit::KILOMETER, _T("12.3 km"), - _T("12.3")); + Unit::KILOMETER, Unit::KILOMETER, "12.3 km", + "12.3"); TestDistanceSmart(Units::ToSysUnit(123.4, Unit::KILOMETER), - Unit::KILOMETER, Unit::KILOMETER, _T("123 km"), _T("123")); + Unit::KILOMETER, Unit::KILOMETER, "123 km", "123"); // Test Nautical Miles TestDistanceSmart(Units::ToSysUnit(123.4, Unit::FEET), - Unit::NAUTICAL_MILES, Unit::FEET, _T("123 ft"), _T("123")); + Unit::NAUTICAL_MILES, Unit::FEET, "123 ft", "123"); TestDistanceSmart(Units::ToSysUnit(1234, Unit::FEET), - Unit::NAUTICAL_MILES, Unit::FEET, _T("1234 ft"), - _T("1234")); + Unit::NAUTICAL_MILES, Unit::FEET, "1234 ft", + "1234"); TestDistanceSmart(Units::ToSysUnit(2345, Unit::FEET), - Unit::NAUTICAL_MILES, Unit::FEET, _T("2345 ft"), - _T("2345")); + Unit::NAUTICAL_MILES, Unit::FEET, "2345 ft", + "2345"); TestDistanceSmart(Units::ToSysUnit(0.61, Unit::NAUTICAL_MILES), - Unit::NAUTICAL_MILES, Unit::NAUTICAL_MILES, _T("0.61 NM"), - _T("0.61")); + Unit::NAUTICAL_MILES, Unit::NAUTICAL_MILES, "0.61 NM", + "0.61"); TestDistanceSmart(Units::ToSysUnit(1.234, Unit::NAUTICAL_MILES), - Unit::NAUTICAL_MILES, Unit::NAUTICAL_MILES, _T("1.23 NM"), - _T("1.23")); + Unit::NAUTICAL_MILES, Unit::NAUTICAL_MILES, "1.23 NM", + "1.23"); TestDistanceSmart(Units::ToSysUnit(12.34, Unit::NAUTICAL_MILES), - Unit::NAUTICAL_MILES, Unit::NAUTICAL_MILES, _T("12.3 NM"), - _T("12.3")); + Unit::NAUTICAL_MILES, Unit::NAUTICAL_MILES, "12.3 NM", + "12.3"); TestDistanceSmart(Units::ToSysUnit(123.4, Unit::NAUTICAL_MILES), - Unit::NAUTICAL_MILES, Unit::NAUTICAL_MILES, _T("123 NM"), - _T("123")); + Unit::NAUTICAL_MILES, Unit::NAUTICAL_MILES, "123 NM", + "123"); // Test Statute Miles TestDistanceSmart(Units::ToSysUnit(123.4, Unit::FEET), - Unit::STATUTE_MILES, Unit::FEET, _T("123 ft"), _T("123")); + Unit::STATUTE_MILES, Unit::FEET, "123 ft", "123"); TestDistanceSmart(Units::ToSysUnit(1234, Unit::FEET), - Unit::STATUTE_MILES, Unit::FEET, _T("1234 ft"), _T("1234")); + Unit::STATUTE_MILES, Unit::FEET, "1234 ft", "1234"); TestDistanceSmart(Units::ToSysUnit(2345, Unit::FEET), - Unit::STATUTE_MILES, Unit::FEET, _T("2345 ft"), _T("2345")); + Unit::STATUTE_MILES, Unit::FEET, "2345 ft", "2345"); TestDistanceSmart(Units::ToSysUnit(0.71, Unit::STATUTE_MILES), - Unit::STATUTE_MILES, Unit::STATUTE_MILES, _T("0.71 mi"), - _T("0.71")); + Unit::STATUTE_MILES, Unit::STATUTE_MILES, "0.71 mi", + "0.71"); TestDistanceSmart(Units::ToSysUnit(1.234, Unit::STATUTE_MILES), - Unit::STATUTE_MILES, Unit::STATUTE_MILES, _T("1.23 mi"), - _T("1.23")); + Unit::STATUTE_MILES, Unit::STATUTE_MILES, "1.23 mi", + "1.23"); TestDistanceSmart(Units::ToSysUnit(12.34, Unit::STATUTE_MILES), - Unit::STATUTE_MILES, Unit::STATUTE_MILES, _T("12.3 mi"), - _T("12.3")); + Unit::STATUTE_MILES, Unit::STATUTE_MILES, "12.3 mi", + "12.3"); TestDistanceSmart(Units::ToSysUnit(123.4, Unit::STATUTE_MILES), - Unit::STATUTE_MILES, Unit::STATUTE_MILES, _T("123 mi"), - _T("123")); + Unit::STATUTE_MILES, Unit::STATUTE_MILES, "123 mi", + "123"); // Test thresholds TestDistanceSmart(Units::ToSysUnit(0.9, Unit::KILOMETER), - Unit::KILOMETER, Unit::METER, _T("900 m"), _T("900"), 1000); + Unit::KILOMETER, Unit::METER, "900 m", "900", 1000); TestDistanceSmart(Units::ToSysUnit(1.1, Unit::KILOMETER), - Unit::KILOMETER, Unit::KILOMETER, _T("1.10 km"), _T("1.10"), 1000); + Unit::KILOMETER, Unit::KILOMETER, "1.10 km", "1.10", 1000); TestDistanceSmart(Units::ToSysUnit(1.1, Unit::KILOMETER), - Unit::KILOMETER, Unit::KILOMETER, _T("1.1 km"), _T("1.1"), 1000, 10); + Unit::KILOMETER, Unit::KILOMETER, "1.1 km", "1.1", 1000, 10); TestDistanceSmart(Units::ToSysUnit(1.1, Unit::KILOMETER), - Unit::KILOMETER, Unit::KILOMETER, _T("1 km"), _T("1"), 1000, 1); + Unit::KILOMETER, Unit::KILOMETER, "1 km", "1", 1000, 1); } static void TestSpeed() { - TCHAR buffer[256]; + char buffer[256]; // Test FormatSpeed() FormatSpeed(buffer, 23.46, Unit::METER_PER_SECOND); - ok1(StringIsEqual(buffer, _T("23 m/s"))); + ok1(StringIsEqual(buffer, "23 m/s")); FormatSpeed(buffer, 23.46, Unit::METER_PER_SECOND, true, true); - ok1(StringIsEqual(buffer, _T("23.5 m/s"))); + ok1(StringIsEqual(buffer, "23.5 m/s")); FormatSpeed(buffer, 23.46, Unit::METER_PER_SECOND, false); - ok1(StringIsEqual(buffer, _T("23"))); + ok1(StringIsEqual(buffer, "23")); FormatSpeed(buffer, 23.46, Unit::METER_PER_SECOND, false, true); - ok1(StringIsEqual(buffer, _T("23.5"))); + ok1(StringIsEqual(buffer, "23.5")); FormatSpeed(buffer, Units::ToSysUnit(123.43, Unit::KILOMETER_PER_HOUR), Unit::KILOMETER_PER_HOUR); - ok1(StringIsEqual(buffer, _T("123 km/h"))); + ok1(StringIsEqual(buffer, "123 km/h")); FormatSpeed(buffer, Units::ToSysUnit(123.43, Unit::KILOMETER_PER_HOUR), Unit::KILOMETER_PER_HOUR, true, true); - ok1(StringIsEqual(buffer, _T("123 km/h"))); + ok1(StringIsEqual(buffer, "123 km/h")); FormatSpeed(buffer, Units::ToSysUnit(83.43, Unit::KILOMETER_PER_HOUR), Unit::KILOMETER_PER_HOUR, true, true); - ok1(StringIsEqual(buffer, _T("83.4 km/h"))); + ok1(StringIsEqual(buffer, "83.4 km/h")); FormatSpeed(buffer, Units::ToSysUnit(123.43, Unit::KNOTS), Unit::KNOTS); - ok1(StringIsEqual(buffer, _T("123 kt"))); + ok1(StringIsEqual(buffer, "123 kt")); FormatSpeed(buffer, Units::ToSysUnit(123.43, Unit::KNOTS), Unit::KNOTS, true, true); - ok1(StringIsEqual(buffer, _T("123 kt"))); + ok1(StringIsEqual(buffer, "123 kt")); FormatSpeed(buffer, Units::ToSysUnit(83.43, Unit::KNOTS), Unit::KNOTS, true, true); - ok1(StringIsEqual(buffer, _T("83.4 kt"))); + ok1(StringIsEqual(buffer, "83.4 kt")); FormatSpeed(buffer, Units::ToSysUnit(123.43, Unit::STATUTE_MILES_PER_HOUR), Unit::STATUTE_MILES_PER_HOUR); - ok1(StringIsEqual(buffer, _T("123 mph"))); + ok1(StringIsEqual(buffer, "123 mph")); FormatSpeed(buffer, Units::ToSysUnit(123.43, Unit::STATUTE_MILES_PER_HOUR), Unit::STATUTE_MILES_PER_HOUR, true, true); - ok1(StringIsEqual(buffer, _T("123 mph"))); + ok1(StringIsEqual(buffer, "123 mph")); FormatSpeed(buffer, Units::ToSysUnit(83.43, Unit::STATUTE_MILES_PER_HOUR), Unit::STATUTE_MILES_PER_HOUR, true, true); - ok1(StringIsEqual(buffer, _T("83.4 mph"))); + ok1(StringIsEqual(buffer, "83.4 mph")); } static void TestVerticalSpeed() { - TCHAR buffer[256]; + char buffer[256]; // Test FormatVerticalSpeed() FormatVerticalSpeed(buffer, 1.42, Unit::METER_PER_SECOND); - ok1(StringIsEqual(buffer, _T("+1.4 m/s"))); + ok1(StringIsEqual(buffer, "+1.4 m/s")); FormatVerticalSpeed(buffer, 1.42, Unit::METER_PER_SECOND, false); - ok1(StringIsEqual(buffer, _T("+1.4"))); + ok1(StringIsEqual(buffer, "+1.4")); FormatVerticalSpeed(buffer, Units::ToSysUnit(2.47, Unit::KNOTS), Unit::KNOTS); - ok1(StringIsEqual(buffer, _T("+2.5 kt"))); + ok1(StringIsEqual(buffer, "+2.5 kt")); FormatVerticalSpeed(buffer, Units::ToSysUnit(2.47, Unit::KNOTS), Unit::KNOTS, false); - ok1(StringIsEqual(buffer, _T("+2.5"))); + ok1(StringIsEqual(buffer, "+2.5")); FormatVerticalSpeed(buffer, Units::ToSysUnit(245.4, Unit::FEET_PER_MINUTE), Unit::FEET_PER_MINUTE); - ok1(StringIsEqual(buffer, _T("+245 fpm"))); + ok1(StringIsEqual(buffer, "+245 fpm")); FormatVerticalSpeed(buffer, Units::ToSysUnit(245.4, Unit::FEET_PER_MINUTE), Unit::FEET_PER_MINUTE, false); - ok1(StringIsEqual(buffer, _T("+245"))); + ok1(StringIsEqual(buffer, "+245")); } static void TestTemperature() { - TCHAR buffer[256]; + char buffer[256]; // Test FormatTemperature() FormatTemperature(buffer, 293.93, Unit::KELVIN); - ok1(StringIsEqual(buffer, _T("294 K"))); + ok1(StringIsEqual(buffer, "294 K")); FormatTemperature(buffer, 293.93, Unit::KELVIN, false); - ok1(StringIsEqual(buffer, _T("294"))); + ok1(StringIsEqual(buffer, "294")); FormatTemperature(buffer, Units::ToSysUnit(13.4, Unit::DEGREES_CELCIUS), Unit::DEGREES_CELCIUS); - ok1(StringIsEqual(buffer, _T("13 " DEG "C"))); + ok1(StringIsEqual(buffer, "13 " DEG "C")); FormatTemperature(buffer, Units::ToSysUnit(13.4, Unit::DEGREES_CELCIUS), Unit::DEGREES_CELCIUS, false); - ok1(StringIsEqual(buffer, _T("13"))); + ok1(StringIsEqual(buffer, "13")); FormatTemperature(buffer, Units::ToSysUnit(92.7, Unit::DEGREES_FAHRENHEIT), Unit::DEGREES_FAHRENHEIT); - ok1(StringIsEqual(buffer, _T("93 " DEG "F"))); + ok1(StringIsEqual(buffer, "93 " DEG "F")); FormatTemperature(buffer, Units::ToSysUnit(92.7, Unit::DEGREES_FAHRENHEIT), Unit::DEGREES_FAHRENHEIT, false); - ok1(StringIsEqual(buffer, _T("93"))); + ok1(StringIsEqual(buffer, "93")); } static void TestPressure() { - TCHAR buffer[256]; + char buffer[256]; // Test FormatPressure() FormatPressure(buffer, AtmosphericPressure::HectoPascal(1013.25), Unit::HECTOPASCAL); - ok1(StringIsEqual(buffer, _T("1013 hPa"))); + ok1(StringIsEqual(buffer, "1013 hPa")); FormatPressure(buffer, AtmosphericPressure::HectoPascal(1013.25), Unit::HECTOPASCAL, false); - ok1(StringIsEqual(buffer, _T("1013"))); + ok1(StringIsEqual(buffer, "1013")); FormatPressure(buffer, AtmosphericPressure::HectoPascal(1013.25), Unit::MILLIBAR); - ok1(StringIsEqual(buffer, _T("1013 mb"))); + ok1(StringIsEqual(buffer, "1013 mb")); FormatPressure(buffer, AtmosphericPressure::HectoPascal(1013.25), Unit::MILLIBAR, false); - ok1(StringIsEqual(buffer, _T("1013"))); + ok1(StringIsEqual(buffer, "1013")); FormatPressure(buffer, AtmosphericPressure::HectoPascal( Units::ToSysUnit(103, Unit::TORR)), Unit::TORR); - ok1(StringIsEqual(buffer, _T("103 mmHg"))); + ok1(StringIsEqual(buffer, "103 mmHg")); FormatPressure(buffer, AtmosphericPressure::HectoPascal( Units::ToSysUnit(103, Unit::TORR)), Unit::TORR, false); - ok1(StringIsEqual(buffer, _T("103"))); + ok1(StringIsEqual(buffer, "103")); FormatPressure(buffer, AtmosphericPressure::HectoPascal( Units::ToSysUnit(29.92, Unit::INCH_MERCURY)), Unit::INCH_MERCURY); - ok1(StringIsEqual(buffer, _T("29.92 inHg"))); + ok1(StringIsEqual(buffer, "29.92 inHg")); FormatPressure(buffer, AtmosphericPressure::HectoPascal( Units::ToSysUnit(29.92, Unit::INCH_MERCURY)), Unit::INCH_MERCURY, false); - ok1(StringIsEqual(buffer, _T("29.92"))); + ok1(StringIsEqual(buffer, "29.92")); } int main() diff --git a/test/src/TestWaypointReader.cpp b/test/src/TestWaypointReader.cpp index 9f7d46f8576..f90655b9f34 100644 --- a/test/src/TestWaypointReader.cpp +++ b/test/src/TestWaypointReader.cpp @@ -11,7 +11,7 @@ #include "system/Path.hpp" #include "io/BufferedOutputStream.hxx" #include "io/StringOutputStream.hxx" -#include "util/tstring.hpp" +#include #include "util/StringAPI.hxx" #include "util/StringStrip.hxx" #include "Operation/Operation.hpp" @@ -86,7 +86,7 @@ static void TestWinPilot(const wp_vector &org_wp) { Waypoints way_points; - if (!TestWaypointFile(Path(_T("test/data/waypoints.dat")), way_points, + if (!TestWaypointFile(Path("test/data/waypoints.dat"), way_points, org_wp.size())) { skip(10 * org_wp.size(), 0, "opening waypoint file failed"); return; @@ -126,7 +126,7 @@ TestSeeYou(const wp_vector &org_wp) { // Test a SeeYou waypoint file with no runway width field: Waypoints way_points; - if (!TestWaypointFile(Path(_T("test/data/waypoints.cup")), way_points, + if (!TestWaypointFile(Path("test/data/waypoints.cup"), way_points, org_wp.size())) { skip(9 * org_wp.size(), 0, "opening waypoints.cup failed"); } else { @@ -138,7 +138,7 @@ TestSeeYou(const wp_vector &org_wp) // Test a SeeYou waypoint file with a runway width field: Waypoints way_points2; - if (!TestWaypointFile(Path(_T("test/data/waypoints2.cup")), way_points2, + if (!TestWaypointFile(Path("test/data/waypoints2.cup"), way_points2, org_wp.size())) { skip(9 * org_wp.size(), 0, "opening waypoints2.cup failed"); return; @@ -150,7 +150,7 @@ TestSeeYou(const wp_vector &org_wp) } // Test a SeeYou waypoint file with useradata and pics fields: Waypoints way_points3; - if (!TestWaypointFile(Path(_T("test/data/waypoints3.cup")), way_points3, + if (!TestWaypointFile(Path("test/data/waypoints3.cup"), way_points3, org_wp.size())) { skip(9 * org_wp.size(), 0, "opening waypoints3.cup failed"); return; @@ -179,9 +179,9 @@ TestZanderWaypoint(const Waypoint org_wp, const Waypoint *wp) } static void -TruncateStrip(tstring &s, std::size_t max_length) noexcept +TruncateStrip(std::string &s, std::size_t max_length) noexcept { - tstring_view v = s; + std::string_view v = s; if (v.size() > max_length) v = v.substr(0, max_length); v = Strip(v); @@ -192,7 +192,7 @@ static void TestZander(const wp_vector &org_wp) { Waypoints way_points; - if (!TestWaypointFile(Path(_T("test/data/waypoints.wpz")), way_points, + if (!TestWaypointFile(Path("test/data/waypoints.wpz"), way_points, org_wp.size())) { skip(10 * org_wp.size(), 0, "opening waypoint file failed"); return; @@ -209,7 +209,7 @@ static void TestFS(const wp_vector &org_wp) { Waypoints way_points; - if (!TestWaypointFile(Path(_T("test/data/waypoints_geo.wpt")), way_points, + if (!TestWaypointFile(Path("test/data/waypoints_geo.wpt"), way_points, org_wp.size())) { skip(3 * org_wp.size(), 0, "opening waypoint file failed"); return; @@ -225,7 +225,7 @@ static void TestFS_UTM(const wp_vector &org_wp) { Waypoints way_points; - if (!TestWaypointFile(Path(_T("test/data/waypoints_utm.wpt")), way_points, + if (!TestWaypointFile(Path("test/data/waypoints_utm.wpt"), way_points, org_wp.size())) { skip(3 * org_wp.size(), 0, "opening waypoint file failed"); return; @@ -241,14 +241,14 @@ static void TestOzi(const wp_vector &org_wp) { Waypoints way_points; - if (!TestWaypointFile(Path(_T("test/data/waypoints_ozi.wpt")), way_points, + if (!TestWaypointFile(Path("test/data/waypoints_ozi.wpt"), way_points, org_wp.size())) { skip(3 * org_wp.size(), 0, "opening waypoint file failed"); return; } for (auto i : org_wp) { - i.name = tstring{Strip(i.name)}; + i.name = std::string{Strip(i.name)}; GetWaypoint(i, way_points); } } @@ -257,7 +257,7 @@ static void TestCompeGPS(const wp_vector &org_wp) { Waypoints way_points; - if (!TestWaypointFile(Path(_T("test/data/waypoints_compe_geo.wpt")), way_points, + if (!TestWaypointFile(Path("test/data/waypoints_compe_geo.wpt"), way_points, org_wp.size())) { skip(3 * org_wp.size(), 0, "opening waypoint file failed"); return; @@ -265,7 +265,7 @@ TestCompeGPS(const wp_vector &org_wp) for (auto i : org_wp) { size_t pos; - while ((pos = i.name.find_first_of(_T(' '))) != tstring::npos) + while ((pos = i.name.find_first_of(' ')) != std::string::npos) i.name.erase(pos, 1); TruncateStrip(i.name, 6); @@ -278,7 +278,7 @@ static void TestCompeGPS_UTM(const wp_vector &org_wp) { Waypoints way_points; - if (!TestWaypointFile(Path(_T("test/data/waypoints_compe_utm.wpt")), way_points, + if (!TestWaypointFile(Path("test/data/waypoints_compe_utm.wpt"), way_points, org_wp.size())) { skip(3 * org_wp.size(), 0, "opening waypoint file failed"); return; @@ -286,7 +286,7 @@ TestCompeGPS_UTM(const wp_vector &org_wp) for (auto i : org_wp) { size_t pos; - while ((pos = i.name.find_first_of(_T(' '))) != tstring::npos) + while ((pos = i.name.find_first_of(' ')) != std::string::npos) i.name.erase(pos, 1); TruncateStrip(i.name, 6); @@ -332,8 +332,8 @@ CreateOriginalWaypoints() Waypoint wp(loc); wp.elevation = 488; wp.has_elevation = true; - wp.name = _T("Bergneustadt"); - wp.comment = _T("Rabbit holes, 20\" ditch south end of rwy"); + wp.name = "Bergneustadt"; + wp.comment = "Rabbit holes, 20\" ditch south end of rwy"; wp.runway.SetDirection(Angle::Degrees(40)); wp.runway.SetLength(590); @@ -351,8 +351,8 @@ CreateOriginalWaypoints() Waypoint wp2(loc); wp2.elevation = 6962; wp2.has_elevation = true; - wp2.name = _T("Aconcagua"); - wp2.comment = _T("Highest mountain in south-america"); + wp2.name = "Aconcagua"; + wp2.comment = "Highest mountain in south-america"; wp2.type = Waypoint::Type::MOUNTAIN_TOP; wp2.flags.turn_point = true; @@ -368,8 +368,8 @@ CreateOriginalWaypoints() Waypoint wp3(loc); wp3.elevation = 227; wp3.has_elevation = true; - wp3.name = _T("Golden Gate Bridge"); - wp3.comment = _T(""); + wp3.name = "Golden Gate Bridge"; + wp3.comment = ""; wp3.type = Waypoint::Type::BRIDGE; wp3.flags.turn_point = true; @@ -385,7 +385,7 @@ CreateOriginalWaypoints() Waypoint wp4(loc); wp4.elevation = 123; wp4.has_elevation = true; - wp4.name = _T("Red Square"); + wp4.name = "Red Square"; wp4.runway.SetDirection(Angle::Degrees(90)); wp4.runway.SetLength((unsigned)Units::ToSysUnit(0.01, Unit::STATUTE_MILES)); @@ -403,8 +403,8 @@ CreateOriginalWaypoints() Waypoint wp5(loc); wp5.elevation = 5; wp5.has_elevation = true; - wp5.name = _T("Sydney Opera"); - wp5.comment = _T(""); + wp5.name = "Sydney Opera"; + wp5.comment = ""; wp5.type = Waypoint::Type::NORMAL; wp5.flags.turn_point = true; diff --git a/test/src/TestWaypoints.cpp b/test/src/TestWaypoints.cpp index 77354f29e1b..6a9fb5f0662 100644 --- a/test/src/TestWaypoints.cpp +++ b/test/src/TestWaypoints.cpp @@ -65,15 +65,15 @@ AddSpiralWaypoints(Waypoints &waypoints, StaticString<256> buffer; if (i % 7 == 0) { - buffer = _T("Airfield"); + buffer = "Airfield"; waypoint.type = Waypoint::Type::AIRFIELD; } else if (i % 3 == 0) { - buffer = _T("Field"); + buffer = "Field"; waypoint.type = Waypoint::Type::OUTLANDING; } else - buffer = _T("Waypoint"); + buffer = "Waypoint"; - buffer.AppendFormat(_T(" #%d"), i + 1); + buffer.AppendFormat(" #%d", i + 1); waypoint.name = buffer; waypoints.Append(std::move(waypoint)); @@ -98,7 +98,7 @@ TestLookups(const Waypoints &waypoints, const GeoPoint ¢er) ok1((waypoint = waypoints.LookupLocation(center, 0)) != NULL); ok1(waypoint->original_id == 0); - ok1((waypoint = waypoints.LookupName(_T("Waypoint #5"))) != NULL); + ok1((waypoint = waypoints.LookupName("Waypoint #5")) != NULL); ok1(waypoint->original_id == 4); ok1((waypoint = waypoints.LookupLocation(waypoint->location, 10000)) != NULL); @@ -107,10 +107,10 @@ TestLookups(const Waypoints &waypoints, const GeoPoint ¢er) class BeginsWith { - const TCHAR *prefix; + const char *prefix; public: - BeginsWith(const TCHAR *_prefix):prefix(_prefix) {} + BeginsWith(const char *_prefix):prefix(_prefix) {} bool operator()(const Waypoint &waypoint) { return StringStartsWith(waypoint.name.c_str(), prefix); @@ -118,7 +118,7 @@ class BeginsWith }; static void -TestNamePrefixVisitor(const Waypoints &waypoints, const TCHAR *prefix, +TestNamePrefixVisitor(const Waypoints &waypoints, const char *prefix, unsigned expected_results) { WaypointPredicateCounter::Predicate predicate = BeginsWith(prefix); @@ -130,12 +130,12 @@ TestNamePrefixVisitor(const Waypoints &waypoints, const TCHAR *prefix, static void TestNamePrefixVisitor(const Waypoints &waypoints) { - TestNamePrefixVisitor(waypoints, _T(""), 151); - TestNamePrefixVisitor(waypoints, _T("Foo"), 0); - TestNamePrefixVisitor(waypoints, _T("a"), 0); - TestNamePrefixVisitor(waypoints, _T("A"), 22); - TestNamePrefixVisitor(waypoints, _T("Air"), 22); - TestNamePrefixVisitor(waypoints, _T("Field"), 51 - 8); + TestNamePrefixVisitor(waypoints, "", 151); + TestNamePrefixVisitor(waypoints, "Foo", 0); + TestNamePrefixVisitor(waypoints, "a", 0); + TestNamePrefixVisitor(waypoints, "A", 22); + TestNamePrefixVisitor(waypoints, "Air", 22); + TestNamePrefixVisitor(waypoints, "Field", 51 - 8); } class CloserThan @@ -181,8 +181,8 @@ static void TestGetNearest(const Waypoints &waypoints, const GeoPoint ¢er) { WaypointPtr waypoint; - GeoPoint near = GeoVector(250, Angle::Degrees(15)).EndPoint(center); - GeoPoint far = GeoVector(750, Angle::Degrees(15)).EndPoint(center); + GeoPoint _near = GeoVector(250, Angle::Degrees(15)).EndPoint(center); + GeoPoint _far = GeoVector(750, Angle::Degrees(15)).EndPoint(center); GeoPoint further = GeoVector(4200, Angle::Degrees(48)).EndPoint(center); ok1((waypoint = waypoints.GetNearest(center, 1)) != NULL); @@ -191,14 +191,14 @@ TestGetNearest(const Waypoints &waypoints, const GeoPoint ¢er) ok1((waypoint = waypoints.GetNearest(center, 10000)) != NULL); ok1(waypoint->original_id == 0); - ok1((waypoint = waypoints.GetNearest(near, 1)) == NULL); + ok1((waypoint = waypoints.GetNearest(_near, 1)) == NULL); - ok1((waypoint = waypoints.GetNearest(near, 10000)) != NULL); + ok1((waypoint = waypoints.GetNearest(_near, 10000)) != NULL); ok1(waypoint->original_id == 0); - ok1((waypoint = waypoints.GetNearest(far, 1)) == NULL); + ok1((waypoint = waypoints.GetNearest(_far, 1)) == NULL); - ok1((waypoint = waypoints.GetNearest(far, 10000)) != NULL); + ok1((waypoint = waypoints.GetNearest(_far, 10000)) != NULL); ok1(waypoint->original_id == 1); ok1((waypoint = waypoints.GetNearestLandable(center, 1)) != NULL); @@ -268,15 +268,15 @@ TestReplace(Waypoints& waypoints, unsigned id) if (wp == NULL) return false; - tstring oldName = wp->name; + std::string oldName = wp->name; Waypoint copy = *wp; - copy.name = _T("Fred"); + copy.name = "Fred"; waypoints.Replace(wp, std::move(copy)); waypoints.Optimise(); wp = waypoints.LookupId(id); - return wp != NULL && wp->name != oldName && wp->name == _T("Fred"); + return wp != NULL && wp->name != oldName && wp->name == "Fred"; } int diff --git a/test/src/ViewImage.cpp b/test/src/ViewImage.cpp index cc9f5216447..975d1a3e35f 100644 --- a/test/src/ViewImage.cpp +++ b/test/src/ViewImage.cpp @@ -42,7 +42,7 @@ static void Main(UI::Display &display) { TestWindow window{display}; - window.Create(_T("ViewImage"), {640, 480}); + window.Create("ViewImage", {640, 480}); if (!window.LoadFile(path)) { fprintf(stderr, "Failed to load file\n"); exit(EXIT_FAILURE); diff --git a/test/src/harness_airspace.cpp b/test/src/harness_airspace.cpp index 2cd94b62922..b3c872bdd33 100644 --- a/test/src/harness_airspace.cpp +++ b/test/src/harness_airspace.cpp @@ -11,7 +11,6 @@ #include "Geo/GeoVector.hpp" #include "Formatter/AirspaceFormatter.hpp" #include "system/FileUtil.hpp" -#include "util/ConvertString.hpp" #include #include @@ -25,7 +24,7 @@ airspace_random_properties(AbstractAirspace& as) AirspaceAltitude top; base.altitude = rand()%4000; top.altitude = base.altitude+rand()%3000; - as.SetProperties(_T("hello"), asclass, _T("E"), base, top); + as.SetProperties("hello", asclass, "E", base, top); } @@ -45,7 +44,7 @@ void setup_airspaces(Airspaces& airspaces, const GeoPoint& center, const unsigne std::ofstream *fin = NULL; if (verbose) { - Directory::Create(Path(_T("output/results"))); + Directory::Create(Path("output/results")); fin = new std::ofstream("output/results/res-bb-in.txt"); } @@ -116,7 +115,7 @@ class AirspaceVisitorPrint { void Visit(const AbstractAirspace &as) { if (do_report) { *fout << as; - *fout << "# Name: " << WideToUTF8Converter(as.GetName()) + *fout << "# Name: " << as.GetName() << "Base: " << as.GetBase() << " Top: " << as.GetTop() << "\n"; @@ -240,7 +239,7 @@ void scan_airspaces(const AircraftState state, { const double range(20000.0); - Directory::Create(Path(_T("output/results"))); + Directory::Create(Path("output/results")); { AirspaceVisitorPrint pvisitor("output/results/res-bb-range.txt", diff --git a/test/src/harness_flight.cpp b/test/src/harness_flight.cpp index 8c0b991b97d..e46ad38950f 100644 --- a/test/src/harness_flight.cpp +++ b/test/src/harness_flight.cpp @@ -97,7 +97,7 @@ run_flight(TestFlightComponents components, TaskManager &task_manager, autopilot.SetSpeedFactor(speed_factor); - Directory::Create(Path(_T("output/results"))); + Directory::Create(Path("output/results")); std::ofstream f4("output/results/res-sample.txt"); std::ofstream f5("output/results/res-sample-filtered.txt"); diff --git a/test/src/harness_waypoints.cpp b/test/src/harness_waypoints.cpp index 54adbe763f5..a70161bc130 100644 --- a/test/src/harness_waypoints.cpp +++ b/test/src/harness_waypoints.cpp @@ -35,7 +35,7 @@ bool SetupWaypoints(Waypoints &waypoints, const unsigned n) wp = waypoints.Create(GeoPoint(Angle::Degrees(1), Angle::Degrees(1))); - wp.name = _T("Hello"); + wp.name = "Hello"; wp.type = Waypoint::Type::AIRFIELD; wp.elevation = 0.5; wp.has_elevation = true; @@ -43,7 +43,7 @@ bool SetupWaypoints(Waypoints &waypoints, const unsigned n) wp = waypoints.Create(GeoPoint(Angle::Degrees(0.8), Angle::Degrees(0.5))); - wp.name = _T("Unk"); + wp.name = "Unk"; wp.type = Waypoint::Type::AIRFIELD; wp.elevation = 0.25; wp.has_elevation = true; @@ -77,7 +77,7 @@ bool SetupWaypoints(Waypoints &waypoints, const unsigned n) waypoints.Optimise(); if (verbose) { - Directory::Create(Path(_T("output/results"))); + Directory::Create(Path("output/results")); std::ofstream fin("output/results/res-wp-in.txt"); for (unsigned i=1; i<=waypoints.size(); i++) { const auto wpt = waypoints.LookupId(i); diff --git a/test/src/test_debug.cpp b/test/src/test_debug.cpp index 9c2cb7bd942..60322b21fcd 100644 --- a/test/src/test_debug.cpp +++ b/test/src/test_debug.cpp @@ -19,8 +19,8 @@ int output_skip = 5; AutopilotParameters autopilot_parms; int terrain_height = 1; -AllocatedPath replay_file = Path(_T("test/data/0asljd01.igc")); -AllocatedPath waypoint_file = Path(_T("test/data/waypoints_geo.wpt")); +AllocatedPath replay_file = Path("test/data/0asljd01.igc"); +AllocatedPath waypoint_file = Path("test/data/waypoints_geo.wpt"); AllocatedPath task_file; double range_threshold = 15000; diff --git a/test/src/test_mc.cpp b/test/src/test_mc.cpp index b5b18e6a0b9..a6b042b72f6 100644 --- a/test/src/test_mc.cpp +++ b/test/src/test_mc.cpp @@ -255,7 +255,7 @@ int main() { plan_tests(3); - Directory::Create(Path(_T("output/results"))); + Directory::Create(Path("output/results")); ok(test_mc(),"mc output",0); ok(test_stf(),"mc stf",0); diff --git a/test/src/test_reach.cpp b/test/src/test_reach.cpp index d873d94e529..6b49abde540 100644 --- a/test/src/test_reach.cpp +++ b/test/src/test_reach.cpp @@ -51,7 +51,7 @@ test_reach(const RasterMap &map, double mwind, double mc, double height_min_work PrintHelper::print(reach_working); { - Directory::Create(Path(_T("output/results"))); + Directory::Create(Path("output/results")); std::ofstream fout("output/results/terrain.txt"); unsigned nx = 100; unsigned ny = 100; diff --git a/test/src/test_replay_olc.cpp b/test/src/test_replay_olc.cpp index fb5a507b6d7..1a2bdc8a2cb 100644 --- a/test/src/test_replay_olc.cpp +++ b/test/src/test_replay_olc.cpp @@ -71,7 +71,7 @@ inline void load_score_file(std::ifstream& fscore, inline void load_scores(unsigned &contest_handicap) { // replay_file - const auto score_file = replay_file.WithSuffix(_T(".txt")); + const auto score_file = replay_file.WithSuffix(".txt"); if (verbose) { std::cout << "# replay file: " << replay_file << "\n"; std::cout << "# score file: " << score_file << "\n"; @@ -114,7 +114,7 @@ static bool test_replay(const Contest olc_type, const ContestResult &official_score) { - Directory::Create(Path(_T("output/results"))); + Directory::Create(Path("output/results")); std::ofstream f("output/results/res-sample.txt"); GlidePolar glide_polar(2); diff --git a/test/src/test_replay_retrospective.cpp b/test/src/test_replay_retrospective.cpp index 0c79745443f..984ef469112 100644 --- a/test/src/test_replay_retrospective.cpp +++ b/test/src/test_replay_retrospective.cpp @@ -18,7 +18,7 @@ static bool test_replay_retrospective() { - Directory::Create(_T("output/results")); + Directory::Create("output/results"); std::ofstream f("output/results/res-sample.txt"); Waypoints waypoints; diff --git a/test/src/test_replay_task.cpp b/test/src/test_replay_task.cpp index 5fa4bc4eaa4..1743ef11bd1 100644 --- a/test/src/test_replay_task.cpp +++ b/test/src/test_replay_task.cpp @@ -77,7 +77,7 @@ class ReplayLoggerSim: public IgcReplay static bool test_replay() { - Directory::Create(Path(_T("output/results"))); + Directory::Create(Path("output/results")); std::ofstream f("output/results/res-sample.txt"); GlidePolar glide_polar(4.0); @@ -184,8 +184,8 @@ int main(int argc, char** argv) try { output_skip = 60; - replay_file = Path(_T("test/data/apf-bug554.igc")); - task_file = Path(_T("test/data/apf-bug554.tsk")); + replay_file = Path("test/data/apf-bug554.igc"); + task_file = Path("test/data/apf-bug554.tsk"); if (!ParseArgs(argc,argv)) { return 0; diff --git a/test/src/test_route.cpp b/test/src/test_route.cpp index 45290f59193..6c5ad5a0a15 100644 --- a/test/src/test_route.cpp +++ b/test/src/test_route.cpp @@ -38,7 +38,7 @@ test_route(const unsigned n_airspaces, const RasterMap& map) setup_airspaces(airspaces, map.GetMapCenter(), n_airspaces); { - Directory::Create(Path(_T("output/results"))); + Directory::Create(Path("output/results")); std::ofstream fout("output/results/terrain.txt"); unsigned nx = 100; diff --git a/test/src/test_troute.cpp b/test/src/test_troute.cpp index 60cf84e11e1..e1111ae04ec 100644 --- a/test/src/test_troute.cpp +++ b/test/src/test_troute.cpp @@ -44,7 +44,7 @@ test_troute(const RasterMap &map, double mwind, double mc, int ceiling) bool retval= true; { - Directory::Create(Path(_T("output/results"))); + Directory::Create(Path("output/results")); std::ofstream fout ("output/results/terrain.txt"); unsigned nx = 100; unsigned ny = 100; diff --git a/tools/BinToC.pl b/tools/BinToC.pl index c01fbb84cfc..f017660e34e 100755 --- a/tools/BinToC.pl +++ b/tools/BinToC.pl @@ -18,7 +18,8 @@ = fileparse $input_file_path; my $array_name = "${input_file_name}${input_file_ext}"; -$array_name =~ s,\.,_,g; +$array_name =~ s/\./_/g; +$array_name =~ s/-/_/g; open my $output_src_fh, '>', $output_src_file_path or die "Could not source open output file $output_src_file_path!\n"; diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt new file mode 100644 index 00000000000..9dacce406e4 --- /dev/null +++ b/tools/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.15) +if (SHOW_SUBPROJECTS) + message(STATUS "+++ Start CMake ${CMAKE_CURRENT_SOURCE_DIR}!") +endif() + +set(TARGET_NAME MathTables) + +add_executable(${TARGET_NAME} GenerateSineTables.cpp) +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER Data) + +add_custom_command(TARGET ${TARGET_NAME} PRE_LINK +# add_custom_command(TARGET ${TARGET_NAME} PRE_BUILD + COMMENT "Make dir '${OUTPUT}/include'" + COMMAND ${CMAKE_COMMAND} -E make_directory ${OUTPUT_FOLDER}/include + WORKING_DIRECTORY ${OUTPUT_FOLDER} +) + diff --git a/tools/GenerateResources.pl b/tools/GenerateResources.pl index a0db6a405b5..9af92af0902 100755 --- a/tools/GenerateResources.pl +++ b/tools/GenerateResources.pl @@ -29,17 +29,15 @@ ($) } } -print "#include \n"; - print "static constexpr struct {\n"; -print " const TCHAR *name;\n"; +print " const char *name;\n"; print " std::span data;\n"; print "} named_resources[] = {"; foreach my $i (@named) { my ($name, $size) = @$i; my $variable = "resource_${name}"; $variable =~ s,\.,_,g; - print " { _T(\"${name}\"), { ${variable}, ${size} } },\n"; + print " { \"${name}\", { ${variable}, ${size} } },\n"; } print " { 0, {} }\n"; print "};\n"; diff --git a/tools/Text2Event.pl b/tools/Text2Event.pl index c35975bb3e7..491936eea99 100755 --- a/tools/Text2Event.pl +++ b/tools/Text2Event.pl @@ -4,6 +4,6 @@ use warnings; while (<>) { - print qq'{ _T("$1"), &InputEvents::event$1 },\n' + print qq'{ "$1", &InputEvents::event$1 },\n' if /^\s*void event([a-zA-Z0-9]+)/; } diff --git a/tools/Text2GCE.pl b/tools/Text2GCE.pl index fd8b12d1e59..e14be90f348 100755 --- a/tools/Text2GCE.pl +++ b/tools/Text2GCE.pl @@ -4,6 +4,6 @@ use warnings; while (<>) { - print qq'_T("$1"),\n' + print qq'"$1",\n' if /GCE_([A-Z0-9_]+)/; } diff --git a/tools/Text2NE.pl b/tools/Text2NE.pl index 56260cc0db1..fc9374c4d2a 100755 --- a/tools/Text2NE.pl +++ b/tools/Text2NE.pl @@ -4,6 +4,6 @@ use warnings; while (<>) { - print qq'_T("$1"),\n' + print qq'"$1",\n' if /NE_([A-Z0-9_]+)/; } diff --git a/tools/changelog.sh b/tools/changelog.sh index 5c9fbf30178..31abfc09aa5 100755 --- a/tools/changelog.sh +++ b/tools/changelog.sh @@ -2,11 +2,11 @@ TAG="${1}" VERSION=$(echo "$TAG" | cut -f2 -d v) -STARTLINENUMBER=$(grep -n -E "^Version $VERSION" NEWS.txt | cut -f1 -d:) +STARTLINENUMBER=$(grep -n -E "^OpenSoar Version $VERSION " OpenSoar-News.md | cut -f1 -d:) if [ -z "${STARTLINENUMBER}" ]; then - echo "ERROR: Version $1 not found in NEWS.txt" + echo "ERROR: Version $1 not found in OpenSoar-News.md" exit 1 fi -FINLINENUMBER=$(tail -n +"${STARTLINENUMBER}" NEWS.txt | grep -E '^$' -n | head -n 1| cut -f1 -d:) +FINLINENUMBER=$(tail -n +"${STARTLINENUMBER}" OpenSoar-News.md | grep -E '^$' -n | head -n 1| cut -f1 -d:) FINLINENUMBER=$(( "${STARTLINENUMBER}" + "${FINLINENUMBER}" - 2 )) -sed -n "${STARTLINENUMBER}","${FINLINENUMBER}"p NEWS.txt +sed -n "${STARTLINENUMBER}","${FINLINENUMBER}"p OpenSoar-News.md diff --git a/tools/gdb.py b/tools/gdb.py index 78f780b5710..89e64a4cd1d 100644 --- a/tools/gdb.py +++ b/tools/gdb.py @@ -245,7 +245,7 @@ def lookup_function(value): return RoughTimePrinter(value) elif typename == 'RoughTimeSpan': return RoughTimeSpanPrinter(value) - elif typename[:12] == 'StaticString' or typename[:12] == 'NarrowString': + elif typename[:12] == 'StaticString': return StaticStringPrinter(value) return None diff --git a/tools/polar_import.py b/tools/polar_import.py index 2f9ee81c90d..3202a71c33e 100755 --- a/tools/polar_import.py +++ b/tools/polar_import.py @@ -116,7 +116,7 @@ def get_current_xc_polar(glider, weight=0.0): return None ret = None for line in f: - if line[0:7] != " { _T(" : continue + if line[0:4] != " { " : continue if glider in line: ##357, 165, 108.8, -0.64, 156.4, -1.18, 211.13, -2.5, 9.0, 0.0, 114 ret = polar() @@ -210,7 +210,7 @@ def polar_store_line(p, wingload=0.0): minsinkspeed = p._x[np.argmax(p._y)] threedots = [minsinkspeed, 130.0, 170.0] print("XCSoar PolarStore template:") - print(' { _T("' + p._name + '"),', wieght, ", 0.0,", threedots[0], ',', p1d(threedots[0]), ',', threedots[1], ',', p1d(threedots[1]), ',', threedots[2],',', p1d(threedots[2]), ',', p._S, ", 0.0, 0 },") + print(' { "' + p._name + '",', wieght, ", 0.0,", threedots[0], ',', p1d(threedots[0]), ',', threedots[1], ',', p1d(threedots[1]), ',', threedots[2],',', p1d(threedots[2]), ',', p._S, ", 0.0, 0 },") print("The raw file for this:") print(p._name) print(p._w) diff --git a/tools/python/bin2c.py b/tools/python/bin2c.py new file mode 100644 index 00000000000..0e908101041 --- /dev/null +++ b/tools/python/bin2c.py @@ -0,0 +1,71 @@ +import sys, os + + +if len(sys.argv) > 1: + filename = sys.argv[1] + +outdir = '' # without this argument 2 write in the same directory like input file! +if len(sys.argv) > 2: + outdir = sys.argv[2] + outdir = outdir + '/' + + +bin_name_file = os.path.basename(filename) +bin_name = bin_name_file.replace('.', '_').replace('-', '_') +# bin_name = os.path.splitext(bin_name_file)[0] + + +if not bin_name: + bin_name = 'de' + +with open(filename, 'rb') as readfile: + bytes_read = readfile.read() + i = 0 + filelength = '0x'+ ''.join('{:08X}'.format(len(bytes_read))) # Format 0x00000000 + # LANGUAGE = bin_name.upper() + + # C Source file : + with open(outdir + os.path.basename(filename) +'.c', 'wt', newline='') as writefile: + writefile.write('#include \n') + writefile.write('#include \n') + writefile.write('const uint8_t ' + bin_name + '[] = {\n') + + for b in bytes_read: + i = i + 1 + writefile.write('0x' + ''.join('{:02X}'.format(b)) + ', ') # Format 0x00 + if i >= 16 : + writefile.write('\n') + i = 0 + writefile.write('};\n\n') + # writefile.write('const unsigned long ' + language + '_mo_termination = 0x00000000;\n') + # writefile.write('const unsigned long ' + language + '_mo_start = 0x00000000;\n') + # writefile.write('const unsigned long ' + language + '_mo_finish = ' + filelength + ';\n') + # writefile.write('const unsigned long ' + language + '_mo_length = ' + filelength + ';\n') + # writefile.write('\n') + writefile.write('const size_t ' + bin_name + '_size = ' + filelength + ';\n') + # writefile.write('const uint8_t *' + bin_name + '_end = ' + bin_name + ' + ' + bin_name + '_size;\n') + writefile.write('const uint8_t *' + bin_name + '_end = ' + bin_name + ' + ' + filelength + ';\n') + # writefile.write('#define ' + LANGUAGE + '_MO_TERMINATION 0x00000000\n') + # writefile.write('#define ' + LANGUAGE + '_MO_START 0x00000000\n') + # writefile.write('#define ' + LANGUAGE + '_MO_FINISH ' + filelength + '\n') + # writefile.write('#define ' + LANGUAGE + '_MO_LENGTH ' + filelength + '\n') + # writefile.write('\n') + # writefile.write('const size_t ' + language + '_mo_size = ' + LANGUAGE + '_MO_LENGTH;\n') + writefile.close() +### H - Header file : not necessary ??? +### with open(outdir + os.path.basename(filename) +'.h', 'wt', newline='') as writefile: +### writefile.write('#ifndef OUTPUT_PO_' + LANGUAGE + '_MO_H\n') +### writefile.write('#define OUTPUT_PO_' + LANGUAGE + '_MO_H\n') +### writefile.write('\n') +### writefile.write('extern const unsigned long ' + language + '_mo_termination;\n') +### writefile.write('extern const unsigned long ' + language + '_mo_start;\n') +### writefile.write('extern const unsigned long ' + language + '_mo_finish;\n') +### writefile.write('extern const unsigned long ' + language + '_mo_length;\n') +### writefile.write('extern const unsigned char ' + language + '_mo[];\n') +### writefile.write('\n') +### writefile.write('#endif // OUTPUT_PO_' + LANGUAGE + '_MO_H\n') +### +### writefile.close() +readfile.close() + + diff --git a/tools/python/create_resource.py b/tools/python/create_resource.py new file mode 100644 index 00000000000..7f4c65bd6c5 --- /dev/null +++ b/tools/python/create_resource.py @@ -0,0 +1,92 @@ +import sys +import os +import io + +debug = False + +print('========= CREATE_RESOURCE ===============') +print('CurrDir: ', os.getcwd()) + +res_array = [] + + +# def write_resource(outfile, line, macro, type, extension): +def create_line(name, res_name, path, file, ext): + line = '{:30s}'.format(name) + ' ' + '{:12s}'.format(res_name) + line = line + 'DISCARDABLE "' + path + '/' + line = line + file + '.' + ext + '"' + outfile.write(line + '\n') # Copy of read line (with replaced field) + if debug: + print(line) + ## return line + +def write_resource(outfile, line, resource): + params = line.split(' ') + # if debug: + if len(params) >= 2: + if resource[0] == 'bitmap_icon_scaled ': + basename = params[2].strip(' \n').replace('"','') + create_line(params[1], resource[2], resource[3], basename + '_96', resource[4]) + create_line(params[1] + '_HD', resource[2], resource[3], basename + '_160', resource[4]) + create_line(params[1] + '_UHD', resource[2], resource[3], basename + '_300', resource[4]) + else: + create_line(params[1], resource[2], resource[3], params[2].strip(' \n').replace('"',''), resource[4]) + # if len(line) > 0: + # outfile.write(line.replace('/', '\\\\') + '\n') # Copy of read line (with replaced field) + else: + outfile.write(line + '\n') + +def write_line(outfile, line): + line = line.strip() + + if line.startswith('//'): + print('!!\n') + elif line.startswith('#include') or \ + line.startswith('ID') or \ + line.startswith('#if') or \ + line.startswith('#else') or \ + line.startswith('#elif') or \ + line.startswith('#endif'): + outfile.write(line+ '\n') # Copy of read line (with replaced field) + print(line + '\n') + else: + updated = False + for resource in res_array: + if line.startswith(resource[0]): + write_resource(outfile, line, resource) # 'BITMAP_ICON', 'ICON', '.bmp') + updated = True # if one of this lines + + if not updated: + outfile.write('\n') # Copy of read line (with replaced field) + # outfile.write(line+ '\n') # Copy of read line (with replaced field) + # print(line + '\n') +#============================================================================ + +if debug: + count = 0 + for arg in sys.argv: + print('argument ',count + 1,': ', sys.argv[count]) + count = count + 1 + +src_location1 = sys.argv[3] +src_location2 = sys.argv[4] + +res_array.append(['bitmap_icon_scaled ', 'BITMAP_ICON', 'BITMAP', src_location2 + '/icons', 'bmp']) +res_array.append(['bitmap_bitmap ', 'BITMAP_BITMAP', 'BITMAP', src_location1 + '/bitmaps', 'bmp']) +res_array.append(['bitmap_graphic ', 'BITMAP_GRAPHIC','BITMAP', src_location2 + '/graphics', 'bmp']) +res_array.append(['hatch_bitmap ', 'HATCH_BITMAP', 'BITMAP', src_location1 + '/bitmaps', 'bmp']) +res_array.append(['sound ' 'SOUND', 'WAVE', src_location1 + '/sound', 'wav']) +res_array.append(['app_icon ', 'ICON_ICON', 'ICON', src_location1 + '/bitmaps', 'ico']) + +if len(sys.argv) < 2: + print('to less arguments: ', len(sys.argv)) +else: + infile = io.open(sys.argv[1]) + outfile = io.open(sys.argv[2], 'w', newline='\n') + outfile2 = io.open(sys.argv[2]+'.h', 'w', newline='\n') + + for line in infile: + write_line(outfile, line) + infile.close() + outfile.close() + \ No newline at end of file diff --git a/tools/python/icons_convert.py b/tools/python/icons_convert.py new file mode 100644 index 00000000000..965d83f0c95 --- /dev/null +++ b/tools/python/icons_convert.py @@ -0,0 +1,17 @@ +import sys, os + +import imagemagick # (or wand?) +import inkscape + +# Convert SVG images in bitmaps (only usefull for Windows - GDI?) + +# August2111: noch in Vorbereitung - aber brauche ich das überhaupt, wenn ich die Bitmaps auf PNG umstelle (oder noch besser: auf SVG)? + +if len(sys.argv) > 1: + filename = sys.argv[1] + +outdir = '' # without this argument 2 write in the same directory like input file! +if len(sys.argv) > 2: + outdir = sys.argv[2] + outdir = outdir + '/' + diff --git a/tools/python/replace.py b/tools/python/replace.py new file mode 100644 index 00000000000..f2e13ecc33d --- /dev/null +++ b/tools/python/replace.py @@ -0,0 +1,55 @@ +import sys + +debug = False +headerfile = None + +if debug: + count = 0 + for arg in sys.argv: + print('argument ',count + 1,': ', sys.argv[count]) + count = count + 1 + +if len(sys.argv) < 3: + print('to less arguments: ', len(sys.argv)) +else: + infile = open(sys.argv[2]) + outfile = open(sys.argv[3], 'w') + try: + headerfile = open(sys.argv[4], 'w') + except Exception as e: + print("Exception on creating '", sys.argv[4], "'") + print("Exception: ", e) + # no headerfile ? exit(-1) + + repl = [] + count = 0 + configfile = open(sys.argv[1]) + for line in configfile: + if debug: + print('argument ',count + 1,': ', line) + config_pair = line.split('=') + if len(config_pair) == 2: + repl.append([config_pair[0].strip(), config_pair[1].strip()]) + count = count + 1 + configfile.close() + + for param in repl: + if len(param) == 2: + if debug: + print('param0 = ',param[0],', param1 = ',param[1]) + if headerfile: + headerfile.write('#define ' + '{:24s}'.format(param[0]) + ' "' + param[1] + '"\n') + + for line in infile: + for param in repl: + if len(param) == 2: + line = line.replace('@'+param[0]+'@',param[1]) + outfile.write(line) # Copy of read line (with replaced field) + + infile.close() + outfile.close() + if headerfile: + headerfile.close() + +print('EOF replace.py') +exit(0) \ No newline at end of file diff --git a/tools/xci2cpp.pl b/tools/xci2cpp.pl index dcc5bf89c1f..a04f4aa8c65 100755 --- a/tools/xci2cpp.pl +++ b/tools/xci2cpp.pl @@ -167,10 +167,10 @@ (\%) sub c_string($) { my $value = shift; return 'NULL' unless defined $value; - return qq|_T("$value")|; + return qq|"$value"|; } -print "static const TCHAR *const default_modes[] = {\n"; +print "static const char *const default_modes[] = {\n"; splice @modes, 0, 4; foreach my $m (@modes) { $m = c_string($m); @@ -215,7 +215,7 @@ ($) print "static constexpr struct flat_label default_labels[] = {\n"; foreach my $l (@labels) { my ($mode, $label, $location, $event) = @$l; - print qq| { $mode, $location, $event, _T("$label") },\n|; + print qq| { $mode, $location, $event, "$label" },\n|; } print " { 0, 0, 0, NULL },\n"; print "};\n"; @@ -223,7 +223,7 @@ ($) print "static constexpr struct flat_gesture_map default_gesture2event[] = {\n"; foreach my $g (@gestures) { my ($mode, $event, $data) = @$g; - print " { $mode, $event, _T(\"$data\") },\n"; + print " { $mode, $event, \"$data\" },\n"; } print " { 0, 0, NULL },\n"; print "};\n"; diff --git a/tools/xcs2cpp.pl b/tools/xcs2cpp.pl index 4ff8a00da98..54df1baf219 100755 --- a/tools/xcs2cpp.pl +++ b/tools/xcs2cpp.pl @@ -9,7 +9,7 @@ sub c_string($) { my $value = shift; return 'NULL' unless defined $value; - return qq|_T("$value")|; + return qq|"$value"|; } sub c_bool($) {