Version 1.9.7 master
authorKeith Packard <keithp@keithp.com>
Tue, 13 Apr 2021 01:39:48 +0000 (18:39 -0700)
committerKeith Packard <keithp@keithp.com>
Tue, 13 Apr 2021 04:07:10 +0000 (21:07 -0700)
Signed-off-by: Keith Packard <keithp@keithp.com>
28 files changed:
Makefile.am
Releasing
altoslib/AltosCSV.java
altoslib/AltosMapTransform.java
altosui/AltosUI.app/Contents/MacOS/JavaApplicationStub
altosui/Makefile.am
altosui/altos-windows.nsi.in
altosuilib/AltosUIMap.java
altosuilib/AltosUIMapPreload.java
ao-bringup/test-easymotor [new file with mode: 0755]
ao-bringup/turnon_easymotor [new file with mode: 0755]
ao-tools/ao-flash/ao-flash-stm32f0x
configure.ac
doc/Makefile.am
doc/altusmetrum-theme.yml
doc/altusmetrum.txt
doc/easymini-release-notes.inc
doc/motortest-configuration.inc
doc/motortest-installation.inc
doc/motortest-intro.inc
doc/motortest-operation.inc
doc/release-notes-1.9.7.inc [new file with mode: 0644]
doc/release-notes.inc
doc/specs.inc
doc/telegps-release-notes.inc
micropeak/MicroPeak.app/Contents/MacOS/JavaApplicationStub
src/Makefile
telegps/TeleGPS.app/Contents/MacOS/JavaApplicationStub

index 328d5700cfd1fbbdc74d2b8a8be8ec7d3bc194e2..fa38cf2fcdd1031aa2dba6f957f70b665b5db173 100644 (file)
@@ -53,6 +53,7 @@ fat_altos = \
        src/easymega-v1.0/easymega-v1.0-$(VERSION).ihx \
        src/easymega-v2.0/easymega-v2.0-$(VERSION).ihx \
        src/easymini-v1.0/easymini-v1.0-$(VERSION).ihx \
+       src/easymotor-v2/easymotor-v2-$(VERSION).ihx \
        src/easytimer-v1/easytimer-v1-$(VERSION).ihx \
        src/telebt-v3.0/telebt-v3.0-$(VERSION).ihx \
        src/telebt-v4.0/telebt-v4.0-$(VERSION).ihx \
index 4c8e4970fb1f4d823e1c097bd52857c5b347b8b3..b54e236f552eade76a526cf05254ec6ac4b77663 100644 (file)
--- a/Releasing
+++ b/Releasing
@@ -109,6 +109,7 @@ These are Bdale's notes on how to do a release.
           src/easymega-v2.0/{*.elf,*.ihx,*.map} \
           src/easymini-v1.0/{*.elf,*.ihx,*.map} \
           src/easymini-v2.0/{*.elf,*.ihx,*.map} \
+          src/easymotor-v2/{*.elf,*.ihx,*.map} \
           src/easytimer-v1/{*.elf,*.ihx,*.map} \
           src/telebt-v3.0/{*.elf,*.ihx,*.map} \
           src/telebt-v4.0/{*.elf,*.ihx,*.map} \
@@ -128,6 +129,7 @@ These are Bdale's notes on how to do a release.
           src/easymega-v2.0/flash-loader/*.elf \
           src/easymini-v1.0/flash-loader/*.elf \
           src/easymini-v2.0/flash-loader/{*.elf,*.bin,*.map} \
+          src/easymotor-v2/flash-loader/*.elf \
           src/easytimer-v1/flash-loader/*.elf \
           src/telebt-v3.0/flash-loader/*.elf \
           src/telebt-v4.0/flash-loader/{*.elf,*.bin,*.map} \
index 765eb44598f337b6fd9e58da4413c5346a021ebf..16c57ec187104e5f8449f3ba030d496f734bd894 100644 (file)
@@ -408,6 +408,10 @@ public class AltosCSV implements AltosWriter {
                        out.printf(",");
                        write_3d_accel_header();
                }
+               if (has_imu) {
+                       out.printf(",");
+                       write_imu_header();
+               }
                if (has_igniter) {
                        out.printf(",");
                        write_igniter_header();
index ba9d1ae46121ca5ce72895562dd13ec736e88a38..3f8f290c9f87faa419358de317a3210ea879d583 100644 (file)
@@ -29,6 +29,8 @@ public class AltosMapTransform {
 
        double  offset_x, offset_y;
 
+       int     width, height;
+
        public AltosLatLon lat_lon (AltosPointDouble point) {
                double lat, lon;
                double rads;
@@ -110,6 +112,39 @@ public class AltosMapTransform {
                return screen(point(lat, lon));
        }
 
+       /* Return first longitude value which ends up on-screen */
+       public double first_lon(double lon) {
+               /* Find a longitude left of the screen */
+               for (;;) {
+                       double x = lon * scale_x - offset_x;
+                       if (x < 0)
+                               break;
+                       lon -= 360.0;
+               }
+               /* Find the first longitude on the screen */
+               for (;;) {
+                       double x = lon * scale_x - offset_x;
+                       if (x >= 0)
+                               break;
+                       lon += 360.0;
+               }
+               return lon;
+       }
+
+       /* Return last longitude value which ends up on-screen */
+       public double last_lon(double lon) {
+               lon = first_lon(lon);
+
+               for(;;) {
+                       double next_lon = lon + 360.0;
+                       double next_x = next_lon * scale_x - offset_x;
+                       if (next_x >= width)
+                               break;
+                       lon = next_lon;
+               }
+               return lon;
+       }
+
        private boolean has_location;
 
        public boolean has_location() {
@@ -120,6 +155,9 @@ public class AltosMapTransform {
                scale_x = 256/360.0 * Math.pow(2, zoom);
                scale_y = 256/(2.0*Math.PI) * Math.pow(2, zoom);
 
+               this.width = width;
+               this.height = height;
+
                AltosPointDouble centre_pt = point(centre_lat_lon);
 
                has_location = (centre_lat_lon.lat != 0 || centre_lat_lon.lon != 0);
index 145a260ba76c07cfcb7dffb469b6191049f4d556..aa96638f5cf9822d1ca1fda58eccc6579903a4f2 100755 (executable)
@@ -1,16 +1,4 @@
 #!/bin/bash
-#
-# Fix fonts. I don't know why the getting the
-# basename of the app set to . matters, but it does
-#
-case "$0" in
-    /*)
-        cd `dirname "$0"`
-        ./`basename "$0"` "$@"
-        exit $?
-        ;;
-esac
-export FREETYPE_PROPERTIES=truetype:interpreter-version=35
 ##################################################################################
 #                                                                                #
 # universalJavaApplicationStub                                                   #
@@ -23,14 +11,14 @@ export FREETYPE_PROPERTIES=truetype:interpreter-version=35
 #                                                                                #
 # @author    Tobias Fischer                                                      #
 # @url       https://github.com/tofi86/universalJavaApplicationStub              #
-# @date      2018-08-24                                                          #
-# @version   3.0.4                                                               #
+# @date      2021-02-21                                                          #
+# @version   3.2.0                                                               #
 #                                                                                #
 ##################################################################################
 #                                                                                #
 # The MIT License (MIT)                                                          #
 #                                                                                #
-# Copyright (c) 2014-2018 Tobias Fischer                                         #
+# Copyright (c) 2014-2021 Tobias Fischer                                         #
 #                                                                                #
 # Permission is hereby granted, free of charge, to any person obtaining a copy   #
 # of this software and associated documentation files (the "Software"), to deal  #
@@ -52,7 +40,18 @@ export FREETYPE_PROPERTIES=truetype:interpreter-version=35
 #                                                                                #
 ##################################################################################
 
-
+#
+# Fix fonts. I don't know why the getting the
+# basename of the app set to . matters, but it does
+#
+case "$0" in
+    /*)
+        cd `dirname "$0"`
+        ./`basename "$0"` "$@"
+        exit $?
+        ;;
+esac
+export FREETYPE_PROPERTIES=truetype:interpreter-version=35
 
 # function 'stub_logger()'
 #
@@ -178,6 +177,8 @@ if [ $exitcode -eq 0 ]; then
        JavaFolder="${AppleJavaFolder}"
        ResourcesFolder="${AppleResourcesFolder}"
 
+       # set expandable variables
+       APP_ROOT="${AppPackageFolder}"
        APP_PACKAGE="${AppPackageFolder}"
        JAVAROOT="${AppleJavaFolder}"
        USER_HOME="$HOME"
@@ -192,7 +193,7 @@ if [ $exitcode -eq 0 ]; then
                # AppPackageRoot is the standard WorkingDirectory when the script is started
                WorkingDirectory="${AppPackageRoot}"
        fi
-       # expand variables $APP_PACKAGE, $JAVAROOT, $USER_HOME
+       # expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
        WorkingDirectory=$(eval echo "${WorkingDirectory}")
 
 
@@ -215,7 +216,7 @@ if [ $exitcode -eq 0 ]; then
        else
                JVMClassPath=${JVMClassPath_RAW}
        fi
-       # expand variables $APP_PACKAGE, $JAVAROOT, $USER_HOME
+       # expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
        JVMClassPath=$(eval echo "${JVMClassPath}")
 
        # read the JVM Options in either Array or String style
@@ -225,6 +226,8 @@ if [ $exitcode -eq 0 ]; then
        else
                JVMDefaultOptions=${JVMDefaultOptions_RAW}
        fi
+       # expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME (#84)
+       JVMDefaultOptions=$(eval echo "${JVMDefaultOptions}")
 
        # read StartOnMainThread and add as -XstartOnFirstThread
        JVMStartOnMainThread=$(plist_get_java ':StartOnMainThread')
@@ -232,9 +235,14 @@ if [ $exitcode -eq 0 ]; then
                JVMDefaultOptions+=" -XstartOnFirstThread"
        fi
 
-       # read the JVM Arguments as an array and retain spaces
+       # read the JVM Arguments in either Array or String style (#76) and retain spaces
        IFS=$'\t\n'
-       MainArgs=($(xargs -n1 <<<$(plist_get_java ':Arguments')))
+       MainArgs_RAW=$(plist_get_java ':Arguments' | xargs)
+       if [[ $MainArgs_RAW == *Array* ]] ; then
+               MainArgs=($(xargs -n1 <<<$(plist_get_java ':Arguments' | tr -d '\n' | sed -E 's/Array \{ *(.*) *\}/\1/g' | sed 's/  */ /g')))
+       else
+               MainArgs=($(xargs -n1 <<<$(plist_get_java ':Arguments')))
+       fi
        unset IFS
        # post processing of the array follows further below...
 
@@ -252,7 +260,11 @@ else
        ResourcesFolder="${OracleResourcesFolder}"
        WorkingDirectory="${OracleJavaFolder}"
 
+       # set expandable variables
        APP_ROOT="${AppPackageFolder}"
+       APP_PACKAGE="${AppPackageFolder}"
+       JAVAROOT="${OracleJavaFolder}"
+       USER_HOME="$HOME"
 
        # read the MainClass name
        JVMMainClass="$(plist_get ':JVMMainClassName')"
@@ -270,12 +282,12 @@ else
        JVMClassPath_RAW=$(plist_get ':JVMClassPath')
        if [[ $JVMClassPath_RAW == *Array* ]] ; then
                JVMClassPath=.$(plist_get ':JVMClassPath' | grep "    " | sed 's/^ */:/g' | tr -d '\n' | xargs)
-               # expand variables $APP_PACKAGE, $JAVAROOT, $USER_HOME
+               # expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
                JVMClassPath=$(eval echo "${JVMClassPath}")
 
        elif [[ ! -z ${JVMClassPath_RAW} ]] ; then
                JVMClassPath=${JVMClassPath_RAW}
-               # expand variables $APP_PACKAGE, $JAVAROOT, $USER_HOME
+               # expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
                JVMClassPath=$(eval echo "${JVMClassPath}")
 
        else
@@ -284,8 +296,11 @@ else
                # Do NOT expand the default 'AppName.app/Contents/Java/*' classpath (#42)
        fi
 
-       # read the JVM Default Options
+       # read the JVM Default Options by parsing the :JVMDefaultOptions <dict>
+       # and pulling all <string> values starting with a dash (-)
        JVMDefaultOptions=$(plist_get ':JVMDefaultOptions' | grep -o " \-.*" | tr -d '\n' | xargs)
+       # expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME (#99)
+       JVMDefaultOptions=$(eval echo "${JVMDefaultOptions}")
 
        # read the Main Arguments from JVMArguments key as an array and retain spaces (see #46 for naming details)
        IFS=$'\t\n'
@@ -299,6 +314,18 @@ else
 fi
 
 
+# (#75) check for undefined icons or icon names without .icns extension and prepare
+# an osascript statement for those cases when the icon can be shown in the dialog
+DialogWithIcon=""
+if [ ! -z ${CFBundleIconFile} ]; then
+       if [[ ${CFBundleIconFile} == *.icns ]] && [[ -f "${ResourcesFolder}/${CFBundleIconFile}" ]] ; then
+               DialogWithIcon=" with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)"
+       elif [[ ${CFBundleIconFile} != *.icns ]] && [[ -f "${ResourcesFolder}/${CFBundleIconFile}.icns" ]] ; then
+               CFBundleIconFile+=".icns"
+               DialogWithIcon=" with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)"
+       fi
+fi
+
 
 # JVMVersion: post processing and optional splitting
 if [[ ${JVMVersion} == *";"* ]]; then
@@ -309,14 +336,14 @@ fi
 stub_logger "[JavaRequirement] JVM minimum version: ${JVMVersion}"
 stub_logger "[JavaRequirement] JVM maximum version: ${JVMMaxVersion}"
 
-# MainArgs: replace occurences of $APP_ROOT with its content
+# MainArgs: expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
 MainArgsArr=()
 for i in "${MainArgs[@]}"
 do
        MainArgsArr+=("$(eval echo "$i")")
 done
 
-# JVMOptions: replace occurences of $APP_ROOT with its content
+# JVMOptions: expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
 JVMOptionsArr=()
 for i in "${JVMOptions[@]}"
 do
@@ -327,14 +354,37 @@ done
 # internationalized messages
 ############################################
 
-LANG=$(defaults read -g AppleLocale)
-stub_logger "[Language] $LANG"
+# supported languages / available translations
+stubLanguages="^(fr|de|zh|es|en)-"
+
+# read user preferred languages as defined in macOS System Preferences (#101)
+stub_logger '[LanguageSearch] Checking preferred languages in macOS System Preferences...'
+appleLanguages=($(defaults read -g AppleLanguages | grep '\s"' | tr -d ',' | xargs))
+stub_logger "[LanguageSearch] ... found [${appleLanguages[*]}]"
+
+language=""
+for i in "${appleLanguages[@]}"
+do
+       langValue="${i%-*}"
+    if [[ "$i" =~ $stubLanguages ]]; then 
+               stub_logger "[LanguageSearch] ... selected '$i' ('$langValue') as the default language for the launcher stub"
+               language=${langValue}
+        break
+       fi
+done
+if [ -z "${language}" ]; then
+    language="en"
+    stub_logger "[LanguageSearch] ... selected fallback 'en' as the default language for the launcher stub"
+fi
+stub_logger "[Language] $language"
 
-# French localization
-if [[ $LANG == fr* ]] ; then
+
+case "${language}" in
+# French
+fr)
        MSG_ERROR_LAUNCHING="ERREUR au lancement de '${CFBundleName}'."
        MSG_MISSING_MAINCLASS="'MainClass' n'est pas spécifié.\nL'application Java ne peut pas être lancée."
-       MSG_JVMVERSION_REQ_INVALID="La syntaxe de la version Java demandée est invalide: %s\nVeuillez contacter le développeur de l'application."
+       MSG_JVMVERSION_REQ_INVALID="La syntaxe de la version de Java demandée est invalide: %s\nVeuillez contacter le développeur de l'application."
        MSG_NO_SUITABLE_JAVA="La version de Java installée sur votre système ne convient pas.\nCe programme nécessite Java %s"
        MSG_JAVA_VERSION_OR_LATER="ou ultérieur"
        MSG_JAVA_VERSION_LATEST="(dernière mise à jour)"
@@ -342,10 +392,12 @@ if [[ $LANG == fr* ]] ; then
        MSG_NO_SUITABLE_JAVA_CHECK="Merci de bien vouloir installer la version de Java requise."
        MSG_INSTALL_JAVA="Java doit être installé sur votre système.\nRendez-vous sur java.com et suivez les instructions d'installation..."
        MSG_LATER="Plus tard"
-       MSG_VISIT_JAVA_DOT_COM="Visiter java.com"
+       MSG_VISIT_JAVA_DOT_COM="Java by Oracle"
+       MSG_VISIT_ADOPTOPENJDK="Java by AdoptOpenJDK"
+    ;;
 
-# German localization
-elif [[ $LANG == de* ]] ; then
+# German
+de)
        MSG_ERROR_LAUNCHING="FEHLER beim Starten von '${CFBundleName}'."
        MSG_MISSING_MAINCLASS="Die 'MainClass' ist nicht spezifiziert!\nDie Java-Anwendung kann nicht gestartet werden!"
        MSG_JVMVERSION_REQ_INVALID="Die Syntax der angeforderten Java-Version ist ungültig: %s\nBitte kontaktieren Sie den Entwickler der App."
