Initial Commit - Copy from Altus Metrum AltOS
This commit is contained in:
27
telegps/.gitignore
vendored
Normal file
27
telegps/.gitignore
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
windows/
|
||||
linux/
|
||||
macosx/
|
||||
fat/
|
||||
Manifest.txt
|
||||
Manifest-fat.txt
|
||||
AltosVersion.java
|
||||
Info.plist
|
||||
libaltosJNI
|
||||
classes
|
||||
telegps
|
||||
telegps-test
|
||||
telegps-jdb
|
||||
classtelegps.stamp
|
||||
telegps-windows.nsi
|
||||
TeleGPS-Linux-*.tar.bz2
|
||||
TeleGPS-Linux-*.sh
|
||||
TeleGPS-Mac-*.zip
|
||||
TeleGPS-Windows-*.exe
|
||||
*.desktop
|
||||
telegps-windows.log
|
||||
*.dll
|
||||
*.dylib
|
||||
*.so
|
||||
*.jar
|
||||
*.class
|
||||
*.dmg
|
73
telegps/Info.plist.in
Normal file
73
telegps/Info.plist.in
Normal file
@@ -0,0 +1,73 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
|
||||
<plist version="0.9">
|
||||
<dict>
|
||||
<key>CFBundleName</key>
|
||||
<string>TeleGPS</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>@VERSION@</string>
|
||||
<key>CFBundleAllowMixedLocalizations</key>
|
||||
<string>true</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>JavaApplicationStub</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.altusmetrum.telegps</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>Altu</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string>TeleGPS version @VERSION@</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>altusmetrum-telegps.icns</string>
|
||||
<key>CFBundleDocumentTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Telemetry</string>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>application-vnd.altusmetrum.telemetry.icns</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>telem</string>
|
||||
</array>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Eeprom</string>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>application-vnd.altusmetrum.eeprom.icns</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>eeprom</string>
|
||||
</array>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Java</key>
|
||||
<dict>
|
||||
<key>MainClass</key>
|
||||
<string>org.altusmetrum.telegps.TeleGPS</string>
|
||||
<key>JVMVersion</key>
|
||||
<string>1.5+</string>
|
||||
<key>ClassPath</key>
|
||||
<array>
|
||||
<string>$JAVAROOT/telegps.jar</string>
|
||||
<string>$JAVAROOT/freetts.jar</string>
|
||||
</array>
|
||||
<key>VMOptions</key>
|
||||
<array>
|
||||
<string>-Xms512M</string>
|
||||
<string>-Xmx512M</string>
|
||||
<string>-Dosgi.clean=true</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
356
telegps/Makefile.am
Normal file
356
telegps/Makefile.am
Normal file
@@ -0,0 +1,356 @@
|
||||
# location of code signing key, et al
|
||||
|
||||
JAVAROOT=classes
|
||||
AM_JAVACFLAGS=$(JAVAC_VERSION_FLAGS) -encoding UTF-8 -Xlint:deprecation -Xlint:unchecked
|
||||
|
||||
man_MANS=telegps.1
|
||||
|
||||
altoslibdir=$(libdir)/altos
|
||||
|
||||
CLASSPATH_ENV=mkdir -p $(JAVAROOT); CLASSPATH=".:classes:../altoslib/*:../altosuilib/*:../libaltos:$(JCOMMON)/jcommon.jar:$(JFREECHART)/jfreechart.jar:$(FREETTS)/freetts.jar"
|
||||
|
||||
bin_SCRIPTS=telegps
|
||||
|
||||
telegpsdir=$(datadir)/java
|
||||
|
||||
telegps_JAVA= \
|
||||
TeleGPS.java \
|
||||
TeleGPSStatus.java \
|
||||
TeleGPSStatusUpdate.java \
|
||||
TeleGPSInfo.java \
|
||||
TeleGPSState.java \
|
||||
TeleGPSConfig.java \
|
||||
TeleGPSConfigUI.java \
|
||||
TeleGPSPreferences.java \
|
||||
TeleGPSGraphUI.java \
|
||||
TeleGPSDisplayThread.java
|
||||
|
||||
JFREECHART_CLASS= \
|
||||
jfreechart.jar
|
||||
|
||||
JCOMMON_CLASS=\
|
||||
jcommon.jar
|
||||
|
||||
FREETTS_CLASS= \
|
||||
cmudict04.jar \
|
||||
cmulex.jar \
|
||||
cmu_time_awb.jar \
|
||||
cmutimelex.jar \
|
||||
cmu_us_kal.jar \
|
||||
en_us.jar \
|
||||
freetts.jar
|
||||
|
||||
JAR=telegps.jar
|
||||
|
||||
FATJAR=telegps-fat.jar
|
||||
|
||||
if MULTI_ARCH
|
||||
LIBALTOS_LINUX=libaltos_i686.so libaltos_amd64.so libaltos_aarch64.so libaltos_armel.so libaltos_armhf.so
|
||||
else
|
||||
LIBALTOS_LINUX=libaltos.so
|
||||
endif
|
||||
|
||||
LIBALTOS= \
|
||||
$(LIBALTOS_LINUX) \
|
||||
libaltos.dylib \
|
||||
altos64.dll \
|
||||
altos.dll
|
||||
|
||||
ALTOSLIB_CLASS=\
|
||||
altoslib_$(ALTOSLIB_VERSION).jar
|
||||
|
||||
ALTOSUILIB_CLASS=\
|
||||
altosuilib_$(ALTOSUILIB_VERSION).jar
|
||||
|
||||
# Icons
|
||||
ICONDIR=$(top_srcdir)/icon
|
||||
|
||||
JAVA_ICONS=\
|
||||
$(ICONDIR)/altusmetrum-telegps-16.png \
|
||||
$(ICONDIR)/altusmetrum-telegps-32.png \
|
||||
$(ICONDIR)/altusmetrum-telegps-48.png \
|
||||
$(ICONDIR)/altusmetrum-telegps-64.png \
|
||||
$(ICONDIR)/altusmetrum-telegps-128.png\
|
||||
$(ICONDIR)/altusmetrum-telegps-256.png
|
||||
|
||||
# icon base names for jar
|
||||
ICONJAR= \
|
||||
-C $(ICONDIR) altusmetrum-telegps-16.png \
|
||||
-C $(ICONDIR) altusmetrum-telegps-32.png \
|
||||
-C $(ICONDIR) altusmetrum-telegps-48.png \
|
||||
-C $(ICONDIR) altusmetrum-telegps-64.png \
|
||||
-C $(ICONDIR) altusmetrum-telegps-128.png\
|
||||
-C $(ICONDIR) altusmetrum-telegps-256.png
|
||||
|
||||
WINDOWS_ICONS =\
|
||||
../icon/altusmetrum-telegps.ico \
|
||||
../icon/altusmetrum-telegps.exe
|
||||
../icon/application-vnd.altusmetrum.eeprom.ico \
|
||||
../icon/application-vnd.altusmetrum.eeprom.exe \
|
||||
../icon/application-vnd.altusmetrum.telemetry.ico \
|
||||
../icon/application-vnd.altusmetrum.telemetry.exe
|
||||
|
||||
MACOSX_ICONS =\
|
||||
../icon/altusmetrum-telegps.icns \
|
||||
../icon/application-vnd.altusmetrum.eeprom.icns \
|
||||
../icon/application-vnd.altusmetrum.telemetry.icns
|
||||
|
||||
LINUX_ICONS =\
|
||||
$(ICONDIR)/altusmetrum-altosui.svg \
|
||||
$(ICONDIR)/application-vnd.altusmetrum.eeprom.svg \
|
||||
$(ICONDIR)/application-vnd.altusmetrum.telemetry.svg
|
||||
|
||||
LINUX_MIMETYPE =\
|
||||
$(ICONDIR)/org-altusmetrum-mimetypes.xml
|
||||
|
||||
# Firmware
|
||||
FIRMWARE_TD_3_0=$(top_srcdir)/src/teledongle-v3.0/teledongle-v3.0-$(VERSION).ihx
|
||||
FIRMWARE_TD=$(FIRMWARE_TD_3_0)
|
||||
|
||||
FIRMWARE_TBT_3_0=$(top_srcdir)/src/telebt-v3.0/telebt-v3.0-$(VERSION).ihx
|
||||
FIRMWARE_TBT_4_0=$(top_srcdir)/src/telebt-v4.0/telebt-v4.0-$(VERSION).ihx
|
||||
FIRMWARE_TBT=$(FIRMWARE_TBT_3_0) $(FIRMWARE_TBT_4_0)
|
||||
|
||||
FIRMWARE_TGPS_1_0=$(top_srcdir)/src/telegps-v1.0/telegps-v1.0-$(VERSION).ihx
|
||||
FIRMWARE_TGPS_2_0=$(top_srcdir)/src/telegps-v2.0/telegps-v2.0-$(VERSION).ihx
|
||||
FIRMWARE_TGPS_3_0=$(top_srcdir)/src/telegps-v3.0/telegps-v3.0-$(VERSION).ihx
|
||||
FIRMWARE_TGPS=$(FIRMWARE_TGPS_1_0) $(FIRMWARE_TGPS_2_0) $(FIRMWARE_TGPS_3_0)
|
||||
|
||||
FIRMWARE=$(FIRMWARE_TGPS) $(FIRMWARE_TD) $(FIRMWARE_TBT)
|
||||
|
||||
desktopdir = $(datadir)/applications
|
||||
desktop_file = altusmetrum-telegps.desktop
|
||||
desktop_SCRIPTS = $(desktop_file)
|
||||
|
||||
all-local: telegps-test telegps-jdb $(JAR) $(MDWN)
|
||||
|
||||
clean-local:
|
||||
-rm -rf classes $(JAR) $(FATJAR) \
|
||||
TeleGPS-Linux-*.tar.bz2 TeleGPS-Mac-*.dmg TeleGPS-Windows-*.exe \
|
||||
altoslib_*.jar altosuilib_*.jar \
|
||||
$(JFREECHART_CLASS) $(JCOMMON_CLASS) $(FREETTS_CLASS) $(LIBALTOS) Manifest.txt Manifest-fat.txt \
|
||||
telegps telegps-test telegps-jdb macosx linux windows telegps-windows.log \
|
||||
telegps-windows.nsi *.desktop *.mdwn
|
||||
|
||||
EXTRA_DIST = $(desktop_file).in
|
||||
|
||||
$(desktop_file): $(desktop_file).in
|
||||
sed -e 's#%bindir%#@bindir@#' -e 's#%icondir%#$(datadir)/icons/hicolor/scalable/apps#' ${srcdir}/$(desktop_file).in > $@
|
||||
chmod +x $@
|
||||
|
||||
LINUX_DIST=TeleGPS-Linux-$(VERSION).tar.bz2
|
||||
LINUX_SH=TeleGPS-Linux-$(VERSION).sh
|
||||
MACOSX_DIST=TeleGPS-Mac-$(VERSION).dmg
|
||||
WINDOWS_DIST=TeleGPS-Windows-$(VERSION_DASH).exe
|
||||
MDWN=$(VERSION).mdwn
|
||||
MDWNTMPL=mdwn.tmpl
|
||||
|
||||
TELEGPS_DOC=$(top_srcdir)/doc/telegps.pdf
|
||||
|
||||
DOC=$(TELEGPS_DOC)
|
||||
|
||||
FAT_FILES=$(FATJAR) $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) $(FREETTS_CLASS) $(JFREECHART_CLASS) $(JCOMMON_CLASS)
|
||||
|
||||
LINUX_FILES=$(FAT_FILES) $(LIBALTOS_LINUX) $(FIRMWARE) $(DOC) $(desktop_file).in $(LINUX_ICONS) $(LINUX_MIMETYPE)
|
||||
LINUX_EXTRA=telegps-fat $(desktop_file).in
|
||||
|
||||
MACOSX_INFO_PLIST=Info.plist
|
||||
MACOSX_README=ReadMe-Mac.rtf
|
||||
MACOSX_INSTALL=../altosui/install-macosx ../altosui/ask-pass
|
||||
MACOSX_FILES=$(FAT_FILES) libaltos.dylib $(MACOSX_INFO_PLIST) $(MACOSX_README) $(DOC) $(MACOSX_ICONS) $(MACOSX_INSTALL)
|
||||
MACOSX_EXTRA=$(FIRMWARE)
|
||||
|
||||
WINDOWS_FILES=$(FAT_FILES) altos.dll altos64.dll $(top_srcdir)/altusmetrum.inf $(top_srcdir)/altusmetrum.cat $(DOC) $(WINDOWS_ICONS)
|
||||
|
||||
if FATINSTALL
|
||||
|
||||
FATTARGET=$(FATDIR)/TeleGPS/releases/$(VERSION)
|
||||
|
||||
LINUX_SH_TARGET=$(FATTARGET)/$(LINUX_SH)
|
||||
MACOSX_DIST_TARGET=$(FATTARGET)/$(MACOSX_DIST)
|
||||
WINDOWS_DIST_TARGET=$(FATTARGET)/$(WINDOWS_DIST)
|
||||
MDWN_TARGET=$(FATDIR)/TeleGPS/releases/$(MDWN)
|
||||
RELNOTES=release-notes-$(VERSION).html
|
||||
RELNOTES_SRC=$(top_builddir)/doc/$(RELNOTES)
|
||||
RELNOTES_TARGET=$(FATTARGET)/$(RELNOTES)
|
||||
|
||||
fat-install: $(LINUX_SH_TARGET) $(MACOSX_DIST_TARGET) $(WINDOWS_DIST_TARGET) $(MDWN_TARGET) $(RELNOTES_TARGET)
|
||||
|
||||
$(LINUX_SH_TARGET): $(LINUX_SH)
|
||||
mkdir -p $(FATTARGET)
|
||||
cp -p $< $@
|
||||
|
||||
$(MACOSX_DIST_TARGET): $(MACOSX_DIST)
|
||||
mkdir -p $(FATTARGET)
|
||||
cp -p $< $@
|
||||
|
||||
$(WINDOWS_DIST_TARGET): $(WINDOWS_DIST)
|
||||
mkdir -p $(FATTARGET)
|
||||
cp -p $< $@
|
||||
|
||||
$(MDWN_TARGET): $(MDWN)
|
||||
mkdir -p $(FATTARGET)
|
||||
cp -p $< $@
|
||||
|
||||
$(RELNOTES_TARGET): $(RELNOTES_SRC)
|
||||
mkdir -p $(FATTARGET)
|
||||
sh $(top_srcdir)/doc/install-html -d $(FATTARGET) $(RELNOTES_SRC)
|
||||
|
||||
endif
|
||||
|
||||
$(MDWN): $(MDWNTMPL)
|
||||
sed -e 's/%version%/$(VERSION)/g' -e 's/%version_dash%/$(VERSION_DASH)/g' $(MDWNTMPL) > $@
|
||||
|
||||
fat: $(LINUX_DIST) $(LINUX_SH) $(MACOSX_DIST) $(WINDOWS_DIST)
|
||||
|
||||
|
||||
telegps: Makefile
|
||||
echo "#!/bin/sh" > $@
|
||||
echo 'exec java -Djava.library.path="$(altoslibdir)" -jar "$(telegpsdir)/telegps.jar" "$$@"' >> $@
|
||||
chmod +x $@
|
||||
|
||||
telegps-jdb: Makefile
|
||||
echo "#!/bin/sh" > $@
|
||||
echo 'exec jdb -classpath "classes:./*:../libaltos:$(JCOMMON)/jcommon.jar:$(JFREECHART)/jfreechart.jar" -Djava.library.path="../libaltos/.libs" org.altusmetrum.telegps.TeleGPS "$$@"' >> $@
|
||||
chmod +x $@
|
||||
|
||||
telegps-test: Makefile
|
||||
echo "#!/bin/sh" > $@
|
||||
echo 'exec java -Djava.library.path="../libaltos/.libs" -jar telegps.jar "$$@"' >> $@
|
||||
chmod +x $@
|
||||
|
||||
install-telegpsJAVA: telegps.jar
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(telegpsdir)" || $(MKDIR_P) "$(DESTDIR)$(telegpsdir)"
|
||||
echo " $(INSTALL_DATA)" "$<" "'$(DESTDIR)$(telegpsdir)/telegps.jar'"; \
|
||||
$(INSTALL_DATA) "$<" "$(DESTDIR)$(telegpsdir)"
|
||||
|
||||
$(JAR): classtelegps.stamp Manifest.txt $(JAVA_ICONS) $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS)
|
||||
jar cfm $@ Manifest.txt \
|
||||
$(ICONJAR) \
|
||||
-C classes org \
|
||||
-C ../libaltos libaltosJNI
|
||||
if STRIP_NONDETERMINISM
|
||||
$(STRIP_NONDETERMINISM) $@
|
||||
endif
|
||||
|
||||
$(FATJAR): classtelegps.stamp Manifest-fat.txt $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) $(JFREECHART_CLASS) $(JCOMMON_CLASS) $(JAVA_ICONS)
|
||||
jar cfm $@ Manifest-fat.txt \
|
||||
$(ICONJAR) \
|
||||
-C classes org \
|
||||
-C ../libaltos libaltosJNI
|
||||
if STRIP_NONDETERMINISM
|
||||
$(STRIP_NONDETERMINISM) $@
|
||||
endif
|
||||
|
||||
libaltos.so: build-libaltos
|
||||
-rm -f "$@"
|
||||
$(LN_S) ../libaltos/.libs/"$@" .
|
||||
|
||||
libaltos_i686.so: build-libaltos
|
||||
-rm -f "$@"
|
||||
$(LN_S) ../libaltos/.libs/"$@" .
|
||||
|
||||
libaltos_amd64.so: build-libaltos
|
||||
-rm -f "$@"
|
||||
$(LN_S) ../libaltos/.libs/"$@" .
|
||||
|
||||
libaltos_aarch64.so: build-libaltos
|
||||
-rm -f "$@"
|
||||
$(LN_S) ../libaltos/.libs/"$@" .
|
||||
|
||||
libaltos_armel.so: build-libaltos
|
||||
-rm -f "$@"
|
||||
$(LN_S) ../libaltos/.libs/"$@" .
|
||||
|
||||
libaltos_armhf.so: build-libaltos
|
||||
-rm -f "$@"
|
||||
$(LN_S) ../libaltos/.libs/"$@" .
|
||||
|
||||
libaltos.dylib:
|
||||
-rm -f "$@"
|
||||
$(LN_S) ../libaltos/"$@" .
|
||||
|
||||
altos.dll: build-libaltos
|
||||
-rm -f "$@"
|
||||
$(LN_S) ../libaltos/"$@" .
|
||||
|
||||
altos64.dll: build-libaltos
|
||||
-rm -f "$@"
|
||||
$(LN_S) ../libaltos/"$@" .
|
||||
|
||||
build-libaltos:
|
||||
+cd ../libaltos && make
|
||||
|
||||
$(ALTOSLIB_CLASS):
|
||||
-rm -f "$@"
|
||||
$(LN_S) ../altoslib/"$@" .
|
||||
|
||||
$(ALTOSUILIB_CLASS):
|
||||
-rm -f "$@"
|
||||
$(LN_S) ../altosuilib/"$@" .
|
||||
|
||||
$(FREETTS_CLASS):
|
||||
-rm -f "$@"
|
||||
$(LN_S) "$(FREETTS)"/"$@" .
|
||||
|
||||
$(JFREECHART_CLASS):
|
||||
-rm -f "$@"
|
||||
$(LN_S) "$(JFREECHART)"/"$@" .
|
||||
|
||||
$(JCOMMON_CLASS):
|
||||
-rm -f "$@"
|
||||
$(LN_S) "$(JCOMMON)"/"$@" .
|
||||
|
||||
$(LINUX_DIST): $(LINUX_FILES) $(LINUX_EXTRA)
|
||||
-rm -f $@
|
||||
-rm -rf linux
|
||||
mkdir -p linux/TeleGPS
|
||||
cp -p $(LINUX_FILES) linux/TeleGPS
|
||||
cp -p telegps-fat linux/TeleGPS/telegps
|
||||
chmod +x linux/TeleGPS/telegps
|
||||
tar cjf $@ -C linux TeleGPS
|
||||
|
||||
$(LINUX_SH): $(LINUX_DIST) $(srcdir)/../altosui/linux-install.sh
|
||||
sed 's/AltOS/TeleGPS/g' $(srcdir)/../altosui/linux-install.sh | cat - $(LINUX_DIST) > $@
|
||||
chmod +x $@
|
||||
|
||||
$(MACOSX_DIST): $(MACOSX_FILES) $(MACOSX_EXTRA) Makefile
|
||||
-rm -f $@
|
||||
-rm -rf macosx
|
||||
mkdir macosx
|
||||
cp -a TeleGPS.app macosx/
|
||||
cp -a $(MACOSX_README) macosx/ReadMe-TeleGPS.rtf
|
||||
cp -a $(MACOSX_INSTALL) macosx
|
||||
mkdir -p macosx/Doc
|
||||
cp -a $(DOC) macosx/Doc
|
||||
cp -p Info.plist macosx/TeleGPS.app/Contents
|
||||
mkdir -p macosx/AltOS-$(VERSION) macosx/TeleGPS.app/Contents/Resources/Java
|
||||
cp -p $(MACOSX_ICONS) macosx/TeleGPS.app/Contents/Resources
|
||||
cp -p $(FATJAR) macosx/TeleGPS.app/Contents/Resources/Java/telegps.jar
|
||||
cp -p libaltos.dylib macosx/TeleGPS.app/Contents/Resources/Java
|
||||
cp -p $(ALTOSLIB_CLASS) macosx/TeleGPS.app/Contents/Resources/Java
|
||||
cp -p $(ALTOSUILIB_CLASS) macosx/TeleGPS.app/Contents/Resources/Java
|
||||
cp -p $(FREETTS_CLASS) macosx/TeleGPS.app/Contents/Resources/Java
|
||||
cp -p $(JFREECHART_CLASS) macosx/TeleGPS.app/Contents/Resources/Java
|
||||
cp -p $(JCOMMON_CLASS) macosx/TeleGPS.app/Contents/Resources/Java
|
||||
cp -p $(MACOSX_EXTRA) macosx/AltOS-$(VERSION)
|
||||
genisoimage -D -V TeleGPS-$(VERSION) -no-pad -r -apple -o $@ macosx
|
||||
|
||||
$(WINDOWS_DIST): $(WINDOWS_FILES) telegps-windows.nsi
|
||||
-rm -f $@
|
||||
makensis -Otelegps-windows.log "-XOutFile $@" "-DVERSION=$(VERSION)" telegps-windows.nsi || (cat telegps-windows.log && exit 1)
|
||||
if [ "$(HAVE_WINDOWS_KEY)" = "yes" ]; then \
|
||||
jsign --keystore "$(WINDOWSKEYFILE)" --alias 1 \
|
||||
--storetype PKCS12 --storepass `cat "$(WINDOWSKEYPASSFILE)"` \
|
||||
--tsaurl http://ts.ssl.com --tsmode RFC3161 $@ ; \
|
||||
fi
|
||||
|
||||
Manifest.txt: Makefile
|
||||
echo 'Main-Class: org.altusmetrum.telegps.TeleGPS' > $@
|
||||
echo "Class-Path: $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) $(FREETTS)/freetts.jar $(JCOMMON)/jcommon.jar $(JFREECHART)/jfreechart.jar" >> $@
|
||||
|
||||
Manifest-fat.txt:
|
||||
echo 'Main-Class: org.altusmetrum.telegps.TeleGPS' > $@
|
||||
echo "Class-Path: $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) freetts.jar jcommon.jar jfreechart.jar" >> $@
|
||||
|
97
telegps/ReadMe-Mac.rtf
Normal file
97
telegps/ReadMe-Mac.rtf
Normal file
@@ -0,0 +1,97 @@
|
||||
{\rtf1\ansi\deff3\adeflang1025
|
||||
{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq2\fcharset0 Liberation Serif{\*\falt Times New Roman};}{\f4\froman\fprq2\fcharset0 Liberation Sans{\*\falt Arial};}{\f5\fswiss\fprq2\fcharset0 Arial;}{\f6\froman\fprq2\fcharset0 Helvetica{\*\falt Arial};}{\f7\froman\fprq2\fcharset0 Arial;}{\f8\froman\fprq2\fcharset0 Courier New;}{\f9\froman\fprq2\fcharset0 Helvetica LT Std;}{\f10\fnil\fprq2\fcharset0 SimSun;}{\f11\fnil\fprq2\fcharset0 Courier New;}{\f12\fnil\fprq2\fcharset0 Arial Unicode MS;}{\f13\fnil\fprq2\fcharset0 Arial;}{\f14\fnil\fprq2\fcharset0 Helvetica{\*\falt Arial};}{\f15\fnil\fprq2\fcharset0 Liberation Serif{\*\falt Times New Roman};}{\f16\fnil\fprq2\fcharset0 Helvetica LT Std;}}
|
||||
{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}
|
||||
{\stylesheet{\s0\snext0\ql\widctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f3\fs24\lang1033 Normal;}
|
||||
{\s1\sbasedon19\snext1\ql\widctlpar\hyphpar0\sb440\sa60\keepn\ltrpar\cf0\b\kerning1\dbch\af12\langfe1081\dbch\af15\afs24\loch\f5\fs34\lang1033 Heading 1;}
|
||||
{\s2\sbasedon19\snext2\ql\widctlpar\hyphpar0\sb440\sa60\keepn\ltrpar\cf0\b\kerning1\dbch\af12\langfe1081\dbch\af15\afs24\loch\f5\fs28\lang1033 Heading 2;}
|
||||
{\s3\sbasedon19\snext3\ql\widctlpar\hyphpar0\sb440\sa60\keepn\ltrpar\cf0\b\kerning1\dbch\af12\langfe1081\dbch\af15\afs24\loch\f5\fs24\lang1033 Heading 3;}
|
||||
{\s4\sbasedon19\snext4\ql\widctlpar\hyphpar0\sb440\sa60\keepn\ltrpar\cf0\b\kerning1\dbch\af12\langfe1081\dbch\af15\afs24\loch\f5\fs24\lang1033 Heading 4;}
|
||||
{\*\cs15\snext15\super\fs20 Endnote Characters;}
|
||||
{\*\cs16\snext16\super\fs20 Endnote Anchor;}
|
||||
{\*\cs17\snext17\super\fs20 Footnote Characters;}
|
||||
{\*\cs18\snext18\super\fs20 Footnote Anchor;}
|
||||
{\s19\sbasedon0\snext20\ql\widctlpar\hyphpar0\sb240\sa120\keepn\ltrpar\cf0\kerning1\dbch\af12\langfe1081\dbch\af15\afs24\loch\f4\fs28\lang1033 Heading;}
|
||||
{\s20\sbasedon0\snext20\sl276\slmult1\ql\widctlpar\hyphpar0\sb0\sa140\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\loch\f3\fs24\lang1033 Text Body;}
|
||||
{\s21\sbasedon20\snext21\sl276\slmult1\ql\widctlpar\hyphpar0\sb0\sa140\ltrpar\cf0\kerning1\dbch\af12\langfe1081\dbch\af15\afs24\loch\f3\fs24\lang1033 List;}
|
||||
{\s22\sbasedon0\snext22\ql\widctlpar\hyphpar0\sb120\sa120\ltrpar\cf0\i\kerning1\dbch\af12\langfe1081\dbch\af15\afs24\loch\f3\fs24\lang1033 Caption;}
|
||||
{\s23\sbasedon0\snext23\ql\widctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af12\langfe1081\dbch\af15\afs24\loch\f3\fs24\lang1033 Index;}
|
||||
{\s24\snext24\ql\widctlpar\hyphpar0\li720\ri0\lin720\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f6\fs24\lang1033 Arrowhead List;}
|
||||
{\s25\sbasedon0\snext25\ql\widctlpar\hyphpar0\li1440\ri1440\lin1440\rin1440\fi0\sb0\sa120\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\loch\f3\fs24\lang1033 Block Text;}
|
||||
{\s26\snext26\ql\widctlpar\hyphpar0\li720\ri0\lin720\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f6\fs24\lang1033 Box List;}
|
||||
{\s27\snext27\ql\widctlpar\hyphpar0\li720\ri0\lin720\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f6\fs24\lang1033 Bullet List;}
|
||||
{\s28\snext28\tx1584\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af17\langfe2052\dbch\af12\afs24\alang1081\loch\f3\hich\af3\fs24\lang1033 Chapter Heading;}
|
||||
{\s29\sbasedon23\snext29\ql\widctlpar\hyphpar0\li720\ri0\lin720\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af12\langfe1081\dbch\af15\afs24\loch\f3\fs24\lang1033 Contents 1;}
|
||||
{\s30\sbasedon23\snext30\ql\widctlpar\hyphpar0\li1440\ri0\lin1440\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af12\langfe1081\dbch\af15\afs24\loch\f3\fs24\lang1033 Contents 2;}
|
||||
{\s31\sbasedon23\snext31\ql\widctlpar\hyphpar0\li2160\ri0\lin2160\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af12\langfe1081\dbch\af15\afs24\loch\f3\fs24\lang1033 Contents 3;}
|
||||
{\s32\sbasedon23\snext32\ql\widctlpar\hyphpar0\li2880\ri0\lin2880\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af12\langfe1081\dbch\af15\afs24\loch\f3\fs24\lang1033 Contents 4;}
|
||||
{\s33\snext33\qc\nowidctlpar\hyphpar0\sb240\sa120\ltrpar\cf0\b\kerning1\dbch\af12\langfe1081\dbch\af13\afs32\alang1033\loch\f7\fs24\lang1033 Contents Header;}
|
||||
{\s34\snext34\ql\widctlpar\hyphpar0\li720\ri0\lin720\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f6\fs24\lang1033 Dashed List;}
|
||||
{\s35\snext35\ql\widctlpar\hyphpar0\li720\ri0\lin720\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f6\fs24\lang1033 Diamond List;}
|
||||
{\s36\sbasedon0\snext36\ql\widctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\loch\f3\fs24\lang1033 Endnote;}
|
||||
{\s37\sbasedon0\snext37\ql\widctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\loch\f3\fs20\lang1033 Footnote;}
|
||||
{\s38\snext38\ql\widctlpar\hyphpar0\li720\ri0\lin720\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f6\fs24\lang1033 Hand List;}
|
||||
{\s39\snext39\ql\widctlpar\hyphpar0\li720\ri0\lin720\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f6\fs24\lang1033 Heart List;}
|
||||
{\s40\snext40\ql\widctlpar\hyphpar0\li720\ri0\lin720\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f6\fs24\lang1033 Implies List;}
|
||||
{\s41\snext41\ql\widctlpar\li720\ri0\lin720\rin0\fi-431\ltrpar\hyphpar0\dbch\af11\cf0\kerning1\langfe2052\dbch\af12\afs24\alang1081\loch\f6\fs24\lang1033 Lower Case List;}
|
||||
{\s42\snext42\ql\nowidctlpar\hyphpar0\li720\ri0\lin720\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af12\langfe1081\dbch\af15\afs24\alang1033\loch\f3\fs24\lang1033 Lower Roman List;}
|
||||
{\s43\snext43\ql\nowidctlpar\tx431\hyphpar0\ltrpar\cf0\kerning1\dbch\af12\langfe1081\dbch\af15\afs24\alang1033\loch\f3\fs24\lang1033 Numbered Heading 1;}
|
||||
{\s44\snext44\ql\nowidctlpar\tx431\hyphpar0\ltrpar\cf0\kerning1\dbch\af12\langfe1081\dbch\af15\afs24\alang1033\loch\f3\fs24\lang1033 Numbered Heading 2;}
|
||||
{\s45\snext45\ql\nowidctlpar\tx431\hyphpar0\ltrpar\cf0\kerning1\dbch\af12\langfe1081\dbch\af15\afs24\alang1033\loch\f3\fs24\lang1033 Numbered Heading 3;}
|
||||
{\s46\snext46\ql\widctlpar\hyphpar0\li720\ri0\lin720\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f6\fs24\lang1033 Numbered List;}
|
||||
{\s47\sbasedon0\snext47\ql\widctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\loch\f8\fs24\lang1033 Plain Text;}
|
||||
{\s48\sbasedon43\snext48\ql\nowidctlpar\tx1584\hyphpar0\ltrpar\cf0\kerning1\dbch\af12\langfe1081\dbch\af15\afs24\alang1033\loch\f3\fs24 Section Heading;}
|
||||
{\s49\snext49\ql\widctlpar\hyphpar0\li720\ri0\lin720\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f6\fs24\lang1033 Square List;}
|
||||
{\s50\snext50\ql\widctlpar\hyphpar0\li720\ri0\lin720\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f6\fs24\lang1033 Star List;}
|
||||
{\s51\snext51\ql\widctlpar\hyphpar0\li720\ri0\lin720\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f6\fs24\lang1033 Tick List;}
|
||||
{\s52\snext52\ql\widctlpar\hyphpar0\li720\ri0\lin720\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f6\fs24\lang1033 Triangle List;}
|
||||
{\s53\sbasedon46\snext53\ql\widctlpar\hyphpar0\li720\ri0\lin720\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\loch\f6\fs24\lang1033 Upper Case List;}
|
||||
{\s54\sbasedon46\snext54\ql\widctlpar\hyphpar0\li720\ri0\lin720\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\loch\f6\fs24\lang1033 Upper Roman List;}
|
||||
}{\*\listtable{\list\listtemplateid1
|
||||
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'02\'00);}{\levelnumbers\'01;}\fi-360\li720}
|
||||
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'02\'01.;}{\levelnumbers\'01;}\fi-360\li1080}
|
||||
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'02\'02.;}{\levelnumbers\'01;}\fi-360\li1440}
|
||||
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'02\'03.;}{\levelnumbers\'01;}\fi-360\li1800}
|
||||
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'02\'04.;}{\levelnumbers\'01;}\fi-360\li2160}
|
||||
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'02\'05.;}{\levelnumbers\'01;}\fi-360\li2520}
|
||||
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'02\'06.;}{\levelnumbers\'01;}\fi-360\li2880}
|
||||
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'02\'07.;}{\levelnumbers\'01;}\fi-360\li3240}
|
||||
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'02\'08.;}{\levelnumbers\'01;}\fi-360\li3600}\listid1}
|
||||
{\list\listtemplateid2
|
||||
{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
|
||||
{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
|
||||
{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
|
||||
{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
|
||||
{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
|
||||
{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
|
||||
{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
|
||||
{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
|
||||
{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}\listid2}
|
||||
}{\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}}{\*\generator LibreOffice/6.1.2.1$Linux_X86_64 LibreOffice_project/10$Build-1}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr2018\mo10\dy5\hr19\min21}{\printim\yr0\mo0\dy0\hr0\min0}}{\*\userprops}\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720
|
||||
\hyphauto0\viewscale150
|
||||
{\*\pgdsctbl
|
||||
{\pgdsc0\pgdscuse451\pgwsxn12240\pghsxn15840\marglsxn1440\margrsxn1440\margtsxn1440\margbsxn1440\pgdscnxt0 Default Style;}
|
||||
{\pgdsc1\pgdscuse451\pgndec\pgwsxn12240\pghsxn15840\marglsxn1134\margrsxn1134\margtsxn1134\margbsxn1134\pgdscnxt1 Endnote;}}
|
||||
\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1440\margr1440\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1440\margrsxn1440\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnar
|
||||
{\*\ftnsep\chftnsep}\pgndec\pard\plain \s0\ql\widctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f3\fs24\lang1033\sl240\slmult1\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640{\cf0\kerning1\dbch\af11\langfe1081\dbch\af14\rtlch \ltrch\loch\fs24\lang1033\loch\f6\hich\af6
|
||||
Installing TeleGPS software for Mac OS X computers}
|
||||
\par \pard\plain \s0\ql\widctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f3\fs24\lang1033\sl240\slmult1\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\cf0\kerning1\dbch\af11\langfe1081\dbch\af14\rtlch \ltrch\loch\fs24\lang1033\loch\f6\hich\af6
|
||||
|
||||
\par \pard\plain \s0\ql\widctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f3\fs24\lang1033{\cf0\kerning1\dbch\af10\langfe1081\dbch\af16\rtlch \ltrch\loch\fs24\lang1033\loch\f9\hich\af9
|
||||
The TeleGPS distribution for Mac OS X consists of:}
|
||||
\par \pard\plain \s0\ql\widctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f3\fs24\lang1033\cf0\kerning1\dbch\af10\langfe1081\dbch\af16\rtlch \ltrch\loch\fs24\lang1033\loch\f9\hich\af9
|
||||
|
||||
\par \pard\plain \s0\ql\widctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f3\fs24\lang1033{\listtext\pard\plain 1)\tab}\ilvl0\ls1 \li1440\ri0\lin1440\rin0\fi-360\li720\ri0\lin720\rin0\fi-360{\cf0\kerning1\dbch\af10\langfe1081\dbch\af16\rtlch \ltrch\loch\fs24\lang1033\loch\f9\hich\af9
|
||||
The TeleGPS application}
|
||||
\par \pard\plain \s0\ql\widctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f3\fs24\lang1033{\listtext\pard\plain 2)\tab}\ilvl0\ls1 \li1440\ri0\lin1440\rin0\fi-360\li720\ri0\lin720\rin0\fi-360{\cf0\kerning1\dbch\af10\langfe1081\dbch\af16\rtlch \ltrch\loch\fs24\lang1033\loch\f9\hich\af9
|
||||
Current AltOS firmware for TeleGPS products}
|
||||
\par \pard\plain \s0\ql\widctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f3\fs24\lang1033\cf0\kerning1\dbch\af10\langfe1081\dbch\af16\rtlch \ltrch\loch\fs24\lang1033\loch\f9\hich\af9
|
||||
|
||||
\par \pard\plain \s0\ql\widctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f3\fs24\lang1033{\cf0\kerning1\dbch\af10\langfe1081\dbch\af16\rtlch \ltrch\loch\fs24\lang1033\loch\f9\hich\af9
|
||||
Install the TeleGPS application by control-clicking the install-macosx script and selecting \u8220\'93Open\u8221\'94 from the menu. This will display a dialog asking if you are sure you want to open it. Select \u8220\'93Open\u8221\'94 from the dialog to execute the script. This will install the software, documentation and firmware in your home Applications/AltOS folder. You can move it afte}{\cf0\kerning1\dbch\af10\langfe1081\dbch\af16\rtlch \ltrch\loch\fs24\lang1033\loch\f9\hich\af9
|
||||
r}{\cf0\kerning1\dbch\af10\langfe1081\dbch\af16\rtlch \ltrch\loch\fs24\lang1033\loch\f9\hich\af9
|
||||
wards if you choose.}
|
||||
\par \pard\plain \s0\ql\widctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f3\fs24\lang1033\cf0\kerning1\dbch\af11\langfe1081\dbch\af16\rtlch \ltrch\loch\fs24\lang1033\loch\f9\hich\af9
|
||||
|
||||
\par \pard\plain \s0\ql\widctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f3\fs24\lang1033\sl240\slmult1\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640{\cf0\kerning1\dbch\af10\langfe1081\dbch\af14\rtlch \ltrch\loch\fs24\lang1033\loch\f6\hich\af6
|
||||
Thanks for choosing AltusMetrum products!}
|
||||
\par }
|
906
telegps/TeleGPS.app/Contents/MacOS/JavaApplicationStub
Executable file
906
telegps/TeleGPS.app/Contents/MacOS/JavaApplicationStub
Executable file
@@ -0,0 +1,906 @@
|
||||
#!/bin/bash
|
||||
##################################################################################
|
||||
# #
|
||||
# universalJavaApplicationStub #
|
||||
# #
|
||||
# A BASH based JavaApplicationStub for Java Apps on Mac OS X #
|
||||
# that works with both Apple's and Oracle's plist format. #
|
||||
# #
|
||||
# Inspired by Ian Roberts stackoverflow answer #
|
||||
# at http://stackoverflow.com/a/17546508/1128689 #
|
||||
# #
|
||||
# @author Tobias Fischer #
|
||||
# @url https://github.com/tofi86/universalJavaApplicationStub #
|
||||
# @date 2021-02-21 #
|
||||
# @version 3.2.0 #
|
||||
# #
|
||||
##################################################################################
|
||||
# #
|
||||
# The MIT License (MIT) #
|
||||
# #
|
||||
# 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 #
|
||||
# in the Software without restriction, including without limitation the rights #
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell #
|
||||
# copies of the Software, and to permit persons to whom the Software is #
|
||||
# furnished to do so, subject to the following conditions: #
|
||||
# #
|
||||
# The above copyright notice and this permission notice shall be included in all #
|
||||
# copies or substantial portions of the Software. #
|
||||
# #
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, #
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE #
|
||||
# SOFTWARE. #
|
||||
# #
|
||||
##################################################################################
|
||||
|
||||
#
|
||||
# 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()'
|
||||
#
|
||||
# A logger which logs to the macOS Console.app using the 'syslog' command
|
||||
#
|
||||
# @param1 the log message
|
||||
# @return void
|
||||
################################################################################
|
||||
function stub_logger() {
|
||||
syslog -s -k \
|
||||
Facility com.apple.console \
|
||||
Level Notice \
|
||||
Sender "$(basename "$0")" \
|
||||
Message "[$$][${CFBundleName:-$(basename "$0")}] $1"
|
||||
}
|
||||
|
||||
|
||||
|
||||
# set the directory abspath of the current
|
||||
# shell script with symlinks being resolved
|
||||
############################################
|
||||
|
||||
PRG=$0
|
||||
while [ -h "$PRG" ]; do
|
||||
ls=$(ls -ld "$PRG")
|
||||
link=$(expr "$ls" : '^.*-> \(.*\)$' 2>/dev/null)
|
||||
if expr "$link" : '^/' 2> /dev/null >/dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG="$(dirname "$PRG")/$link"
|
||||
fi
|
||||
done
|
||||
PROGDIR=$(dirname "$PRG")
|
||||
stub_logger "[StubDir] $PROGDIR"
|
||||
|
||||
|
||||
|
||||
# set files and folders
|
||||
############################################
|
||||
|
||||
# the absolute path of the app package
|
||||
cd "$PROGDIR"/../../ || exit 11
|
||||
AppPackageFolder=$(pwd)
|
||||
|
||||
# the base path of the app package
|
||||
cd .. || exit 12
|
||||
AppPackageRoot=$(pwd)
|
||||
|
||||
# set Apple's Java folder
|
||||
AppleJavaFolder="${AppPackageFolder}"/Contents/Resources/Java
|
||||
|
||||
# set Apple's Resources folder
|
||||
AppleResourcesFolder="${AppPackageFolder}"/Contents/Resources
|
||||
|
||||
# set Oracle's Java folder
|
||||
OracleJavaFolder="${AppPackageFolder}"/Contents/Java
|
||||
|
||||
# set Oracle's Resources folder
|
||||
OracleResourcesFolder="${AppPackageFolder}"/Contents/Resources
|
||||
|
||||
# set path to Info.plist in bundle
|
||||
InfoPlistFile="${AppPackageFolder}"/Contents/Info.plist
|
||||
|
||||
# set the default JVM Version to a null string
|
||||
JVMVersion=""
|
||||
JVMMaxVersion=""
|
||||
|
||||
|
||||
|
||||
# function 'plist_get()'
|
||||
#
|
||||
# read a specific Plist key with 'PlistBuddy' utility
|
||||
#
|
||||
# @param1 the Plist key with leading colon ':'
|
||||
# @return the value as String or Array
|
||||
################################################################################
|
||||
plist_get(){
|
||||
/usr/libexec/PlistBuddy -c "print $1" "${InfoPlistFile}" 2> /dev/null
|
||||
}
|
||||
|
||||
# function 'plist_get_java()'
|
||||
#
|
||||
# read a specific Plist key with 'PlistBuddy' utility
|
||||
# in the 'Java' or 'JavaX' dictionary (<dict>)
|
||||
#
|
||||
# @param1 the Plist :Java(X):Key with leading colon ':'
|
||||
# @return the value as String or Array
|
||||
################################################################################
|
||||
plist_get_java(){
|
||||
plist_get ${JavaKey:-":Java"}$1
|
||||
}
|
||||
|
||||
|
||||
|
||||
# read Info.plist and extract JVM options
|
||||
############################################
|
||||
|
||||
# read the program name from CFBundleName
|
||||
CFBundleName=$(plist_get ':CFBundleName')
|
||||
|
||||
# read the icon file name
|
||||
CFBundleIconFile=$(plist_get ':CFBundleIconFile')
|
||||
|
||||
|
||||
# check Info.plist for Apple style Java keys -> if key :Java is present, parse in apple mode
|
||||
/usr/libexec/PlistBuddy -c "print :Java" "${InfoPlistFile}" > /dev/null 2>&1
|
||||
exitcode=$?
|
||||
JavaKey=":Java"
|
||||
|
||||
# if no :Java key is present, check Info.plist for universalJavaApplication style JavaX keys -> if key :JavaX is present, parse in apple mode
|
||||
if [ $exitcode -ne 0 ]; then
|
||||
/usr/libexec/PlistBuddy -c "print :JavaX" "${InfoPlistFile}" > /dev/null 2>&1
|
||||
exitcode=$?
|
||||
JavaKey=":JavaX"
|
||||
fi
|
||||
|
||||
|
||||
# read 'Info.plist' file in Apple style if exit code returns 0 (true, ':Java' key is present)
|
||||
if [ $exitcode -eq 0 ]; then
|
||||
stub_logger "[PlistStyle] Apple"
|
||||
|
||||
# set Java and Resources folder
|
||||
JavaFolder="${AppleJavaFolder}"
|
||||
ResourcesFolder="${AppleResourcesFolder}"
|
||||
|
||||
# set expandable variables
|
||||
APP_ROOT="${AppPackageFolder}"
|
||||
APP_PACKAGE="${AppPackageFolder}"
|
||||
JAVAROOT="${AppleJavaFolder}"
|
||||
USER_HOME="$HOME"
|
||||
|
||||
|
||||
# read the Java WorkingDirectory
|
||||
JVMWorkDir=$(plist_get_java ':WorkingDirectory' | xargs)
|
||||
# set Working Directory based upon PList value
|
||||
if [[ ! -z ${JVMWorkDir} ]]; then
|
||||
WorkingDirectory="${JVMWorkDir}"
|
||||
else
|
||||
# AppPackageRoot is the standard WorkingDirectory when the script is started
|
||||
WorkingDirectory="${AppPackageRoot}"
|
||||
fi
|
||||
# expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
|
||||
WorkingDirectory=$(eval echo "${WorkingDirectory}")
|
||||
|
||||
|
||||
# read the MainClass name
|
||||
JVMMainClass="$(plist_get_java ':MainClass')"
|
||||
|
||||
# read the SplashFile name
|
||||
JVMSplashFile=$(plist_get_java ':SplashFile')
|
||||
|
||||
# read the JVM Properties as an array and retain spaces
|
||||
IFS=$'\t\n'
|
||||
JVMOptions=($(xargs -n1 <<<$(plist_get_java ':Properties' | grep " =" | sed 's/^ */-D/g' | sed -E 's/ = (.*)$/="\1"/g')))
|
||||
unset IFS
|
||||
# post processing of the array follows further below...
|
||||
|
||||
# read the ClassPath in either Array or String style
|
||||
JVMClassPath_RAW=$(plist_get_java ':ClassPath' | xargs)
|
||||
if [[ $JVMClassPath_RAW == *Array* ]] ; then
|
||||
JVMClassPath=.$(plist_get_java ':ClassPath' | grep " " | sed 's/^ */:/g' | tr -d '\n' | xargs)
|
||||
else
|
||||
JVMClassPath=${JVMClassPath_RAW}
|
||||
fi
|
||||
# expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
|
||||
JVMClassPath=$(eval echo "${JVMClassPath}")
|
||||
|
||||
# read the JVM Options in either Array or String style
|
||||
JVMDefaultOptions_RAW=$(plist_get_java ':VMOptions' | xargs)
|
||||
if [[ $JVMDefaultOptions_RAW == *Array* ]] ; then
|
||||
JVMDefaultOptions=$(plist_get_java ':VMOptions' | grep " " | sed 's/^ */ /g' | tr -d '\n' | xargs)
|
||||
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')
|
||||
if [ "${JVMStartOnMainThread}" == "true" ]; then
|
||||
JVMDefaultOptions+=" -XstartOnFirstThread"
|
||||
fi
|
||||
|
||||
# read the JVM Arguments in either Array or String style (#76) and retain spaces
|
||||
IFS=$'\t\n'
|
||||
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...
|
||||
|
||||
# read the Java version we want to find
|
||||
JVMVersion=$(plist_get_java ':JVMVersion' | xargs)
|
||||
# post processing of the version string follows below...
|
||||
|
||||
|
||||
# read 'Info.plist' file in Oracle style
|
||||
else
|
||||
stub_logger "[PlistStyle] Oracle"
|
||||
|
||||
# set Working Directory and Java and Resources folder
|
||||
JavaFolder="${OracleJavaFolder}"
|
||||
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')"
|
||||
|
||||
# read the SplashFile name
|
||||
JVMSplashFile=$(plist_get ':JVMSplashFile')
|
||||
|
||||
# read the JVM Options as an array and retain spaces
|
||||
IFS=$'\t\n'
|
||||
JVMOptions=($(plist_get ':JVMOptions' | grep " " | sed 's/^ *//g'))
|
||||
unset IFS
|
||||
# post processing of the array follows further below...
|
||||
|
||||
# read the ClassPath in either Array or String style
|
||||
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, $APP_ROOT, $JAVAROOT, $USER_HOME
|
||||
JVMClassPath=$(eval echo "${JVMClassPath}")
|
||||
|
||||
elif [[ ! -z ${JVMClassPath_RAW} ]] ; then
|
||||
JVMClassPath=${JVMClassPath_RAW}
|
||||
# expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
|
||||
JVMClassPath=$(eval echo "${JVMClassPath}")
|
||||
|
||||
else
|
||||
#default: fallback to OracleJavaFolder
|
||||
JVMClassPath="${JavaFolder}/*"
|
||||
# Do NOT expand the default 'AppName.app/Contents/Java/*' classpath (#42)
|
||||
fi
|
||||
|
||||
# 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'
|
||||
MainArgs=($(xargs -n1 <<<$(plist_get ':JVMArguments' | tr -d '\n' | sed -E 's/Array \{ *(.*) *\}/\1/g' | sed 's/ */ /g')))
|
||||
unset IFS
|
||||
# post processing of the array follows further below...
|
||||
|
||||
# read the Java version we want to find
|
||||
JVMVersion=$(plist_get ':JVMVersion' | xargs)
|
||||
# post processing of the version string follows below...
|
||||
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
|
||||
minMaxArray=(${JVMVersion//;/ })
|
||||
JVMVersion=${minMaxArray[0]//+}
|
||||
JVMMaxVersion=${minMaxArray[1]//+}
|
||||
fi
|
||||
stub_logger "[JavaRequirement] JVM minimum version: ${JVMVersion}"
|
||||
stub_logger "[JavaRequirement] JVM maximum version: ${JVMMaxVersion}"
|
||||
|
||||
# MainArgs: expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
|
||||
MainArgsArr=()
|
||||
for i in "${MainArgs[@]}"
|
||||
do
|
||||
MainArgsArr+=("$(eval echo "$i")")
|
||||
done
|
||||
|
||||
# JVMOptions: expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
|
||||
JVMOptionsArr=()
|
||||
for i in "${JVMOptions[@]}"
|
||||
do
|
||||
JVMOptionsArr+=("$(eval echo "$i")")
|
||||
done
|
||||
|
||||
|
||||
# internationalized messages
|
||||
############################################
|
||||
|
||||
# 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"
|
||||
|
||||
|
||||
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 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)"
|
||||
MSG_JAVA_VERSION_MAX="à %s"
|
||||
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="Java by Oracle"
|
||||
MSG_VISIT_ADOPTIUM="Java by Adoptium"
|
||||
;;
|
||||
|
||||
# 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."
|
||||
MSG_NO_SUITABLE_JAVA="Es wurde keine passende Java-Version auf Ihrem System gefunden!\nDieses Programm benötigt Java %s"
|
||||
MSG_JAVA_VERSION_OR_LATER="oder neuer"
|
||||
MSG_JAVA_VERSION_LATEST="(neuste Unterversion)"
|
||||
MSG_JAVA_VERSION_MAX="bis %s"
|
||||
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 von Oracle"
|
||||
MSG_VISIT_ADOPTIUM="Java von Adoptium"
|
||||
;;
|
||||
|
||||
# Simplified Chinese
|
||||
zh)
|
||||
MSG_ERROR_LAUNCHING="无法启动 '${CFBundleName}'."
|
||||
MSG_MISSING_MAINCLASS="没有指定 'MainClass'!\nJava程序无法启动!"
|
||||
MSG_JVMVERSION_REQ_INVALID="Java版本参数语法错误: %s\n请联系该应用的开发者。"
|
||||
MSG_NO_SUITABLE_JAVA="没有在系统中找到合适的Java版本!\n必须安装Java %s才能够使用该程序!"
|
||||
MSG_JAVA_VERSION_OR_LATER="及以上版本"
|
||||
MSG_JAVA_VERSION_LATEST="(最新版本)"
|
||||
MSG_JAVA_VERSION_MAX="最高为 %s"
|
||||
MSG_NO_SUITABLE_JAVA_CHECK="请确保系统中安装了所需的Java版本"
|
||||
MSG_INSTALL_JAVA="你需要在Mac中安装Java运行环境!\n访问 java.com 了解如何安装。"
|
||||
MSG_LATER="稍后"
|
||||
MSG_VISIT_JAVA_DOT_COM="Java by Oracle"
|
||||
MSG_VISIT_ADOPTIUM="Java by Adoptium"
|
||||
;;
|
||||
|
||||
# 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_ADOPTIUM="Java de Adoptium"
|
||||
;;
|
||||
|
||||
# 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."
|
||||
MSG_NO_SUITABLE_JAVA="No suitable Java version found on your system!\nThis program requires Java %s"
|
||||
MSG_JAVA_VERSION_OR_LATER="or later"
|
||||
MSG_JAVA_VERSION_LATEST="(latest update)"
|
||||
MSG_JAVA_VERSION_MAX="up to %s"
|
||||
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="Java by Oracle"
|
||||
MSG_VISIT_ADOPTIUM="Java by Adoptium"
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
|
||||
# function 'get_java_version_from_cmd()'
|
||||
#
|
||||
# returns Java version string from 'java -version' command
|
||||
# works for both old (1.8) and new (9) version schema
|
||||
#
|
||||
# @param1 path to a java JVM executable
|
||||
# @return the Java version number as displayed in 'java -version' command
|
||||
################################################################################
|
||||
function get_java_version_from_cmd() {
|
||||
# second sed command strips " and -ea from the version string
|
||||
echo $("$1" -version 2>&1 | awk '/version/{print $3}' | sed -E 's/"//g;s/-ea//g')
|
||||
}
|
||||
|
||||
|
||||
# function 'extract_java_major_version()'
|
||||
#
|
||||
# extract Java major version from a version string
|
||||
#
|
||||
# @param1 a Java version number ('1.8.0_45') or requirement string ('1.8+')
|
||||
# @return the major version (e.g. '7', '8' or '9', etc.)
|
||||
################################################################################
|
||||
function extract_java_major_version() {
|
||||
echo $(echo "$1" | sed -E 's/^1\.//;s/^([0-9]+)(-ea|(\.[0-9_.]{1,7})?)(-b[0-9]+-[0-9]+)?[+*]?$/\1/')
|
||||
}
|
||||
|
||||
|
||||
# function 'get_comparable_java_version()'
|
||||
#
|
||||
# return comparable version for a Java version number or requirement string
|
||||
#
|
||||
# @param1 a Java version number ('1.8.0_45') or requirement string ('1.8+')
|
||||
# @return an 8 digit numeral ('1.8.0_45'->'08000045'; '9.1.13'->'09001013')
|
||||
################################################################################
|
||||
function get_comparable_java_version() {
|
||||
# cleaning: 1) remove leading '1.'; 2) remove build string (e.g. '-b14-468'); 3) remove 'a-Z' and '-*+' (e.g. '-ea'); 4) replace '_' with '.'
|
||||
local cleaned=$(echo "$1" | sed -E 's/^1\.//g;s/-b[0-9]+-[0-9]+$//g;s/[a-zA-Z+*\-]//g;s/_/./g')
|
||||
# splitting at '.' into an array
|
||||
local arr=( ${cleaned//./ } )
|
||||
# echo a string with left padded version numbers
|
||||
echo "$(printf '%02s' ${arr[0]})$(printf '%03s' ${arr[1]})$(printf '%03s' ${arr[2]})"
|
||||
}
|
||||
|
||||
|
||||
# function 'is_valid_requirement_pattern()'
|
||||
#
|
||||
# check whether the Java requirement is a valid requirement pattern
|
||||
#
|
||||
# supported requirements are for example:
|
||||
# - 1.6 requires Java 6 (any update) [1.6, 1.6.0_45, 1.6.0_88]
|
||||
# - 1.6* requires Java 6 (any update) [1.6, 1.6.0_45, 1.6.0_88]
|
||||
# - 1.6+ requires Java 6 or higher [1.6, 1.6.0_45, 1.8, 9, etc.]
|
||||
# - 1.6.0 requires Java 6 (any update) [1.6, 1.6.0_45, 1.6.0_88]
|
||||
# - 1.6.0_45 requires Java 6u45 [1.6.0_45]
|
||||
# - 1.6.0_45+ requires Java 6u45 or higher [1.6.0_45, 1.6.0_88, 1.8, etc.]
|
||||
# - 9 requires Java 9 (any update) [9.0.*, 9.1, 9.3, etc.]
|
||||
# - 9* requires Java 9 (any update) [9.0.*, 9.1, 9.3, etc.]
|
||||
# - 9+ requires Java 9 or higher [9.0, 9.1, 10, etc.]
|
||||
# - 9.1 requires Java 9.1 (any update) [9.1.*, 9.1.2, 9.1.13, etc.]
|
||||
# - 9.1* requires Java 9.1 (any update) [9.1.*, 9.1.2, 9.1.13, etc.]
|
||||
# - 9.1+ requires Java 9.1 or higher [9.1, 9.2, 10, etc.]
|
||||
# - 9.1.3 requires Java 9.1.3 [9.1.3]
|
||||
# - 9.1.3* requires Java 9.1.3 (any update) [9.1.3]
|
||||
# - 9.1.3+ requires Java 9.1.3 or higher [9.1.3, 9.1.4, 9.2.*, 10, etc.]
|
||||
# - 10-ea requires Java 10 (early access release)
|
||||
#
|
||||
# unsupported requirement patterns are for example:
|
||||
# - 1.2, 1.3, 1.9 Java 2, 3 are not supported
|
||||
# - 1.9 Java 9 introduced a new versioning scheme
|
||||
# - 6u45 known versioning syntax, but unsupported
|
||||
# - 9-ea*, 9-ea+ early access releases paired with */+
|
||||
# - 9., 9.*, 9.+ version ending with a .
|
||||
# - 9.1., 9.1.*, 9.1.+ version ending with a .
|
||||
# - 9.3.5.6 4 part version number is unsupported
|
||||
#
|
||||
# @param1 a Java requirement string ('1.8+')
|
||||
# @return boolean exit code: 0 (is valid), 1 (is not valid)
|
||||
################################################################################
|
||||
function is_valid_requirement_pattern() {
|
||||
local java_req=$1
|
||||
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
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
|
||||
# determine which JVM to use
|
||||
############################################
|
||||
|
||||
# default Apple JRE plugin path (< 1.6)
|
||||
apple_jre_plugin="/Library/Java/Home/bin/java"
|
||||
apple_jre_version=$(get_java_version_from_cmd "${apple_jre_plugin}")
|
||||
# default Oracle JRE plugin path (>= 1.7)
|
||||
oracle_jre_plugin="/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java"
|
||||
oracle_jre_version=$(get_java_version_from_cmd "${oracle_jre_plugin}")
|
||||
|
||||
|
||||
# first check system variable "$JAVA_HOME" -> has precedence over any other System JVM
|
||||
stub_logger '[JavaSearch] Checking for $JAVA_HOME ...'
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
stub_logger "[JavaSearch] ... found JAVA_HOME with value $JAVA_HOME"
|
||||
|
||||
# PR 26: Allow specifying "$JAVA_HOME" relative to "$AppPackageFolder"
|
||||
# which allows for bundling a custom version of Java inside your app!
|
||||
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] ... 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
|
||||
|
||||
# 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=""
|
||||
|
||||
# first check whether JVMVersion string is a valid requirement string
|
||||
if [ ! -z "${JVMVersion}" ] && ! is_valid_requirement_pattern ${JVMVersion} ; then
|
||||
MSG_JVMVERSION_REQ_INVALID_EXPANDED=$(printf "${MSG_JVMVERSION_REQ_INVALID}" "${JVMVersion}")
|
||||
# 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${DialogWithIcon}"
|
||||
# exit with error
|
||||
exit 4
|
||||
fi
|
||||
# then check whether JVMMaxVersion string is a valid requirement string
|
||||
if [ ! -z "${JVMMaxVersion}" ] && ! is_valid_requirement_pattern ${JVMMaxVersion} ; then
|
||||
MSG_JVMVERSION_REQ_INVALID_EXPANDED=$(printf "${MSG_JVMVERSION_REQ_INVALID}" "${JVMMaxVersion}")
|
||||
# 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${DialogWithIcon}"
|
||||
# exit with error
|
||||
exit 5
|
||||
fi
|
||||
|
||||
|
||||
# find installed JavaVirtualMachines (JDK + JRE)
|
||||
allJVMs=()
|
||||
|
||||
# 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
|
||||
allJVMs+=("$apple_jre_version:$apple_jre_plugin")
|
||||
fi
|
||||
|
||||
# add Oracle JRE if available
|
||||
if [ -x "${oracle_jre_plugin}" ] ; then
|
||||
allJVMs+=("$oracle_jre_version:$oracle_jre_plugin")
|
||||
fi
|
||||
|
||||
# debug output
|
||||
for i in "${allJVMs[@]}"
|
||||
do
|
||||
stub_logger "[JavaSearch] ... found JVM: $i"
|
||||
done
|
||||
|
||||
|
||||
# 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=()
|
||||
|
||||
for i in "${allJVMs[@]}"
|
||||
do
|
||||
# split JVM string at ':' delimiter to retain spaces in $path substring
|
||||
IFS=: arr=($i) ; unset IFS
|
||||
# [0] JVM version number
|
||||
ver=${arr[0]}
|
||||
# comparable JVM version number
|
||||
comp=$(get_comparable_java_version $ver)
|
||||
# [1] JVM path
|
||||
path="${arr[1]}"
|
||||
# construct string item for adding to the "matchingJVMs" array
|
||||
item="$comp:$ver:$path"
|
||||
|
||||
# pre-requisite: current version number needs to be greater than min version number
|
||||
if [ "$comp" -ge "$minC" ] ; then
|
||||
|
||||
# perform max version checks if max version requirement is present
|
||||
if [ ! -z ${JVMMaxVersion} ] ; then
|
||||
|
||||
# max version requirement ends with '*' modifier
|
||||
if [[ ${JVMMaxVersion} == *\* ]] ; then
|
||||
|
||||
# use the '*' modifier from the max version string as wildcard for a 'starts with' comparison
|
||||
# and check whether the current version number starts with the max version wildcard string
|
||||
if [[ ${ver} == ${JVMMaxVersion} ]]; then
|
||||
matchingJVMs+=("$item")
|
||||
|
||||
# or whether the current comparable version is lower than the comparable max version
|
||||
elif [ "$comp" -le "$maxC" ] ; then
|
||||
matchingJVMs+=("$item")
|
||||
fi
|
||||
|
||||
# max version requirement ends with '+' modifier -> always add this version if it's greater than $min
|
||||
# because a max requirement with + modifier doesn't make sense
|
||||
elif [[ ${JVMMaxVersion} == *+ ]] ; then
|
||||
matchingJVMs+=("$item")
|
||||
|
||||
# matches 6 zeros at the end of the max version string (e.g. for 1.8, 9)
|
||||
# -> then the max version string should be treated like with a '*' modifier at the end
|
||||
#elif [[ ${maxC} =~ ^[0-9]{2}0{6}$ ]] && [ "$comp" -le $(( ${maxC#0} + 999 )) ] ; then
|
||||
# matchingJVMs+=("$item")
|
||||
|
||||
# matches 3 zeros at the end of the max version string (e.g. for 9.1, 10.3)
|
||||
# -> then the max version string should be treated like with a '*' modifier at the end
|
||||
#elif [[ ${maxC} =~ ^[0-9]{5}0{3}$ ]] && [ "$comp" -le "${maxC}" ] ; then
|
||||
# matchingJVMs+=("$item")
|
||||
|
||||
# matches standard requirements without modifier
|
||||
elif [ "$comp" -le "$maxC" ]; then
|
||||
matchingJVMs+=("$item")
|
||||
fi
|
||||
|
||||
# no max version requirement:
|
||||
|
||||
# min version requirement ends with '+' modifier
|
||||
# -> always add the current version because it's greater than $min
|
||||
elif [[ ${JVMVersion} == *+ ]] ; then
|
||||
matchingJVMs+=("$item")
|
||||
|
||||
# min version requirement ends with '*' modifier
|
||||
# -> use the '*' modifier from the min version string as wildcard for a 'starts with' comparison
|
||||
# and check whether the current version number starts with the min version wildcard string
|
||||
elif [[ ${JVMVersion} == *\* ]] ; then
|
||||
if [[ ${ver} == ${JVMVersion} ]] ; then
|
||||
matchingJVMs+=("$item")
|
||||
fi
|
||||
|
||||
# compare the min version against the current version with an additional * wildcard for a 'starts with' comparison
|
||||
# -> e.g. add 1.8.0_44 when the requirement is 1.8
|
||||
elif [[ ${ver} == ${JVMVersion}* ]] ; then
|
||||
matchingJVMs+=("$item")
|
||||
fi
|
||||
fi
|
||||
done
|
||||
# unset for loop variables
|
||||
unset arr ver comp path item
|
||||
|
||||
# debug output
|
||||
for i in "${matchingJVMs[@]}"
|
||||
do
|
||||
stub_logger "[JavaSearch] ... matches all requirements: $i"
|
||||
done
|
||||
|
||||
|
||||
# sort the matching JavaVirtualMachines by version number
|
||||
# https://stackoverflow.com/a/11789688/1128689
|
||||
IFS=$'\n' matchingJVMs=($(sort -nr <<<"${matchingJVMs[*]}"))
|
||||
unset IFS
|
||||
|
||||
|
||||
# get the highest matching JVM
|
||||
for ((i = 0; i < ${#matchingJVMs[@]}; i++));
|
||||
do
|
||||
# split JVM string at ':' delimiter to retain spaces in $path substring
|
||||
IFS=: arr=(${matchingJVMs[$i]}) ; unset IFS
|
||||
# [0] comparable JVM version number
|
||||
comp=${arr[0]}
|
||||
# [1] JVM version number
|
||||
ver=${arr[1]}
|
||||
# [2] JVM path
|
||||
path="${arr[2]}"
|
||||
|
||||
# use current value as JAVACMD if it's executable
|
||||
if [ -x "$path" ] ; then
|
||||
JAVACMD="$path"
|
||||
JAVACMD_version=$comp
|
||||
break
|
||||
fi
|
||||
done
|
||||
# unset for loop variables
|
||||
unset arr comp ver path
|
||||
fi
|
||||
|
||||
# log the Java Command and the extracted version number
|
||||
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
|
||||
|
||||
# different error messages when a specific JVM was required
|
||||
if [ ! -z "${JVMVersion}" ] ; then
|
||||
# display human readable java version (#28)
|
||||
java_version_hr=$(echo ${JVMVersion} | sed -E 's/^1\.([0-9+*]+)$/ \1/g' | sed "s/+/ ${MSG_JAVA_VERSION_OR_LATER}/;s/*/ ${MSG_JAVA_VERSION_LATEST}/")
|
||||
MSG_NO_SUITABLE_JAVA_EXPANDED=$(printf "${MSG_NO_SUITABLE_JAVA}" "${java_version_hr}").
|
||||
|
||||
if [ ! -z "${JVMMaxVersion}" ] ; then
|
||||
java_version_hr=$(extract_java_major_version ${JVMVersion})
|
||||
java_version_max_hr=$(echo ${JVMMaxVersion} | sed -E 's/^1\.([0-9+*]+)$/ \1/g' | sed "s/+//;s/*/ ${MSG_JAVA_VERSION_LATEST}/")
|
||||
MSG_NO_SUITABLE_JAVA_EXPANDED="$(printf "${MSG_NO_SUITABLE_JAVA}" "${java_version_hr}") $(printf "${MSG_JAVA_VERSION_MAX}" "${java_version_max_hr}")"
|
||||
fi
|
||||
|
||||
# log exit cause
|
||||
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}\", \"${MSG_VISIT_ADOPTIUM}\"} 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 \"https://www.java.com/download/\"" \
|
||||
-e "if response is \"${MSG_VISIT_ADOPTIUM}\" then open location \"https://adoptium.net/releases.html\""
|
||||
# exit with error
|
||||
exit 3
|
||||
|
||||
else
|
||||
# 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}\", \"${MSG_VISIT_ADOPTIUM}\"} 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 \"https://www.java.com/download/\"" \
|
||||
-e "if response is \"${MSG_VISIT_ADOPTIUM}\" then open location \"https://adoptium.net/releases.html\""
|
||||
# exit with error
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
|
||||
# MainClass check
|
||||
############################################
|
||||
|
||||
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${DialogWithIcon}"
|
||||
# exit with error
|
||||
exit 2
|
||||
fi
|
||||
|
||||
|
||||
|
||||
# execute $JAVACMD and do some preparation
|
||||
############################################
|
||||
|
||||
# enable drag&drop to the dock icon
|
||||
export CFProcessPath="$0"
|
||||
|
||||
# remove Apples ProcessSerialNumber from passthru arguments (#39)
|
||||
if [[ "$*" == -psn* ]] ; then
|
||||
ArgsPassthru=()
|
||||
else
|
||||
ArgsPassthru=("$@")
|
||||
fi
|
||||
|
||||
# change to Working Directory based upon Apple/Oracle Plist info
|
||||
cd "${WorkingDirectory}" || exit 13
|
||||
stub_logger "[WorkingDirectory] ${WorkingDirectory}"
|
||||
|
||||
# execute Java and set
|
||||
# - classpath
|
||||
# - splash image
|
||||
# - dock icon
|
||||
# - app name
|
||||
# - JVM options / properties (-D)
|
||||
# - JVM default options (-X)
|
||||
# - main class
|
||||
# - main class arguments
|
||||
# - passthrough arguments from Terminal or Drag'n'Drop to Finder icon
|
||||
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}" \
|
||||
${JVMSplashFile:+ -splash:"${ResourcesFolder}/${JVMSplashFile}"} \
|
||||
-Xdock:icon="${ResourcesFolder}/${CFBundleIconFile}" \
|
||||
-Xdock:name="${CFBundleName}" \
|
||||
${JVMOptionsArr:+"${JVMOptionsArr[@]}" }\
|
||||
${JVMDefaultOptions:+$JVMDefaultOptions }\
|
||||
"${JVMMainClass}"\
|
||||
${MainArgsArr:+ "${MainArgsArr[@]}"}\
|
||||
${ArgsPassthru:+ "${ArgsPassthru[@]}"}
|
1
telegps/TeleGPS.app/Contents/PkgInfo
Normal file
1
telegps/TeleGPS.app/Contents/PkgInfo
Normal file
@@ -0,0 +1 @@
|
||||
APPLAM.O
|
BIN
telegps/TeleGPS.app/Contents/Resources/TeleGPSIcon.icns
Normal file
BIN
telegps/TeleGPS.app/Contents/Resources/TeleGPSIcon.icns
Normal file
Binary file not shown.
777
telegps/TeleGPS.java
Normal file
777
telegps/TeleGPS.java
Normal file
@@ -0,0 +1,777 @@
|
||||
/*
|
||||
* Copyright © 2014 Keith Packard <keithp@keithp.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
*/
|
||||
|
||||
package org.altusmetrum.telegps;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import java.io.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
import org.altusmetrum.altoslib_14.*;
|
||||
import org.altusmetrum.altosuilib_14.*;
|
||||
|
||||
public class TeleGPS
|
||||
extends AltosUIFrame
|
||||
implements AltosFlightDisplay, AltosFontListener, AltosUnitsListener, ActionListener, AltosEepromGrapher
|
||||
{
|
||||
|
||||
static String[] telegps_icon_names = {
|
||||
"/altusmetrum-telegps-16.png",
|
||||
"/altusmetrum-telegps-32.png",
|
||||
"/altusmetrum-telegps-48.png",
|
||||
"/altusmetrum-telegps-64.png",
|
||||
"/altusmetrum-telegps-128.png",
|
||||
"/altusmetrum-telegps-256.png"
|
||||
};
|
||||
|
||||
static { set_icon_names(telegps_icon_names); }
|
||||
|
||||
static AltosVoice voice;
|
||||
|
||||
static AltosVoice voice() {
|
||||
if (voice == null)
|
||||
voice = new AltosVoice();
|
||||
return voice;
|
||||
}
|
||||
|
||||
AltosFlightReader reader;
|
||||
TeleGPSDisplayThread thread;
|
||||
boolean idle_mode;
|
||||
|
||||
JMenuBar menu_bar;
|
||||
|
||||
JMenu file_menu;
|
||||
JMenu monitor_menu;
|
||||
JMenu device_menu;
|
||||
AltosUIFreqList frequencies;
|
||||
ActionListener frequency_listener;
|
||||
AltosUIRateList rates;
|
||||
ActionListener rate_listener;
|
||||
|
||||
Container bag;
|
||||
|
||||
TeleGPSStatus telegps_status;
|
||||
TeleGPSStatusUpdate status_update;
|
||||
|
||||
JTabbedPane pane;
|
||||
|
||||
AltosUIMap map;
|
||||
TeleGPSInfo gps_info;
|
||||
TeleGPSState gps_state;
|
||||
AltosInfoTable info_table;
|
||||
|
||||
LinkedList<AltosFlightDisplay> displays;
|
||||
|
||||
/* File menu */
|
||||
final static String new_command = "new";
|
||||
final static String graph_command = "graph";
|
||||
final static String export_command = "export";
|
||||
final static String load_maps_command = "loadmaps";
|
||||
final static String preferences_command = "preferences";
|
||||
final static String close_command = "close";
|
||||
final static String exit_command = "exit";
|
||||
|
||||
static final String[][] file_menu_entries = new String[][] {
|
||||
{ "New Window", new_command },
|
||||
{ "Graph Data", graph_command },
|
||||
{ "Export Data", export_command },
|
||||
{ "Load Maps", load_maps_command },
|
||||
{ "Preferences", preferences_command },
|
||||
{ "Close", close_command },
|
||||
{ "Exit", exit_command },
|
||||
};
|
||||
|
||||
/* Monitor menu */
|
||||
final static String connect_command = "connect";
|
||||
final static String disconnect_command = "disconnect";
|
||||
final static String scan_command = "scan";
|
||||
|
||||
static final String[][] monitor_menu_entries = new String[][] {
|
||||
{ "Connect Device", connect_command },
|
||||
{ "Disconnect", disconnect_command },
|
||||
{ "Scan Channels", scan_command },
|
||||
};
|
||||
|
||||
/* Device menu */
|
||||
final static String download_command = "download";
|
||||
final static String configure_command = "configure";
|
||||
final static String flash_command = "flash";
|
||||
|
||||
static final String[][] device_menu_entries = new String[][] {
|
||||
{ "Download Data", download_command },
|
||||
{ "Configure Device", configure_command },
|
||||
{ "Flash Device", flash_command },
|
||||
};
|
||||
|
||||
void stop_display() {
|
||||
if (thread != null && thread.isAlive()) {
|
||||
thread.interrupt();
|
||||
try {
|
||||
thread.join();
|
||||
} catch (InterruptedException ie) {}
|
||||
}
|
||||
thread = null;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
for (AltosFlightDisplay display : displays)
|
||||
display.reset();
|
||||
}
|
||||
|
||||
public void font_size_changed(int font_size) {
|
||||
for (AltosFlightDisplay display : displays)
|
||||
display.font_size_changed(font_size);
|
||||
}
|
||||
|
||||
public void units_changed(boolean imperial_units) {
|
||||
for (AltosFlightDisplay display : displays)
|
||||
display.units_changed(imperial_units);
|
||||
}
|
||||
|
||||
public void show(AltosState state, AltosListenerState listener_state) {
|
||||
try {
|
||||
status_update.saved_state = state;
|
||||
status_update.saved_listener_state = listener_state;
|
||||
|
||||
if (state == null)
|
||||
state = new AltosState(new AltosCalData());
|
||||
|
||||
int i = 0;
|
||||
for (AltosFlightDisplay display : displays) {
|
||||
display.show(state, listener_state);
|
||||
i++;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
System.out.printf("Exception %s\n", ex.toString());
|
||||
for (StackTraceElement e : ex.getStackTrace())
|
||||
System.out.printf("%s\n", e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
void new_window() {
|
||||
new TeleGPS();
|
||||
}
|
||||
|
||||
void preferences() {
|
||||
new TeleGPSPreferences(this, voice());
|
||||
}
|
||||
|
||||
void load_maps() {
|
||||
new AltosUIMapPreload(this);
|
||||
}
|
||||
|
||||
void disconnect() {
|
||||
setTitle("TeleGPS");
|
||||
stop_display();
|
||||
telegps_status.stop();
|
||||
|
||||
telegps_status.disable_receive();
|
||||
disable_frequency_menu();
|
||||
disable_rate_menu();
|
||||
}
|
||||
|
||||
void connect_flight(AltosDevice device) {
|
||||
try {
|
||||
AltosFlightReader reader = new AltosTelemetryReader(new AltosSerial(device));
|
||||
set_reader(reader, device, false);
|
||||
} catch (FileNotFoundException ee) {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
ee.getMessage(),
|
||||
String.format ("Cannot open %s", device.toShortString()),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
} catch (AltosSerialInUseException si) {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
String.format("Device \"%s\" already in use",
|
||||
device.toShortString()),
|
||||
"Device in use",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
} catch (IOException ee) {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
String.format ("Unknown I/O error on %s", device.toShortString()),
|
||||
"Unknown I/O error",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
} catch (TimeoutException te) {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
String.format ("Timeout on %s", device.toShortString()),
|
||||
"Timeout error",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
} catch (InterruptedException ie) {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
String.format("Interrupted %s", device.toShortString()),
|
||||
"Interrupted exception",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
void connect_idle(AltosDevice device) {
|
||||
try {
|
||||
AltosFlightReader reader = new AltosIdleReader(new AltosSerial(device), false);
|
||||
set_reader(reader, device, true);
|
||||
} catch (FileNotFoundException ee) {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
ee.getMessage(),
|
||||
String.format ("Cannot open %s", device.toShortString()),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
} catch (AltosSerialInUseException si) {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
String.format("Device \"%s\" already in use",
|
||||
device.toShortString()),
|
||||
"Device in use",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
} catch (IOException ee) {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
String.format ("Unknown I/O error on %s", device.toShortString()),
|
||||
"Unknown I/O error",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
} catch (TimeoutException te) {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
String.format ("Timeout on %s", device.toShortString()),
|
||||
"Timeout error",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
} catch (InterruptedException ie) {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
String.format("Interrupted %s", device.toShortString()),
|
||||
"Interrupted exception",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
void connect(AltosDevice device) {
|
||||
if (reader != null)
|
||||
disconnect();
|
||||
if (device.matchProduct(AltosLib.product_basestation))
|
||||
connect_flight(device);
|
||||
else
|
||||
connect_idle(device);
|
||||
}
|
||||
|
||||
void connect() {
|
||||
AltosDevice device = AltosDeviceUIDialog.show(this,
|
||||
AltosLib.product_any);
|
||||
if (device == null)
|
||||
return;
|
||||
connect(device);
|
||||
}
|
||||
|
||||
public void scan_device_selected(AltosDevice device) {
|
||||
connect(device);
|
||||
}
|
||||
|
||||
void scan() {
|
||||
new AltosScanUI(this, false);
|
||||
}
|
||||
|
||||
void download(){
|
||||
new AltosEepromManage(this, this, AltosLib.product_telegps);
|
||||
}
|
||||
|
||||
void configure() {
|
||||
new TeleGPSConfig(this);
|
||||
}
|
||||
|
||||
private static AltosFlightSeries make_series(AltosRecordSet set) {
|
||||
AltosFlightSeries series = new AltosFlightSeries(set.cal_data());
|
||||
set.capture_series(series);
|
||||
series.finish();
|
||||
return series;
|
||||
}
|
||||
|
||||
void export() {
|
||||
AltosDataChooser chooser = new AltosDataChooser(this);
|
||||
|
||||
AltosRecordSet set = chooser.runDialog();
|
||||
if (set == null)
|
||||
return;
|
||||
AltosFlightSeries series = make_series(set);
|
||||
new AltosCSVUI(this, series, chooser.file());
|
||||
}
|
||||
|
||||
void graph() {
|
||||
AltosDataChooser chooser = new AltosDataChooser(this);
|
||||
AltosRecordSet set = chooser.runDialog();
|
||||
graph_file(this, set, chooser.file());
|
||||
}
|
||||
|
||||
public void graph_flights(AltosEepromList list) {
|
||||
for (AltosEepromLog log : list) {
|
||||
if (log.file != null) {
|
||||
AltosRecordSet set = record_set(log.file);
|
||||
graph_file(this, set, log.file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void flash() {
|
||||
AltosFlashUI.show(this);
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent ev) {
|
||||
|
||||
/* File menu */
|
||||
if (new_command.equals(ev.getActionCommand())) {
|
||||
new_window();
|
||||
return;
|
||||
}
|
||||
if (preferences_command.equals(ev.getActionCommand())) {
|
||||
preferences();
|
||||
return;
|
||||
}
|
||||
if (load_maps_command.equals(ev.getActionCommand())) {
|
||||
load_maps();
|
||||
return;
|
||||
}
|
||||
if (close_command.equals(ev.getActionCommand())) {
|
||||
close();
|
||||
return;
|
||||
}
|
||||
if (exit_command.equals(ev.getActionCommand()))
|
||||
System.exit(0);
|
||||
|
||||
/* Monitor menu */
|
||||
if (connect_command.equals(ev.getActionCommand())) {
|
||||
connect();
|
||||
return;
|
||||
}
|
||||
if (disconnect_command.equals(ev.getActionCommand())) {
|
||||
disconnect();
|
||||
return;
|
||||
}
|
||||
if (scan_command.equals(ev.getActionCommand())) {
|
||||
scan();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Device menu */
|
||||
if (download_command.equals(ev.getActionCommand())) {
|
||||
download();
|
||||
return;
|
||||
}
|
||||
if (configure_command.equals(ev.getActionCommand())) {
|
||||
configure();
|
||||
return;
|
||||
}
|
||||
if (export_command.equals(ev.getActionCommand())) {
|
||||
export();
|
||||
return;
|
||||
}
|
||||
if (graph_command.equals(ev.getActionCommand())) {
|
||||
graph();
|
||||
return;
|
||||
}
|
||||
if (flash_command.equals(ev.getActionCommand())) {
|
||||
flash();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void enable_frequency_menu(int serial, final AltosFlightReader reader) {
|
||||
|
||||
if (frequency_listener != null)
|
||||
disable_frequency_menu();
|
||||
|
||||
frequency_listener = new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
double frequency = frequencies.frequency();
|
||||
try {
|
||||
reader.set_frequency(frequency);
|
||||
} catch (TimeoutException te) {
|
||||
} catch (InterruptedException ie) {
|
||||
}
|
||||
reader.save_frequency();
|
||||
}
|
||||
};
|
||||
|
||||
frequencies.addActionListener(frequency_listener);
|
||||
frequencies.set_product("Monitor");
|
||||
frequencies.set_serial(serial);
|
||||
frequencies.set_frequency(AltosUIPreferences.frequency(serial));
|
||||
frequencies.setEnabled(true);
|
||||
|
||||
}
|
||||
|
||||
void disable_frequency_menu() {
|
||||
if (frequency_listener != null) {
|
||||
frequencies.removeActionListener(frequency_listener);
|
||||
frequencies.setEnabled(false);
|
||||
frequency_listener = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void enable_rate_menu(int serial, final AltosFlightReader reader) {
|
||||
|
||||
if (rate_listener != null)
|
||||
disable_rate_menu();
|
||||
|
||||
rate_listener = new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
int rate = rates.rate();
|
||||
try {
|
||||
reader.set_telemetry_rate(rate);
|
||||
} catch (TimeoutException te) {
|
||||
} catch (InterruptedException ie) {
|
||||
}
|
||||
reader.save_telemetry_rate();
|
||||
}
|
||||
};
|
||||
|
||||
rates.addActionListener(rate_listener);
|
||||
rates.set_product("Monitor");
|
||||
rates.set_serial(serial);
|
||||
rates.set_rate(AltosUIPreferences.telemetry_rate(serial));
|
||||
rates.setEnabled(reader.supports_telemetry_rate(AltosLib.ao_telemetry_rate_2400));
|
||||
}
|
||||
|
||||
void disable_rate_menu() {
|
||||
if (rate_listener != null) {
|
||||
rates.removeActionListener(rate_listener);
|
||||
rates.setEnabled(false);
|
||||
rate_listener = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void set_reader(AltosFlightReader reader, AltosDevice device, boolean idle_mode) {
|
||||
this.idle_mode = idle_mode;
|
||||
status_update = new TeleGPSStatusUpdate(telegps_status);
|
||||
|
||||
telegps_status.start(status_update);
|
||||
|
||||
setTitle(String.format("TeleGPS %s", reader.name));
|
||||
thread = new TeleGPSDisplayThread(this, voice(), this, reader);
|
||||
thread.start();
|
||||
|
||||
if (device != null) {
|
||||
if (idle_mode) {
|
||||
disable_frequency_menu();
|
||||
disable_rate_menu();
|
||||
} else {
|
||||
enable_frequency_menu(device.getSerial(), reader);
|
||||
enable_rate_menu(device.getSerial(), reader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int number_of_windows;
|
||||
|
||||
static public void add_window() {
|
||||
++number_of_windows;
|
||||
}
|
||||
|
||||
static public void subtract_window() {
|
||||
--number_of_windows;
|
||||
if (number_of_windows == 0)
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
private void close() {
|
||||
disconnect();
|
||||
AltosUIPreferences.unregister_font_listener(this);
|
||||
AltosPreferences.unregister_units_listener(this);
|
||||
setVisible(false);
|
||||
dispose();
|
||||
subtract_window();
|
||||
}
|
||||
|
||||
private void add_menu(JMenu menu, String label, String action) {
|
||||
JMenuItem item = new JMenuItem(label);
|
||||
menu.add(item);
|
||||
item.addActionListener(this);
|
||||
item.setActionCommand(action);
|
||||
}
|
||||
|
||||
|
||||
private JMenu make_menu(String label, String[][] items) {
|
||||
JMenu menu = new JMenu(label);
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
if (MAC_OS_X) {
|
||||
if (items[i][1].equals("exit"))
|
||||
continue;
|
||||
if (items[i][1].equals("preferences"))
|
||||
continue;
|
||||
}
|
||||
add_menu(menu, items[i][0], items[i][1]);
|
||||
}
|
||||
menu_bar.add(menu);
|
||||
return menu;
|
||||
}
|
||||
|
||||
/* OSXAdapter interfaces */
|
||||
public void macosx_file_handler(String path) {
|
||||
process_graph(new File(path));
|
||||
}
|
||||
|
||||
public void macosx_quit_handler() {
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
public void macosx_preferences_handler() {
|
||||
preferences();
|
||||
}
|
||||
|
||||
public TeleGPS() {
|
||||
|
||||
AltosUIPreferences.set_component(this);
|
||||
|
||||
register_for_macosx_events();
|
||||
|
||||
reader = null;
|
||||
|
||||
bag = getContentPane();
|
||||
bag.setLayout(new GridBagLayout());
|
||||
|
||||
setTitle("TeleGPS");
|
||||
|
||||
menu_bar = new JMenuBar();
|
||||
setJMenuBar(menu_bar);
|
||||
|
||||
file_menu = make_menu("File", file_menu_entries);
|
||||
monitor_menu = make_menu("Monitor", monitor_menu_entries);
|
||||
device_menu = make_menu("Device", device_menu_entries);
|
||||
|
||||
set_inset(3);
|
||||
frequencies = new AltosUIFreqList();
|
||||
frequencies.setEnabled(false);
|
||||
bag.add(frequencies, constraints (0, 1));
|
||||
|
||||
rates = new AltosUIRateList();
|
||||
rates.setEnabled(false);
|
||||
bag.add(rates, constraints(1, 1));
|
||||
next_row();
|
||||
set_inset(0);
|
||||
|
||||
displays = new LinkedList<AltosFlightDisplay>();
|
||||
|
||||
int serial = -1;
|
||||
|
||||
/* TeleGPS status is always visible */
|
||||
telegps_status = new TeleGPSStatus();
|
||||
bag.add(telegps_status, constraints(0, 3, GridBagConstraints.HORIZONTAL));
|
||||
next_row();
|
||||
|
||||
displays.add(telegps_status);
|
||||
|
||||
|
||||
/* The rest of the window uses a tabbed pane to
|
||||
* show one of the alternate data views
|
||||
*/
|
||||
pane = new JTabbedPane();
|
||||
|
||||
/* Make the tabbed pane use the rest of the window space */
|
||||
bag.add(pane, constraints(0, 3, GridBagConstraints.BOTH));
|
||||
|
||||
map = new AltosUIMap();
|
||||
pane.add(map.getName(), map);
|
||||
displays.add(map);
|
||||
|
||||
gps_info = new TeleGPSInfo();
|
||||
pane.add(gps_info.getName(), gps_info);
|
||||
displays.add(gps_info);
|
||||
|
||||
gps_state = new TeleGPSState();
|
||||
pane.add(gps_state.getName(), gps_state);
|
||||
displays.add(gps_state);
|
||||
|
||||
info_table = new AltosInfoTable();
|
||||
pane.add("Table", info_table);
|
||||
displays.add(info_table);
|
||||
|
||||
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
|
||||
|
||||
AltosUIPreferences.register_font_listener(this);
|
||||
AltosPreferences.register_units_listener(this);
|
||||
|
||||
addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
close();
|
||||
}
|
||||
});
|
||||
|
||||
pack();
|
||||
setVisible(true);
|
||||
|
||||
add_window();
|
||||
}
|
||||
|
||||
public TeleGPS(AltosFlightReader reader, boolean idle_mode) {
|
||||
this();
|
||||
set_reader(reader, null, idle_mode);
|
||||
}
|
||||
|
||||
public TeleGPS(AltosDevice device) {
|
||||
this();
|
||||
connect(device);
|
||||
}
|
||||
|
||||
static AltosRecordSet record_set(File file) {
|
||||
try {
|
||||
return AltosLib.record_set(file);
|
||||
} catch (IOException ie) {
|
||||
System.out.printf("%s\n", ie.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static AltosReplayReader replay_file(File file) {
|
||||
AltosRecordSet set = record_set(file);
|
||||
if (set == null)
|
||||
return null;
|
||||
return new AltosReplayReader(set, file);
|
||||
}
|
||||
|
||||
private static boolean graph_file(TeleGPS telegps, AltosRecordSet set, File file) {
|
||||
if (set == null)
|
||||
return false;
|
||||
if (!set.valid()) {
|
||||
JOptionPane.showMessageDialog(telegps,
|
||||
String.format("Failed to parse file %s", file),
|
||||
"Graph Failed",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
new TeleGPSGraphUI(set, file);
|
||||
} catch (IOException e) {
|
||||
System.out.printf("Exception %s\n", e.toString());
|
||||
} catch (InterruptedException e) {
|
||||
System.out.printf("Exception %s\n", e.toString());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static boolean process_graph(File file) {
|
||||
AltosRecordSet set = record_set(file);
|
||||
return graph_file(null, set, file);
|
||||
}
|
||||
|
||||
static boolean process_replay(File file) {
|
||||
AltosReplayReader new_reader = replay_file(file);
|
||||
if (new_reader == null)
|
||||
return false;
|
||||
|
||||
new TeleGPS(new_reader, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
static final int process_none = 0;
|
||||
static final int process_csv = 1;
|
||||
static final int process_kml = 2;
|
||||
static final int process_graph = 3;
|
||||
static final int process_replay = 4;
|
||||
static final int process_summary = 5;
|
||||
static final int process_cat = 6;
|
||||
|
||||
public static boolean load_library(Frame frame) {
|
||||
if (!AltosUILib.load_library()) {
|
||||
JOptionPane.showMessageDialog(frame,
|
||||
String.format("No AltOS library in \"%s\"",
|
||||
System.getProperty("java.library.path","<undefined>")),
|
||||
"Cannot load device access library",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void help(int code) {
|
||||
System.out.printf("Usage: altosui [OPTION]... [FILE]...\n");
|
||||
System.out.printf(" Options:\n");
|
||||
System.out.printf(" --replay <filename>\t\trelive the glory of past flights \n");
|
||||
System.out.printf(" --graph <filename>\t\tgraph a flight\n");
|
||||
System.out.printf(" --csv\tgenerate comma separated output for spreadsheets, etc\n");
|
||||
System.out.printf(" --kml\tgenerate KML output for use with Google Earth\n");
|
||||
System.exit(code);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int errors = 0;
|
||||
|
||||
load_library(null);
|
||||
try {
|
||||
UIManager.setLookAndFeel(AltosUIPreferences.look_and_feel());
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
boolean any_created = false;
|
||||
|
||||
|
||||
/* Handle batch-mode */
|
||||
int process = process_none;
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if (args[i].equals("--help"))
|
||||
help(0);
|
||||
else if (args[i].equals("--replay"))
|
||||
process = process_replay;
|
||||
else if (args[i].equals("--kml"))
|
||||
process = process_kml;
|
||||
else if (args[i].equals("--csv"))
|
||||
process = process_csv;
|
||||
else if (args[i].equals("--graph"))
|
||||
process = process_graph;
|
||||
else if (args[i].equals("--summary"))
|
||||
process = process_summary;
|
||||
else if (args[i].equals("--cat"))
|
||||
process = process_cat;
|
||||
else if (args[i].startsWith("--"))
|
||||
help(1);
|
||||
else {
|
||||
File file = new File(args[i]);
|
||||
switch (process) {
|
||||
case process_none:
|
||||
case process_graph:
|
||||
if (!process_graph(file))
|
||||
++errors;
|
||||
break;
|
||||
case process_replay:
|
||||
if (!process_replay(file))
|
||||
++errors;
|
||||
any_created = true;
|
||||
break;
|
||||
case process_kml:
|
||||
++errors;
|
||||
break;
|
||||
case process_csv:
|
||||
++errors;
|
||||
break;
|
||||
case process_summary:
|
||||
++errors;
|
||||
break;
|
||||
case process_cat:
|
||||
++errors;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (errors != 0)
|
||||
System.exit(errors);
|
||||
if (number_of_windows == 0) {
|
||||
java.util.List<AltosDevice> devices = AltosUSBDevice.list(AltosLib.product_basestation);
|
||||
if (devices != null)
|
||||
for (AltosDevice device : devices) {
|
||||
new TeleGPS(device);
|
||||
any_created = true;
|
||||
}
|
||||
if (number_of_windows == 0)
|
||||
new TeleGPS();
|
||||
}
|
||||
}
|
||||
}
|
298
telegps/TeleGPSConfig.java
Normal file
298
telegps/TeleGPSConfig.java
Normal file
@@ -0,0 +1,298 @@
|
||||
/*
|
||||
* Copyright © 2010 Keith Packard <keithp@keithp.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
*/
|
||||
|
||||
package org.altusmetrum.telegps;
|
||||
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import java.io.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.text.*;
|
||||
import org.altusmetrum.altoslib_14.*;
|
||||
import org.altusmetrum.altosuilib_14.*;
|
||||
|
||||
public class TeleGPSConfig implements ActionListener {
|
||||
|
||||
class int_ref {
|
||||
int value;
|
||||
|
||||
public int get() {
|
||||
return value;
|
||||
}
|
||||
public void set(int i) {
|
||||
value = i;
|
||||
}
|
||||
public int_ref(int i) {
|
||||
value = i;
|
||||
}
|
||||
}
|
||||
|
||||
class string_ref {
|
||||
String value;
|
||||
|
||||
public String get() {
|
||||
return value;
|
||||
}
|
||||
public void set(String i) {
|
||||
value = i;
|
||||
}
|
||||
public string_ref(String i) {
|
||||
value = i;
|
||||
}
|
||||
}
|
||||
|
||||
JFrame owner;
|
||||
AltosDevice device;
|
||||
AltosSerial serial_line;
|
||||
|
||||
AltosConfigData data;
|
||||
TeleGPSConfigUI config_ui;
|
||||
boolean serial_started;
|
||||
boolean made_visible;
|
||||
|
||||
void start_serial() throws InterruptedException, TimeoutException {
|
||||
serial_started = true;
|
||||
}
|
||||
|
||||
void stop_serial() throws InterruptedException {
|
||||
if (!serial_started)
|
||||
return;
|
||||
serial_started = false;
|
||||
}
|
||||
|
||||
void update_ui() {
|
||||
data.set_values(config_ui);
|
||||
config_ui.set_clean();
|
||||
if (!made_visible) {
|
||||
made_visible = true;
|
||||
config_ui.make_visible();
|
||||
}
|
||||
}
|
||||
|
||||
int pyro;
|
||||
|
||||
final static int serial_mode_read = 0;
|
||||
final static int serial_mode_save = 1;
|
||||
final static int serial_mode_reboot = 2;
|
||||
|
||||
class SerialData implements Runnable {
|
||||
TeleGPSConfig config;
|
||||
int serial_mode;
|
||||
|
||||
void callback(String in_cmd) {
|
||||
final String cmd = in_cmd;
|
||||
Runnable r = new Runnable() {
|
||||
public void run() {
|
||||
if (cmd.equals("abort")) {
|
||||
abort();
|
||||
} else if (cmd.equals("all finished")) {
|
||||
if (serial_line != null)
|
||||
update_ui();
|
||||
}
|
||||
}
|
||||
};
|
||||
SwingUtilities.invokeLater(r);
|
||||
}
|
||||
|
||||
void get_data() {
|
||||
data = null;
|
||||
try {
|
||||
start_serial();
|
||||
data = new AltosConfigData(config.serial_line);
|
||||
} catch (InterruptedException ie) {
|
||||
} catch (TimeoutException te) {
|
||||
try {
|
||||
stop_serial();
|
||||
callback("abort");
|
||||
} catch (InterruptedException ie) {
|
||||
}
|
||||
} finally {
|
||||
try {
|
||||
stop_serial();
|
||||
} catch (InterruptedException ie) {
|
||||
}
|
||||
}
|
||||
callback("all finished");
|
||||
}
|
||||
|
||||
void save_data() {
|
||||
try {
|
||||
start_serial();
|
||||
data.save(serial_line, false);
|
||||
} catch (InterruptedException ie) {
|
||||
} catch (TimeoutException te) {
|
||||
} finally {
|
||||
try {
|
||||
stop_serial();
|
||||
} catch (InterruptedException ie) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void reboot() {
|
||||
try {
|
||||
start_serial();
|
||||
serial_line.printf("r eboot\n");
|
||||
serial_line.flush_output();
|
||||
} catch (InterruptedException ie) {
|
||||
} catch (TimeoutException te) {
|
||||
} finally {
|
||||
try {
|
||||
stop_serial();
|
||||
serial_line.close();
|
||||
} catch (InterruptedException ie) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void run () {
|
||||
switch (serial_mode) {
|
||||
case serial_mode_save:
|
||||
save_data();
|
||||
/* fall through ... */
|
||||
case serial_mode_read:
|
||||
get_data();
|
||||
break;
|
||||
case serial_mode_reboot:
|
||||
reboot();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public SerialData(TeleGPSConfig in_config, int in_serial_mode) {
|
||||
config = in_config;
|
||||
serial_mode = in_serial_mode;
|
||||
}
|
||||
}
|
||||
|
||||
void run_serial_thread(int serial_mode) {
|
||||
SerialData sd = new SerialData(this, serial_mode);
|
||||
Thread st = new Thread(sd);
|
||||
st.start();
|
||||
}
|
||||
|
||||
void init_ui () throws InterruptedException, TimeoutException {
|
||||
config_ui = new TeleGPSConfigUI(owner);
|
||||
config_ui.addActionListener(this);
|
||||
serial_line.set_frame(owner);
|
||||
set_ui();
|
||||
}
|
||||
|
||||
void abort() {
|
||||
if (serial_line != null) {
|
||||
serial_line.close();
|
||||
serial_line = null;
|
||||
}
|
||||
JOptionPane.showMessageDialog(owner,
|
||||
String.format("Connection to \"%s\" failed",
|
||||
device.toShortString()),
|
||||
"Connection Failed",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
config_ui.setVisible(false);
|
||||
}
|
||||
|
||||
void set_ui() throws InterruptedException, TimeoutException {
|
||||
if (serial_line != null)
|
||||
run_serial_thread(serial_mode_read);
|
||||
else
|
||||
update_ui();
|
||||
}
|
||||
|
||||
double frequency() {
|
||||
return AltosConvert.radio_to_frequency(data.radio_frequency,
|
||||
data.radio_setting,
|
||||
data.radio_calibration,
|
||||
data.radio_channel);
|
||||
}
|
||||
|
||||
void save_data() {
|
||||
|
||||
try {
|
||||
/* bounds check stuff */
|
||||
if (config_ui.flight_log_max() > data.log_space()/1024) {
|
||||
JOptionPane.showMessageDialog(owner,
|
||||
String.format("Requested flight log, %dk, is larger than the available space, %dk.\n",
|
||||
config_ui.flight_log_max(),
|
||||
data.log_space()/1024),
|
||||
"Maximum Flight Log Too Large",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Pull data out of the UI and stuff back into our local data record */
|
||||
|
||||
data.get_values(config_ui);
|
||||
run_serial_thread(serial_mode_save);
|
||||
} catch (AltosConfigDataException ae) {
|
||||
JOptionPane.showMessageDialog(owner,
|
||||
ae.getMessage(),
|
||||
"Configuration Data Error",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
String cmd = e.getActionCommand();
|
||||
try {
|
||||
if (cmd.equals("Save")) {
|
||||
save_data();
|
||||
} else if (cmd.equals("Reset")) {
|
||||
set_ui();
|
||||
} else if (cmd.equals("Reboot")) {
|
||||
if (serial_line != null)
|
||||
run_serial_thread(serial_mode_reboot);
|
||||
} else if (cmd.equals("Close")) {
|
||||
if (serial_line != null)
|
||||
serial_line.close();
|
||||
}
|
||||
} catch (InterruptedException ie) {
|
||||
abort();
|
||||
} catch (TimeoutException te) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
public TeleGPSConfig(JFrame given_owner) {
|
||||
owner = given_owner;
|
||||
|
||||
device = AltosDeviceUIDialog.show(owner, AltosLib.product_telegps);
|
||||
if (device != null) {
|
||||
try {
|
||||
serial_line = new AltosSerial(device);
|
||||
try {
|
||||
init_ui();
|
||||
} catch (InterruptedException ie) {
|
||||
abort();
|
||||
} catch (TimeoutException te) {
|
||||
abort();
|
||||
}
|
||||
} catch (FileNotFoundException ee) {
|
||||
JOptionPane.showMessageDialog(owner,
|
||||
ee.getMessage(),
|
||||
"Cannot open target device",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
} catch (AltosSerialInUseException si) {
|
||||
JOptionPane.showMessageDialog(owner,
|
||||
String.format("Device \"%s\" already in use",
|
||||
device.toShortString()),
|
||||
"Device in use",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
1205
telegps/TeleGPSConfigUI.java
Normal file
1205
telegps/TeleGPSConfigUI.java
Normal file
File diff suppressed because it is too large
Load Diff
212
telegps/TeleGPSDisplayThread.java
Normal file
212
telegps/TeleGPSDisplayThread.java
Normal file
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* Copyright © 2010 Keith Packard <keithp@keithp.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
*/
|
||||
|
||||
package org.altusmetrum.telegps;
|
||||
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
import java.io.*;
|
||||
import java.text.*;
|
||||
import org.altusmetrum.altoslib_14.*;
|
||||
import org.altusmetrum.altosuilib_14.*;
|
||||
|
||||
public class TeleGPSDisplayThread extends Thread {
|
||||
|
||||
Frame parent;
|
||||
IdleThread idle_thread;
|
||||
AltosVoice voice;
|
||||
AltosFlightReader reader;
|
||||
AltosState state;
|
||||
int old_state = AltosLib.ao_flight_invalid;
|
||||
boolean old_gps_ready = false;
|
||||
AltosListenerState listener_state;
|
||||
AltosFlightDisplay display;
|
||||
|
||||
synchronized void show_safely() {
|
||||
final AltosState my_state = state;
|
||||
final AltosListenerState my_listener_state = listener_state;
|
||||
Runnable r = new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
display.show(my_state, my_listener_state);
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
}
|
||||
};
|
||||
SwingUtilities.invokeLater(r);
|
||||
}
|
||||
|
||||
void reading_error_internal() {
|
||||
JOptionPane.showMessageDialog(parent,
|
||||
String.format("Error reading from \"%s\"", reader.name),
|
||||
"Telemetry Read Error",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
|
||||
void reading_error_safely() {
|
||||
Runnable r = new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
reading_error_internal();
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
}
|
||||
};
|
||||
SwingUtilities.invokeLater(r);
|
||||
}
|
||||
|
||||
class IdleThread extends Thread {
|
||||
|
||||
boolean started;
|
||||
int report_interval;
|
||||
long report_time;
|
||||
|
||||
public synchronized void report(boolean last) {
|
||||
if (state == null)
|
||||
return;
|
||||
|
||||
if (state.height() != AltosLib.MISSING) {
|
||||
if (state.from_pad != null) {
|
||||
voice.speak("Height %s, bearing %s %d, elevation %d, range %s, .\n",
|
||||
AltosConvert.height.say(state.gps_height()),
|
||||
state.from_pad.bearing_words(
|
||||
AltosGreatCircle.BEARING_VOICE),
|
||||
(int) (state.from_pad.bearing + 0.5),
|
||||
(int) (state.elevation + 0.5),
|
||||
AltosConvert.distance.say(state.range));
|
||||
} else {
|
||||
voice.speak("Height %s.\n",
|
||||
AltosConvert.height.say(state.height()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long now () {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
|
||||
void set_report_time() {
|
||||
report_time = now() + report_interval;
|
||||
}
|
||||
|
||||
public void run () {
|
||||
try {
|
||||
for (;;) {
|
||||
if (reader.has_monitor_battery()) {
|
||||
listener_state.battery = reader.monitor_battery();
|
||||
show_safely();
|
||||
}
|
||||
set_report_time();
|
||||
for (;;) {
|
||||
voice.drain();
|
||||
synchronized (this) {
|
||||
long sleep_time = report_time - now();
|
||||
if (sleep_time <= 0)
|
||||
break;
|
||||
wait(sleep_time);
|
||||
}
|
||||
}
|
||||
|
||||
report(false);
|
||||
}
|
||||
} catch (InterruptedException ie) {
|
||||
try {
|
||||
voice.drain();
|
||||
} catch (InterruptedException iie) { }
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void notice(boolean spoken) {
|
||||
if (old_state != state.state()) {
|
||||
report_time = now();
|
||||
this.notify();
|
||||
} else if (spoken)
|
||||
set_report_time();
|
||||
old_state = state.state();
|
||||
}
|
||||
|
||||
public IdleThread() {
|
||||
report_interval = 10000;
|
||||
}
|
||||
}
|
||||
|
||||
synchronized boolean tell() {
|
||||
boolean ret = false;
|
||||
if (old_gps_ready != state.gps_ready) {
|
||||
if (state.gps_ready) {
|
||||
voice.speak("GPS ready");
|
||||
ret = true;
|
||||
}
|
||||
else if (old_gps_ready) {
|
||||
voice.speak("GPS lost");
|
||||
ret = true;
|
||||
}
|
||||
old_gps_ready = state.gps_ready;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
boolean interrupted = false;
|
||||
boolean told;
|
||||
|
||||
idle_thread = new IdleThread();
|
||||
idle_thread.start();
|
||||
|
||||
try {
|
||||
for (;;) {
|
||||
try {
|
||||
state = reader.read();
|
||||
if (state == null) {
|
||||
listener_state.running = false;
|
||||
break;
|
||||
}
|
||||
show_safely();
|
||||
told = tell();
|
||||
idle_thread.notice(told);
|
||||
} catch (ParseException pp) {
|
||||
System.out.printf("Parse error: %d \"%s\"\n", pp.getErrorOffset(), pp.getMessage());
|
||||
} catch (AltosCRCException ce) {
|
||||
++listener_state.crc_errors;
|
||||
show_safely();
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException ee) {
|
||||
interrupted = true;
|
||||
} catch (IOException ie) {
|
||||
reading_error_safely();
|
||||
} finally {
|
||||
if (!interrupted)
|
||||
idle_thread.report(true);
|
||||
reader.close(interrupted);
|
||||
idle_thread.interrupt();
|
||||
try {
|
||||
idle_thread.join();
|
||||
} catch (InterruptedException ie) {}
|
||||
}
|
||||
}
|
||||
|
||||
public TeleGPSDisplayThread(Frame in_parent, AltosVoice in_voice, AltosFlightDisplay in_display, AltosFlightReader in_reader) {
|
||||
listener_state = new AltosListenerState();
|
||||
parent = in_parent;
|
||||
voice = in_voice;
|
||||
display = in_display;
|
||||
reader = in_reader;
|
||||
display.reset();
|
||||
}
|
||||
}
|
168
telegps/TeleGPSGraphUI.java
Normal file
168
telegps/TeleGPSGraphUI.java
Normal file
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright © 2010 Anthony Towns
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
*/
|
||||
|
||||
package org.altusmetrum.telegps;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import java.io.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.*;
|
||||
import org.altusmetrum.altoslib_14.*;
|
||||
import org.altusmetrum.altosuilib_14.*;
|
||||
|
||||
import org.jfree.chart.ChartPanel;
|
||||
import org.jfree.chart.JFreeChart;
|
||||
import org.jfree.ui.RefineryUtilities;
|
||||
|
||||
public class TeleGPSGraphUI extends AltosUIFrame implements AltosFontListener, AltosUnitsListener, AltosFilterListener
|
||||
{
|
||||
JTabbedPane pane;
|
||||
AltosGraph graph;
|
||||
AltosUIEnable enable;
|
||||
AltosUIMap map;
|
||||
AltosState state;
|
||||
AltosFlightStats stats;
|
||||
AltosFlightStatsTable statsTable;
|
||||
AltosGPS gps;
|
||||
boolean has_gps;
|
||||
|
||||
void fill_map(AltosFlightSeries flight_series) {
|
||||
boolean any_gps = false;
|
||||
AltosGPSTimeValue gtv_last = null;
|
||||
double gps_pad_altitude = flight_series.cal_data().gps_pad_altitude;;
|
||||
|
||||
if (flight_series.gps_series != null) {
|
||||
for (AltosGPSTimeValue gtv : flight_series.gps_series) {
|
||||
gtv_last = gtv;
|
||||
AltosGPS gps = gtv.gps;
|
||||
if (gps != null &&
|
||||
gps.locked &&
|
||||
gps.nsat >= 4) {
|
||||
if (map == null)
|
||||
map = new AltosUIMap();
|
||||
double gps_height = gps.alt - gps_pad_altitude;
|
||||
int state = (int) flight_series.value_before(AltosFlightSeries.state_name, gtv.time);
|
||||
map.show(gps, gtv.time, state, gps_height);
|
||||
this.gps = gps;
|
||||
has_gps = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (gtv_last != null) {
|
||||
int state = (int) flight_series.value_after(AltosFlightSeries.state_name, gtv_last.time);
|
||||
double gps_height = gps.alt - gps_pad_altitude;
|
||||
if (state == AltosLib.ao_flight_landed)
|
||||
map.show(gtv_last.gps, gtv_last.time, state, gps_height);
|
||||
}
|
||||
}
|
||||
|
||||
private void close() {
|
||||
setVisible(false);
|
||||
dispose();
|
||||
TeleGPS.subtract_window();
|
||||
}
|
||||
|
||||
public void font_size_changed(int font_size) {
|
||||
if (map != null)
|
||||
map.font_size_changed(font_size);
|
||||
if (statsTable != null)
|
||||
statsTable.font_size_changed(font_size);
|
||||
}
|
||||
|
||||
public void units_changed(boolean imperial_units) {
|
||||
if (map != null)
|
||||
map.units_changed(imperial_units);
|
||||
if (enable != null)
|
||||
enable.units_changed(imperial_units);
|
||||
}
|
||||
|
||||
AltosUIFlightSeries flight_series;
|
||||
|
||||
public void filter_changed(double speed_filter, double accel_filter) {
|
||||
flight_series.set_filter(speed_filter, accel_filter);
|
||||
graph.filter_changed();
|
||||
stats = new AltosFlightStats(flight_series);
|
||||
statsTable.filter_changed(stats);
|
||||
}
|
||||
|
||||
public double speed_filter() {
|
||||
return flight_series.speed_filter_width;
|
||||
}
|
||||
|
||||
public double accel_filter() {
|
||||
return flight_series.accel_filter_width;
|
||||
}
|
||||
|
||||
TeleGPSGraphUI(AltosRecordSet set, File file) throws InterruptedException, IOException {
|
||||
super(file.getName());
|
||||
AltosCalData cal_data = set.cal_data();
|
||||
|
||||
pane = new JTabbedPane();
|
||||
|
||||
flight_series = new AltosUIFlightSeries(cal_data);
|
||||
|
||||
enable = new AltosUIEnable(this);
|
||||
|
||||
set.capture_series(flight_series);
|
||||
|
||||
flight_series.finish();
|
||||
|
||||
stats = new AltosFlightStats(flight_series);
|
||||
|
||||
graph = new AltosGraph(enable, stats, flight_series);
|
||||
|
||||
statsTable = new AltosFlightStatsTable(stats);
|
||||
|
||||
map = new AltosUIMap();
|
||||
|
||||
pane.add("Graph", graph.panel);
|
||||
pane.add("Configure Graph", enable);
|
||||
pane.add("Statistics", statsTable);
|
||||
fill_map(flight_series);
|
||||
pane.add("Map", map);
|
||||
|
||||
setContentPane (pane);
|
||||
|
||||
AltosUIPreferences.register_font_listener(this);
|
||||
AltosPreferences.register_units_listener(this);
|
||||
|
||||
addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
close();
|
||||
}
|
||||
});
|
||||
|
||||
pack();
|
||||
|
||||
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
|
||||
|
||||
TeleGPS.add_window();
|
||||
|
||||
setVisible(true);
|
||||
|
||||
if (state != null)
|
||||
map.centre(state);
|
||||
|
||||
}
|
||||
}
|
215
telegps/TeleGPSInfo.java
Normal file
215
telegps/TeleGPSInfo.java
Normal file
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* Copyright © 2010 Keith Packard <keithp@keithp.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
*/
|
||||
|
||||
package org.altusmetrum.telegps;
|
||||
|
||||
import java.util.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import org.altusmetrum.altoslib_14.*;
|
||||
import org.altusmetrum.altosuilib_14.*;
|
||||
|
||||
public class TeleGPSInfo extends AltosUIFlightTab {
|
||||
|
||||
JLabel cur, max;
|
||||
|
||||
abstract class Value extends AltosUIUnitsIndicator {
|
||||
public abstract void show(AltosState state, AltosListenerState listener_state);
|
||||
|
||||
public Value (Container container, int y, AltosUnits units, String text) {
|
||||
super(container, y, units, text, 1, false, 2);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class DualValue extends AltosUIUnitsIndicator {
|
||||
public DualValue (Container container, int y, AltosUnits units, String text) {
|
||||
super(container, y, units, text, 2, false, 1);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class ValueHold extends DualValue {
|
||||
public void reset() {
|
||||
super.reset();
|
||||
}
|
||||
public ValueHold (Container container, int y, AltosUnits units, String text) {
|
||||
super(container, y, units, text);
|
||||
}
|
||||
}
|
||||
|
||||
class Altitude extends ValueHold {
|
||||
public double value(AltosState state, int i) {
|
||||
if (i == 0)
|
||||
return state.altitude();
|
||||
else
|
||||
return state.max_altitude();
|
||||
}
|
||||
|
||||
public Altitude (Container container, int y) {
|
||||
super (container, y, AltosConvert.height, "Altitude");
|
||||
}
|
||||
}
|
||||
|
||||
class AscentRate extends ValueHold {
|
||||
public double value(AltosState state, int i) {
|
||||
if (i == 0)
|
||||
return state.gps_ascent_rate();
|
||||
else
|
||||
return state.max_gps_ascent_rate();
|
||||
}
|
||||
public AscentRate (Container container, int y) {
|
||||
super (container, y, AltosConvert.speed, "Ascent Rate");
|
||||
}
|
||||
}
|
||||
|
||||
class GroundSpeed extends ValueHold {
|
||||
public double value(AltosState state, int i) {
|
||||
if (i == 0)
|
||||
return state.gps_ground_speed();
|
||||
else
|
||||
return state.max_gps_ground_speed();
|
||||
}
|
||||
public GroundSpeed (Container container, int y) {
|
||||
super (container, y, AltosConvert.speed, "Ground Speed");
|
||||
}
|
||||
}
|
||||
|
||||
class Course extends AltosUIIndicator {
|
||||
|
||||
public void show (AltosState state, AltosListenerState listener_state) {
|
||||
double course = state.gps_course();
|
||||
if (course == AltosLib.MISSING)
|
||||
show("Missing", "Missing");
|
||||
else
|
||||
show( String.format("%3.0f°", course),
|
||||
AltosConvert.bearing_to_words(
|
||||
AltosConvert.BEARING_LONG,
|
||||
course));
|
||||
}
|
||||
public Course (Container container, int y) {
|
||||
super (container, y, "Course", 2, false, 1);
|
||||
}
|
||||
}
|
||||
|
||||
class Lat extends AltosUIIndicator {
|
||||
|
||||
String pos(double p, String pos, String neg) {
|
||||
String h = pos;
|
||||
if (p < 0) {
|
||||
h = neg;
|
||||
p = -p;
|
||||
}
|
||||
int deg = (int) Math.floor(p);
|
||||
double min = (p - Math.floor(p)) * 60.0;
|
||||
return String.format("%s %4d° %9.6f", h, deg, min);
|
||||
}
|
||||
|
||||
public void show (AltosState state, AltosListenerState listener_state) {
|
||||
if (state.gps != null && state.gps.connected && state.gps.lat != AltosLib.MISSING)
|
||||
show(pos(state.gps.lat,"N", "S"));
|
||||
else
|
||||
show("Missing");
|
||||
}
|
||||
public Lat (Container container, int y) {
|
||||
super (container, y, "Latitude", 1, false, 2);
|
||||
}
|
||||
}
|
||||
|
||||
class Lon extends AltosUIIndicator {
|
||||
|
||||
String pos(double p, String pos, String neg) {
|
||||
String h = pos;
|
||||
if (p < 0) {
|
||||
h = neg;
|
||||
p = -p;
|
||||
}
|
||||
int deg = (int) Math.floor(p);
|
||||
double min = (p - Math.floor(p)) * 60.0;
|
||||
return String.format("%s %4d° %9.6f", h, deg, min);
|
||||
}
|
||||
|
||||
public void show (AltosState state, AltosListenerState listener_state) {
|
||||
if (state.gps != null && state.gps.connected && state.gps.lon != AltosLib.MISSING)
|
||||
show(pos(state.gps.lon,"E", "W"));
|
||||
else
|
||||
show("Missing");
|
||||
}
|
||||
public Lon (Container container, int y) {
|
||||
super (container, y, "Longitude", 1, false, 2);
|
||||
}
|
||||
}
|
||||
|
||||
class GPSLocked extends AltosUIIndicator {
|
||||
|
||||
public void show (AltosState state, AltosListenerState listener_state) {
|
||||
if (state == null || state.gps == null)
|
||||
hide();
|
||||
else {
|
||||
int soln = state.gps.nsat;
|
||||
int nsat = state.gps.cc_gps_sat != null ? state.gps.cc_gps_sat.length : 0;
|
||||
show("%4d in solution", soln,
|
||||
"%4d in view", nsat);
|
||||
set_lights(state.gps.locked && soln >= 4);
|
||||
}
|
||||
}
|
||||
public GPSLocked (Container container, int y) {
|
||||
super (container, y, "GPS Locked", 2, true, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public void font_size_changed(int font_size) {
|
||||
cur.setFont(AltosUILib.label_font);
|
||||
max.setFont(AltosUILib.label_font);
|
||||
super.font_size_changed(font_size);
|
||||
}
|
||||
|
||||
public void labels(Container container, int y) {
|
||||
GridBagLayout layout = (GridBagLayout)(container.getLayout());
|
||||
GridBagConstraints c;
|
||||
|
||||
cur = new JLabel("Current");
|
||||
cur.setFont(AltosUILib.label_font);
|
||||
c = new GridBagConstraints();
|
||||
c.gridx = 2; c.gridy = y;
|
||||
c.insets = new Insets(AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad);
|
||||
layout.setConstraints(cur, c);
|
||||
add(cur);
|
||||
|
||||
max = new JLabel("Maximum");
|
||||
max.setFont(AltosUILib.label_font);
|
||||
c.gridx = 3; c.gridy = y;
|
||||
layout.setConstraints(max, c);
|
||||
add(max);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "Location";
|
||||
}
|
||||
|
||||
public TeleGPSInfo() {
|
||||
int y = 0;
|
||||
labels(this, y++);
|
||||
add(new Altitude(this, y++));
|
||||
add(new GroundSpeed(this, y++));
|
||||
add(new AscentRate(this, y++));
|
||||
add(new Course(this, y++));
|
||||
add(new Lat(this, y++));
|
||||
add(new Lon(this, y++));
|
||||
add(new GPSLocked(this, y++));
|
||||
}
|
||||
}
|
121
telegps/TeleGPSPreferences.java
Normal file
121
telegps/TeleGPSPreferences.java
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright © 2010 Keith Packard <keithp@keithp.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
*/
|
||||
|
||||
package org.altusmetrum.telegps;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.beans.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
import org.altusmetrum.altosuilib_14.*;
|
||||
|
||||
public class TeleGPSPreferences
|
||||
extends AltosUIConfigure
|
||||
implements DocumentListener
|
||||
{
|
||||
AltosVoice voice;
|
||||
|
||||
public JTextField callsign_value;
|
||||
public JComboBox<String> position_value;
|
||||
|
||||
/* DocumentListener interface methods */
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
changedUpdate(e);
|
||||
}
|
||||
|
||||
public void removeUpdate(DocumentEvent e) {
|
||||
changedUpdate(e);
|
||||
}
|
||||
|
||||
public void changedUpdate(DocumentEvent e) {
|
||||
if (callsign_value != null)
|
||||
AltosUIPreferences.set_callsign(callsign_value.getText());
|
||||
}
|
||||
|
||||
public void add_voice() {
|
||||
|
||||
/* Voice settings */
|
||||
pane.add(new JLabel("Voice"), constraints(0, 1));
|
||||
|
||||
JRadioButton enable_voice = new JRadioButton("Enable", AltosUIPreferences.voice());
|
||||
enable_voice.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
JRadioButton item = (JRadioButton) e.getSource();
|
||||
boolean enabled = item.isSelected();
|
||||
AltosUIPreferences.set_voice(enabled);
|
||||
if (enabled)
|
||||
voice.speak_always("Enable voice.");
|
||||
else
|
||||
voice.speak_always("Disable voice.");
|
||||
}
|
||||
});
|
||||
pane.add(enable_voice, constraints(1, 1));
|
||||
enable_voice.setToolTipText("Enable/Disable all audio in-flight announcements");
|
||||
|
||||
JButton test_voice = new JButton("Test Voice");
|
||||
test_voice.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
voice.speak("That's one small step for man; one giant leap for mankind.");
|
||||
}
|
||||
});
|
||||
pane.add(test_voice, constraints(2, 1));
|
||||
test_voice.setToolTipText("Play a stock audio clip to check volume");
|
||||
row++;
|
||||
}
|
||||
|
||||
public void add_callsign() {
|
||||
/* Callsign setting */
|
||||
pane.add(new JLabel("Callsign"), constraints(0, 1));
|
||||
|
||||
callsign_value = new JTextField(AltosUIPreferences.callsign());
|
||||
callsign_value.getDocument().addDocumentListener(this);
|
||||
callsign_value.setToolTipText("Callsign sent in packet mode");
|
||||
pane.add(callsign_value, constraints(1, 2, GridBagConstraints.BOTH));
|
||||
row++;
|
||||
}
|
||||
|
||||
public void add_bluetooth() {
|
||||
JButton manage_bluetooth = new JButton("Manage Bluetooth");
|
||||
manage_bluetooth.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
AltosBTManage.show(owner, AltosBTKnown.bt_known());
|
||||
}
|
||||
});
|
||||
pane.add(manage_bluetooth, constraints(0, 2));
|
||||
/* in the same row as add_frequencies, so don't bump row */
|
||||
}
|
||||
|
||||
public void add_frequencies() {
|
||||
JButton manage_frequencies = new JButton("Manage Frequencies");
|
||||
manage_frequencies.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
AltosConfigFreqUI.show(owner);
|
||||
}
|
||||
});
|
||||
manage_frequencies.setToolTipText("Configure which values are shown in frequency menus");
|
||||
pane.add(manage_frequencies, constraints(2, 1));
|
||||
row++;
|
||||
}
|
||||
|
||||
public TeleGPSPreferences(JFrame owner, AltosVoice voice) {
|
||||
super(owner, "TeleGPS Preferences", "Configure TeleGPS");
|
||||
|
||||
this.voice = voice;
|
||||
}
|
||||
}
|
232
telegps/TeleGPSState.java
Normal file
232
telegps/TeleGPSState.java
Normal file
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
* Copyright © 2014 Keith Packard <keithp@keithp.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
*/
|
||||
|
||||
package org.altusmetrum.telegps;
|
||||
|
||||
import java.util.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import org.altusmetrum.altoslib_14.*;
|
||||
import org.altusmetrum.altosuilib_14.*;
|
||||
|
||||
public class TeleGPSState extends AltosUIFlightTab {
|
||||
|
||||
JLabel cur, max;
|
||||
|
||||
abstract class Value extends AltosUIUnitsIndicator {
|
||||
public Value (Container container, int y, AltosUnits units, String text) {
|
||||
super(container, y, units, text, 1, false, 2);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class DualValue extends AltosUIUnitsIndicator {
|
||||
public DualValue (Container container, int y, AltosUnits units, String text) {
|
||||
super(container, y, units, text, 2, false, 1);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class ValueHold extends DualValue {
|
||||
public ValueHold (Container container, int y, AltosUnits units, String text) {
|
||||
super(container, y, units, text);
|
||||
}
|
||||
}
|
||||
|
||||
class Height extends ValueHold {
|
||||
public double value(AltosState state, int i) {
|
||||
if (i == 0)
|
||||
return state.height();
|
||||
else
|
||||
return state.max_height();
|
||||
}
|
||||
|
||||
public Height(Container container, int y) {
|
||||
super(container, y, AltosConvert.height, "Height");
|
||||
}
|
||||
}
|
||||
|
||||
class Speed extends ValueHold {
|
||||
public double value(AltosState state, int i) {
|
||||
if (i == 0)
|
||||
return state.gps_speed();
|
||||
else
|
||||
return state.max_gps_speed();
|
||||
}
|
||||
|
||||
public Speed(Container container, int y) {
|
||||
super(container, y, AltosConvert.speed, "Speed");
|
||||
}
|
||||
}
|
||||
|
||||
class Distance extends Value {
|
||||
public double value(AltosState state, int i) {
|
||||
if (state.from_pad != null)
|
||||
return state.from_pad.distance;
|
||||
else
|
||||
return AltosLib.MISSING;
|
||||
}
|
||||
|
||||
public Distance(Container container, int y) {
|
||||
super(container, y, AltosConvert.distance, "Distance");
|
||||
}
|
||||
}
|
||||
|
||||
class Range extends Value {
|
||||
public double value(AltosState state, int i) {
|
||||
return state.range;
|
||||
}
|
||||
public Range (Container container, int y) {
|
||||
super (container, y, AltosConvert.distance, "Range");
|
||||
}
|
||||
}
|
||||
|
||||
class Bearing extends AltosUIIndicator {
|
||||
public void show (AltosState state, AltosListenerState listener_state) {
|
||||
if (state.from_pad != null && state.from_pad.bearing != AltosLib.MISSING) {
|
||||
show( String.format("%3.0f°", state.from_pad.bearing),
|
||||
state.from_pad.bearing_words(
|
||||
AltosGreatCircle.BEARING_LONG));
|
||||
} else {
|
||||
show("Missing", "Missing");
|
||||
}
|
||||
}
|
||||
public Bearing (Container container, int y) {
|
||||
super (container, y, "Bearing", 2, false, 1);
|
||||
}
|
||||
}
|
||||
|
||||
class Elevation extends AltosUIIndicator {
|
||||
public void show (AltosState state, AltosListenerState listener_state) {
|
||||
if (state.elevation == AltosLib.MISSING)
|
||||
show("Missing");
|
||||
else
|
||||
show("%3.0f°", state.elevation);
|
||||
}
|
||||
public Elevation (Container container, int y) {
|
||||
super (container, y, "Elevation", 1, false, 2);
|
||||
}
|
||||
}
|
||||
|
||||
class FirmwareVersion extends AltosUIIndicator {
|
||||
public void show(AltosState state, AltosListenerState listener_state) {
|
||||
AltosCalData cal_data = state.cal_data();
|
||||
if (cal_data.firmware_version == null)
|
||||
show("Missing");
|
||||
else
|
||||
show(cal_data.firmware_version);
|
||||
}
|
||||
|
||||
public FirmwareVersion(Container container, int y) {
|
||||
super(container, y, "Firmware Version", 1, false, 2);
|
||||
}
|
||||
}
|
||||
|
||||
class FlightLogMax extends AltosUIIndicator {
|
||||
public void show(AltosState state, AltosListenerState listener_state) {
|
||||
AltosCalData cal_data = state.cal_data();
|
||||
int storage = cal_data.flight_log_max;
|
||||
if (storage == AltosLib.MISSING)
|
||||
show("Missing");
|
||||
else
|
||||
show(String.format("%dkB", storage));
|
||||
}
|
||||
|
||||
public FlightLogMax(Container container, int y) {
|
||||
super(container, y, "Flight Log Storage", 1, false, 2);
|
||||
}
|
||||
}
|
||||
|
||||
class BatteryVoltage extends AltosUIVoltageIndicator {
|
||||
public double voltage(AltosState state) {
|
||||
return state.battery_voltage;
|
||||
}
|
||||
|
||||
public double good() {
|
||||
return AltosLib.ao_battery_good;
|
||||
}
|
||||
|
||||
public BatteryVoltage(Container container, int y) {
|
||||
super(container, y, "Battery Voltage", 2);
|
||||
}
|
||||
}
|
||||
|
||||
class ReceiverBattery extends AltosUIVoltageIndicator {
|
||||
|
||||
public double voltage(AltosState state) { return AltosLib.MISSING; }
|
||||
|
||||
public double good() { return AltosLib.ao_battery_good; }
|
||||
|
||||
public boolean hide(AltosState state, AltosListenerState listener_state, int i) {
|
||||
return value(state, listener_state, i) == AltosLib.MISSING;
|
||||
}
|
||||
|
||||
public double value(AltosState state, AltosListenerState listener_state, int i) {
|
||||
if (listener_state == null)
|
||||
return AltosLib.MISSING;
|
||||
return listener_state.battery;
|
||||
}
|
||||
|
||||
public ReceiverBattery (AltosUIFlightTab container, int y) {
|
||||
super(container, y, "Receiver Battery", 2);
|
||||
}
|
||||
}
|
||||
|
||||
public void labels(Container container, int y) {
|
||||
GridBagLayout layout = (GridBagLayout)(container.getLayout());
|
||||
GridBagConstraints c;
|
||||
|
||||
cur = new JLabel("Current");
|
||||
cur.setFont(AltosUILib.label_font);
|
||||
c = new GridBagConstraints();
|
||||
c.gridx = 2; c.gridy = y;
|
||||
c.insets = new Insets(AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad);
|
||||
layout.setConstraints(cur, c);
|
||||
add(cur);
|
||||
|
||||
max = new JLabel("Maximum");
|
||||
max.setFont(AltosUILib.label_font);
|
||||
c.gridx = 3; c.gridy = y;
|
||||
layout.setConstraints(max, c);
|
||||
add(max);
|
||||
}
|
||||
|
||||
public void font_size_changed(int font_size) {
|
||||
cur.setFont(AltosUILib.label_font);
|
||||
max.setFont(AltosUILib.label_font);
|
||||
super.font_size_changed(font_size);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "Status";
|
||||
}
|
||||
|
||||
public TeleGPSState() {
|
||||
int y = 0;
|
||||
labels(this, y++);
|
||||
add(new Height(this, y++));
|
||||
add(new Speed(this, y++));
|
||||
add(new Distance(this, y++));
|
||||
add(new Range(this, y++));
|
||||
add(new Bearing(this, y++));
|
||||
add(new Elevation(this, y++));
|
||||
add(new FirmwareVersion(this, y++));
|
||||
add(new FlightLogMax(this, y++));
|
||||
add(new BatteryVoltage(this, y++));
|
||||
add(new ReceiverBattery(this, y++));
|
||||
}
|
||||
}
|
281
telegps/TeleGPSStatus.java
Normal file
281
telegps/TeleGPSStatus.java
Normal file
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
* Copyright © 2010 Keith Packard <keithp@keithp.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
*/
|
||||
|
||||
package org.altusmetrum.telegps;
|
||||
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
import org.altusmetrum.altoslib_14.*;
|
||||
import org.altusmetrum.altosuilib_14.*;
|
||||
|
||||
public class TeleGPSStatus extends JComponent implements AltosFlightDisplay {
|
||||
GridBagLayout layout;
|
||||
|
||||
public class Value {
|
||||
JLabel label;
|
||||
JTextField value;
|
||||
|
||||
void show(AltosState state, AltosListenerState listener_state) {}
|
||||
|
||||
void reset() {
|
||||
value.setText("");
|
||||
}
|
||||
|
||||
void set_font() {
|
||||
label.setFont(AltosUILib.status_font);
|
||||
value.setFont(AltosUILib.status_font);
|
||||
}
|
||||
|
||||
void setVisible(boolean visible) {
|
||||
label.setVisible(visible);
|
||||
value.setVisible(visible);
|
||||
}
|
||||
|
||||
public Value (GridBagLayout layout, int x, String text) {
|
||||
GridBagConstraints c = new GridBagConstraints();
|
||||
c.insets = new Insets(5, 5, 5, 5);
|
||||
c.anchor = GridBagConstraints.CENTER;
|
||||
c.fill = GridBagConstraints.BOTH;
|
||||
c.weightx = 1;
|
||||
c.weighty = 1;
|
||||
|
||||
label = new JLabel(text);
|
||||
label.setFont(AltosUILib.status_font);
|
||||
label.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
c.gridx = x; c.gridy = 0;
|
||||
layout.setConstraints(label, c);
|
||||
add(label);
|
||||
|
||||
value = new JTextField("");
|
||||
value.setEditable(false);
|
||||
value.setFont(AltosUILib.status_font);
|
||||
value.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
c.gridx = x; c.gridy = 1;
|
||||
layout.setConstraints(value, c);
|
||||
add(value);
|
||||
}
|
||||
}
|
||||
|
||||
class Call extends Value {
|
||||
String call;
|
||||
|
||||
void show(AltosState state, AltosListenerState listener_state) {
|
||||
AltosCalData cal_data = state.cal_data();
|
||||
if (cal_data == null)
|
||||
System.out.printf("null cal data?\n");
|
||||
if (cal_data.callsign != call) {
|
||||
value.setText(cal_data.callsign);
|
||||
call = cal_data.callsign;
|
||||
}
|
||||
if (cal_data.callsign == null)
|
||||
setVisible(false);
|
||||
else
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
super.reset();
|
||||
call = "";
|
||||
}
|
||||
|
||||
public Call (GridBagLayout layout, int x) {
|
||||
super (layout, x, "Callsign");
|
||||
}
|
||||
}
|
||||
|
||||
Call call;
|
||||
|
||||
class Serial extends Value {
|
||||
int serial = -1;
|
||||
void show(AltosState state, AltosListenerState listener_state) {
|
||||
AltosCalData cal_data = state.cal_data();
|
||||
if (cal_data.serial != serial) {
|
||||
if (cal_data.serial == AltosLib.MISSING)
|
||||
value.setText("none");
|
||||
else
|
||||
value.setText(String.format("%d", cal_data.serial));
|
||||
serial = cal_data.serial;
|
||||
}
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
super.reset();
|
||||
serial = -1;
|
||||
}
|
||||
|
||||
public Serial (GridBagLayout layout, int x) {
|
||||
super (layout, x, "Serial");
|
||||
}
|
||||
}
|
||||
|
||||
Serial serial;
|
||||
|
||||
class Flight extends Value {
|
||||
|
||||
int last_flight = -1;
|
||||
|
||||
void show(AltosState state, AltosListenerState listener_state) {
|
||||
AltosCalData cal_data = state.cal_data();
|
||||
if (cal_data.flight != last_flight) {
|
||||
if (cal_data.flight == AltosLib.MISSING)
|
||||
value.setText("none");
|
||||
else
|
||||
value.setText(String.format("%d", cal_data.flight));
|
||||
last_flight = cal_data.flight;
|
||||
}
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
super.reset();
|
||||
last_flight = -1;
|
||||
}
|
||||
|
||||
public Flight (GridBagLayout layout, int x) {
|
||||
super (layout, x, "Flight");
|
||||
}
|
||||
}
|
||||
|
||||
Flight flight;
|
||||
|
||||
class RSSI extends Value {
|
||||
int rssi = 10000;
|
||||
|
||||
void show(AltosState state, AltosListenerState listener_state) {
|
||||
int new_rssi = state.rssi();
|
||||
|
||||
if (new_rssi != rssi) {
|
||||
value.setText(String.format("%d", new_rssi));
|
||||
if (state.rssi == AltosLib.MISSING)
|
||||
setVisible(false);
|
||||
else
|
||||
setVisible(true);
|
||||
rssi = new_rssi;
|
||||
}
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
super.reset();
|
||||
rssi = 10000;
|
||||
}
|
||||
|
||||
public RSSI (GridBagLayout layout, int x) {
|
||||
super (layout, x, "RSSI");
|
||||
}
|
||||
}
|
||||
|
||||
RSSI rssi;
|
||||
|
||||
class LastPacket extends Value {
|
||||
|
||||
long last_secs = -1;
|
||||
|
||||
void show(AltosState state, AltosListenerState listener_state) {
|
||||
if (listener_state.running) {
|
||||
long secs = (System.currentTimeMillis() - state.received_time + 500) / 1000;
|
||||
|
||||
if (secs != last_secs) {
|
||||
value.setText(String.format("%d", secs));
|
||||
last_secs = secs;
|
||||
}
|
||||
} else {
|
||||
value.setText("done");
|
||||
}
|
||||
}
|
||||
|
||||
void reset() {
|
||||
super.reset();
|
||||
last_secs = -1;
|
||||
}
|
||||
|
||||
void disable() {
|
||||
value.setText("");
|
||||
}
|
||||
|
||||
public LastPacket(GridBagLayout layout, int x) {
|
||||
super (layout, x, "Age");
|
||||
}
|
||||
}
|
||||
|
||||
LastPacket last_packet;
|
||||
|
||||
public void disable_receive() {
|
||||
last_packet.disable();
|
||||
}
|
||||
|
||||
public void reset () {
|
||||
call.reset();
|
||||
serial.reset();
|
||||
flight.reset();
|
||||
rssi.reset();
|
||||
last_packet.reset();
|
||||
}
|
||||
|
||||
public void font_size_changed(int font_size) {
|
||||
call.set_font();
|
||||
serial.set_font();
|
||||
flight.set_font();
|
||||
rssi.set_font();
|
||||
last_packet.set_font();
|
||||
}
|
||||
|
||||
public void units_changed(boolean imperial_units) {
|
||||
}
|
||||
|
||||
public void show (AltosState state, AltosListenerState listener_state) {
|
||||
call.show(state, listener_state);
|
||||
serial.show(state, listener_state);
|
||||
flight.show(state, listener_state);
|
||||
rssi.show(state, listener_state);
|
||||
last_packet.show(state, listener_state);
|
||||
if (!listener_state.running)
|
||||
stop();
|
||||
}
|
||||
|
||||
public int height() {
|
||||
Dimension d = layout.preferredLayoutSize(this);
|
||||
return d.height;
|
||||
}
|
||||
|
||||
TeleGPSStatusUpdate status_update;
|
||||
javax.swing.Timer timer;
|
||||
|
||||
public void start(TeleGPSStatusUpdate status_update) {
|
||||
this.status_update = status_update;
|
||||
timer = new javax.swing.Timer(100, status_update);
|
||||
timer.start();
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
if (timer != null) {
|
||||
timer.stop();
|
||||
timer = null;
|
||||
}
|
||||
}
|
||||
|
||||
public TeleGPSStatus() {
|
||||
layout = new GridBagLayout();
|
||||
|
||||
setLayout(layout);
|
||||
|
||||
call = new Call(layout, 0);
|
||||
serial = new Serial(layout, 1);
|
||||
flight = new Flight(layout, 2);
|
||||
rssi = new RSSI(layout, 4);
|
||||
last_packet = new LastPacket(layout, 5);
|
||||
}
|
||||
}
|
42
telegps/TeleGPSStatusUpdate.java
Normal file
42
telegps/TeleGPSStatusUpdate.java
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright © 2012 Keith Packard <keithp@keithp.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
*/
|
||||
|
||||
package org.altusmetrum.telegps;
|
||||
|
||||
import java.awt.event.*;
|
||||
import org.altusmetrum.altoslib_14.*;
|
||||
|
||||
public class TeleGPSStatusUpdate implements ActionListener {
|
||||
|
||||
public AltosState saved_state;
|
||||
public AltosListenerState saved_listener_state;
|
||||
TeleGPSStatus status;
|
||||
|
||||
public void actionPerformed (ActionEvent e) {
|
||||
if (saved_state != null) {
|
||||
if (saved_listener_state == null)
|
||||
saved_listener_state = new AltosListenerState();
|
||||
status.show(saved_state, saved_listener_state);
|
||||
}
|
||||
}
|
||||
|
||||
public TeleGPSStatusUpdate (TeleGPSStatus in_status) {
|
||||
status = in_status;
|
||||
}
|
||||
}
|
||||
|
11
telegps/altusmetrum-telegps.desktop.in
Normal file
11
telegps/altusmetrum-telegps.desktop.in
Normal file
@@ -0,0 +1,11 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=TeleGPS
|
||||
GenericName=TeleGPS monitor, download and analysis
|
||||
Comment=View and log data from TeleGPS tracking devices
|
||||
Icon=%icondir%/altusmetrum-telegps.svg
|
||||
Exec=%bindir%/telegps %F
|
||||
Terminal=false
|
||||
MimeType=application/vnd.altusmetrum.telemetry;application/vnd.altusmetrum.eeprom
|
||||
Categories=Education;Electronics;Science;
|
||||
Keywords=Telemetry;GPS
|
7
telegps/mdwn.tmpl
Normal file
7
telegps/mdwn.tmpl
Normal file
@@ -0,0 +1,7 @@
|
||||
[[!inline pages="./%version%/release-notes-%version%.html" rss="no" raw="yes" ]]
|
||||
|
||||
- Available Files:
|
||||
- [Windows Installer](/TeleGPS/releases/%version%/TeleGPS-Windows-%version_dash%.exe)
|
||||
- [Mac OS X Package](/TeleGPS/releases/%version%/TeleGPS-Mac-%version%.dmg)
|
||||
- [Linux](/TeleGPS/releases/%version%/TeleGPS-Linux-%version%.sh)
|
||||
- [Source Snapshot](http://git.gag.com/?p=fw/altos;a=snapshot;h=refs/tags/%version%;sf=tgz)
|
4
telegps/telegps-fat
Executable file
4
telegps/telegps-fat
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
me=`which "$0"`
|
||||
dir=`dirname "$me"`
|
||||
exec java -cp "$dir/*" -Djava.library.path="$dir" -jar "$dir"/telegps-fat.jar "$@"
|
241
telegps/telegps-windows.nsi.in
Normal file
241
telegps/telegps-windows.nsi.in
Normal file
@@ -0,0 +1,241 @@
|
||||
!addplugindir ../altosui/Instdrv/NSIS/Plugins
|
||||
!addincludedir ../altosui/Instdrv/NSIS/Includes
|
||||
!include x64.nsh
|
||||
!include java.nsh
|
||||
!include refresh-sh.nsh
|
||||
|
||||
!define REG_NAME "TeleGPS"
|
||||
!define PROG_ID_TELEM "altusmetrum.telegps.telem.1"
|
||||
!define PROG_ID_EEPROM "altusmetrum.telegps.eeprom.1"
|
||||
!define FAT_NAME "telegps-fat.jar"
|
||||
!define WIN_APP_ICON "altusmetrum-telegps.ico"
|
||||
!define WIN_APP_EXE "altusmetrum-telegps.exe"
|
||||
!define WIN_TELEM_EXE "application-vnd.altusmetrum.telemetry.exe"
|
||||
!define WIN_EEPROM_EXE "application-vnd.altusmetrum.eeprom.exe"
|
||||
|
||||
Name "${REG_NAME} Installer"
|
||||
|
||||
; Default install directory
|
||||
InstallDir "$PROGRAMFILES\AltusMetrum"
|
||||
|
||||
; Tell the installer where to re-install a new version
|
||||
InstallDirRegKey HKLM "Software\${REG_NAME}" "Install_Dir"
|
||||
|
||||
LicenseText "GNU General Public License Version 2"
|
||||
LicenseData "../COPYING"
|
||||
|
||||
; Need admin privs for Vista or Win7
|
||||
RequestExecutionLevel admin
|
||||
|
||||
ShowInstDetails Show
|
||||
|
||||
ComponentText "${REG_NAME} Software and Driver Installer"
|
||||
|
||||
Function .onInit
|
||||
DetailPrint "Checking host operating system"
|
||||
${If} ${RunningX64}
|
||||
DetailPrint "Installer running on 64-bit host"
|
||||
SetRegView 64
|
||||
StrCpy $INSTDIR "$PROGRAMFILES64\AltusMetrum"
|
||||
${DisableX64FSRedirection}
|
||||
${EndIf}
|
||||
FunctionEnd
|
||||
|
||||
Function un.onInit
|
||||
DetailPrint "Checking host operating system"
|
||||
${If} ${RunningX64}
|
||||
DetailPrint "Installer running on 64-bit host"
|
||||
SetRegView 64
|
||||
StrCpy $INSTDIR "$PROGRAMFILES64\AltusMetrum"
|
||||
${DisableX64FSRedirection}
|
||||
${EndIf}
|
||||
FunctionEnd
|
||||
|
||||
; Pages to present
|
||||
|
||||
Page license
|
||||
Page components
|
||||
Page directory
|
||||
Page instfiles
|
||||
|
||||
UninstPage uninstConfirm
|
||||
UninstPage instfiles
|
||||
|
||||
; And the stuff to install
|
||||
|
||||
Section "Install Driver" InstDriver
|
||||
|
||||
InstDrv::InitDriverSetup /NOUNLOAD {4D36E96D-E325-11CE-BFC1-08002BE10318} AltusMetrumSerial
|
||||
Pop $0
|
||||
DetailPrint "InitDriverSetup: $0"
|
||||
InstDrv::DeleteOemInfFiles /NOUNLOAD
|
||||
InstDrv::CreateDevice /NOUNLOAD
|
||||
|
||||
SetOutPath $INSTDIR
|
||||
File "../altusmetrum.inf"
|
||||
File "../altusmetrum.cat"
|
||||
|
||||
${DisableX64FSRedirection}
|
||||
IfFileExists $WINDIR\System32\PnPutil.exe 0 nopnp
|
||||
${DisableX64FSRedirection}
|
||||
nsExec::ExecToLog '"$WINDIR\System32\PnPutil.exe" -i -a "$INSTDIR\altusmetrum.inf"'
|
||||
Goto done
|
||||
nopnp:
|
||||
InstDrv::InstallDriver /NOUNLOAD "$INSTDIR\altusmetrum.inf"
|
||||
done:
|
||||
|
||||
SectionEnd
|
||||
|
||||
Section "${REG_NAME} Application"
|
||||
Call DetectJRE
|
||||
|
||||
SetOutPath $INSTDIR
|
||||
|
||||
File "${FAT_NAME}"
|
||||
File "altoslib_@ALTOSLIB_VERSION@.jar"
|
||||
File "altosuilib_@ALTOSUILIB_VERSION@.jar"
|
||||
File "cmudict04.jar"
|
||||
File "cmulex.jar"
|
||||
File "cmu_time_awb.jar"
|
||||
File "cmutimelex.jar"
|
||||
File "cmu_us_kal.jar"
|
||||
File "en_us.jar"
|
||||
File "freetts.jar"
|
||||
File "jfreechart.jar"
|
||||
File "jcommon.jar"
|
||||
File "../icon/${WIN_APP_EXE}"
|
||||
|
||||
File "*.dll"
|
||||
|
||||
File "../icon/${WIN_APP_ICON}"
|
||||
|
||||
CreateShortCut "$SMPROGRAMS\${REG_NAME}.lnk" "$INSTDIR\${WIN_APP_EXE}" "" "$INSTDIR\${WIN_APP_ICON}"
|
||||
SectionEnd
|
||||
|
||||
Section "${REG_NAME} Desktop Shortcut"
|
||||
CreateShortCut "$DESKTOP\${REG_NAME}.lnk" "$INSTDIR\${WIN_APP_EXE}" "" "$INSTDIR\${WIN_APP_ICON}"
|
||||
SectionEnd
|
||||
|
||||
Section "TeleGPS, TeleDongle and TeleBT Firmware"
|
||||
|
||||
SetOutPath $INSTDIR
|
||||
|
||||
File "../src/telegps-v1.0/telegps-v1.0-${VERSION}.ihx"
|
||||
File "../src/telegps-v2.0/telegps-v2.0-${VERSION}.ihx"
|
||||
File "../src/telegps-v3.0/telegps-v3.0-${VERSION}.ihx"
|
||||
File "../src/teledongle-v3.0/teledongle-v3.0-${VERSION}.ihx"
|
||||
File "../src/telebt-v3.0/telebt-v3.0-${VERSION}.ihx"
|
||||
File "../src/telebt-v4.0/telebt-v4.0-${VERSION}.ihx"
|
||||
|
||||
SectionEnd
|
||||
|
||||
Section "Documentation"
|
||||
|
||||
SetOutPath $INSTDIR
|
||||
|
||||
File "../doc/telegps.pdf"
|
||||
File "../doc/altos.pdf"
|
||||
File "../doc/telemetry.pdf"
|
||||
SectionEnd
|
||||
|
||||
Section "File Associations"
|
||||
|
||||
${DisableX64FSRedirection}
|
||||
|
||||
SetOutPath $INSTDIR
|
||||
|
||||
File "../icon/${WIN_TELEM_EXE}"
|
||||
File "../icon/${WIN_EEPROM_EXE}"
|
||||
|
||||
DeleteRegKey HKCR "${PROG_ID_TELEM}"
|
||||
DeleteRegKey HKCR "${PROG_ID_EEPROM}"
|
||||
|
||||
DeleteRegKey HKCR ".eeprom\${PROG_ID_EEPROM}"
|
||||
DeleteRegValue HKCR ".eeprom\OpenWithProgids" "${PROG_ID_EEPROM}"
|
||||
DeleteRegKey HKCR ".telem\${PROG_ID_EEPROM}"
|
||||
DeleteRegValue HKCR ".telem\OpenWithProgids" "${PROG_ID_EEPROM}"
|
||||
|
||||
; .eeprom elements
|
||||
|
||||
WriteRegStr HKCR "${PROG_ID_EEPROM}" "" "Altus Metrum Log File"
|
||||
WriteRegStr HKCR "${PROG_ID_EEPROM}" "FriendlyTypeName" "Altus Metrum Log File"
|
||||
WriteRegStr HKCR "${PROG_ID_EEPROM}\CurVer" "" "${PROG_ID_EEPROM}"
|
||||
WriteRegStr HKCR "${PROG_ID_EEPROM}\DefaultIcon" "" '"$INSTDIR\${WIN_EEPROM_EXE}",-101'
|
||||
WriteRegExpandStr HKCR "${PROG_ID_EEPROM}\shell\open\command" "" '"$INSTDIR\${WIN_APP_EXE}" "%1"'
|
||||
|
||||
WriteRegStr HKCR ".eeprom" "" "${PROG_ID_EEPROM}"
|
||||
WriteRegStr HKCR ".eeprom" "PerceivedType" "Altus Metrum Log File"
|
||||
WriteRegStr HKCR ".eeprom" "Content Type" "application/vnd.altusmetrum.eeprom"
|
||||
|
||||
WriteRegStr HKCR ".eeprom\OpenWithProgids" "${PROG_ID_EEPROM}" ""
|
||||
WriteRegStr HKCR ".eeprom\${PROG_ID_EEPROM}" "" "${REG_NAME}"
|
||||
|
||||
; .telem elements
|
||||
|
||||
WriteRegStr HKCR "${PROG_ID_TELEM}" "" "Altus Metrum Telemetry File"
|
||||
WriteRegStr HKCR "${PROG_ID_TELEM}" "FriendlyTypeName" "Altus Metrum Telemetry File"
|
||||
WriteRegStr HKCR "${PROG_ID_TELEM}\CurVer" "" "${PROG_ID_TELEM}"
|
||||
WriteRegStr HKCR "${PROG_ID_TELEM}\DefaultIcon" "" '"$INSTDIR\${WIN_TELEM_EXE}",-101'
|
||||
WriteRegExpandStr HKCR "${PROG_ID_TELEM}\shell\open\command" "" '"$INSTDIR\${WIN_APP_EXE}" "%1"'
|
||||
|
||||
WriteRegStr HKCR ".telem" "" "${PROG_ID_TELEM}"
|
||||
WriteRegStr HKCR ".telem" "PerceivedType" "Altus Metrum Telemetry File"
|
||||
WriteRegStr HKCR ".telem" "Content Type" "application/vnd.altusmetrum.telemetry"
|
||||
|
||||
WriteRegStr HKCR ".telem\OpenWithProgids" "${PROG_ID_TELEM}" ""
|
||||
WriteRegStr HKCR ".telem\${PROG_ID_TELEM}" "" "${REG_NAME}"
|
||||
|
||||
Call RefreshShellIcons
|
||||
SectionEnd
|
||||
|
||||
Section "Uninstaller"
|
||||
|
||||
; Deal with the uninstaller
|
||||
|
||||
${DisableX64FSRedirection}
|
||||
SetOutPath $INSTDIR
|
||||
|
||||
; Write the install path to the registry
|
||||
WriteRegStr HKLM "SOFTWARE\${REG_NAME}" "Install_Dir" "$INSTDIR"
|
||||
|
||||
; Write the uninstall keys for windows
|
||||
WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\${REG_NAME}" "DisplayName" "${REG_NAME}"
|
||||
WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\${REG_NAME}" "UninstallString" '"$INSTDIR\uninstall-${REG_NAME}.exe"'
|
||||
WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\${REG_NAME}" "NoModify" "1"
|
||||
WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\${REG_NAME}" "NoRepair" "1"
|
||||
|
||||
WriteUninstaller "uninstall-${REG_NAME}.exe"
|
||||
SectionEnd
|
||||
|
||||
Section "Uninstall"
|
||||
|
||||
${DisableX64FSRedirection}
|
||||
|
||||
DeleteRegKey HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\${REG_NAME}"
|
||||
DeleteRegKey HKLM "SOFTWARE\${REG_NAME}"
|
||||
|
||||
DetailPrint "Delete uninstall reg entries"
|
||||
|
||||
DeleteRegKey HKCR "${PROG_ID_EEPROM}"
|
||||
DeleteRegKey HKCR "${PROG_ID_TELEM}"
|
||||
|
||||
DeleteRegKey HKCR ".eeprom\${PROG_ID_EEPROM}"
|
||||
DeleteRegValue HKCR ".eeprom\OpenWithProgids" "${PROG_ID_EEPROM}"
|
||||
|
||||
DeleteRegKey HKCR ".telem\${PROG_ID_TELEM}"
|
||||
DeleteRegValue HKCR ".telem\OpenWithProgids" "${PROG_ID_TELEM}"
|
||||
|
||||
DetailPrint "Delete file association reg entries"
|
||||
|
||||
Delete "$INSTDIR\${FAT_NAME}"
|
||||
Delete "$INSTDIR\uninstall-${REG_NAME}.exe"
|
||||
|
||||
Delete "$INSTDIR\${WIN_APP_ICON}"
|
||||
Delete "$INSTDIR\${WIN_APP_EXE}"
|
||||
|
||||
; Remove shortcuts, if any
|
||||
Delete "$SMPROGRAMS\${REG_NAME}.lnk"
|
||||
Delete "$DESKTOP\${REG_NAME}.lnk"
|
||||
|
||||
Call un.RefreshShellIcons
|
||||
SectionEnd
|
46
telegps/telegps.1
Normal file
46
telegps/telegps.1
Normal file
@@ -0,0 +1,46 @@
|
||||
.\"
|
||||
.\" Copyright © 2010 Bdale Garbee <bdale@gag.com>
|
||||
.\"
|
||||
.\" This program is free software; you can redistribute it and/or modify
|
||||
.\" it under the terms of the GNU General Public License as published by
|
||||
.\" the Free Software Foundation; either version 2 of the License, or
|
||||
.\" (at your option) any later version.
|
||||
.\"
|
||||
.\" This program is distributed in the hope that it will be useful, but
|
||||
.\" WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
.\" General Public License for more details.
|
||||
.\"
|
||||
.\" You should have received a copy of the GNU General Public License along
|
||||
.\" with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
.\" 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
.\"
|
||||
.\"
|
||||
.TH ALTOSUI 1 "altosui" ""
|
||||
.SH NAME
|
||||
altosui \- Rocket flight monitor
|
||||
.SH SYNOPSIS
|
||||
.B "altosui"
|
||||
.SH DESCRIPTION
|
||||
.I altosui
|
||||
connects to a TeleDongle or TeleMetrum device through a USB serial device.
|
||||
It provides a menu-oriented
|
||||
user interface to monitor, record and review rocket flight data.
|
||||
.SH USAGE
|
||||
When connected to a TeleDongle device, altosui turns on the radio
|
||||
receiver and listens for telemetry packets. It displays the received
|
||||
telemetry data, and reports flight status via voice synthesis. All
|
||||
received telemetry information is recorded to a file.
|
||||
.P
|
||||
When connected to a TeleMetrum device, altosui can be used to configure the
|
||||
TeleMetrum, and to downloads the eeprom data and store it in a file.
|
||||
.P
|
||||
A number of other menu options exist, including the ability to export flight
|
||||
data in different formats.
|
||||
.SH FILES
|
||||
All data log files are recorded into a user-specified directory
|
||||
(default ~/TeleMetrum). Files are named using the current date, the serial
|
||||
number of the reporting device, the flight number recorded in the data
|
||||
and either '.telem' for telemetry data or '.eeprom' for eeprom data.
|
||||
.SH AUTHOR
|
||||
Keith Packard
|
Reference in New Issue
Block a user