@@ -356,10 +408,12 @@ elif [[ $LANG == de* ]] ; then
        MSG_NO_SUITABLE_JAVA_CHECK="Stellen Sie sicher, dass die angeforderte Java-Version installiert ist."
        MSG_INSTALL_JAVA="Auf Ihrem System muss die 'Java'-Software installiert sein.\nBesuchen Sie java.com für weitere Installationshinweise."
        MSG_LATER="Später"
-       MSG_VISIT_JAVA_DOT_COM="java.com öffnen"
+       MSG_VISIT_JAVA_DOT_COM="Java von Oracle"
+       MSG_VISIT_ADOPTOPENJDK="Java von AdoptOpenJDK"
+    ;;
 
-# Simplifyed Chinese localization
-elif [[ $LANG == zh* ]] ; then
+# Simplified Chinese
+zh)
        MSG_ERROR_LAUNCHING="无法启动 '${CFBundleName}'."
        MSG_MISSING_MAINCLASS="没有指定 'MainClass'!\nJava程序无法启动!"
        MSG_JVMVERSION_REQ_INVALID="Java版本参数语法错误: %s\n请联系该应用的开发者。"
@@ -370,10 +424,28 @@ elif [[ $LANG == zh* ]] ; then
        MSG_NO_SUITABLE_JAVA_CHECK="请确保系统中安装了所需的Java版本"
        MSG_INSTALL_JAVA="你需要在Mac中安装Java运行环境!\n访问 java.com 了解如何安装。"
        MSG_LATER="稍后"
-       MSG_VISIT_JAVA_DOT_COM="访问 java.com"
-
-# English default localization
-else
+       MSG_VISIT_JAVA_DOT_COM="Java by Oracle"
+       MSG_VISIT_ADOPTOPENJDK="Java by AdoptOpenJDK"
+    ;;
+
+# Spanish
+es)
+       MSG_ERROR_LAUNCHING="ERROR iniciando '${CFBundleName}'."
+       MSG_MISSING_MAINCLASS="¡'MainClass' no especificada!\n¡La aplicación Java no puede iniciarse!"
+       MSG_JVMVERSION_REQ_INVALID="La sintaxis de la versión Java requerida no es válida: %s\nPor favor, contacte con el desarrollador de la aplicación."
+       MSG_NO_SUITABLE_JAVA="¡No se encontró una versión de Java adecuada en su sistema!\nEste programa requiere Java %s"
+       MSG_JAVA_VERSION_OR_LATER="o posterior"
+       MSG_JAVA_VERSION_LATEST="(ultima actualización)"
+       MSG_JAVA_VERSION_MAX="superior a %s"
+       MSG_NO_SUITABLE_JAVA_CHECK="Asegúrese de instalar la versión Java requerida."
+       MSG_INSTALL_JAVA="¡Necesita tener JAVA instalado en su Mac!\nVisite java.com para consultar las instrucciones para su instalación..."
+       MSG_LATER="Más tarde"
+       MSG_VISIT_JAVA_DOT_COM="Java de Oracle"
+       MSG_VISIT_ADOPTOPENJDK="Java de AdoptOpenJDK"
+    ;;
+
+# English | default
+en|*)
        MSG_ERROR_LAUNCHING="ERROR launching '${CFBundleName}'."
        MSG_MISSING_MAINCLASS="'MainClass' isn't specified!\nJava application cannot be started!"
        MSG_JVMVERSION_REQ_INVALID="The syntax of the required Java version is invalid: %s\nPlease contact the App developer."
@@ -384,8 +456,10 @@ else
        MSG_NO_SUITABLE_JAVA_CHECK="Make sure you install the required Java version."
        MSG_INSTALL_JAVA="You need to have JAVA installed on your Mac!\nVisit java.com for installation instructions..."
        MSG_LATER="Later"
-       MSG_VISIT_JAVA_DOT_COM="Visit java.com"
-fi
+       MSG_VISIT_JAVA_DOT_COM="Java by Oracle"
+       MSG_VISIT_ADOPTOPENJDK="Java by AdoptOpenJDK"
+    ;;
+esac
 
 
 
@@ -468,7 +542,7 @@ function get_comparable_java_version() {
 ################################################################################
 function is_valid_requirement_pattern() {
        local java_req=$1
-       java8pattern='1\.[4-8](\.0)?(\.0_[0-9]+)?[*+]?'
+       java8pattern='1\.[4-8](\.[0-9]+)?(\.0_[0-9]+)?[*+]?'
        java9pattern='(9|1[0-9])(-ea|[*+]|(\.[0-9]+){1,2}[*+]?)?'
        # test matches either old Java versioning scheme (up to 1.8) or new scheme (starting with 9)
        if [[ ${java_req} =~ ^(${java8pattern}|${java9pattern})$ ]]; then
@@ -501,20 +575,28 @@ if [ -n "$JAVA_HOME" ] ; then
        if [[ $JAVA_HOME == /* ]] ; then
                # if "$JAVA_HOME" starts with a Slash it's an absolute path
                JAVACMD="$JAVA_HOME/bin/java"
+               stub_logger "[JavaSearch] ... parsing JAVA_HOME as absolute path to the executable '$JAVACMD'"
        else
                # otherwise it's a relative path to "$AppPackageFolder"
                JAVACMD="$AppPackageFolder/$JAVA_HOME/bin/java"
+               stub_logger "[JavaSearch] ... parsing JAVA_HOME as relative path inside the App bundle to the executable '$JAVACMD'"
        fi
        JAVACMD_version=$(get_comparable_java_version $(get_java_version_from_cmd "${JAVACMD}"))
 else
-       stub_logger "[JavaSearch] ... didn't found JAVA_HOME"
+       stub_logger "[JavaSearch] ... haven't found JAVA_HOME"
 fi
 
 
 # check for any other or a specific Java version
 # also if $JAVA_HOME exists but isn't executable
 if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
-       stub_logger "[JavaSearch] Checking for JavaVirtualMachines on the system ..."
+
+       # add a warning in the syslog if JAVA_HOME is not executable or not found (#100)
+       if [ -n "$JAVA_HOME" ] ; then
+               stub_logger "[JavaSearch] ... but no 'java' executable was found at the JAVA_HOME location!"
+       fi
+
+       stub_logger "[JavaSearch] Searching for JavaVirtualMachines on the system ..."
        # reset variables
        JAVACMD=""
        JAVACMD_version=""
@@ -525,7 +607,7 @@ if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
                # log exit cause
                stub_logger "[EXIT 4] ${MSG_JVMVERSION_REQ_INVALID_EXPANDED}"
                # display error message with AppleScript
-               osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_JVMVERSION_REQ_INVALID_EXPANDED}\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1 with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)"
+               osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_JVMVERSION_REQ_INVALID_EXPANDED}\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1${DialogWithIcon}"
                # exit with error
                exit 4
        fi
@@ -535,7 +617,7 @@ if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
                # log exit cause
                stub_logger "[EXIT 5] ${MSG_JVMVERSION_REQ_INVALID_EXPANDED}"
                # display error message with AppleScript
-               osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_JVMVERSION_REQ_INVALID_EXPANDED}\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1 with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)"
+               osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_JVMVERSION_REQ_INVALID_EXPANDED}\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1${DialogWithIcon}"
                # exit with error
                exit 5
        fi
@@ -543,15 +625,41 @@ if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
 
        # find installed JavaVirtualMachines (JDK + JRE)
        allJVMs=()
-       # read JDK's from '/usr/libexec/java_home -V' command
-       while read -r line; do
-               version=$(echo $line | awk -F $',' '{print $1;}')
-               path=$(echo $line | awk -F $'" ' '{print $2;}')
-               path+="/bin/java"
-               allJVMs+=("$version:$path")
-       done < <(/usr/libexec/java_home -V 2>&1 | grep '^[[:space:]]')
-       # unset while loop variables
-       unset version path
+       
+       # read JDK's from '/usr/libexec/java_home --xml' command with PlistBuddy and a custom Dict iterator
+       # idea: https://stackoverflow.com/a/14085460/1128689 and https://scriptingosx.com/2018/07/parsing-dscl-output-in-scripts/
+       javaXml=$(/usr/libexec/java_home --xml)
+       javaCounter=$(/usr/libexec/PlistBuddy -c "Print" /dev/stdin <<< $javaXml | grep "Dict" | wc -l | tr -d ' ')
+
+       # iterate over all Dict entries
+       # but only if there are any JVMs at all (#93)
+       if [ "$javaCounter" -gt "0" ] ; then
+               for idx in $(seq 0 $((javaCounter - 1)))
+               do
+                       version=$(/usr/libexec/PlistBuddy -c "print :$idx:JVMVersion" /dev/stdin <<< $javaXml)
+                       path=$(/usr/libexec/PlistBuddy -c "print :$idx:JVMHomePath" /dev/stdin <<< $javaXml)
+                       path+="/bin/java"
+                       allJVMs+=("$version:$path")
+               done
+               # unset for loop variables
+               unset version path
+       fi
+
+       # add SDKMAN! java versions (#95)
+       if [ -d ~/.sdkman/candidates/java/ ] ; then
+               for sdkjdk in ~/.sdkman/candidates/java/*/
+               do
+                       if [[ ${sdkjdk} =~ /current/$ ]] ; then
+                               continue
+                       fi
+
+                       sdkjdkcmd="${sdkjdk}bin/java"
+                       version=$(get_java_version_from_cmd "${sdkjdkcmd}")
+                       allJVMs+=("$version:$sdkjdkcmd")
+               done
+               # unset for loop variables
+               unset version
+       fi
 
        # add Apple JRE if available
        if [ -x "${apple_jre_plugin}" ] ; then
@@ -571,6 +679,9 @@ if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
 
 
        # determine JVMs matching the min/max version requirement
+
+       stub_logger "[JavaSearch] Filtering the result list for JVMs matching the min/max version requirement ..."
+
        minC=$(get_comparable_java_version ${JVMVersion})
        maxC=$(get_comparable_java_version ${JVMMaxVersion})
        matchingJVMs=()
@@ -655,7 +766,7 @@ if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
        # debug output
        for i in "${matchingJVMs[@]}"
        do
-               stub_logger "[JavaSearch] ... ... matches all requirements: $i"
+               stub_logger "[JavaSearch] ... matches all requirements: $i"
        done
 
 
@@ -692,7 +803,13 @@ fi
 stub_logger "[JavaCommand] '$JAVACMD'"
 stub_logger "[JavaVersion] $(get_java_version_from_cmd "${JAVACMD}")${JAVACMD_version:+ / $JAVACMD_version}"
 
+# Make sure tabbing mode is disabled for the selected java version
+
+CFBundleIdentifier=net.java.openjdk.$(get_java_version_from_cmd "${JAVACMD}").java
 
+if [ x$(defaults read ${CFBundleIdentifier} AppleWindowTabbingMode) != "xnever" ]; then
+    defaults write ${CFBundleIdentifier} AppleWindowTabbingMode never
+fi
 
 if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
 
@@ -712,9 +829,10 @@ if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
                stub_logger "[EXIT 3] ${MSG_NO_SUITABLE_JAVA_EXPANDED}"
 
                # display error message with AppleScript
-               osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_NO_SUITABLE_JAVA_EXPANDED}\n${MSG_NO_SUITABLE_JAVA_CHECK}\" with title \"${CFBundleName}\"  buttons {\" OK \", \"${MSG_VISIT_JAVA_DOT_COM}\"} default button \"${MSG_VISIT_JAVA_DOT_COM}\" with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)" \
+               osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_NO_SUITABLE_JAVA_EXPANDED}\n${MSG_NO_SUITABLE_JAVA_CHECK}\" with title \"${CFBundleName}\"  buttons {\" OK \", \"${MSG_VISIT_JAVA_DOT_COM}\", \"${MSG_VISIT_ADOPTOPENJDK}\"} default button 1${DialogWithIcon}" \
                                -e "set response to button returned of the result" \
-                               -e "if response is \"${MSG_VISIT_JAVA_DOT_COM}\" then open location \"http://java.com\""
+                               -e "if response is \"${MSG_VISIT_JAVA_DOT_COM}\" then open location \"https://www.java.com/download/\"" \
+                               -e "if response is \"${MSG_VISIT_ADOPTOPENJDK}\" then open location \"https://adoptopenjdk.net/releases.html\""
                # exit with error
                exit 3
 
@@ -722,9 +840,10 @@ if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
                # log exit cause
                stub_logger "[EXIT 1] ${MSG_ERROR_LAUNCHING}"
                # display error message with AppleScript
-               osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_INSTALL_JAVA}\" with title \"${CFBundleName}\" buttons {\"${MSG_LATER}\", \"${MSG_VISIT_JAVA_DOT_COM}\"} default button \"${MSG_VISIT_JAVA_DOT_COM}\" with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)" \
+               osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_INSTALL_JAVA}\" with title \"${CFBundleName}\" buttons {\"${MSG_LATER}\", \"${MSG_VISIT_JAVA_DOT_COM}\", \"${MSG_VISIT_ADOPTOPENJDK}\"} default button 1${DialogWithIcon}" \
                                        -e "set response to button returned of the result" \
-                                       -e "if response is \"${MSG_VISIT_JAVA_DOT_COM}\" then open location \"http://java.com\""
+                                       -e "if response is \"${MSG_VISIT_JAVA_DOT_COM}\" then open location \"https://www.java.com/download/\"" \
+                                       -e "if response is \"${MSG_VISIT_ADOPTOPENJDK}\" then open location \"https://adoptopenjdk.net/releases.html\""
                # exit with error
                exit 1
        fi
@@ -739,7 +858,7 @@ if [ -z "${JVMMainClass}" ]; then
        # log exit cause
        stub_logger "[EXIT 2] ${MSG_MISSING_MAINCLASS}"
        # display error message with AppleScript
-       osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_MISSING_MAINCLASS}\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1 with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)"
+       osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_MISSING_MAINCLASS}\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1${DialogWithIcon}"
        # exit with error
        exit 2
 fi
@@ -773,11 +892,11 @@ stub_logger "[WorkingDirectory] ${WorkingDirectory}"
 # - main class
 # - main class arguments
 # - passthrough arguments from Terminal or Drag'n'Drop to Finder icon
-stub_logger "[Exec] \"$JAVACMD\" -cp \"${JVMClassPath}\" -splash:\"${ResourcesFolder}/${JVMSplashFile}\" -Xdock:icon=\"${ResourcesFolder}/${CFBundleIconFile}\" -Xdock:name=\"${CFBundleName}\" ${JVMOptionsArr:+$(printf "'%s' " "${JVMOptionsArr[@]}") }${JVMDefaultOptions:+$JVMDefaultOptions }${JVMMainClass}${MainArgsArr:+ $(printf "'%s' " "${MainArgsArr[@]}")}${ArgsPassthru:+ $(printf "'%s' " "${ArgsPassthru[@]}")}"
+stub_logger "[Exec] \"$JAVACMD\" -cp \"${JVMClassPath}\" ${JVMSplashFile:+ -splash:\"${ResourcesFolder}/${JVMSplashFile}\"} -Xdock:icon=\"${ResourcesFolder}/${CFBundleIconFile}\" -Xdock:name=\"${CFBundleName}\" ${JVMOptionsArr:+$(printf "'%s' " "${JVMOptionsArr[@]}") }${JVMDefaultOptions:+$JVMDefaultOptions }${JVMMainClass}${MainArgsArr:+ $(printf "'%s' " "${MainArgsArr[@]}")}${ArgsPassthru:+ $(printf "'%s' " "${ArgsPassthru[@]}")}"
 exec "${JAVACMD}" \
                -Djava.library.path="${AppleJavaFolder}" \
                -cp "${JVMClassPath}" \
-               -splash:"${ResourcesFolder}/${JVMSplashFile}" \
+               ${JVMSplashFile:+ -splash:"${ResourcesFolder}/${JVMSplashFile}"} \
                -Xdock:icon="${ResourcesFolder}/${CFBundleIconFile}" \
                -Xdock:name="${CFBundleName}" \
                ${JVMOptionsArr:+"${JVMOptionsArr[@]}" }\
index 78d3ec15b011adad2f5e87976ca1dfe3e36f8bc2..1cbb919f16ce299310014934bbd23e86cd0f46ec 100644 (file)
@@ -146,6 +146,9 @@ FIRMWARE_EMEGA_1_0=$(top_srcdir)/src/easymega-v1.0/easymega-v1.0-$(VERSION).ihx
 FIRMWARE_EMEGA_2_0=$(top_srcdir)/src/easymega-v2.0/easymega-v2.0-$(VERSION).ihx
 FIRMWARE_EMEGA=$(FIRMWARE_EMEGA_1_0) $(FIRMWARE_EMEGA_2_0)
 
+FIRMWARE_EMOTOR_2=$(top_srcdir)/src/easymotor-v2/easymotor-v2-$(VERSION).ihx
+FIRMWARE_EMOTOR=$(FIRMWARE_EMOTOR_2)
+
 FIRMWARE_ETIMER_1=$(top_srcdir)/src/easytimer-v1/easytimer-v1-$(VERSION).ihx
 FIRMWARE_ETIMER=$(FIRMWARE_ETIMER_1)
 
@@ -160,7 +163,7 @@ FIRMWARE_TFIRE8_1_0=$(top_srcdir)/src/telefireeight-v1.0/telefireeight-v1.0-$(VE
 FIRMWARE_TFIRE8_2_0=$(top_srcdir)/src/telefireeight-v2.0/telefireeight-v2.0-$(VERSION).ihx
 FIRMWARE_TFIRE8=$(FIRMWARE_TFIRE8_1_0) $(FIRMWARE_TFIRE8_2_0)
 
-FIRMWARE=$(FIRMWARE_TM) $(FIRMWARE_TELEMINI) $(FIRMWARE_TD) $(FIRMWARE_TBT) $(FIRMWARE_TMEGA) $(FIRMWARE_EMINI) $(FIRMWARE_TGPS) $(FIRMWARE_EMEGA) $(FIRMWARE_ETIMER) $(FIRMWARE_TLCO) $(FIRMWARE_TFIRE8)
+FIRMWARE=$(FIRMWARE_TM) $(FIRMWARE_TELEMINI) $(FIRMWARE_TD) $(FIRMWARE_TBT) $(FIRMWARE_TMEGA) $(FIRMWARE_EMINI) $(FIRMWARE_TGPS) $(FIRMWARE_EMEGA) $(FIRMWARE_EMOTOR) $(FIRMWARE_ETIMER) $(FIRMWARE_TLCO) $(FIRMWARE_TFIRE8)
 
 ALTUSMETRUM_DOC=$(top_srcdir)/doc/altusmetrum.pdf
 ALTOS_DOC=$(top_srcdir)/doc/altos.pdf
index ad155a2c4ff387aeed0a5bceea335d229cfab34f..196dd7411d9e7f0d75777643c34041391c98d295 100644 (file)
@@ -136,6 +136,7 @@ Section "Firmware"
        File "../src/easymini-v2.0/easymini-v2.0-${VERSION}.ihx"
        File "../src/easymega-v1.0/easymega-v1.0-${VERSION}.ihx"
        File "../src/easymega-v2.0/easymega-v2.0-${VERSION}.ihx"
+       File "../src/easymotor-v2/easymotor-v2-${VERSION}.ihx"
        File "../src/easytimer-v1/easytimer-v1-${VERSION}.ihx"
        File "../src/telelco-v2.0/telelco-v2.0-${VERSION}.ihx"
        File "../src/telefireeight-v1.0/telefireeight-v1.0-${VERSION}.ihx"
index 58371f05a090d892f88bc4f74ade73763a00039b..0a80959fe80a9c02416968f8e35beed860f03f3e 100644 (file)
@@ -48,37 +48,43 @@ public class AltosUIMap extends JComponent implements AltosFlightDisplay, AltosM
 
        class MapMark extends AltosMapMark {
                public void paint(AltosMapTransform t) {
-                       AltosPointDouble pt = t.screen(lat_lon);
+                       double lat = lat_lon.lat;
+                       double lon;
+                       double first_lon = t.first_lon(lat_lon.lon);
+                       double last_lon = t.last_lon(lat_lon.lon);
+                       for (lon = first_lon; lon <= last_lon; lon += 360.0) {
+                               AltosPointDouble pt = t.screen(lat, lon);
 
-                       g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
-                                          RenderingHints.VALUE_ANTIALIAS_ON);
-                       g.setStroke(new BasicStroke(stroke_width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
+                               g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                                                  RenderingHints.VALUE_ANTIALIAS_ON);
+                               g.setStroke(new BasicStroke(stroke_width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
 
-                       if (0 <= state && state < AltosUIMap.stateColors.length)
-                               g.setColor(AltosUIMap.stateColors[state]);
-                       else
-                               g.setColor(AltosUIMap.stateColors[AltosLib.ao_flight_invalid]);
-
-                       g.drawOval((int)pt.x-5, (int)pt.y-5, 10, 10);
-                       g.drawOval((int)pt.x-20, (int)pt.y-20, 40, 40);
-                       g.drawOval((int)pt.x-35, (int)pt.y-35, 70, 70);
-
-                       if (label != null) {
-                               Rectangle2D     bounds;
-                               bounds = line_font.getStringBounds(label, g.getFontRenderContext());
-                               float x = (float) pt.x;
-                               float y = (float) pt.y + (float) bounds.getHeight() / 2.0f;
-
-                               g.setFont(line_font);
-                               g.setColor(Color.WHITE);
-                               for (int dy = -2; dy <= 2; dy += 2)
-                                       for (int dx = -2; dx <= 2; dx += 2)
-                                               g.drawString(label, x + dx, y + dy);
                                if (0 <= state && state < AltosUIMap.stateColors.length)
                                        g.setColor(AltosUIMap.stateColors[state]);
                                else
                                        g.setColor(AltosUIMap.stateColors[AltosLib.ao_flight_invalid]);
-                               g.drawString(label, x, y);
+
+                               g.drawOval((int)pt.x-5, (int)pt.y-5, 10, 10);
+                               g.drawOval((int)pt.x-20, (int)pt.y-20, 40, 40);
+                               g.drawOval((int)pt.x-35, (int)pt.y-35, 70, 70);
+
+                               if (label != null) {
+                                       Rectangle2D     bounds;
+                                       bounds = line_font.getStringBounds(label, g.getFontRenderContext());
+                                       float x = (float) pt.x;
+                                       float y = (float) pt.y + (float) bounds.getHeight() / 2.0f;
+
+                                       g.setFont(line_font);
+                                       g.setColor(Color.WHITE);
+                                       for (int dy = -2; dy <= 2; dy += 2)
+                                               for (int dx = -2; dx <= 2; dx += 2)
+                                                       g.drawString(label, x + dx, y + dy);
+                                       if (0 <= state && state < AltosUIMap.stateColors.length)
+                                               g.setColor(AltosUIMap.stateColors[state]);
+                                       else
+                                               g.setColor(AltosUIMap.stateColors[AltosLib.ao_flight_invalid]);
+                                       g.drawString(label, x, y);
+                               }
                        }
                }
 
index 1fec169cd0e6e70ba0ad5b0c2e3f6f4d1a613225..6d0d8b70576e881cae6ec9473eccad5627acd424 100644 (file)
@@ -230,10 +230,6 @@ public class AltosUIMapPreload extends AltosUIFrame implements ActionListener, I
 
        void add_mark(double lat, double lon, int state, String label) {
                map.add_mark(lat, lon, state, label);
-               if (lon <= 0)
-                       map.add_mark(lat, lon + 360, state, label);
-               if (lon >= 0)
-                       map.add_mark(lat, lon - 360, state, label);
        }
 
        void reset_marks() {
diff --git a/ao-bringup/test-easymotor b/ao-bringup/test-easymotor
new file mode 100755 (executable)
index 0000000..a99ca9d
--- /dev/null
@@ -0,0 +1,40 @@
+#!/bin/sh
+
+VERSION=2
+PRODUCT=EasyMotor
+BASE=`echo $PRODUCT | tr 'A-Z' 'a-z'`
+
+echo "$PRODUCT-v$VERSION Test Program"
+echo "Copyright 2021 by Bdale Garbee.  Released under GPL v3"
+echo
+echo "Expectations:"
+echo "\t$PRODUCT v$VERSION powered from USB"
+echo
+
+ret=1
+ao-list | while read product serial dev; do
+    case "$product" in
+       "$PRODUCT-v$VERSION")
+
+           echo "Testing $product $serial $dev"
+           echo ""
+
+           FLASHSIZE=8388608
+
+           echo "Testing flash"
+           ../ao-tools/ao-test-flash/ao-test-flash --tty="$dev" "$FLASHSIZE"
+
+           case $? in
+               0)
+                   ;;
+               *)
+                   echo "failed"
+                   exit 1
+           esac
+           echo""
+
+           echo "$PRODUCT-v$VERSION" serial "$serial" is ready to ship
+           ret=0
+           ;;
+    esac
+done
diff --git a/ao-bringup/turnon_easymotor b/ao-bringup/turnon_easymotor
new file mode 100755 (executable)
index 0000000..b9bc007
--- /dev/null
@@ -0,0 +1,75 @@
+#!/bin/sh
+
+PRODUCT=EasyMotor
+VERSION=2
+REPO=~/altusmetrumllc/Binaries
+
+if [ -x /usr/bin/dfu-util ]; then
+    DFU_UTIL=/usr/bin/dfu-util
+else
+    echo "Can't find dfu-util! Aborting."
+    exit 1
+fi
+
+if [ -x /usr/bin/ao-usbload ]; then
+       USBLOAD=/usr/bin/ao-usbload
+else
+       echo "Can't find ao-usbload!  Aborting."
+       exit 1
+fi
+
+echo "$PRODUCT v$VERSION Turn-On and Calibration Program"
+echo "Copyright 2021 by Bdale Garbee.  Released under GPL v3"
+echo
+echo "Expectations:"
+echo "\t$PRODUCT v$VERSION"
+echo "\t\twith USB cable attached"
+echo
+
+case $# in
+    1)
+       SERIAL="$1"
+       echo "$PRODUCT-$VERSION serial number: $SERIAL" 
+       ;;
+    0)
+       echo -n "$PRODUCT-$VERSION serial number: "
+       read SERIAL
+       ;;
+    *)
+       echo "Usage: $0 <serial-number>" 1>&2
+       exit 1;
+       ;;
+esac
+
+
+echo $DFU_UTIL
+
+$DFU_UTIL -v -v -R -a 0 -s 0x08000000:leave -D $REPO/loaders/easymotor-v$VERSION*.elf
+
+sleep 3
+
+$USBLOAD --serial=$SERIAL $REPO/easymotor-v$VERSION*.elf || exit 1
+
+sleep 5
+
+dev=`ao-list | awk '/'"$PRODUCT"'-v'"$VERSION"'/ { print $3; exit(0); }'`
+
+case "$dev" in
+/dev/tty*)
+       echo "$PRODUCT found on $dev"
+       ;;
+*)
+       echo 'No '"$PRODUCT"'-v'"$VERSION"' found'
+       exit 1
+       ;;
+esac
+
+failed=1
+while [ $failed =  1 ]; do
+    ../ao-tools/ao-cal-accel/ao-cal-accel $dev
+    failed=$?
+done
+
+./test-easymotor
+
+exit $?
index 45643a4ffbfe15eea251a2c52b57c7537630e735..89e266438693e4f10d5734d6282cffb08543a5c4 100755 (executable)
@@ -10,7 +10,7 @@ trap "rm $cmds" 0 1 15
 file="$1"
 echo "program $file verify reset" > $cmds
 openocd \
-       -f interface/stlink-v2.cfg \
-       -f target/stm32f0x_stlink.cfg \
+       -f interface/stlink.cfg \
+       -f target/stm32f0x.cfg \
        -f $cmds \
        -c shutdown
index df5cbfdc662b445f9f510aef1ceba57e09d4b968..ece8ac9386b957a33f18d50b5d5f2a74a143ac60 100644 (file)
@@ -18,13 +18,13 @@ dnl
 dnl Process this file with autoconf to create configure.
 
 AC_PREREQ(2.57)
-AC_INIT([altos], 1.9.6.1)
+AC_INIT([altos], 1.9.7)
 ANDROID_VERSION=27
 AC_CONFIG_SRCDIR([src/kernel/ao.h])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
 AM_MAINTAINER_MODE
 
-RELEASE_DATE=2020-10-29
+RELEASE_DATE=2021-04-12
 AC_SUBST(RELEASE_DATE)
 
 DOC_DATE=`LC_ALL=C date -d $RELEASE_DATE +'%d %b %Y'`
index 4d55898eed784464ab65fc369b69027d16e2b06d..560c868f2c367580b0941236115549c586563504 100644 (file)
@@ -17,6 +17,7 @@ FAKETIME=TZ=UTC faketime -f '$(RELEASE_DATE) 00:00:00 i0'
 endif
 
 RELNOTES_INC=\
+       release-notes-1.9.7.inc \
        release-notes-1.9.6.inc \
        release-notes-1.9.5.inc \
        release-notes-1.9.4.inc \
index f3026222c01088959c2fa10638b0b6fba5463fb0..bed7c141fdb116a17a3520abb3c06d49ca787140 100644 (file)
@@ -51,7 +51,7 @@ footer:
     left:
       content: '{page-number}'
     right:
-      content: '© 2020 Bdale Garbee and Keith Packard. Creative Commons ShareAlike 3.0 License'
+      content: '© 2021 Bdale Garbee and Keith Packard. Creative Commons ShareAlike 3.0 License'
   verso:
     left:
       content: $footer_recto_right_content
index c2492b0f40e282e96d68f50274b8e8402100deb7..4b7699c5cd95f6fb8df6407655b59bcb0b3a97d3 100644 (file)
@@ -5,7 +5,7 @@ Keith Packard <keithp@keithp.com>; Bdale Garbee <bdale@gag.com>; Bob Finch; Anth
 :revdate: 1 Jan 1970
 :icons:
 :icontype: svg
-:copyright: Bdale Garbee and Keith Packard 2020
+:copyright: Bdale Garbee and Keith Packard 2021
 :doctype: book
 :numbered:
 :stylesheet: am.css
@@ -21,6 +21,7 @@ Keith Packard <keithp@keithp.com>; Bdale Garbee <bdale@gag.com>; Bob Finch; Anth
 :easymega: 1
 :telegps: 1
 :easytimer: 1
+:easymotor: 1
 :application: AltosUI
 :pdf-stylesdir: .
 :pdf-style: altusmetrum
index 9dd0058e63062aa1116a28525f447e7b4c75dba8..dad66c2883449211272e75569f03be3b74a4bdbf 100644 (file)
@@ -1,5 +1,9 @@
 [appendix]
 == Release Notes
+       :leveloffset: 2
+       include::release-notes-1.9.7.adoc[]
+
+       <<<<
        :leveloffset: 2
        include::release-notes-1.9.6.adoc[]
 
index 173e0a38d7b4cf61a5f419ed0f01a5d8fbbb1c4f..e75cebb9e73323c3d10c93167fa46629936f04cb 100644 (file)
@@ -13,6 +13,6 @@
        === Changing the Configuration
 
                All available configuration options can be set using the 
-               "Configure Altimeter" menu selection within the AltosUI
+               “Configure Altimeter” menu selection within the AltosUI
                program.
 
index 8a4cd77fb0eb7ce29f468a7d442190cb9c6d5977..290c7b8fa7d3542511944278321f2ae77c012bb6 100644 (file)
@@ -2,50 +2,50 @@
 
        EasyMotor needs to be rigidly attached in the airframe, and the
        long axis of the circuit board needs to be aligned with the axis
-       of flight.  By default, the round beeper on the board should be
-       "up" towards the nose cone, and the screw terminal strips should
-       be "down" towards the fins and motor nozzle end of the rocket.
+       of flight. By default, the round beeper on the board should be
+       “up” towards the nose cone, and the screw terminal strips should
+       be “down” towards the fins and motor nozzle end of the rocket.
 
        === Power Switch and Battery
 
-               In addition to the circuit board itself, EasyMotor needs 
-               a power switch and battery to operate.  Unlike most other 
-               Altus Metrum products, EasyMotor does not work with 
-               single-cell LiPo batteries.  That's because commonly
+               In addition to the circuit board itself, EasyMotor needs
+               a power switch and battery to operate. Unlike most other
+               Altus Metrum products, EasyMotor does not work with
+               single-cell LiPo batteries. That's because commonly
                available inexpensive pressure sensors need 5V, which is
-               more than a single-cell LiPo provides.  Any battery that
-               provides from 6.5 to about 15 volts should work.  Good 
-               choices are the common 9V alkaline battery, or the very 
+               more than a single-cell LiPo provides. Any battery that
+               provides from 6.5 to about 15 volts should work. Good
+               choices are the common 9V alkaline battery, or the very
                small and light A23 12V alkaline batteries.
 
-               Because he often mounts EasyMotor to the motor's forward 
-               bulkhead instead of to the airframe itself, Bdale often 
-               uses a length of "shooter wire" from an e-match or used 
-               motor igniter as a power switch, routing the wire out of 
-               the typical fin can vent hole and using "twist and tape" 
-               to power up the board.  Whatever works!
+               Because he often mounts EasyMotor to the motor's forward
+               bulkhead instead of to the airframe itself, Bdale often
+               uses a length of “shooter wire” from an e-match or used
+               motor igniter as a power switch, routing the wire out of
+               the typical fin can vent hole and using “twist and tape”
+               to power up the board. Whatever works!
 
        === Pressure Sensor
 
                The primary motivation for designing EasyMotor was to have
                a reliable way of recording motor chamber pressure during
-               flight.  To that end, EasyMotor supports attachment of a
-               low-cost analog pressure sensor.  The board provides 5V
-               to power the sensor, and an input for measuring and 
+               flight. To that end, EasyMotor supports attachment of a
+               low-cost analog pressure sensor. The board provides 5V
+               to power the sensor, and an input for measuring and
                logging the output voltage from the sensor.
 
                The kind of sensor EasyMotor is designed to work with
                takes 5V in and has a linear analog output that ranges
                from 0.5V at 0 to 4.5V at the maximum pressure supported
-               by the sensor.  Very inexpensive sensors that have a 
-               "1/8 NPT" threaded input, a "Buick-style" 3-pin connector,
-               and typically ship with a short cable and mating 
+               by the sensor. Very inexpensive sensors that have a
+               “1/8 NPT” threaded input, a “Buick-style” 3-pin connector,
+               and typically ship with a short cable and mating
                connector, are readily available on eBay and AliExpress.
 
                To log in-flight chamber pressure, a typical approach
-               might be to drill a 1/8" sampling hole all the way 
+               might be to drill a 1/8" sampling hole all the way
                through the center of the motor's forward closure, then
-               drill and tap partially through the closure with a "1/8
-               NPT" pipe tap.  Fill the touch hole with grease, screw in 
-               the pressure sensor, and attach the sensor leads to 
+               drill and tap partially through the closure with a 1/8
+               NPT” pipe tap. Fill the touch hole with grease, screw in
+               the pressure sensor, and attach the sensor leads to
                EasyMotor.
index 9a8ea6deb4a239ce47a5c2037bcd3a65f0f20242..fa30cb98cf47e42a44257d242e0970013dd77467 100644 (file)
@@ -1,25 +1,26 @@
 == Introduction and Overview
 
-Welcome to the Altus Metrum community!  Our circuits and software reflect
-our passion for both hobby rocketry and Free Software.  We hope their
+Welcome to the Altus Metrum community! Our circuits and software reflect
+our passion for both hobby rocketry and Free Software. We hope their
 capabilities and performance will delight you in every way, but by
 releasing all of our hardware and software designs under open licenses,
 we also hope to empower you to take as active a role in our collective
 future as you wish!
 
-Thank you for your interest in EasyMotor, an in-flight motor data collection
-board for hobby rockets.  EasyMotor is a small circuit board that is meant
-to log motor chamber pressure and rocket acceleration during flight.  With
+Thank you for your interest in motor testing products from Altus Metrum.
+Our first such product is EasyMotor, an in-flight motor data collection
+board for hobby rockets. EasyMotor is a small circuit board that is meant
+to log motor chamber pressure and rocket acceleration during flight. With
 this data it's possible to determine whether a research motor is performing 
-as expected.  With additional information about masses and airframe drag, 
+as expected. With additional information about masses and airframe drag, 
 it is even possible to closely estimate complete motor performance.
 
-With EasyMotor, the dilemma of "do I burn this on a test stand to learn more 
-about how it actually works, or do I go fly it" is no more!  You can fly your
+With EasyMotor, the dilemma of do I burn this on a test stand to learn more 
+about how it actually works, or do I go fly it” is no more! You can fly your
 motor and get real performance data about it too!
 
-Because documentation is just as prone as software to contain "bugs", and
-can always be improved...  If you have questions that aren't answered in this 
+Because documentation is just as prone as software to contain “bugs”, and
+can always be improved If you have questions that aren't answered in this 
 manual, or just need a little help figuring things out, we strongly suggest 
 joining the Altus Metrum user email list, which you can do by visiting 
 https://lists.gag.com/mailman/listinfo/altusmetrum.
index da0220f2d6c21261eb79ef0c9c3764404f12ad97..e38fbe3a2dd79a85ccea960f187634f06d983008 100644 (file)
@@ -1,15 +1,14 @@
 == Operation
 
-       Operating an EasyMotor board is pretty easy.  Turn the power on
+       Operating an EasyMotor board is pretty easy. Turn the power on
        before launch, typically during the usual pre-flight electronics
-       checklist after the rocket is installed on a launch rail.  
+       checklist after the rocket is installed on a launch rail.
 
-       The board will beep out a Morse code "P" every few seconds 
+       The board will beep out a Morse code “P” every few seconds
        indicating that it's in pad mode and ready to detect launch.
        Once launch is detected, the board logs pressure and acceleration
        data 100 times per second throughout the flight.
 
        After flight, AltosUI can be used to download the flight data,
-       then export it to a comma separated values (CSV) file.  Such a
+       then export it to a comma separated values (CSV) file. Such a
        file can easily be loaded into a spreadsheet for analysis.
-
diff --git a/doc/release-notes-1.9.7.inc b/doc/release-notes-1.9.7.inc
new file mode 100644 (file)
index 0000000..95512df
--- /dev/null
@@ -0,0 +1,23 @@
+= Release Notes for Version 1.9.7
+include::release-head.adoc[]
+:doctype: article
+
+       Version 1.9.7
+
+       == AltOS
+
+       * Add EasyMotor support
+
+       == AltosUI
+
+       * Add EasyMotor support
+
+       * Support Mac OS X 11 (Big Sur)
+
+       * Support Monitor Idle on Easy Timer and Easy Motor
+
+       * Fix TeleMega v4.0 configuration in Antenna Down mode.
+
+       * Show launch sites in Load Maps view
+
+       * Add IMU header names to CSV files
index 2348c4ac8a7a496fbc3a92cfa07df07292b4ad9b..7a4c3348451221608b3c40ca75b8e6c907a0296f 100644 (file)
@@ -1,5 +1,9 @@
 [appendix]
 == Release Notes
+       :leveloffset: 2
+       include::release-notes-1.9.7.adoc[]
+
+       <<<<
        :leveloffset: 2
        include::release-notes-1.9.6.adoc[]
 
index 5c2c83cc626e5eccaf68b77b8883d931cdc52693..639a2b9a85d38420ff5de6e85d83064beaca9143 100644 (file)
        |3.7-12V
        endif::easytimer[]
        
+       ifdef::easymotor[]
+       |EasyMotor v2.0
+       |-
+       |ADXL375 200g
+       |-
+       |-
+       |-
+       |-
+       |6.5-15V
+       endif::easymotor[]
+       
        
        |===
 
        endif::easymega[]
 
        ifdef::easytimer[]
-       |EasyMini
+       |EasyTimer
        |Debug USB Battery
        |Pyro A Pyro B Battery
        |0.8 inch (2.03cm)
        |24mm coupler
        endif::easytimer[]
 
+       ifdef::easymotor[]
+       |EasyMotor
+       |Debug USB
+       |+5V Pres GND Switch Battery
+       |0.8 inch (2.03cm)
+       |1½ inch (3.81cm)
+       |24mm coupler
+       endif::easymotor[]
+
        |===
index 03d3ed76a1955c79e2669538ddf254a2c3042da4..c87b10e45205a3aa52b2f59310bf5d40b4e6a730 100644 (file)
@@ -1,5 +1,9 @@
 [appendix]
 == Release Notes
+       :leveloffset: 2
+       include::release-notes-1.9.7.adoc[]
+
+       <<<<
        :leveloffset: 2
        include::release-notes-1.9.6.adoc[]
 
index 145a260ba76c07cfcb7dffb469b6191049f4d556..aa96638f5cf9822d1ca1fda58eccc6579903a4f2 100755 (executable)
@@ -1,16 +1,4 @@
 #!/bin/bash
-#
-# Fix fonts. I don't know why the getting the
-# basename of the app set to . matters, but it does
-#
-case "$0" in
-    /*)
-        cd `dirname "$0"`
-        ./`basename "$0"` "$@"
-        exit $?
-        ;;
-esac
-export FREETYPE_PROPERTIES=truetype:interpreter-version=35
 ##################################################################################
 #                                                                                #
 # universalJavaApplicationStub                                                   #
@@ -23,14 +11,14 @@ export FREETYPE_PROPERTIES=truetype:interpreter-version=35
 #                                                                                #
 # @author    Tobias Fischer                                                      #
 # @url       https://github.com/tofi86/universalJavaApplicationStub              #
-# @date      2018-08-24                                                          #
-# @version   3.0.4                                                               #
+# @date      2021-02-21                                                          #
+# @version   3.2.0                                                               #
 #                                                                                #
 ##################################################################################
 #                                                                                #
 # The MIT License (MIT)                                                          #
 #                                                                                #
-# Copyright (c) 2014-2018 Tobias Fischer                                         #
+# Copyright (c) 2014-2021 Tobias Fischer                                         #
 #                                                                                #
 # Permission is hereby granted, free of charge, to any person obtaining a copy   #
 # of this software and associated documentation files (the "Software"), to deal  #
@@ -52,7 +40,18 @@ export FREETYPE_PROPERTIES=truetype:interpreter-version=35
 #                                                                                #
 ##################################################################################
 
-
+#
+# Fix fonts. I don't know why the getting the
+# basename of the app set to . matters, but it does
+#
+case "$0" in
+    /*)
+        cd `dirname "$0"`
+        ./`basename "$0"` "$@"
+        exit $?
+        ;;
+esac
+export FREETYPE_PROPERTIES=truetype:interpreter-version=35
 
 # function 'stub_logger()'
 #
@@ -178,6 +177,8 @@ if [ $exitcode -eq 0 ]; then
        JavaFolder="${AppleJavaFolder}"
        ResourcesFolder="${AppleResourcesFolder}"
 
+       # set expandable variables
+       APP_ROOT="${AppPackageFolder}"
        APP_PACKAGE="${AppPackageFolder}"
        JAVAROOT="${AppleJavaFolder}"
        USER_HOME="$HOME"
@@ -192,7 +193,7 @@ if [ $exitcode -eq 0 ]; then
                # AppPackageRoot is the standard WorkingDirectory when the script is started
                WorkingDirectory="${AppPackageRoot}"
        fi
-       # expand variables $APP_PACKAGE, $JAVAROOT, $USER_HOME
+       # expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
        WorkingDirectory=$(eval echo "${WorkingDirectory}")
 
 
@@ -215,7 +216,7 @@ if [ $exitcode -eq 0 ]; then
        else
                JVMClassPath=${JVMClassPath_RAW}
        fi
-       # expand variables $APP_PACKAGE, $JAVAROOT, $USER_HOME
+       # expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
        JVMClassPath=$(eval echo "${JVMClassPath}")
 
        # read the JVM Options in either Array or String style
@@ -225,6 +226,8 @@ if [ $exitcode -eq 0 ]; then
        else
                JVMDefaultOptions=${JVMDefaultOptions_RAW}
        fi
+       # expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME (#84)
+       JVMDefaultOptions=$(eval echo "${JVMDefaultOptions}")
 
        # read StartOnMainThread and add as -XstartOnFirstThread
        JVMStartOnMainThread=$(plist_get_java ':StartOnMainThread')
@@ -232,9 +235,14 @@ if [ $exitcode -eq 0 ]; then
                JVMDefaultOptions+=" -XstartOnFirstThread"
        fi
 
-       # read the JVM Arguments as an array and retain spaces
+       # read the JVM Arguments in either Array or String style (#76) and retain spaces
        IFS=$'\t\n'
-       MainArgs=($(xargs -n1 <<<$(plist_get_java ':Arguments')))
+       MainArgs_RAW=$(plist_get_java ':Arguments' | xargs)
+       if [[ $MainArgs_RAW == *Array* ]] ; then
+               MainArgs=($(xargs -n1 <<<$(plist_get_java ':Arguments' | tr -d '\n' | sed -E 's/Array \{ *(.*) *\}/\1/g' | sed 's/  */ /g')))
+       else
+               MainArgs=($(xargs -n1 <<<$(plist_get_java ':Arguments')))
+       fi
        unset IFS
        # post processing of the array follows further below...
 
@@ -252,7 +260,11 @@ else
        ResourcesFolder="${OracleResourcesFolder}"
        WorkingDirectory="${OracleJavaFolder}"
 
+       # set expandable variables
        APP_ROOT="${AppPackageFolder}"
+       APP_PACKAGE="${AppPackageFolder}"
+       JAVAROOT="${OracleJavaFolder}"
+       USER_HOME="$HOME"
 
        # read the MainClass name
        JVMMainClass="$(plist_get ':JVMMainClassName')"
@@ -270,12 +282,12 @@ else
        JVMClassPath_RAW=$(plist_get ':JVMClassPath')
        if [[ $JVMClassPath_RAW == *Array* ]] ; then
                JVMClassPath=.$(plist_get ':JVMClassPath' | grep "    " | sed 's/^ */:/g' | tr -d '\n' | xargs)
-               # expand variables $APP_PACKAGE, $JAVAROOT, $USER_HOME
+               # expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
                JVMClassPath=$(eval echo "${JVMClassPath}")
 
        elif [[ ! -z ${JVMClassPath_RAW} ]] ; then
                JVMClassPath=${JVMClassPath_RAW}
-               # expand variables $APP_PACKAGE, $JAVAROOT, $USER_HOME
+               # expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
                JVMClassPath=$(eval echo "${JVMClassPath}")
 
        else
@@ -284,8 +296,11 @@ else
                # Do NOT expand the default 'AppName.app/Contents/Java/*' classpath (#42)
        fi
 
-       # read the JVM Default Options
+       # read the JVM Default Options by parsing the :JVMDefaultOptions <dict>
+       # and pulling all <string> values starting with a dash (-)
        JVMDefaultOptions=$(plist_get ':JVMDefaultOptions' | grep -o " \-.*" | tr -d '\n' | xargs)
+       # expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME (#99)
+       JVMDefaultOptions=$(eval echo "${JVMDefaultOptions}")
 
        # read the Main Arguments from JVMArguments key as an array and retain spaces (see #46 for naming details)
        IFS=$'\t\n'
@@ -299,6 +314,18 @@ else
 fi
 
 
+# (#75) check for undefined icons or icon names without .icns extension and prepare
+# an osascript statement for those cases when the icon can be shown in the dialog
+DialogWithIcon=""
+if [ ! -z ${CFBundleIconFile} ]; then
+       if [[ ${CFBundleIconFile} == *.icns ]] && [[ -f "${ResourcesFolder}/${CFBundleIconFile}" ]] ; then
+               DialogWithIcon=" with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)"
+       elif [[ ${CFBundleIconFile} != *.icns ]] && [[ -f "${ResourcesFolder}/${CFBundleIconFile}.icns" ]] ; then
+               CFBundleIconFile+=".icns"
+               DialogWithIcon=" with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)"
+       fi
+fi
+
 
 # JVMVersion: post processing and optional splitting
 if [[ ${JVMVersion} == *";"* ]]; then
@@ -309,14 +336,14 @@ fi
 stub_logger "[JavaRequirement] JVM minimum version: ${JVMVersion}"
 stub_logger "[JavaRequirement] JVM maximum version: ${JVMMaxVersion}"
 
-# MainArgs: replace occurences of $APP_ROOT with its content
+# MainArgs: expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
 MainArgsArr=()
 for i in "${MainArgs[@]}"
 do
        MainArgsArr+=("$(eval echo "$i")")
 done
 
-# JVMOptions: replace occurences of $APP_ROOT with its content
+# JVMOptions: expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
 JVMOptionsArr=()
 for i in "${JVMOptions[@]}"
 do
@@ -327,14 +354,37 @@ done
 # internationalized messages
 ############################################
 
-LANG=$(defaults read -g AppleLocale)
-stub_logger "[Language] $LANG"
+# supported languages / available translations
+stubLanguages="^(fr|de|zh|es|en)-"
+
+# read user preferred languages as defined in macOS System Preferences (#101)
+stub_logger '[LanguageSearch] Checking preferred languages in macOS System Preferences...'
+appleLanguages=($(defaults read -g AppleLanguages | grep '\s"' | tr -d ',' | xargs))
+stub_logger "[LanguageSearch] ... found [${appleLanguages[*]}]"
+
+language=""
+for i in "${appleLanguages[@]}"
+do
+       langValue="${i%-*}"
+    if [[ "$i" =~ $stubLanguages ]]; then 
+               stub_logger "[LanguageSearch] ... selected '$i' ('$langValue') as the default language for the launcher stub"
+               language=${langValue}
+        break
+       fi
+done
+if [ -z "${language}" ]; then
+    language="en"
+    stub_logger "[LanguageSearch] ... selected fallback 'en' as the default language for the launcher stub"
+fi
+stub_logger "[Language] $language"
 
-# French localization
-if [[ $LANG == fr* ]] ; then
+
+case "${language}" in
+# French
+fr)
        MSG_ERROR_LAUNCHING="ERREUR au lancement de '${CFBundleName}'."
        MSG_MISSING_MAINCLASS="'MainClass' n'est pas spécifié.\nL'application Java ne peut pas être lancée."
-       MSG_JVMVERSION_REQ_INVALID="La syntaxe de la version Java demandée est invalide: %s\nVeuillez contacter le développeur de l'application."
+       MSG_JVMVERSION_REQ_INVALID="La syntaxe de la version de Java demandée est invalide: %s\nVeuillez contacter le développeur de l'application."
        MSG_NO_SUITABLE_JAVA="La version de Java installée sur votre système ne convient pas.\nCe programme nécessite Java %s"
        MSG_JAVA_VERSION_OR_LATER="ou ultérieur"
        MSG_JAVA_VERSION_LATEST="(dernière mise à jour)"
@@ -342,10 +392,12 @@ if [[ $LANG == fr* ]] ; then
        MSG_NO_SUITABLE_JAVA_CHECK="Merci de bien vouloir installer la version de Java requise."
        MSG_INSTALL_JAVA="Java doit être installé sur votre système.\nRendez-vous sur java.com et suivez les instructions d'installation..."
        MSG_LATER="Plus tard"
-       MSG_VISIT_JAVA_DOT_COM="Visiter java.com"
+       MSG_VISIT_JAVA_DOT_COM="Java by Oracle"
+       MSG_VISIT_ADOPTOPENJDK="Java by AdoptOpenJDK"
+    ;;
 
-# German localization
-elif [[ $LANG == de* ]] ; then
+# German
+de)
        MSG_ERROR_LAUNCHING="FEHLER beim Starten von '${CFBundleName}'."
        MSG_MISSING_MAINCLASS="Die 'MainClass' ist nicht spezifiziert!\nDie Java-Anwendung kann nicht gestartet werden!"
        MSG_JVMVERSION_REQ_INVALID="Die Syntax der angeforderten Java-Version ist ungültig: %s\nBitte kontaktieren Sie den Entwickler der App."
@@ -356,10 +408,12 @@ elif [[ $LANG == de* ]] ; then
        MSG_NO_SUITABLE_JAVA_CHECK="Stellen Sie sicher, dass die angeforderte Java-Version installiert ist."
        MSG_INSTALL_JAVA="Auf Ihrem System muss die 'Java'-Software installiert sein.\nBesuchen Sie java.com für weitere Installationshinweise."
        MSG_LATER="Später"
-       MSG_VISIT_JAVA_DOT_COM="java.com öffnen"
+       MSG_VISIT_JAVA_DOT_COM="Java von Oracle"
+       MSG_VISIT_ADOPTOPENJDK="Java von AdoptOpenJDK"
+    ;;
 
-# Simplifyed Chinese localization
-elif [[ $LANG == zh* ]] ; then
+# Simplified Chinese
+zh)
        MSG_ERROR_LAUNCHING="无法启动 '${CFBundleName}'."
        MSG_MISSING_MAINCLASS="没有指定 'MainClass'!\nJava程序无法启动!"
        MSG_JVMVERSION_REQ_INVALID="Java版本参数语法错误: %s\n请联系该应用的开发者。"
@@ -370,10 +424,28 @@ elif [[ $LANG == zh* ]] ; then
        MSG_NO_SUITABLE_JAVA_CHECK="请确保系统中安装了所需的Java版本"
        MSG_INSTALL_JAVA="你需要在Mac中安装Java运行环境!\n访问 java.com 了解如何安装。"
        MSG_LATER="稍后"
-       MSG_VISIT_JAVA_DOT_COM="访问 java.com"
-
-# English default localization
-else
+       MSG_VISIT_JAVA_DOT_COM="Java by Oracle"
+       MSG_VISIT_ADOPTOPENJDK="Java by AdoptOpenJDK"
+    ;;
+
+# Spanish
+es)
+       MSG_ERROR_LAUNCHING="ERROR iniciando '${CFBundleName}'."
+       MSG_MISSING_MAINCLASS="¡'MainClass' no especificada!\n¡La aplicación Java no puede iniciarse!"
+       MSG_JVMVERSION_REQ_INVALID="La sintaxis de la versión Java requerida no es válida: %s\nPor favor, contacte con el desarrollador de la aplicación."
+       MSG_NO_SUITABLE_JAVA="¡No se encontró una versión de Java adecuada en su sistema!\nEste programa requiere Java %s"
+       MSG_JAVA_VERSION_OR_LATER="o posterior"
+       MSG_JAVA_VERSION_LATEST="(ultima actualización)"
+       MSG_JAVA_VERSION_MAX="superior a %s"
+       MSG_NO_SUITABLE_JAVA_CHECK="Asegúrese de instalar la versión Java requerida."
+       MSG_INSTALL_JAVA="¡Necesita tener JAVA instalado en su Mac!\nVisite java.com para consultar las instrucciones para su instalación..."
+       MSG_LATER="Más tarde"
+       MSG_VISIT_JAVA_DOT_COM="Java de Oracle"
+       MSG_VISIT_ADOPTOPENJDK="Java de AdoptOpenJDK"
+    ;;
+
+# English | default
+en|*)
        MSG_ERROR_LAUNCHING="ERROR launching '${CFBundleName}'."
        MSG_MISSING_MAINCLASS="'MainClass' isn't specified!\nJava application cannot be started!"
        MSG_JVMVERSION_REQ_INVALID="The syntax of the required Java version is invalid: %s\nPlease contact the App developer."
@@ -384,8 +456,10 @@ else
        MSG_NO_SUITABLE_JAVA_CHECK="Make sure you install the required Java version."
        MSG_INSTALL_JAVA="You need to have JAVA installed on your Mac!\nVisit java.com for installation instructions..."
        MSG_LATER="Later"
-       MSG_VISIT_JAVA_DOT_COM="Visit java.com"
-fi
+       MSG_VISIT_JAVA_DOT_COM="Java by Oracle"
+       MSG_VISIT_ADOPTOPENJDK="Java by AdoptOpenJDK"
+    ;;
+esac
 
 
 
@@ -468,7 +542,7 @@ function get_comparable_java_version() {
 ################################################################################
 function is_valid_requirement_pattern() {
        local java_req=$1
-       java8pattern='1\.[4-8](\.0)?(\.0_[0-9]+)?[*+]?'
+       java8pattern='1\.[4-8](\.[0-9]+)?(\.0_[0-9]+)?[*+]?'
        java9pattern='(9|1[0-9])(-ea|[*+]|(\.[0-9]+){1,2}[*+]?)?'
        # test matches either old Java versioning scheme (up to 1.8) or new scheme (starting with 9)
        if [[ ${java_req} =~ ^(${java8pattern}|${java9pattern})$ ]]; then
@@ -501,20 +575,28 @@ if [ -n "$JAVA_HOME" ] ; then
        if [[ $JAVA_HOME == /* ]] ; then
                # if "$JAVA_HOME" starts with a Slash it's an absolute path
                JAVACMD="$JAVA_HOME/bin/java"
+               stub_logger "[JavaSearch] ... parsing JAVA_HOME as absolute path to the executable '$JAVACMD'"
        else
                # otherwise it's a relative path to "$AppPackageFolder"
                JAVACMD="$AppPackageFolder/$JAVA_HOME/bin/java"
+               stub_logger "[JavaSearch] ... parsing JAVA_HOME as relative path inside the App bundle to the executable '$JAVACMD'"
        fi
        JAVACMD_version=$(get_comparable_java_version $(get_java_version_from_cmd "${JAVACMD}"))
 else
-       stub_logger "[JavaSearch] ... didn't found JAVA_HOME"
+       stub_logger "[JavaSearch] ... haven't found JAVA_HOME"
 fi
 
 
 # check for any other or a specific Java version
 # also if $JAVA_HOME exists but isn't executable
 if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
-       stub_logger "[JavaSearch] Checking for JavaVirtualMachines on the system ..."
+
+       # add a warning in the syslog if JAVA_HOME is not executable or not found (#100)
+       if [ -n "$JAVA_HOME" ] ; then
+               stub_logger "[JavaSearch] ... but no 'java' executable was found at the JAVA_HOME location!"
+       fi
+
+       stub_logger "[JavaSearch] Searching for JavaVirtualMachines on the system ..."
        # reset variables
        JAVACMD=""
        JAVACMD_version=""
@@ -525,7 +607,7 @@ if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
                # log exit cause
                stub_logger "[EXIT 4] ${MSG_JVMVERSION_REQ_INVALID_EXPANDED}"
                # display error message with AppleScript
-               osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_JVMVERSION_REQ_INVALID_EXPANDED}\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1 with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)"
+               osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_JVMVERSION_REQ_INVALID_EXPANDED}\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1${DialogWithIcon}"
                # exit with error
                exit 4
        fi
@@ -535,7 +617,7 @@ if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
                # log exit cause
                stub_logger "[EXIT 5] ${MSG_JVMVERSION_REQ_INVALID_EXPANDED}"
                # display error message with AppleScript
-               osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_JVMVERSION_REQ_INVALID_EXPANDED}\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1 with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)"
+               osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_JVMVERSION_REQ_INVALID_EXPANDED}\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1${DialogWithIcon}"
                # exit with error
                exit 5
        fi
@@ -543,15 +625,41 @@ if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
 
        # find installed JavaVirtualMachines (JDK + JRE)
        allJVMs=()
-       # read JDK's from '/usr/libexec/java_home -V' command
-       while read -r line; do
-               version=$(echo $line | awk -F $',' '{print $1;}')
-               path=$(echo $line | awk -F $'" ' '{print $2;}')
-               path+="/bin/java"
-               allJVMs+=("$version:$path")
-       done < <(/usr/libexec/java_home -V 2>&1 | grep '^[[:space:]]')
-       # unset while loop variables
-       unset version path
+       
+       # read JDK's from '/usr/libexec/java_home --xml' command with PlistBuddy and a custom Dict iterator
+       # idea: https://stackoverflow.com/a/14085460/1128689 and https://scriptingosx.com/2018/07/parsing-dscl-output-in-scripts/
+       javaXml=$(/usr/libexec/java_home --xml)
+       javaCounter=$(/usr/libexec/PlistBuddy -c "Print" /dev/stdin <<< $javaXml | grep "Dict" | wc -l | tr -d ' ')
+
+       # iterate over all Dict entries
+       # but only if there are any JVMs at all (#93)
+       if [ "$javaCounter" -gt "0" ] ; then
+               for idx in $(seq 0 $((javaCounter - 1)))
+               do
+                       version=$(/usr/libexec/PlistBuddy -c "print :$idx:JVMVersion" /dev/stdin <<< $javaXml)
+                       path=$(/usr/libexec/PlistBuddy -c "print :$idx:JVMHomePath" /dev/stdin <<< $javaXml)
+                       path+="/bin/java"
+                       allJVMs+=("$version:$path")
+               done
+               # unset for loop variables
+               unset version path
+       fi
+
+       # add SDKMAN! java versions (#95)
+       if [ -d ~/.sdkman/candidates/java/ ] ; then
+               for sdkjdk in ~/.sdkman/candidates/java/*/
+               do
+                       if [[ ${sdkjdk} =~ /current/$ ]] ; then
+                               continue
+                       fi
+
+                       sdkjdkcmd="${sdkjdk}bin/java"
+                       version=$(get_java_version_from_cmd "${sdkjdkcmd}")
+                       allJVMs+=("$version:$sdkjdkcmd")
+               done
+               # unset for loop variables
+               unset version
+       fi
 
        # add Apple JRE if available
        if [ -x "${apple_jre_plugin}" ] ; then
@@ -571,6 +679,9 @@ if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
 
 
        # determine JVMs matching the min/max version requirement
+
+       stub_logger "[JavaSearch] Filtering the result list for JVMs matching the min/max version requirement ..."
+
        minC=$(get_comparable_java_version ${JVMVersion})
        maxC=$(get_comparable_java_version ${JVMMaxVersion})
        matchingJVMs=()
@@ -655,7 +766,7 @@ if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
        # debug output
        for i in "${matchingJVMs[@]}"
        do
-               stub_logger "[JavaSearch] ... ... matches all requirements: $i"
+               stub_logger "[JavaSearch] ... matches all requirements: $i"
        done
 
 
@@ -692,7 +803,13 @@ fi
 stub_logger "[JavaCommand] '$JAVACMD'"
 stub_logger "[JavaVersion] $(get_java_version_from_cmd "${JAVACMD}")${JAVACMD_version:+ / $JAVACMD_version}"
 
+# Make sure tabbing mode is disabled for the selected java version
+
+CFBundleIdentifier=net.java.openjdk.$(get_java_version_from_cmd "${JAVACMD}").java
 
+if [ x$(defaults read ${CFBundleIdentifier} AppleWindowTabbingMode) != "xnever" ]; then
+    defaults write ${CFBundleIdentifier} AppleWindowTabbingMode never
+fi
 
 if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
 
@@ -712,9 +829,10 @@ if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
                stub_logger "[EXIT 3] ${MSG_NO_SUITABLE_JAVA_EXPANDED}"
 
                # display error message with AppleScript
-               osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_NO_SUITABLE_JAVA_EXPANDED}\n${MSG_NO_SUITABLE_JAVA_CHECK}\" with title \"${CFBundleName}\"  buttons {\" OK \", \"${MSG_VISIT_JAVA_DOT_COM}\"} default button \"${MSG_VISIT_JAVA_DOT_COM}\" with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)" \
+               osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_NO_SUITABLE_JAVA_EXPANDED}\n${MSG_NO_SUITABLE_JAVA_CHECK}\" with title \"${CFBundleName}\"  buttons {\" OK \", \"${MSG_VISIT_JAVA_DOT_COM}\", \"${MSG_VISIT_ADOPTOPENJDK}\"} default button 1${DialogWithIcon}" \
                                -e "set response to button returned of the result" \
-                               -e "if response is \"${MSG_VISIT_JAVA_DOT_COM}\" then open location \"http://java.com\""
+                               -e "if response is \"${MSG_VISIT_JAVA_DOT_COM}\" then open location \"https://www.java.com/download/\"" \
+                               -e "if response is \"${MSG_VISIT_ADOPTOPENJDK}\" then open location \"https://adoptopenjdk.net/releases.html\""
                # exit with error
                exit 3
 
@@ -722,9 +840,10 @@ if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
                # log exit cause
                stub_logger "[EXIT 1] ${MSG_ERROR_LAUNCHING}"
                # display error message with AppleScript
-               osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_INSTALL_JAVA}\" with title \"${CFBundleName}\" buttons {\"${MSG_LATER}\", \"${MSG_VISIT_JAVA_DOT_COM}\"} default button \"${MSG_VISIT_JAVA_DOT_COM}\" with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)" \
+               osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_INSTALL_JAVA}\" with title \"${CFBundleName}\" buttons {\"${MSG_LATER}\", \"${MSG_VISIT_JAVA_DOT_COM}\", \"${MSG_VISIT_ADOPTOPENJDK}\"} default button 1${DialogWithIcon}" \
                                        -e "set response to button returned of the result" \
-                                       -e "if response is \"${MSG_VISIT_JAVA_DOT_COM}\" then open location \"http://java.com\""
+                                       -e "if response is \"${MSG_VISIT_JAVA_DOT_COM}\" then open location \"https://www.java.com/download/\"" \
+                                       -e "if response is \"${MSG_VISIT_ADOPTOPENJDK}\" then open location \"https://adoptopenjdk.net/releases.html\""
                # exit with error
                exit 1
        fi
@@ -739,7 +858,7 @@ if [ -z "${JVMMainClass}" ]; then
        # log exit cause
        stub_logger "[EXIT 2] ${MSG_MISSING_MAINCLASS}"
        # display error message with AppleScript
-       osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_MISSING_MAINCLASS}\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1 with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)"
+       osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_MISSING_MAINCLASS}\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1${DialogWithIcon}"
        # exit with error
        exit 2
 fi
@@ -773,11 +892,11 @@ stub_logger "[WorkingDirectory] ${WorkingDirectory}"
 # - main class
 # - main class arguments
 # - passthrough arguments from Terminal or Drag'n'Drop to Finder icon
-stub_logger "[Exec] \"$JAVACMD\" -cp \"${JVMClassPath}\" -splash:\"${ResourcesFolder}/${JVMSplashFile}\" -Xdock:icon=\"${ResourcesFolder}/${CFBundleIconFile}\" -Xdock:name=\"${CFBundleName}\" ${JVMOptionsArr:+$(printf "'%s' " "${JVMOptionsArr[@]}") }${JVMDefaultOptions:+$JVMDefaultOptions }${JVMMainClass}${MainArgsArr:+ $(printf "'%s' " "${MainArgsArr[@]}")}${ArgsPassthru:+ $(printf "'%s' " "${ArgsPassthru[@]}")}"
+stub_logger "[Exec] \"$JAVACMD\" -cp \"${JVMClassPath}\" ${JVMSplashFile:+ -splash:\"${ResourcesFolder}/${JVMSplashFile}\"} -Xdock:icon=\"${ResourcesFolder}/${CFBundleIconFile}\" -Xdock:name=\"${CFBundleName}\" ${JVMOptionsArr:+$(printf "'%s' " "${JVMOptionsArr[@]}") }${JVMDefaultOptions:+$JVMDefaultOptions }${JVMMainClass}${MainArgsArr:+ $(printf "'%s' " "${MainArgsArr[@]}")}${ArgsPassthru:+ $(printf "'%s' " "${ArgsPassthru[@]}")}"
 exec "${JAVACMD}" \
                -Djava.library.path="${AppleJavaFolder}" \
                -cp "${JVMClassPath}" \
-               -splash:"${ResourcesFolder}/${JVMSplashFile}" \
+               ${JVMSplashFile:+ -splash:"${ResourcesFolder}/${JVMSplashFile}"} \
                -Xdock:icon="${ResourcesFolder}/${CFBundleIconFile}" \
                -Xdock:name="${CFBundleName}" \
                ${JVMOptionsArr:+"${JVMOptionsArr[@]}" }\
index 3443ec8ac394cbd5f630f7d678e23f5dc9239189..0b6a7e278b020c45cf4fa1f105d2947a527b411b 100644 (file)
@@ -19,6 +19,7 @@ include Makedefs
 ARMM3DIRS=\
        easymega-v1.0 easymega-v1.0/flash-loader \
        easymega-v2.0 easymega-v2.0/flash-loader \
+       easymotor-v2 easymotor-v2/flash-loader \
        easytimer-v1 easytimer-v1/flash-loader \
        telemega-v0.1 telemega-v0.1/flash-loader \
        telemega-v1.0 telemega-v1.0/flash-loader \
index 145a260ba76c07cfcb7dffb469b6191049f4d556..aa96638f5cf9822d1ca1fda58eccc6579903a4f2 100755 (executable)
@@ -1,16 +1,4 @@
 #!/bin/bash
-#
-# Fix fonts. I don't know why the getting the
-# basename of the app set to . matters, but it does
-#
-case "$0" in
-    /*)
-        cd `dirname "$0"`
-        ./`basename "$0"` "$@"
-        exit $?
-        ;;
-esac
-export FREETYPE_PROPERTIES=truetype:interpreter-version=35
 ##################################################################################
 #                                                                                #
 # universalJavaApplicationStub                                                   #
@@ -23,14 +11,14 @@ export FREETYPE_PROPERTIES=truetype:interpreter-version=35
 #                                                                                #
 # @author    Tobias Fischer                                                      #
 # @url       https://github.com/tofi86/universalJavaApplicationStub              #
-# @date      2018-08-24                                                          #
-# @version   3.0.4                                                               #
+# @date      2021-02-21                                                          #
+# @version   3.2.0                                                               #
 #                                                                                #
 ##################################################################################
 #                                                                                #
 # The MIT License (MIT)                                                          #
 #                                                                                #
-# Copyright (c) 2014-2018 Tobias Fischer                                         #
+# Copyright (c) 2014-2021 Tobias Fischer                                         #
 #                                                                                #
 # Permission is hereby granted, free of charge, to any person obtaining a copy   #
 # of this software and associated documentation files (the "Software"), to deal  #
@@ -52,7 +40,18 @@ export FREETYPE_PROPERTIES=truetype:interpreter-version=35
 #                                                                                #
 ##################################################################################
 
-
+#
+# Fix fonts. I don't know why the getting the
+# basename of the app set to . matters, but it does
+#
+case "$0" in
+    /*)
+        cd `dirname "$0"`
+        ./`basename "$0"` "$@"
+        exit $?
+        ;;
+esac
+export FREETYPE_PROPERTIES=truetype:interpreter-version=35
 
 # function 'stub_logger()'
 #
@@ -178,6 +177,8 @@ if [ $exitcode -eq 0 ]; then
        JavaFolder="${AppleJavaFolder}"
        ResourcesFolder="${AppleResourcesFolder}"
 
+       # set expandable variables
+       APP_ROOT="${AppPackageFolder}"
        APP_PACKAGE="${AppPackageFolder}"
        JAVAROOT="${AppleJavaFolder}"
        USER_HOME="$HOME"
@@ -192,7 +193,7 @@ if [ $exitcode -eq 0 ]; then
                # AppPackageRoot is the standard WorkingDirectory when the script is started
                WorkingDirectory="${AppPackageRoot}"
        fi
-       # expand variables $APP_PACKAGE, $JAVAROOT, $USER_HOME
+       # expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
        WorkingDirectory=$(eval echo "${WorkingDirectory}")
 
 
@@ -215,7 +216,7 @@ if [ $exitcode -eq 0 ]; then
        else
                JVMClassPath=${JVMClassPath_RAW}
        fi
-       # expand variables $APP_PACKAGE, $JAVAROOT, $USER_HOME
+       # expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
        JVMClassPath=$(eval echo "${JVMClassPath}")
 
        # read the JVM Options in either Array or String style
@@ -225,6 +226,8 @@ if [ $exitcode -eq 0 ]; then
        else
                JVMDefaultOptions=${JVMDefaultOptions_RAW}
        fi
+       # expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME (#84)
+       JVMDefaultOptions=$(eval echo "${JVMDefaultOptions}")
 
        # read StartOnMainThread and add as -XstartOnFirstThread
        JVMStartOnMainThread=$(plist_get_java ':StartOnMainThread')
@@ -232,9 +235,14 @@ if [ $exitcode -eq 0 ]; then
                JVMDefaultOptions+=" -XstartOnFirstThread"
        fi
 
-       # read the JVM Arguments as an array and retain spaces
+       # read the JVM Arguments in either Array or String style (#76) and retain spaces
        IFS=$'\t\n'
-       MainArgs=($(xargs -n1 <<<$(plist_get_java ':Arguments')))
+       MainArgs_RAW=$(plist_get_java ':Arguments' | xargs)
+       if [[ $MainArgs_RAW == *Array* ]] ; then
+               MainArgs=($(xargs -n1 <<<$(plist_get_java ':Arguments' | tr -d '\n' | sed -E 's/Array \{ *(.*) *\}/\1/g' | sed 's/  */ /g')))
+       else
+               MainArgs=($(xargs -n1 <<<$(plist_get_java ':Arguments')))
+       fi
        unset IFS
        # post processing of the array follows further below...
 
@@ -252,7 +260,11 @@ else
        ResourcesFolder="${OracleResourcesFolder}"
        WorkingDirectory="${OracleJavaFolder}"
 
+       # set expandable variables
        APP_ROOT="${AppPackageFolder}"
+       APP_PACKAGE="${AppPackageFolder}"
+       JAVAROOT="${OracleJavaFolder}"
+       USER_HOME="$HOME"
 
        # read the MainClass name
        JVMMainClass="$(plist_get ':JVMMainClassName')"
@@ -270,12 +282,12 @@ else
        JVMClassPath_RAW=$(plist_get ':JVMClassPath')
        if [[ $JVMClassPath_RAW == *Array* ]] ; then
                JVMClassPath=.$(plist_get ':JVMClassPath' | grep "    " | sed 's/^ */:/g' | tr -d '\n' | xargs)
-               # expand variables $APP_PACKAGE, $JAVAROOT, $USER_HOME
+               # expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
                JVMClassPath=$(eval echo "${JVMClassPath}")
 
        elif [[ ! -z ${JVMClassPath_RAW} ]] ; then
                JVMClassPath=${JVMClassPath_RAW}
-               # expand variables $APP_PACKAGE, $JAVAROOT, $USER_HOME
+               # expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
                JVMClassPath=$(eval echo "${JVMClassPath}")
 
        else
@@ -284,8 +296,11 @@ else
                # Do NOT expand the default 'AppName.app/Contents/Java/*' classpath (#42)
        fi
 
-       # read the JVM Default Options
+       # read the JVM Default Options by parsing the :JVMDefaultOptions <dict>
+       # and pulling all <string> values starting with a dash (-)
        JVMDefaultOptions=$(plist_get ':JVMDefaultOptions' | grep -o " \-.*" | tr -d '\n' | xargs)
+       # expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME (#99)
+       JVMDefaultOptions=$(eval echo "${JVMDefaultOptions}")
 
        # read the Main Arguments from JVMArguments key as an array and retain spaces (see #46 for naming details)
        IFS=$'\t\n'
@@ -299,6 +314,18 @@ else
 fi
 
 
+# (#75) check for undefined icons or icon names without .icns extension and prepare
+# an osascript statement for those cases when the icon can be shown in the dialog
+DialogWithIcon=""
+if [ ! -z ${CFBundleIconFile} ]; then
+       if [[ ${CFBundleIconFile} == *.icns ]] && [[ -f "${ResourcesFolder}/${CFBundleIconFile}" ]] ; then
+               DialogWithIcon=" with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)"
+       elif [[ ${CFBundleIconFile} != *.icns ]] && [[ -f "${ResourcesFolder}/${CFBundleIconFile}.icns" ]] ; then
+               CFBundleIconFile+=".icns"
+               DialogWithIcon=" with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)"
+       fi
+fi
+
 
 # JVMVersion: post processing and optional splitting
 if [[ ${JVMVersion} == *";"* ]]; then
@@ -309,14 +336,14 @@ fi
 stub_logger "[JavaRequirement] JVM minimum version: ${JVMVersion}"
 stub_logger "[JavaRequirement] JVM maximum version: ${JVMMaxVersion}"
 
-# MainArgs: replace occurences of $APP_ROOT with its content
+# MainArgs: expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
 MainArgsArr=()
 for i in "${MainArgs[@]}"
 do
        MainArgsArr+=("$(eval echo "$i")")
 done
 
-# JVMOptions: replace occurences of $APP_ROOT with its content
+# JVMOptions: expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
 JVMOptionsArr=()
 for i in "${JVMOptions[@]}"
 do
@@ -327,14 +354,37 @@ done
 # internationalized messages
 ############################################
 
-LANG=$(defaults read -g AppleLocale)
-stub_logger "[Language] $LANG"
+# supported languages / available translations
+stubLanguages="^(fr|de|zh|es|en)-"
+
+# read user preferred languages as defined in macOS System Preferences (#101)
+stub_logger '[LanguageSearch] Checking preferred languages in macOS System Preferences...'
+appleLanguages=($(defaults read -g AppleLanguages | grep '\s"' | tr -d ',' | xargs))
+stub_logger "[LanguageSearch] ... found [${appleLanguages[*]}]"
+
+language=""
+for i in "${appleLanguages[@]}"
+do
+       langValue="${i%-*}"
+    if [[ "$i" =~ $stubLanguages ]]; then 
+               stub_logger "[LanguageSearch] ... selected '$i' ('$langValue') as the default language for the launcher stub"
+               language=${langValue}
+        break
+       fi
+done
+if [ -z "${language}" ]; then
+    language="en"
+    stub_logger "[LanguageSearch] ... selected fallback 'en' as the default language for the launcher stub"
+fi
+stub_logger "[Language] $language"
 
-# French localization
-if [[ $LANG == fr* ]] ; then
+
+case "${language}" in
+# French
+fr)
        MSG_ERROR_LAUNCHING="ERREUR au lancement de '${CFBundleName}'."
        MSG_MISSING_MAINCLASS="'MainClass' n'est pas spécifié.\nL'application Java ne peut pas être lancée."
-       MSG_JVMVERSION_REQ_INVALID="La syntaxe de la version Java demandée est invalide: %s\nVeuillez contacter le développeur de l'application."
+       MSG_JVMVERSION_REQ_INVALID="La syntaxe de la version de Java demandée est invalide: %s\nVeuillez contacter le développeur de l'application."
        MSG_NO_SUITABLE_JAVA="La version de Java installée sur votre système ne convient pas.\nCe programme nécessite Java %s"
        MSG_JAVA_VERSION_OR_LATER="ou ultérieur"
        MSG_JAVA_VERSION_LATEST="(dernière mise à jour)"
@@ -342,10 +392,12 @@ if [[ $LANG == fr* ]] ; then
        MSG_NO_SUITABLE_JAVA_CHECK="Merci de bien vouloir installer la version de Java requise."
        MSG_INSTALL_JAVA="Java doit être installé sur votre système.\nRendez-vous sur java.com et suivez les instructions d'installation..."
        MSG_LATER="Plus tard"
-       MSG_VISIT_JAVA_DOT_COM="Visiter java.com"
+       MSG_VISIT_JAVA_DOT_COM="Java by Oracle"
+       MSG_VISIT_ADOPTOPENJDK="Java by AdoptOpenJDK"
+    ;;
 
-# German localization
-elif [[ $LANG == de* ]] ; then
+# German
+de)
        MSG_ERROR_LAUNCHING="FEHLER beim Starten von '${CFBundleName}'."
        MSG_MISSING_MAINCLASS="Die 'MainClass' ist nicht spezifiziert!\nDie Java-Anwendung kann nicht gestartet werden!"
        MSG_JVMVERSION_REQ_INVALID="Die Syntax der angeforderten Java-Version ist ungültig: %s\nBitte kontaktieren Sie den Entwickler der App."
@@ -356,10 +408,12 @@ elif [[ $LANG == de* ]] ; then
        MSG_NO_SUITABLE_JAVA_CHECK="Stellen Sie sicher, dass die angeforderte Java-Version installiert ist."
        MSG_INSTALL_JAVA="Auf Ihrem System muss die 'Java'-Software installiert sein.\nBesuchen Sie java.com für weitere Installationshinweise."
        MSG_LATER="Später"
-       MSG_VISIT_JAVA_DOT_COM="java.com öffnen"
+       MSG_VISIT_JAVA_DOT_COM="Java von Oracle"
+       MSG_VISIT_ADOPTOPENJDK="Java von AdoptOpenJDK"
+    ;;
 
-# Simplifyed Chinese localization
-elif [[ $LANG == zh* ]] ; then
+# Simplified Chinese
+zh)
        MSG_ERROR_LAUNCHING="无法启动 '${CFBundleName}'."
        MSG_MISSING_MAINCLASS="没有指定 'MainClass'!\nJava程序无法启动!"
        MSG_JVMVERSION_REQ_INVALID="Java版本参数语法错误: %s\n请联系该应用的开发者。"
@@ -370,10 +424,28 @@ elif [[ $LANG == zh* ]] ; then
        MSG_NO_SUITABLE_JAVA_CHECK="请确保系统中安装了所需的Java版本"
        MSG_INSTALL_JAVA="你需要在Mac中安装Java运行环境!\n访问 java.com 了解如何安装。"
        MSG_LATER="稍后"
-       MSG_VISIT_JAVA_DOT_COM="访问 java.com"
-
-# English default localization
-else
+       MSG_VISIT_JAVA_DOT_COM="Java by Oracle"
+       MSG_VISIT_ADOPTOPENJDK="Java by AdoptOpenJDK"
+    ;;
+
+# Spanish
+es)
+       MSG_ERROR_LAUNCHING="ERROR iniciando '${CFBundleName}'."
+       MSG_MISSING_MAINCLASS="¡'MainClass' no especificada!\n¡La aplicación Java no puede iniciarse!"
+       MSG_JVMVERSION_REQ_INVALID="La sintaxis de la versión Java requerida no es válida: %s\nPor favor, contacte con el desarrollador de la aplicación."
+       MSG_NO_SUITABLE_JAVA="¡No se encontró una versión de Java adecuada en su sistema!\nEste programa requiere Java %s"
+       MSG_JAVA_VERSION_OR_LATER="o posterior"
+       MSG_JAVA_VERSION_LATEST="(ultima actualización)"
+       MSG_JAVA_VERSION_MAX="superior a %s"
+       MSG_NO_SUITABLE_JAVA_CHECK="Asegúrese de instalar la versión Java requerida."
+       MSG_INSTALL_JAVA="¡Necesita tener JAVA instalado en su Mac!\nVisite java.com para consultar las instrucciones para su instalación..."
+       MSG_LATER="Más tarde"
+       MSG_VISIT_JAVA_DOT_COM="Java de Oracle"
+       MSG_VISIT_ADOPTOPENJDK="Java de AdoptOpenJDK"
+    ;;
+
+# English | default
+en|*)
        MSG_ERROR_LAUNCHING="ERROR launching '${CFBundleName}'."
        MSG_MISSING_MAINCLASS="'MainClass' isn't specified!\nJava application cannot be started!"
        MSG_JVMVERSION_REQ_INVALID="The syntax of the required Java version is invalid: %s\nPlease contact the App developer."
@@ -384,8 +456,10 @@ else
        MSG_NO_SUITABLE_JAVA_CHECK="Make sure you install the required Java version."
        MSG_INSTALL_JAVA="You need to have JAVA installed on your Mac!\nVisit java.com for installation instructions..."
        MSG_LATER="Later"
-       MSG_VISIT_JAVA_DOT_COM="Visit java.com"
-fi
+       MSG_VISIT_JAVA_DOT_COM="Java by Oracle"
+       MSG_VISIT_ADOPTOPENJDK="Java by AdoptOpenJDK"
+    ;;
+esac
 
 
 
@@ -468,7 +542,7 @@ function get_comparable_java_version() {
 ################################################################################
 function is_valid_requirement_pattern() {
        local java_req=$1
-       java8pattern='1\.[4-8](\.0)?(\.0_[0-9]+)?[*+]?'
+       java8pattern='1\.[4-8](\.[0-9]+)?(\.0_[0-9]+)?[*+]?'
        java9pattern='(9|1[0-9])(-ea|[*+]|(\.[0-9]+){1,2}[*+]?)?'
        # test matches either old Java versioning scheme (up to 1.8) or new scheme (starting with 9)
        if [[ ${java_req} =~ ^(${java8pattern}|${java9pattern})$ ]]; then
@@ -501,20 +575,28 @@ if [ -n "$JAVA_HOME" ] ; then
        if [[ $JAVA_HOME == /* ]] ; then
                # if "$JAVA_HOME" starts with a Slash it's an absolute path
                JAVACMD="$JAVA_HOME/bin/java"
+               stub_logger "[JavaSearch] ... parsing JAVA_HOME as absolute path to the executable '$JAVACMD'"
        else
                # otherwise it's a relative path to "$AppPackageFolder"
                JAVACMD="$AppPackageFolder/$JAVA_HOME/bin/java"
+               stub_logger "[JavaSearch] ... parsing JAVA_HOME as relative path inside the App bundle to the executable '$JAVACMD'"
        fi
        JAVACMD_version=$(get_comparable_java_version $(get_java_version_from_cmd "${JAVACMD}"))
 else
-       stub_logger "[JavaSearch] ... didn't found JAVA_HOME"
+       stub_logger "[JavaSearch] ... haven't found JAVA_HOME"
 fi
 
 
 # check for any other or a specific Java version
 # also if $JAVA_HOME exists but isn't executable
 if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
-       stub_logger "[JavaSearch] Checking for JavaVirtualMachines on the system ..."
+
+       # add a warning in the syslog if JAVA_HOME is not executable or not found (#100)
+       if [ -n "$JAVA_HOME" ] ; then
+               stub_logger "[JavaSearch] ... but no 'java' executable was found at the JAVA_HOME location!"
+       fi
+
+       stub_logger "[JavaSearch] Searching for JavaVirtualMachines on the system ..."
        # reset variables
        JAVACMD=""
        JAVACMD_version=""
@@ -525,7 +607,7 @@ if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
                # log exit cause
                stub_logger "[EXIT 4] ${MSG_JVMVERSION_REQ_INVALID_EXPANDED}"
                # display error message with AppleScript
-               osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_JVMVERSION_REQ_INVALID_EXPANDED}\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1 with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)"
+               osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_JVMVERSION_REQ_INVALID_EXPANDED}\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1${DialogWithIcon}"
                # exit with error
                exit 4
        fi
@@ -535,7 +617,7 @@ if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
                # log exit cause
                stub_logger "[EXIT 5] ${MSG_JVMVERSION_REQ_INVALID_EXPANDED}"
                # display error message with AppleScript
-               osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_JVMVERSION_REQ_INVALID_EXPANDED}\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1 with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)"
+               osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_JVMVERSION_REQ_INVALID_EXPANDED}\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1${DialogWithIcon}"
                # exit with error
                exit 5
        fi
@@ -543,15 +625,41 @@ if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
 
        # find installed JavaVirtualMachines (JDK + JRE)
        allJVMs=()
-       # read JDK's from '/usr/libexec/java_home -V' command
-       while read -r line; do
-               version=$(echo $line | awk -F $',' '{print $1;}')
-               path=$(echo $line | awk -F $'" ' '{print $2;}')
-               path+="/bin/java"
-               allJVMs+=("$version:$path")
-       done < <(/usr/libexec/java_home -V 2>&1 | grep '^[[:space:]]')
-       # unset while loop variables
-       unset version path
+       
+       # read JDK's from '/usr/libexec/java_home --xml' command with PlistBuddy and a custom Dict iterator
+       # idea: https://stackoverflow.com/a/14085460/1128689 and https://scriptingosx.com/2018/07/parsing-dscl-output-in-scripts/
+       javaXml=$(/usr/libexec/java_home --xml)
+       javaCounter=$(/usr/libexec/PlistBuddy -c "Print" /dev/stdin <<< $javaXml | grep "Dict" | wc -l | tr -d ' ')
+
+       # iterate over all Dict entries
+       # but only if there are any JVMs at all (#93)
+       if [ "$javaCounter" -gt "0" ] ; then
+               for idx in $(seq 0 $((javaCounter - 1)))
+               do
+                       version=$(/usr/libexec/PlistBuddy -c "print :$idx:JVMVersion" /dev/stdin <<< $javaXml)
+                       path=$(/usr/libexec/PlistBuddy -c "print :$idx:JVMHomePath" /dev/stdin <<< $javaXml)
+                       path+="/bin/java"
+                       allJVMs+=("$version:$path")
+               done
+               # unset for loop variables
+               unset version path
+       fi
+
+       # add SDKMAN! java versions (#95)
+       if [ -d ~/.sdkman/candidates/java/ ] ; then
+               for sdkjdk in ~/.sdkman/candidates/java/*/
+               do
+                       if [[ ${sdkjdk} =~ /current/$ ]] ; then
+                               continue
+                       fi
+
+                       sdkjdkcmd="${sdkjdk}bin/java"
+                       version=$(get_java_version_from_cmd "${sdkjdkcmd}")
+                       allJVMs+=("$version:$sdkjdkcmd")
+               done
+               # unset for loop variables
+               unset version
+       fi
 
        # add Apple JRE if available
        if [ -x "${apple_jre_plugin}" ] ; then
@@ -571,6 +679,9 @@ if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
 
 
        # determine JVMs matching the min/max version requirement
+
+       stub_logger "[JavaSearch] Filtering the result list for JVMs matching the min/max version requirement ..."
+
        minC=$(get_comparable_java_version ${JVMVersion})
        maxC=$(get_comparable_java_version ${JVMMaxVersion})
        matchingJVMs=()
@@ -655,7 +766,7 @@ if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
        # debug output
        for i in "${matchingJVMs[@]}"
        do
-               stub_logger "[JavaSearch] ... ... matches all requirements: $i"
+               stub_logger "[JavaSearch] ... matches all requirements: $i"
        done
 
 
@@ -692,7 +803,13 @@ fi
 stub_logger "[JavaCommand] '$JAVACMD'"
 stub_logger "[JavaVersion] $(get_java_version_from_cmd "${JAVACMD}")${JAVACMD_version:+ / $JAVACMD_version}"
 
+# Make sure tabbing mode is disabled for the selected java version
+
+CFBundleIdentifier=net.java.openjdk.$(get_java_version_from_cmd "${JAVACMD}").java
 
+if [ x$(defaults read ${CFBundleIdentifier} AppleWindowTabbingMode) != "xnever" ]; then
+    defaults write ${CFBundleIdentifier} AppleWindowTabbingMode never
+fi
 
 if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
 
@@ -712,9 +829,10 @@ if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
                stub_logger "[EXIT 3] ${MSG_NO_SUITABLE_JAVA_EXPANDED}"
 
                # display error message with AppleScript
-               osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_NO_SUITABLE_JAVA_EXPANDED}\n${MSG_NO_SUITABLE_JAVA_CHECK}\" with title \"${CFBundleName}\"  buttons {\" OK \", \"${MSG_VISIT_JAVA_DOT_COM}\"} default button \"${MSG_VISIT_JAVA_DOT_COM}\" with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)" \
+               osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_NO_SUITABLE_JAVA_EXPANDED}\n${MSG_NO_SUITABLE_JAVA_CHECK}\" with title \"${CFBundleName}\"  buttons {\" OK \", \"${MSG_VISIT_JAVA_DOT_COM}\", \"${MSG_VISIT_ADOPTOPENJDK}\"} default button 1${DialogWithIcon}" \
                                -e "set response to button returned of the result" \
-                               -e "if response is \"${MSG_VISIT_JAVA_DOT_COM}\" then open location \"http://java.com\""
+                               -e "if response is \"${MSG_VISIT_JAVA_DOT_COM}\" then open location \"https://www.java.com/download/\"" \
+                               -e "if response is \"${MSG_VISIT_ADOPTOPENJDK}\" then open location \"https://adoptopenjdk.net/releases.html\""
                # exit with error
                exit 3
 
@@ -722,9 +840,10 @@ if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
                # log exit cause
                stub_logger "[EXIT 1] ${MSG_ERROR_LAUNCHING}"
                # display error message with AppleScript
-               osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_INSTALL_JAVA}\" with title \"${CFBundleName}\" buttons {\"${MSG_LATER}\", \"${MSG_VISIT_JAVA_DOT_COM}\"} default button \"${MSG_VISIT_JAVA_DOT_COM}\" with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)" \
+               osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_INSTALL_JAVA}\" with title \"${CFBundleName}\" buttons {\"${MSG_LATER}\", \"${MSG_VISIT_JAVA_DOT_COM}\", \"${MSG_VISIT_ADOPTOPENJDK}\"} default button 1${DialogWithIcon}" \
                                        -e "set response to button returned of the result" \
-                                       -e "if response is \"${MSG_VISIT_JAVA_DOT_COM}\" then open location \"http://java.com\""
+                                       -e "if response is \"${MSG_VISIT_JAVA_DOT_COM}\" then open location \"https://www.java.com/download/\"" \
+                                       -e "if response is \"${MSG_VISIT_ADOPTOPENJDK}\" then open location \"https://adoptopenjdk.net/releases.html\""
                # exit with error
                exit 1
        fi
@@ -739,7 +858,7 @@ if [ -z "${JVMMainClass}" ]; then
        # log exit cause
        stub_logger "[EXIT 2] ${MSG_MISSING_MAINCLASS}"
        # display error message with AppleScript
-       osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_MISSING_MAINCLASS}\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1 with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)"
+       osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_MISSING_MAINCLASS}\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1${DialogWithIcon}"
        # exit with error
        exit 2
 fi
@@ -773,11 +892,11 @@ stub_logger "[WorkingDirectory] ${WorkingDirectory}"
 # - main class
 # - main class arguments
 # - passthrough arguments from Terminal or Drag'n'Drop to Finder icon
-stub_logger "[Exec] \"$JAVACMD\" -cp \"${JVMClassPath}\" -splash:\"${ResourcesFolder}/${JVMSplashFile}\" -Xdock:icon=\"${ResourcesFolder}/${CFBundleIconFile}\" -Xdock:name=\"${CFBundleName}\" ${JVMOptionsArr:+$(printf "'%s' " "${JVMOptionsArr[@]}") }${JVMDefaultOptions:+$JVMDefaultOptions }${JVMMainClass}${MainArgsArr:+ $(printf "'%s' " "${MainArgsArr[@]}")}${ArgsPassthru:+ $(printf "'%s' " "${ArgsPassthru[@]}")}"
+stub_logger "[Exec] \"$JAVACMD\" -cp \"${JVMClassPath}\" ${JVMSplashFile:+ -splash:\"${ResourcesFolder}/${JVMSplashFile}\"} -Xdock:icon=\"${ResourcesFolder}/${CFBundleIconFile}\" -Xdock:name=\"${CFBundleName}\" ${JVMOptionsArr:+$(printf "'%s' " "${JVMOptionsArr[@]}") }${JVMDefaultOptions:+$JVMDefaultOptions }${JVMMainClass}${MainArgsArr:+ $(printf "'%s' " "${MainArgsArr[@]}")}${ArgsPassthru:+ $(printf "'%s' " "${ArgsPassthru[@]}")}"
 exec "${JAVACMD}" \
                -Djava.library.path="${AppleJavaFolder}" \
                -cp "${JVMClassPath}" \
-               -splash:"${ResourcesFolder}/${JVMSplashFile}" \
+               ${JVMSplashFile:+ -splash:"${ResourcesFolder}/${JVMSplashFile}"} \
                -Xdock:icon="${ResourcesFolder}/${CFBundleIconFile}" \
                -Xdock:name="${CFBundleName}" \
                ${JVMOptionsArr:+"${JVMOptionsArr[@]}" }\