From 6b81b3747545185a8e77985dfb581d80c31e907c Mon Sep 17 00:00:00 2001 From: Stelios Bounanos Date: Sat, 17 May 2008 04:24:15 +0100 Subject: [PATCH] Upstream version 2.11AH --- ChangeLog | 1 + INSTALL | 3 + README | 10 +- configure.ac | 10 +- m4/xmlrpc.m4 | 49 + src/Makefile.am | 19 +- src/dialogs/confdialog.cxx | 200 ++- src/dialogs/confdialog.fl | 110 +- src/dialogs/fl_digi.cxx | 72 +- src/feld/feld.cxx | 17 +- src/fileselector/fileselect.cxx | 131 +- src/globals/globals.cxx | 14 +- src/include/confdialog.h | 13 +- src/include/configuration.h | 23 +- src/include/digiscope.h | 2 + src/include/fileselect.h | 32 +- src/include/fl_digi.h | 2 +- src/include/globals.h | 14 +- src/include/modem.h | 14 +- src/include/qrunner.h | 22 +- src/include/status.h | 2 + src/include/{dex.h => thor.h} | 40 +- src/include/{dexvaricode.h => thorvaricode.h} | 6 +- src/include/threads.h | 7 +- src/include/waterfall.h | 13 +- src/include/xmlrpc.h | 25 + src/main.cxx | 47 + src/mfsk/mfsk.cxx | 4 +- src/misc/configuration.cxx | 124 +- src/misc/macros.cxx | 4 +- src/misc/status.cxx | 12 +- src/misc/xmlrpc.cxx | 1485 +++++++++++++++++ src/soundcard/sound.cxx | 4 +- src/{dex/dex.cxx => thor/thor.cxx} | 184 +- .../dexvaricode.cxx => thor/thorvaricode.cxx} | 18 +- src/trx/modem.cxx | 766 ++++++--- src/waterfall/colorbox.cxx | 4 +- src/waterfall/digiscope.cxx | 16 +- src/widgets/FTextView.cxx | 46 +- 39 files changed, 2834 insertions(+), 731 deletions(-) create mode 100644 m4/xmlrpc.m4 rename src/include/{dex.h => thor.h} (85%) rename src/include/{dexvaricode.h => thorvaricode.h} (87%) create mode 100644 src/include/xmlrpc.h create mode 100644 src/misc/xmlrpc.cxx rename src/{dex/dex.cxx => thor/thor.cxx} (72%) rename src/{dex/dexvaricode.cxx => thor/thorvaricode.cxx} (93%) diff --git a/ChangeLog b/ChangeLog index 8c59ed05..7ec1ccee 100644 --- a/ChangeLog +++ b/ChangeLog @@ -80,6 +80,7 @@ Change Log: dominoex.cxx and mt63base.cxx 35) Bug fixes for the FM Hell modes 36) Changed the way that the video text / id is generated. + 37) Added XML-RPC support. 2.10.3) 1) Corrected memory leak bug. diff --git a/INSTALL b/INSTALL index e5535e45..38c11329 100644 --- a/INSTALL +++ b/INSTALL @@ -30,6 +30,9 @@ present on your system: * The PulseAudio sound backend is compiled if the development files for libpulse-simple, the PulseAudio simple API library, are present. + * The embedded XML-RPC web server is enabled if `configure' can find + the C++ bindings for the libxmlrpc-c3 library. + Once you have installed the required packages, the following commands should be sufficient to compile fldigi and install it under /usr/local: diff --git a/README b/README index cb51e810..953e2c9c 100644 --- a/README +++ b/README @@ -2,14 +2,16 @@ Fldigi is a software modem for Amateur Radio use. It is a sound card based program that is used for both transmitting and receiving data in any of the following modes: +BPSK and QPSK 31, 63, 125, and 250 CW speeds from 5 to 200 wpm DominoEX 4, 5, 8, 11, 16 and 22 -Hellschreiber Feld-Hell, FSK-Hell and FSK-Hell 105 +Hellschreiber Feld Hell, Slow Hell, Hell x5/x9, FSKHell(-105) and Hell 80 MFSK 8 and 16; images can be sent and received in MFSK-16 mode -BPSK and QPSK 31, 63, 125, and 250 -Throb and ThrobX 1, 2, and 4 +MT63 500, 1000 and 2000 OLIVIA various tones and bandwidths RTTY various baud rates, shifts, nbr. of data bits, etc. +THOR 4, 5, 8, 11, 16 and 22 +Throb and ThrobX 1, 2, and 4 WWV receive only - calibrate your sound card to WWV Frequency Analysis receive only - measure the frequency of a carrier @@ -19,7 +21,7 @@ or cdrom QRZ queries, and log QSOs with fl_logbook or xlog. The latest version can always be found at: - http://www.w1hkj.com/Fldigi-2.x.html + http://www.w1hkj.com/Fldigi.html Visit this page for extensive documentation and an archive of XML files for transceivers supported by RigCAT. diff --git a/configure.ac b/configure.ac index b4d8493e..0f917afe 100644 --- a/configure.ac +++ b/configure.ac @@ -9,7 +9,7 @@ dnl major and minor must be integers; patch may dnl contain other characters or be empty m4_define(FLDIGI_MAJOR, [2]) m4_define(FLDIGI_MINOR, [11]) -m4_define(FLDIGI_PATCH, [AG]) +m4_define(FLDIGI_PATCH, [AH]) AC_INIT([fldigi], FLDIGI_MAJOR.FLDIGI_MINOR[FLDIGI_PATCH], [w1hkj AT w1hkj DOT com]) @@ -157,6 +157,13 @@ AC_FLDIGI_FLTK # Substitute IMAGE_CFLAGS and IMAGE_LIBS in Makefile AC_FLDIGI_IMAGES +### XML-RPC library +# Set ac_cv_xmlrpc to yes/no +# Substitute XMLRPC_CFLAGS and XMLRPC_LIBS in Makefile +# Define USE_XMLRPC in config.h +# Set ENABLE_XMLRPC Makefile conditional +AC_FLDIGI_XMLRPC + ### OSS # Set ac_cv_oss to yes/no # Define USE_OSS in config.h @@ -233,4 +240,5 @@ Configuration summary: PortAudio ........................... $ac_cv_portaudio PulseAudio .......................... $ac_cv_pulseaudio hamlib .............................. $ac_cv_hamlib + xml-rpc ............................. $ac_cv_xmlrpc ]) diff --git a/m4/xmlrpc.m4 b/m4/xmlrpc.m4 new file mode 100644 index 00000000..abf2472a --- /dev/null +++ b/m4/xmlrpc.m4 @@ -0,0 +1,49 @@ +AC_DEFUN([AC_FLDIGI_XMLRPC_CONFIG], [ + ac_cv_xmlrpc=no + AC_PATH_PROG([XMLRPC_C_CONFIG], [xmlrpc-c-config], [no]) + if test "x$XMLRPC_C_CONFIG" != "xno" && $XMLRPC_C_CONFIG c++2 abyss-server; then + XMLRPC_CFLAGS=`$XMLRPC_C_CONFIG c++2 abyss-server --cflags` + XMLRPC_LIBS=`$XMLRPC_C_CONFIG c++2 abyss-server --ldadd` + ac_cv_xmlrpc=yes + fi +]) + +AC_DEFUN([AC_FLDIGI_XMLRPC], [ + AC_ARG_VAR([XMLRPC_CFLAGS], [C compiler flags for libxmlrpc-c, overrriding xmlrpc-c-config]) + AC_ARG_VAR([XMLRPC_LIBS], [linker flags for libxmlrpc-c, overrriding xmlrpc-c-config]) + + AC_ARG_WITH([xmlrpc], + AC_HELP_STRING([--with-xmlrpc], [enable xmlrpc server support @<:@autodetect@:>@]), + [case "${withval}" in + yes|no) ac_cv_want_xmlrpc="${withval}" ;; + *) AC_MSG_ERROR([bad value "${withval}" for --with-xmlrpc]) ;; + esac], + [ac_cv_want_xmlrpc=check]) + + if test "x$ac_cv_want_xmlrpc" = "xno"; then + AC_DEFINE(USE_XMLRPC, 0, [Define to 1 if we are using xmlrpc]) + ac_cv_xmlrpc=no + else + if test "x$ac_cv_want_xmlrpc" = "xcheck"; then + AC_FLDIGI_XMLRPC_CONFIG + if test "x$ac_cv_xmlrpc" = "xyes"; then + AC_DEFINE(USE_XMLRPC, 1, [Define to 1 if we are using xmlrpc]) + else + AC_DEFINE(USE_XMLRPC, 0, [Define to 1 if we are using xmlrpc]) + fi + else # $ac_cv_want_xmlrpc is yes + if test "x$XMLRPC_CFLAGS" != "x" || test "x$XMLRPC_LIBS" != "x"; then + ac_cv_xmlrpc=yes + else + AC_FLDIGI_XMLRPC_CONFIG + fi + if test "x$ac_cv_xmlrpc" = "xno"; then + AC_MSG_FAILURE([--with-xmlrpc was given, but check for libxmlrpc-c failed]) + else + AC_DEFINE(USE_XMLRPC, 1, [Define to 1 if we are using xmlrpc]) + fi + fi + fi + + AM_CONDITIONAL([ENABLE_XMLRPC], [test "x$ac_cv_xmlrpc" = "xyes"]) +]) diff --git a/src/Makefile.am b/src/Makefile.am index d32bcaa7..bd4661fd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,21 +8,22 @@ AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/include -I$(srcdir)/irrxml -Ifileselector AM_CXXFLAGS = @PORTAUDIO_CFLAGS@ @FLTK_CFLAGS@ @SNDFILE_CFLAGS@ \ @SAMPLERATE_CFLAGS@ @PULSEAUDIO_CFLAGS@ @HAMLIB_CFLAGS@ \ - @IMAGE_CFLAGS@ @MAC_UNIVERSAL_CFLAGS@ \ + @IMAGE_CFLAGS@ @XMLRPC_CFLAGS@ @MAC_UNIVERSAL_CFLAGS@ \ -pipe -Wall -fexceptions @OPT_CFLAGS@ @DEBUG_CFLAGS@ AM_CFLAGS = $(AM_CXXFLAGS) AM_LDFLAGS = @MAC_UNIVERSAL_LDFLAGS@ LDADD = @PORTAUDIO_LIBS@ @BOOST_LDFLAGS@ @FLTK_LIBS@ @SNDFILE_LIBS@ \ - @SAMPLERATE_LIBS@ @PULSEAUDIO_LIBS@ @HAMLIB_LIBS@ @IMAGE_LIBS@ @RTLIB@ + @SAMPLERATE_LIBS@ @PULSEAUDIO_LIBS@ @HAMLIB_LIBS@ @IMAGE_LIBS@ @XMLRPC_LIBS@ @RTLIB@ HAMLIB_SRC = include/hamlib.h rigcontrol/hamlib.cxx include/rigclass.h rigcontrol/rigclass.cxx +XMLRPC_SRC = include/xmlrpc.h misc/xmlrpc.cxx WIN32_RES_SRC = fldigirc.rc # We distribute these but do not always compile them -EXTRA_fldigi_SOURCES = $(HAMLIB_SRC) $(WIN32_RES_SRC) +EXTRA_fldigi_SOURCES = $(HAMLIB_SRC) $(XMLRPC_SRC) $(WIN32_RES_SRC) fldigi_SOURCES = @@ -37,6 +38,10 @@ if ENABLE_HAMLIB fldigi_SOURCES += $(HAMLIB_SRC) endif +if ENABLE_XMLRPC + fldigi_SOURCES += $(XMLRPC_SRC) +endif + FLDIGI_VERSION_MAJOR = @FLDIGI_VERSION_MAJOR@ FLDIGI_VERSION_MINOR = @FLDIGI_VERSION_MINOR@ FLDIGI_VERSION_PATCH = @FLDIGI_VERSION_PATCH@ @@ -115,8 +120,8 @@ fldigi_SOURCES += \ dialogs/fl_digi.cxx \ dialogs/font_browser.cxx \ dialogs/Viewer.cxx \ - dex/dex.cxx \ - dex/dexvaricode.cxx \ + thor/thor.cxx \ + thor/thorvaricode.cxx \ dominoex/dominoex.cxx \ dominoex/dominovar.cxx \ feld/feld.cxx \ @@ -148,8 +153,8 @@ fldigi_SOURCES += \ include/configuration.h \ include/cw.h \ include/digiscope.h \ - include/dex.h \ - include/dexvaricode.h \ + include/thor.h \ + include/thorvaricode.h \ include/dominoex.h \ include/dominovar.h \ include/feld.h \ diff --git a/src/dialogs/confdialog.cxx b/src/dialogs/confdialog.cxx index 90db42c8..5bbe1502 100644 --- a/src/dialogs/confdialog.cxx +++ b/src/dialogs/confdialog.cxx @@ -284,6 +284,17 @@ static void cb_sldrVideowidth(Fl_Value_Slider* o, void*) { progdefaults.changed = true; } +Fl_Check_Button *chkID_SMALL=(Fl_Check_Button *)0; + +static void cb_chkID_SMALL(Fl_Check_Button* o, void*) { + progdefaults.ID_SMALL=o->value(); +if (o->value() == 1) +sldrVideowidth->deactivate(); +else +sldrVideowidth->activate(); +progdefaults.changed = true; +} + Fl_Check_Button *btnViewXmtSignal=(Fl_Check_Button *)0; static void cb_btnViewXmtSignal(Fl_Check_Button* o, void*) { @@ -884,42 +895,42 @@ static void cb_cntPostTiming(Fl_Counter* o, void*) { progdefaults.changed = true; } -Fl_Group *tabDEX=(Fl_Group *)0; +Fl_Group *tabTHOR=(Fl_Group *)0; -Fl_Input *txtDEXSecondary=(Fl_Input *)0; +Fl_Input *txtTHORSecondary=(Fl_Input *)0; -static void cb_txtDEXSecondary(Fl_Input* o, void*) { - progdefaults.DEXsecText = o->value(); +static void cb_txtTHORSecondary(Fl_Input* o, void*) { + progdefaults.THORsecText = o->value(); progdefaults.changed = true; } -Fl_Counter *valDEX_BW=(Fl_Counter *)0; +Fl_Counter *valTHOR_BW=(Fl_Counter *)0; -static void cb_valDEX_BW(Fl_Counter* o, void*) { - progdefaults.DEX_BW = o->value(); -resetDEX(); +static void cb_valTHOR_BW(Fl_Counter* o, void*) { + progdefaults.THOR_BW = o->value(); +resetTHOR(); progdefaults.changed = true; } -Fl_Check_Button *valDEX_FILTER=(Fl_Check_Button *)0; +Fl_Check_Button *valTHOR_FILTER=(Fl_Check_Button *)0; -static void cb_valDEX_FILTER(Fl_Check_Button* o, void*) { - progdefaults.DEX_FILTER = o->value(); -resetDEX(); +static void cb_valTHOR_FILTER(Fl_Check_Button* o, void*) { + progdefaults.THOR_FILTER = o->value(); +resetTHOR(); progdefaults.changed = true; } -Fl_Counter *valDEX_PATHS=(Fl_Counter *)0; +Fl_Counter *valTHOR_PATHS=(Fl_Counter *)0; -static void cb_valDEX_PATHS(Fl_Counter* o, void*) { - progdefaults.DEX_PATHS = (int)o->value(); +static void cb_valTHOR_PATHS(Fl_Counter* o, void*) { + progdefaults.THOR_PATHS = (int)o->value(); progdefaults.changed = true; } -Fl_Check_Button *valDEX_SOFT=(Fl_Check_Button *)0; +Fl_Check_Button *valTHOR_SOFT=(Fl_Check_Button *)0; -static void cb_valDEX_SOFT(Fl_Check_Button* o, void*) { - progdefaults.DEX_SOFT = o->value(); +static void cb_valTHOR_SOFT(Fl_Check_Button* o, void*) { + progdefaults.THOR_SOFT = o->value(); progdefaults.changed = true; } @@ -979,46 +990,55 @@ static void cb_sldrHellBW(Fl_Value_Slider*, void*) { Fl_Check_Button *btnHellXmtWidth=(Fl_Check_Button *)0; -static void cb_btnHellXmtWidth(Fl_Check_Button*, void*) { - progdefaults.changed = true; +static void cb_btnHellXmtWidth(Fl_Check_Button* o, void*) { + progdefaults.HellXmtWidth=o->value(); +progdefaults.changed = true; } Fl_Check_Button *btnHellRcvWidth=(Fl_Check_Button *)0; -static void cb_btnHellRcvWidth(Fl_Check_Button*, void*) { - progdefaults.changed = true; +static void cb_btnHellRcvWidth(Fl_Check_Button* o, void*) { + progdefaults.HellRcvWidth=o->value(); +progdefaults.changed = true; } Fl_Check_Button *btnBlackboard=(Fl_Check_Button *)0; -static void cb_btnBlackboard(Fl_Check_Button*, void*) { - progdefaults.changed = true; +static void cb_btnBlackboard(Fl_Check_Button* o, void*) { + progdefaults.HellBlackboard=o->value(); +progdefaults.changed = true; } Fl_Check_Button *btnHellFastAttack=(Fl_Check_Button *)0; static void cb_btnHellFastAttack(Fl_Check_Button* o, void*) { - if (o->value() == 1) + if (o->value() == 1) { btnHellSlowAttack->value(0); -else +progdefaults.HellPulseFast = true; +}else{ btnHellSlowAttack->value(1); +progdefaults.HellPulseFast = false; +} progdefaults.changed = true; } Fl_Check_Button *btnHellSlowAttack=(Fl_Check_Button *)0; static void cb_btnHellSlowAttack(Fl_Check_Button* o, void*) { - if (o->value() == 1) + if (o->value() == 1) { btnHellFastAttack->value(0); -else +progdefaults.HellPulseFast = false; +}else{ btnHellFastAttack->value(1); +progdefaults.HellPulseFast = true; +} progdefaults.changed = true; } Fl_Check_Button *btnFeldHellIdle=(Fl_Check_Button *)0; static void cb_btnFeldHellIdle(Fl_Check_Button* o, void*) { - progdefaults.FELD_IDLE=o->value(); + progdefaults.HellXmtIdle=o->value(); progdefaults.changed = true; } @@ -1514,26 +1534,25 @@ static const char szBaudRates[] = "300|600|1200|2400|4800|9600|19200|38400|57600 { tabVideo = new Fl_Group(0, 25, 400, 195, "Video"); tabVideo->color((Fl_Color)51); tabVideo->selection_color((Fl_Color)51); - tabVideo->hide(); - { Fl_Group* o = new Fl_Group(5, 40, 390, 67, "Video Preamble"); + { Fl_Group* o = new Fl_Group(5, 40, 390, 77, "Video Preamble"); o->box(FL_ENGRAVED_FRAME); o->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE); { btnsendid = new Fl_Check_Button(11, 57, 115, 20, "Xmt Mode ID"); btnsendid->down_box(FL_DOWN_BOX); btnsendid->callback((Fl_Callback*)cb_btnsendid); } // Fl_Check_Button* btnsendid - { Fl_Check_Button* o = btnsendvideotext = new Fl_Check_Button(11, 82, 115, 20, "Xmt Video Text"); + { Fl_Check_Button* o = btnsendvideotext = new Fl_Check_Button(11, 89, 115, 20, "Xmt Video Text"); btnsendvideotext->down_box(FL_DOWN_BOX); btnsendvideotext->callback((Fl_Callback*)cb_btnsendvideotext); o->value(progdefaults.sendtextid); } // Fl_Check_Button* btnsendvideotext - { Fl_Input* o = valVideotext = new Fl_Input(159, 82, 94, 20, "Video Text:"); + { Fl_Input* o = valVideotext = new Fl_Input(159, 89, 120, 20, "Video Text:"); valVideotext->tooltip("Limit to a few characters as in CQEM or IOTA etc."); valVideotext->callback((Fl_Callback*)cb_valVideotext); valVideotext->align(FL_ALIGN_TOP_LEFT); o->value(progdefaults.strTextid.c_str()); } // Fl_Input* valVideotext - { Fl_Value_Slider* o = sldrVideowidth = new Fl_Value_Slider(286, 82, 101, 20, "Video Width:"); + { Fl_Value_Slider* o = sldrVideowidth = new Fl_Value_Slider(290, 89, 95, 20, "Video Width:"); sldrVideowidth->tooltip("Set the # of chars per row"); sldrVideowidth->type(1); sldrVideowidth->color((Fl_Color)26); @@ -1545,23 +1564,30 @@ static const char szBaudRates[] = "300|600|1200|2400|4800|9600|19200|38400|57600 sldrVideowidth->callback((Fl_Callback*)cb_sldrVideowidth); sldrVideowidth->align(FL_ALIGN_TOP); o->value(progdefaults.videowidth); + if (progdefaults.ID_SMALL) o->deactivate(); } // Fl_Value_Slider* sldrVideowidth + { Fl_Check_Button* o = chkID_SMALL = new Fl_Check_Button(290, 49, 100, 20, "small font"); + chkID_SMALL->down_box(FL_DOWN_BOX); + chkID_SMALL->value(1); + chkID_SMALL->callback((Fl_Callback*)cb_chkID_SMALL); + o->value(progdefaults.ID_SMALL); + } // Fl_Check_Button* chkID_SMALL o->end(); } // Fl_Group* o - { Fl_Check_Button* o = btnViewXmtSignal = new Fl_Check_Button(11, 115, 135, 20, "View Xmt Signal"); + { Fl_Check_Button* o = btnViewXmtSignal = new Fl_Check_Button(11, 122, 135, 20, "View Xmt Signal"); btnViewXmtSignal->down_box(FL_DOWN_BOX); btnViewXmtSignal->callback((Fl_Callback*)cb_btnViewXmtSignal); o->value(progdefaults.viewXmtSignal); } // Fl_Check_Button* btnViewXmtSignal - { sld = new Fl_Group(5, 143, 390, 70, "CW Postamble"); + { sld = new Fl_Group(5, 150, 390, 63, "CW Postamble"); sld->box(FL_ENGRAVED_FRAME); sld->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE); - { Fl_Check_Button* o = btnCWID = new Fl_Check_Button(13, 179, 98, 15, "Xmt CWID"); + { Fl_Check_Button* o = btnCWID = new Fl_Check_Button(13, 185, 98, 15, "Xmt CWID"); btnCWID->down_box(FL_DOWN_BOX); btnCWID->callback((Fl_Callback*)cb_btnCWID); o->value(progdefaults.CWid); } // Fl_Check_Button* btnCWID - { Fl_Value_Slider* o = sldrCWIDwpm = new Fl_Value_Slider(124, 176, 233, 20, "CWID wpm:"); + { Fl_Value_Slider* o = sldrCWIDwpm = new Fl_Value_Slider(124, 182, 233, 20, "CWID wpm:"); sldrCWIDwpm->type(1); sldrCWIDwpm->color((Fl_Color)26); sldrCWIDwpm->minimum(15); @@ -1947,6 +1973,7 @@ l with your sound hardware."); { tabModems = new Fl_Group(0, 25, 401, 195, "Modem"); tabModems->color((Fl_Color)51); tabModems->selection_color((Fl_Color)51); + tabModems->hide(); { tabsModems = new Fl_Tabs(0, 25, 401, 195); tabsModems->color((Fl_Color)51); tabsModems->selection_color((Fl_Color)10); @@ -2100,46 +2127,47 @@ l with your sound hardware."); } // Fl_Counter* cntPostTiming tabCWQSK->end(); } // Fl_Group* tabCWQSK - { tabDEX = new Fl_Group(0, 44, 400, 170, "Dex"); - tabDEX->color((Fl_Color)51); - tabDEX->selection_color((Fl_Color)51); - { txtDEXSecondary = new Fl_Input(20, 75, 360, 44, "Secondary Text"); - txtDEXSecondary->type(4); - txtDEXSecondary->callback((Fl_Callback*)cb_txtDEXSecondary); - txtDEXSecondary->align(FL_ALIGN_TOP_LEFT); - txtDEXSecondary->when(FL_WHEN_CHANGED); - } // Fl_Input* txtDEXSecondary - { Fl_Counter* o = valDEX_BW = new Fl_Counter(20, 130, 63, 21, "BW factor:"); - valDEX_BW->type(1); - valDEX_BW->minimum(1); - valDEX_BW->maximum(2); - valDEX_BW->step(0.1); - valDEX_BW->value(1.5); - valDEX_BW->callback((Fl_Callback*)cb_valDEX_BW); - o->value(progdefaults.DEX_BW); - } // Fl_Counter* valDEX_BW - { Fl_Check_Button* o = valDEX_FILTER = new Fl_Check_Button(110, 130, 83, 19, "Filter ON"); - valDEX_FILTER->down_box(FL_DOWN_BOX); - valDEX_FILTER->value(1); - valDEX_FILTER->callback((Fl_Callback*)cb_valDEX_FILTER); - o->value(progdefaults.DEX_FILTER); - } // Fl_Check_Button* valDEX_FILTER - { Fl_Counter* o = valDEX_PATHS = new Fl_Counter(20, 174, 63, 21, "Paths"); - valDEX_PATHS->type(1); - valDEX_PATHS->minimum(4); - valDEX_PATHS->maximum(8); - valDEX_PATHS->step(1); - valDEX_PATHS->value(5); - valDEX_PATHS->callback((Fl_Callback*)cb_valDEX_PATHS); - o->value(progdefaults.DEX_PATHS); - } // Fl_Counter* valDEX_PATHS - { Fl_Check_Button* o = valDEX_SOFT = new Fl_Check_Button(110, 177, 70, 15, "Soft decode"); - valDEX_SOFT->down_box(FL_DOWN_BOX); - valDEX_SOFT->callback((Fl_Callback*)cb_valDEX_SOFT); - o->value(progdefaults.DEX_SOFT); - } // Fl_Check_Button* valDEX_SOFT - tabDEX->end(); - } // Fl_Group* tabDEX + { tabTHOR = new Fl_Group(0, 44, 400, 170, "Thor"); + tabTHOR->color((Fl_Color)51); + tabTHOR->selection_color((Fl_Color)51); + tabTHOR->hide(); + { txtTHORSecondary = new Fl_Input(20, 75, 360, 44, "Secondary Text"); + txtTHORSecondary->type(4); + txtTHORSecondary->callback((Fl_Callback*)cb_txtTHORSecondary); + txtTHORSecondary->align(FL_ALIGN_TOP_LEFT); + txtTHORSecondary->when(FL_WHEN_CHANGED); + } // Fl_Input* txtTHORSecondary + { Fl_Counter* o = valTHOR_BW = new Fl_Counter(20, 130, 63, 21, "BW factor:"); + valTHOR_BW->type(1); + valTHOR_BW->minimum(1); + valTHOR_BW->maximum(2); + valTHOR_BW->step(0.1); + valTHOR_BW->value(1.5); + valTHOR_BW->callback((Fl_Callback*)cb_valTHOR_BW); + o->value(progdefaults.THOR_BW); + } // Fl_Counter* valTHOR_BW + { Fl_Check_Button* o = valTHOR_FILTER = new Fl_Check_Button(110, 130, 83, 19, "Filter ON"); + valTHOR_FILTER->down_box(FL_DOWN_BOX); + valTHOR_FILTER->value(1); + valTHOR_FILTER->callback((Fl_Callback*)cb_valTHOR_FILTER); + o->value(progdefaults.THOR_FILTER); + } // Fl_Check_Button* valTHOR_FILTER + { Fl_Counter* o = valTHOR_PATHS = new Fl_Counter(20, 174, 63, 21, "Paths"); + valTHOR_PATHS->type(1); + valTHOR_PATHS->minimum(4); + valTHOR_PATHS->maximum(8); + valTHOR_PATHS->step(1); + valTHOR_PATHS->value(5); + valTHOR_PATHS->callback((Fl_Callback*)cb_valTHOR_PATHS); + o->value(progdefaults.THOR_PATHS); + } // Fl_Counter* valTHOR_PATHS + { Fl_Check_Button* o = valTHOR_SOFT = new Fl_Check_Button(110, 177, 70, 15, "Soft decode"); + valTHOR_SOFT->down_box(FL_DOWN_BOX); + valTHOR_SOFT->callback((Fl_Callback*)cb_valTHOR_SOFT); + o->value(progdefaults.THOR_SOFT); + } // Fl_Check_Button* valTHOR_SOFT + tabTHOR->end(); + } // Fl_Group* tabTHOR { tabDomEX = new Fl_Group(0, 50, 400, 170, "Dom"); tabDomEX->color((Fl_Color)51); tabDomEX->selection_color((Fl_Color)51); @@ -2184,7 +2212,6 @@ l with your sound hardware."); { tabFeld = new Fl_Group(0, 50, 400, 170, "Feld"); tabFeld->color((Fl_Color)51); tabFeld->selection_color((Fl_Color)51); - tabFeld->hide(); { Fl_Choice* o = selHellFont = new Fl_Choice(175, 62, 122, 20, "Feld Hell Font:"); selHellFont->down_box(FL_BORDER_BOX); selHellFont->labelfont(4); @@ -2205,17 +2232,20 @@ l with your sound hardware."); sldrHellBW->align(FL_ALIGN_TOP_LEFT); o->value(progdefaults.HELL_BW); } // Fl_Value_Slider* sldrHellBW - { btnHellXmtWidth = new Fl_Check_Button(40, 93, 113, 15, "2x Xmt Width"); + { Fl_Check_Button* o = btnHellXmtWidth = new Fl_Check_Button(40, 93, 113, 15, "2x Xmt Width"); btnHellXmtWidth->down_box(FL_DOWN_BOX); btnHellXmtWidth->callback((Fl_Callback*)cb_btnHellXmtWidth); + o->value(progdefaults.HellXmtWidth); } // Fl_Check_Button* btnHellXmtWidth - { btnHellRcvWidth = new Fl_Check_Button(40, 113, 130, 15, "1/2 x Rcv Width"); + { Fl_Check_Button* o = btnHellRcvWidth = new Fl_Check_Button(40, 113, 130, 15, "1/2 x Rcv Width"); btnHellRcvWidth->down_box(FL_DOWN_BOX); btnHellRcvWidth->callback((Fl_Callback*)cb_btnHellRcvWidth); + o->value(progdefaults.HellRcvWidth); } // Fl_Check_Button* btnHellRcvWidth - { btnBlackboard = new Fl_Check_Button(40, 134, 100, 15, "blackboard"); + { Fl_Check_Button* o = btnBlackboard = new Fl_Check_Button(40, 134, 100, 15, "blackboard"); btnBlackboard->down_box(FL_DOWN_BOX); btnBlackboard->callback((Fl_Callback*)cb_btnBlackboard); + o->value(progdefaults.HellBlackboard); } // Fl_Check_Button* btnBlackboard { Fl_Group* o = new Fl_Group(175, 90, 195, 85, "Pulse Shape"); o->box(FL_ENGRAVED_FRAME); @@ -2223,13 +2253,13 @@ l with your sound hardware."); { Fl_Check_Button* o = btnHellFastAttack = new Fl_Check_Button(185, 110, 169, 15, "Fast Attack (2 msec)"); btnHellFastAttack->down_box(FL_DOWN_BOX); btnHellFastAttack->callback((Fl_Callback*)cb_btnHellFastAttack); - o->value(0); + o->value(progdefaults.HellPulseFast); } // Fl_Check_Button* btnHellFastAttack { Fl_Check_Button* o = btnHellSlowAttack = new Fl_Check_Button(185, 131, 70, 15, "Slow Attack (4 msec)"); btnHellSlowAttack->down_box(FL_DOWN_BOX); btnHellSlowAttack->value(1); btnHellSlowAttack->callback((Fl_Callback*)cb_btnHellSlowAttack); - o->value(1); + o->value(!progdefaults.HellPulseFast); } // Fl_Check_Button* btnHellSlowAttack o->end(); } // Fl_Group* o @@ -2237,7 +2267,7 @@ l with your sound hardware."); btnFeldHellIdle->down_box(FL_DOWN_BOX); btnFeldHellIdle->value(1); btnFeldHellIdle->callback((Fl_Callback*)cb_btnFeldHellIdle); - o->value(progdefaults.FELD_IDLE); + o->value(progdefaults.HellXmtIdle); } // Fl_Check_Button* btnFeldHellIdle tabFeld->end(); } // Fl_Group* tabFeld diff --git a/src/dialogs/confdialog.fl b/src/dialogs/confdialog.fl index 22827635..b7dee3ba 100644 --- a/src/dialogs/confdialog.fl +++ b/src/dialogs/confdialog.fl @@ -325,12 +325,12 @@ progdefaults.changed = true; } } Fl_Group tabVideo { - label Video - xywh {0 25 400 195} color 51 selection_color 51 hide + label Video open + xywh {0 25 400 195} color 51 selection_color 51 } { Fl_Group {} { label {Video Preamble} open - xywh {5 40 390 67} box ENGRAVED_FRAME align 21 + xywh {5 40 390 77} box ENGRAVED_FRAME align 21 } { Fl_Check_Button btnsendid { label {Xmt Mode ID} @@ -342,47 +342,59 @@ progdefaults.changed = true;} label {Xmt Video Text} callback {progdefaults.sendtextid=o->value(); progdefaults.changed = true;} - xywh {11 82 115 20} down_box DOWN_BOX + xywh {11 89 115 20} down_box DOWN_BOX code0 {o->value(progdefaults.sendtextid);} } Fl_Input valVideotext { label {Video Text:} callback {progdefaults.strTextid = o->value(); progdefaults.changed = true;} - tooltip {Limit to a few characters as in CQEM or IOTA etc.} xywh {159 82 94 20} align 5 + tooltip {Limit to a few characters as in CQEM or IOTA etc.} xywh {159 89 120 20} align 5 code0 {o->value(progdefaults.strTextid.c_str());} } Fl_Value_Slider sldrVideowidth { label {Video Width:} callback {progdefaults.videowidth = (int)o->value(); progdefaults.changed = true;} - tooltip {Set the \# of chars per row} xywh {286 82 101 20} type Horizontal color 26 align 1 minimum 1 maximum 4 step 1 value 1 textsize 14 + tooltip {Set the \# of chars per row} xywh {290 89 95 20} type Horizontal color 26 align 1 minimum 1 maximum 4 step 1 value 1 textsize 14 code0 {o->value(progdefaults.videowidth);} + code1 {if (progdefaults.ID_SMALL) o->deactivate();} + } + Fl_Check_Button chkID_SMALL { + label {small font} + callback {progdefaults.ID_SMALL=o->value(); +if (o->value() == 1) +sldrVideowidth->deactivate(); +else +sldrVideowidth->activate(); +progdefaults.changed = true;} selected + xywh {290 49 100 20} down_box DOWN_BOX value 1 + code0 {o->value(progdefaults.ID_SMALL);} } } Fl_Check_Button btnViewXmtSignal { label {View Xmt Signal} callback {progdefaults.viewXmtSignal=o->value(); progdefaults.changed = true;} - xywh {11 115 135 20} down_box DOWN_BOX + xywh {11 122 135 20} down_box DOWN_BOX code0 {o->value(progdefaults.viewXmtSignal);} } Fl_Group sld { label {CW Postamble} open - xywh {5 143 390 70} box ENGRAVED_FRAME align 21 + xywh {5 150 390 63} box ENGRAVED_FRAME align 21 } { Fl_Check_Button btnCWID { label {Xmt CWID} callback {progdefaults.CWid = o->value(); progdefaults.changed = true;} - xywh {13 179 98 15} down_box DOWN_BOX + xywh {13 185 98 15} down_box DOWN_BOX code0 {o->value(progdefaults.CWid);} } Fl_Value_Slider sldrCWIDwpm { label {CWID wpm:} callback {progdefaults.CWIDwpm = (int)o->value(); progdefaults.changed = true;} - xywh {124 176 233 20} type Horizontal color 26 align 5 minimum 15 maximum 40 step 1 value 18 textsize 14 + xywh {124 182 233 20} type Horizontal color 26 align 5 minimum 15 maximum 40 step 1 value 18 textsize 14 code0 {o->value(progdefaults.CWIDwpm);} } } @@ -924,7 +936,7 @@ progdefaults.changed = true;} } Fl_Group tabModems { label Modem open - xywh {0 25 401 195} color 51 selection_color 51 + xywh {0 25 401 195} color 51 selection_color 51 hide } { Fl_Tabs tabsModems {open xywh {0 25 401 195} color 51 selection_color 10 align 9 @@ -1054,45 +1066,45 @@ progdefaults.changed = true;} code1 {o->maximum((int)(2400/progdefaults.CWspeed)/2.0);} } } - Fl_Group tabDEX { - label Dex open - xywh {0 44 400 170} color 51 selection_color 51 + Fl_Group tabTHOR { + label Thor open + xywh {0 44 400 170} color 51 selection_color 51 hide } { - Fl_Input txtDEXSecondary { + Fl_Input txtTHORSecondary { label {Secondary Text} - callback {progdefaults.DEXsecText = o->value(); + callback {progdefaults.THORsecText = o->value(); progdefaults.changed = true;} xywh {20 75 360 44} type Multiline align 5 when 1 } - Fl_Counter valDEX_BW { + Fl_Counter valTHOR_BW { label {BW factor:} - callback {progdefaults.DEX_BW = o->value(); -resetDEX(); + callback {progdefaults.THOR_BW = o->value(); +resetTHOR(); progdefaults.changed = true;} xywh {20 130 63 21} type Simple minimum 1 maximum 2 step 0.1 value 1.5 - code0 {o->value(progdefaults.DEX_BW);} + code0 {o->value(progdefaults.THOR_BW);} } - Fl_Check_Button valDEX_FILTER { + Fl_Check_Button valTHOR_FILTER { label {Filter ON} - callback {progdefaults.DEX_FILTER = o->value(); -resetDEX(); + callback {progdefaults.THOR_FILTER = o->value(); +resetTHOR(); progdefaults.changed = true;} xywh {110 130 83 19} down_box DOWN_BOX value 1 - code0 {o->value(progdefaults.DEX_FILTER);} + code0 {o->value(progdefaults.THOR_FILTER);} } - Fl_Counter valDEX_PATHS { + Fl_Counter valTHOR_PATHS { label Paths - callback {progdefaults.DEX_PATHS = (int)o->value(); + callback {progdefaults.THOR_PATHS = (int)o->value(); progdefaults.changed = true;} xywh {20 174 63 21} type Simple minimum 4 maximum 8 step 1 value 5 - code0 {o->value(progdefaults.DEX_PATHS);} + code0 {o->value(progdefaults.THOR_PATHS);} } - Fl_Check_Button valDEX_SOFT { + Fl_Check_Button valTHOR_SOFT { label {Soft decode} - callback {progdefaults.DEX_SOFT = o->value(); -progdefaults.changed = true;} selected + callback {progdefaults.THOR_SOFT = o->value(); +progdefaults.changed = true;} xywh {110 177 70 15} down_box DOWN_BOX - code0 {o->value(progdefaults.DEX_SOFT);} + code0 {o->value(progdefaults.THOR_SOFT);} } } Fl_Group tabDomEX { @@ -1138,7 +1150,7 @@ progdefaults.changed = true;} } Fl_Group tabFeld { label Feld open - xywh {0 50 400 170} color 51 selection_color 51 hide + xywh {0 50 400 170} color 51 selection_color 51 } { Fl_Choice selHellFont { label {Feld Hell Font:} @@ -1157,18 +1169,24 @@ progdefaults.changed = true;} open } Fl_Check_Button btnHellXmtWidth { label {2x Xmt Width} - callback {progdefaults.changed = true;} + callback {progdefaults.HellXmtWidth=o->value(); +progdefaults.changed = true;} xywh {40 93 113 15} down_box DOWN_BOX + code0 {o->value(progdefaults.HellXmtWidth);} } Fl_Check_Button btnHellRcvWidth { label {1/2 x Rcv Width} - callback {progdefaults.changed = true;} + callback {progdefaults.HellRcvWidth=o->value(); +progdefaults.changed = true;} xywh {40 113 130 15} down_box DOWN_BOX + code0 {o->value(progdefaults.HellRcvWidth);} } Fl_Check_Button btnBlackboard { label blackboard - callback {progdefaults.changed = true;} + callback {progdefaults.HellBlackboard=o->value(); +progdefaults.changed = true;} xywh {40 134 100 15} down_box DOWN_BOX + code0 {o->value(progdefaults.HellBlackboard);} } Fl_Group {} { label {Pulse Shape} open @@ -1176,31 +1194,37 @@ progdefaults.changed = true;} open } { Fl_Check_Button btnHellFastAttack { label {Fast Attack (2 msec)} - callback {if (o->value() == 1) + callback {if (o->value() == 1) { btnHellSlowAttack->value(0); -else +progdefaults.HellPulseFast = true; +}else{ btnHellSlowAttack->value(1); +progdefaults.HellPulseFast = false; +} progdefaults.changed = true;} xywh {185 110 169 15} down_box DOWN_BOX - code0 {o->value(0);} + code0 {o->value(progdefaults.HellPulseFast);} } Fl_Check_Button btnHellSlowAttack { label {Slow Attack (4 msec)} - callback {if (o->value() == 1) + callback {if (o->value() == 1) { btnHellFastAttack->value(0); -else +progdefaults.HellPulseFast = false; +}else{ btnHellFastAttack->value(1); +progdefaults.HellPulseFast = true; +} progdefaults.changed = true;} xywh {185 131 70 15} down_box DOWN_BOX value 1 - code0 {o->value(1);} + code0 {o->value(!progdefaults.HellPulseFast);} } } Fl_Check_Button btnFeldHellIdle { label {Xmt (.) Idle Char} - callback {progdefaults.FELD_IDLE=o->value(); + callback {progdefaults.HellXmtIdle=o->value(); progdefaults.changed = true;} xywh {40 155 70 15} down_box DOWN_BOX value 1 - code0 {o->value(progdefaults.FELD_IDLE);} + code0 {o->value(progdefaults.HellXmtIdle);} } } Fl_Group tabOlivia { diff --git a/src/dialogs/fl_digi.cxx b/src/dialogs/fl_digi.cxx index 92742fdf..25ce0031 100644 --- a/src/dialogs/fl_digi.cxx +++ b/src/dialogs/fl_digi.cxx @@ -65,7 +65,7 @@ #include "mt63.h" #include "rtty.h" #include "olivia.h" -#include "dex.h" +#include "thor.h" #include "dominoex.h" #include "feld.h" #include "throb.h" @@ -202,14 +202,14 @@ Fl_Menu_Item quick_change_mt63[] = { { 0 } }; -Fl_Menu_Item quick_change_dex[] = { - { mode_info[MODE_DEX4].name, 0, cb_init_mode, (void *)MODE_DEX4 }, - { mode_info[MODE_DEX5].name, 0, cb_init_mode, (void *)MODE_DEX5 }, - { mode_info[MODE_DEX8].name, 0, cb_init_mode, (void *)MODE_DEX8 }, - { mode_info[MODE_DEX11].name, 0, cb_init_mode, (void *)MODE_DEX11 }, - { mode_info[MODE_DSX11].name, 0, cb_init_mode, (void *)MODE_DSX11 }, - { mode_info[MODE_DEX16].name, 0, cb_init_mode, (void *)MODE_DEX16 }, - { mode_info[MODE_DEX22].name, 0, cb_init_mode, (void *)MODE_DEX22 }, +Fl_Menu_Item quick_change_thor[] = { + { mode_info[MODE_THOR4].name, 0, cb_init_mode, (void *)MODE_THOR4 }, + { mode_info[MODE_THOR5].name, 0, cb_init_mode, (void *)MODE_THOR5 }, + { mode_info[MODE_THOR8].name, 0, cb_init_mode, (void *)MODE_THOR8 }, + { mode_info[MODE_THOR11].name, 0, cb_init_mode, (void *)MODE_THOR11 }, + { mode_info[MODE_TSOR11].name, 0, cb_init_mode, (void *)MODE_TSOR11 }, + { mode_info[MODE_THOR16].name, 0, cb_init_mode, (void *)MODE_THOR16 }, + { mode_info[MODE_THOR22].name, 0, cb_init_mode, (void *)MODE_THOR22 }, { 0 } }; @@ -290,7 +290,7 @@ void cb_mnuSaveMacro(Fl_Menu_*, void*) { bool clean_exit() { if (progdefaults.changed == true) { - switch (fl_choice("Save changed configuration?", "Don't exit", "Save", "Don't save")) { + switch (fl_choice("Save changed configuration before exiting?", "Cancel", "Save", "Don't save")) { case 0: return false; case 1: @@ -301,7 +301,7 @@ bool clean_exit() { } } if (macros.changed == true) { - switch (fl_choice("Save changed macros?", "Don't exit", "Save", "Don't save")) { + switch (fl_choice("Save changed macros before exiting?", "Cancel", "Save", "Don't save")) { case 0: return false; case 1: @@ -403,12 +403,12 @@ void init_modem(trx_mode mode) modem_config_tab = tabCW; break; - case MODE_DEX4: case MODE_DEX5: case MODE_DEX8: - case MODE_DEX11: case MODE_DSX11: case MODE_DEX16: case MODE_DEX22: + case MODE_THOR4: case MODE_THOR5: case MODE_THOR8: + case MODE_THOR11: case MODE_TSOR11: case MODE_THOR16: case MODE_THOR22: startup_modem(*mode_info[mode].modem ? *mode_info[mode].modem : - *mode_info[mode].modem = new dex(mode)); - quick_change = quick_change_dex; - modem_config_tab = tabDEX; + *mode_info[mode].modem = new thor(mode)); + quick_change = quick_change_thor; + modem_config_tab = tabTHOR; break; case MODE_DOMINOEX4: case MODE_DOMINOEX5: case MODE_DOMINOEX8: @@ -895,9 +895,9 @@ void clearQSO() void qsoClear_cb(Fl_Widget *b, void *) { - if (fl_choice ("Confirm Clear", "Cancel", "OK", NULL) == 1) { + if (fl_choice ("Clear log fields?", "Cancel", "OK", NULL) == 1) { clearQSO(); - FL_AWAKE(); + FL_AWAKE_D(); } restoreFocus(); } @@ -1041,16 +1041,6 @@ Fl_Menu_Item menu_[] = { { mode_info[MODE_CW].name, 0, cb_init_mode, (void *)MODE_CW, 0, FL_NORMAL_LABEL, 0, 14, 0}, -{"DEX", 0, 0, 0, FL_SUBMENU, FL_NORMAL_LABEL, 0, 14, 0}, -{ mode_info[MODE_DEX4].name, 0, cb_init_mode, (void *)MODE_DEX4, 0, FL_NORMAL_LABEL, 0, 14, 0}, -{ mode_info[MODE_DEX5].name, 0, cb_init_mode, (void *)MODE_DEX5, 0, FL_NORMAL_LABEL, 0, 14, 0}, -{ mode_info[MODE_DEX8].name, 0, cb_init_mode, (void *)MODE_DEX8, 0, FL_NORMAL_LABEL, 0, 14, 0}, -{ mode_info[MODE_DEX11].name, 0, cb_init_mode, (void *)MODE_DEX11, 0, FL_NORMAL_LABEL, 0, 14, 0}, -{ mode_info[MODE_DSX11].name, 0, cb_init_mode, (void *)MODE_DSX11, 0, FL_NORMAL_LABEL, 0, 14, 0}, -{ mode_info[MODE_DEX16].name, 0, cb_init_mode, (void *)MODE_DEX16, 0, FL_NORMAL_LABEL, 0, 14, 0}, -{ mode_info[MODE_DEX22].name, 0, cb_init_mode, (void *)MODE_DEX22, 0, FL_NORMAL_LABEL, 0, 14, 0}, -{0,0,0,0,0,0,0,0,0}, - {"DominoEX", 0, 0, 0, FL_SUBMENU, FL_NORMAL_LABEL, 0, 14, 0}, { mode_info[MODE_DOMINOEX4].name, 0, cb_init_mode, (void *)MODE_DOMINOEX4, 0, FL_NORMAL_LABEL, 0, 14, 0}, { mode_info[MODE_DOMINOEX5].name, 0, cb_init_mode, (void *)MODE_DOMINOEX5, 0, FL_NORMAL_LABEL, 0, 14, 0}, @@ -1096,6 +1086,16 @@ Fl_Menu_Item menu_[] = { { mode_info[MODE_RTTY].name, 0, cb_init_mode, (void *)MODE_RTTY, 0, FL_NORMAL_LABEL, 0, 14, 0}, +{"THOR", 0, 0, 0, FL_SUBMENU, FL_NORMAL_LABEL, 0, 14, 0}, +{ mode_info[MODE_THOR4].name, 0, cb_init_mode, (void *)MODE_THOR4, 0, FL_NORMAL_LABEL, 0, 14, 0}, +{ mode_info[MODE_THOR5].name, 0, cb_init_mode, (void *)MODE_THOR5, 0, FL_NORMAL_LABEL, 0, 14, 0}, +{ mode_info[MODE_THOR8].name, 0, cb_init_mode, (void *)MODE_THOR8, 0, FL_NORMAL_LABEL, 0, 14, 0}, +{ mode_info[MODE_THOR11].name, 0, cb_init_mode, (void *)MODE_THOR11, 0, FL_NORMAL_LABEL, 0, 14, 0}, +{ mode_info[MODE_TSOR11].name, 0, cb_init_mode, (void *)MODE_TSOR11, 0, FL_NORMAL_LABEL, 0, 14, 0}, +{ mode_info[MODE_THOR16].name, 0, cb_init_mode, (void *)MODE_THOR16, 0, FL_NORMAL_LABEL, 0, 14, 0}, +{ mode_info[MODE_THOR22].name, 0, cb_init_mode, (void *)MODE_THOR22, 0, FL_NORMAL_LABEL, 0, 14, 0}, +{0,0,0,0,0,0,0,0,0}, + {"Throb", 0, 0, 0, FL_SUBMENU, FL_NORMAL_LABEL, 0, 14, 0}, { mode_info[MODE_THROB1].name, 0, cb_init_mode, (void *)MODE_THROB1, 0, FL_NORMAL_LABEL, 0, 14, 0}, { mode_info[MODE_THROB2].name, 0, cb_init_mode, (void *)MODE_THROB2, 0, FL_NORMAL_LABEL, 0, 14, 0}, @@ -1958,15 +1958,15 @@ void resetOLIVIA() { active_modem->restart(); } -void resetDEX() { +void resetTHOR() { trx_mode md = active_modem->get_mode(); - if (md == MODE_DEX4 || - md == MODE_DEX5 || - md == MODE_DEX8 || - md == MODE_DEX11 || - md == MODE_DSX11 || - md == MODE_DEX16 || - md == MODE_DEX22 ) { + if (md == MODE_THOR4 || + md == MODE_THOR5 || + md == MODE_THOR8 || + md == MODE_THOR11 || + md == MODE_TSOR11 || + md == MODE_THOR16 || + md == MODE_THOR22 ) { active_modem->restart(); } } diff --git a/src/feld/feld.cxx b/src/feld/feld.cxx index 9c487d0b..5835295f 100644 --- a/src/feld/feld.cxx +++ b/src/feld/feld.cxx @@ -142,8 +142,6 @@ feld::feld(trx_mode m) if (filter_bandwidth != progdefaults.HELL_BW) progdefaults.HELL_BW = filter_bandwidth; -std::cout << hell_bandwidth << ", " << progdefaults.HELL_BW << std::endl; - lp = 1.5 * filter_bandwidth / samplerate; bpfilt = new fftfilt(0, lp, 1024); @@ -275,10 +273,8 @@ int feld::rx_process(const double *buf, int len) complex z, *zp; int i, n; - FL_LOCK_D(); - halfwidth = btnHellRcvWidth->value(); - blackboard = btnBlackboard->value(); - FL_UNLOCK_D(); + halfwidth = progdefaults.HellRcvWidth; + blackboard = progdefaults.HellBlackboard; if (progdefaults.HELL_BW != filter_bandwidth) { double lp; @@ -414,7 +410,7 @@ void feld::send_symbol(int currsymb, int nextsymb) outbuf[outlen++] = Amp * nco(tone); if (outlen >= OUTBUFSIZE) { - std::cout << "feld reset\n"; std::cout.flush(); + std::cout << "feld reset" << std::endl; break; } txcounter += upsampleinc; @@ -470,10 +466,9 @@ int feld::tx_process() int c; bool hdkey; - FL_LOCK_D(); - dxmode = 1 + btnHellXmtWidth->value(); - hdkey = btnHellFastAttack->value(); - FL_UNLOCK_D(); + dxmode = 1 + progdefaults.HellXmtWidth; + hdkey = progdefaults.HellPulseFast; + fntnbr = progdefaults.feldfontnbr; if (hardkeying != hdkey) { hardkeying = hdkey; diff --git a/src/fileselector/fileselect.cxx b/src/fileselector/fileselect.cxx index 6be176ec..ef827459 100644 --- a/src/fileselector/fileselect.cxx +++ b/src/fileselector/fileselect.cxx @@ -7,76 +7,139 @@ #include #include +#if FSEL_THREAD +# include +# include +# include "threads.h" +#endif + using namespace std; -static Fl_Native_File_Chooser chooser; -static std::string filename; -static const char* get_file(void) +FSEL* FSEL::inst = 0; +static std::string filename; +#if FSEL_THREAD +static Fl_Thread fsel_thread; +sem_t fsel_sem; +#endif + +void FSEL::create(void) { - const char* preset = chooser.preset_file(); - if (preset && *preset != '/' && chooser.directory()) { - filename = chooser.directory(); + if (inst) + return; +#if FSEL_THREAD + if (sem_init(&fsel_sem, 0, 0) == -1) { + perror("sem_init"); + return; + } +#endif + inst = new FSEL; +} + +void FSEL::destroy(void) +{ +#if FSEL_THREAD + sem_destroy(&fsel_sem); +#endif + delete inst; + inst = 0; +} + + +FSEL::FSEL() + : chooser(new Fl_Native_File_Chooser) { } +FSEL::~FSEL() { delete chooser; } + + +#if FSEL_THREAD +void* FSEL::thread_func(void* arg) +{ + FSEL* fsel = reinterpret_cast(arg); + fsel->result = fsel->chooser->show(); + sem_post(&fsel_sem); + return NULL; +} +#endif + +const char* FSEL::get_file(void) +{ + const char* preset = chooser->preset_file(); + if (preset && *preset != '/' && chooser->directory()) { + filename = chooser->directory(); filename.append("/").append(preset); - chooser.preset_file(filename.c_str()); + chooser->preset_file(filename.c_str()); } - switch (chooser.show()) { +#if FSEL_THREAD + if (fl_create_thread(fsel_thread, thread_func, this) != 0) { + fl_alert("%s", "could not create file selector thread"); + return NULL; + } + for (;;) { + if (sem_trywait(&fsel_sem) == 0) + break; + Fl::wait(0.1); + } +#else + result = chooser->show(); +#endif + + switch (result) { case -1: - fl_alert("%s", chooser.errmsg()); + fl_alert("%s", chooser->errmsg()); // fall through case 1: return NULL; default: - filename = chooser.filename(); + filename = chooser->filename(); string::size_type i = filename.rfind('/'); if (i != string::npos) - chooser.directory(filename.substr(0, i).c_str()); + chooser->directory(filename.substr(0, i).c_str()); return filename.c_str(); } } -const char* file_select(const char* title, const char* filter, const char* def, int* fsel) +const char* FSEL::select(const char* title, const char* filter, const char* def, int* fsel) { - chooser.title(title); - chooser.filter(filter); + inst->chooser->title(title); + inst->chooser->filter(filter); if (def) - chooser.preset_file(def); - chooser.options(Fl_Native_File_Chooser::PREVIEW); - chooser.type(Fl_Native_File_Chooser::BROWSE_FILE); + inst->chooser->preset_file(def); + inst->chooser->options(Fl_Native_File_Chooser::PREVIEW); + inst->chooser->type(Fl_Native_File_Chooser::BROWSE_FILE); - const char* fn = get_file(); + const char* fn = inst->get_file(); if (fsel) - *fsel = chooser.filter_value(); + *fsel = inst->chooser->filter_value(); return fn; } -const char* file_saveas(const char* title, const char* filter, const char* def, int* fsel) +const char* FSEL::saveas(const char* title, const char* filter, const char* def, int* fsel) { - chooser.title(title); - chooser.filter(filter); + inst->chooser->title(title); + inst->chooser->filter(filter); if (def) - chooser.preset_file(def); - chooser.options(Fl_Native_File_Chooser::SAVEAS_CONFIRM | + inst->chooser->preset_file(def); + inst->chooser->options(Fl_Native_File_Chooser::SAVEAS_CONFIRM | Fl_Native_File_Chooser::NEW_FOLDER | Fl_Native_File_Chooser::PREVIEW); - chooser.type(Fl_Native_File_Chooser::BROWSE_SAVE_FILE); + inst->chooser->type(Fl_Native_File_Chooser::BROWSE_SAVE_FILE); - const char* fn = get_file(); + const char* fn = inst->get_file(); if (fsel) - *fsel = chooser.filter_value(); + *fsel = inst->chooser->filter_value(); return fn; } -const char* dir_select(const char* title, const char* filter, const char* def) +const char* FSEL::dir_select(const char* title, const char* filter, const char* def) { - chooser.title(title); - chooser.filter(filter); + inst->chooser->title(title); + inst->chooser->filter(filter); if (def) - chooser.directory(def); - chooser.options(Fl_Native_File_Chooser::NEW_FOLDER | + inst->chooser->directory(def); + inst->chooser->options(Fl_Native_File_Chooser::NEW_FOLDER | Fl_Native_File_Chooser::PREVIEW); - chooser.type(Fl_Native_File_Chooser::BROWSE_DIRECTORY); + inst->chooser->type(Fl_Native_File_Chooser::BROWSE_DIRECTORY); - return get_file(); + return inst->get_file(); } diff --git a/src/globals/globals.cxx b/src/globals/globals.cxx index 81054657..5855a02b 100644 --- a/src/globals/globals.cxx +++ b/src/globals/globals.cxx @@ -45,13 +45,13 @@ const char *state_names[] = { const struct mode_info_t mode_info[NUM_MODES] = { { MODE_CW, &cw_modem, "CW", "CW", "CW", "CW" }, - { MODE_DEX4, &dex4_modem, "DEX4", "DEX 4", "DEX4", "DEX" }, - { MODE_DEX5, &dex5_modem, "DEX5", "DEX 5", "DEX5", "DEX" }, - { MODE_DEX8, &dex8_modem, "DEX8", "DEX 8", "DEX8", "DEX" }, - { MODE_DEX11, &dex11_modem, "DEX11", "DEX 11", "DEX11", "DEX" }, - { MODE_DSX11, &dsx11_modem, "DSX11", "DSX 11", "DSX11", "DEX" }, - { MODE_DEX16, &dex16_modem, "DEX16", "DEX 16", "DEX16", "DEX" }, - { MODE_DEX22, &dex22_modem, "DEX22", "DEX 22", "DEX22", "DEX" }, + { MODE_THOR4, &thor4_modem, "THOR4", "THOR 4", "THOR4", "THOR" }, + { MODE_THOR5, &thor5_modem, "THOR5", "THOR 5", "THOR5", "THOR" }, + { MODE_THOR8, &thor8_modem, "THOR8", "THOR 8", "THOR8", "THOR" }, + { MODE_THOR11, &thor11_modem, "THOR11", "THOR 11", "THOR11", "THOR" }, + { MODE_TSOR11, &tsor11_modem, "TSOR11", "TSOR 11", "TSOR11", "TSOR" }, + { MODE_THOR16, &thor16_modem, "THOR16", "THOR 16", "THOR16", "THOR" }, + { MODE_THOR22, &thor22_modem, "THOR22", "THOR 22", "THOR22", "THOR" }, { MODE_DOMINOEX4, &dominoex4_modem, "DomEX4", "DominoEX 4", "DOMINOEX4", "DOMINO" }, { MODE_DOMINOEX5, &dominoex5_modem, "DomEX5", "DominoEX 5", "DOMINOEX5", "DOMINO" }, diff --git a/src/include/confdialog.h b/src/include/confdialog.h index ade27687..26ae0b5f 100644 --- a/src/include/confdialog.h +++ b/src/include/confdialog.h @@ -50,6 +50,7 @@ extern Fl_Check_Button *btnsendvideotext; extern Fl_Input *valVideotext; #include extern Fl_Value_Slider *sldrVideowidth; +extern Fl_Check_Button *chkID_SMALL; extern Fl_Check_Button *btnViewXmtSignal; extern Fl_Group *sld; extern Fl_Check_Button *btnCWID; @@ -137,12 +138,12 @@ extern Fl_Group *tabCWQSK; extern Fl_Check_Button *btnQSK; extern Fl_Counter *cntPreTiming; extern Fl_Counter *cntPostTiming; -extern Fl_Group *tabDEX; -extern Fl_Input *txtDEXSecondary; -extern Fl_Counter *valDEX_BW; -extern Fl_Check_Button *valDEX_FILTER; -extern Fl_Counter *valDEX_PATHS; -extern Fl_Check_Button *valDEX_SOFT; +extern Fl_Group *tabTHOR; +extern Fl_Input *txtTHORSecondary; +extern Fl_Counter *valTHOR_BW; +extern Fl_Check_Button *valTHOR_FILTER; +extern Fl_Counter *valTHOR_PATHS; +extern Fl_Check_Button *valTHOR_SOFT; extern Fl_Group *tabDomEX; extern Fl_Input *txtSecondary; extern Fl_Counter *valDominoEX_BW; diff --git a/src/include/configuration.h b/src/include/configuration.h index b33cf4de..13298407 100644 --- a/src/include/configuration.h +++ b/src/include/configuration.h @@ -68,18 +68,23 @@ struct configuration { // FELD-HELL bool FELD_IDLE; double HELL_BW; + bool HellRcvWidth; + bool HellBlackboard; + bool HellXmtWidth; + bool HellXmtIdle; + bool HellPulseFast; // OLIVIA int oliviatones; int oliviabw; int oliviasmargin; int oliviasinteg; bool olivia8bit; -// DEX - double DEX_BW; - bool DEX_FILTER; - string DEXsecText; - int DEX_PATHS; - bool DEX_SOFT; +// THOR + double THOR_BW; + bool THOR_FILTER; + string THORsecText; + int THOR_PATHS; + bool THOR_SOFT; // DOMINOEX double DOMINOEX_BW; bool DOMINOEX_FILTER; @@ -110,6 +115,7 @@ struct configuration { string strTextid; bool macroCWid; int videowidth; + bool ID_SMALL; bool macrotextid; int QRZ; string QRZusername; @@ -203,6 +209,11 @@ struct configuration { double VIEWERsquelch; int VIEWERtimeout; +// XMLRPC parameters + bool xmlrpc_server; + string xmlrpc_address; + string xmlrpc_port; + public: void writeDefaultsXML(); void storeDefaults(); diff --git a/src/include/digiscope.h b/src/include/digiscope.h index 57802667..dfb8d9f9 100644 --- a/src/include/digiscope.h +++ b/src/include/digiscope.h @@ -51,6 +51,7 @@ public: enum scope_mode { SCOPE, PHASE, + PHASE1, PHASE2, PHASE3, RTTY, @@ -75,6 +76,7 @@ private: double _quality; double _flo, _fhi, _amp; bool _highlight; + scope_mode phase_mode; public: Digiscope(int, int, int, int); diff --git a/src/include/fileselect.h b/src/include/fileselect.h index f0f9d4fd..19cfe78c 100644 --- a/src/include/fileselect.h +++ b/src/include/fileselect.h @@ -1,8 +1,34 @@ #ifndef FILESELECT_H #define FILESELECT_H -const char* file_select(const char* title, const char* filter, const char* def = 0, int* fsel = 0); -const char* file_saveas(const char* title, const char* filter, const char* def = 0, int* fsel = 0); -const char* dir_select(const char* title, const char* filter, const char* def = 0); +#ifdef __CYGWIN__ +# define FSEL_THREAD 1 +#endif + +class Fl_Native_File_Chooser; + +class FSEL +{ +public: + static void create(void); + static void destroy(void); + static const char* select(const char* title, const char* filter, const char* def = 0, int* fsel = 0); + static const char* saveas(const char* title, const char* filter, const char* def = 0, int* fsel = 0); + static const char* dir_select(const char* title, const char* filter, const char* def = 0); + ~FSEL(); +private: + FSEL(); + FSEL(const FSEL&); + FSEL& operator=(const FSEL&); + + const char* get_file(void); +#if FSEL_THREAD + static void* thread_func(void* arg); +#endif +private: + static FSEL* inst; + Fl_Native_File_Chooser* chooser; + int result; +}; #endif // FILESELECT_H diff --git a/src/include/fl_digi.h b/src/include/fl_digi.h index ff27f307..8e60258c 100644 --- a/src/include/fl_digi.h +++ b/src/include/fl_digi.h @@ -133,7 +133,7 @@ extern int get_secondary_char(); extern void put_echo_char(unsigned int data); extern void resetRTTY(); extern void resetOLIVIA(); -extern void resetDEX(); +extern void resetTHOR(); extern void resetDOMEX(); extern void resetSoundCard(); extern void restoreFocus(); diff --git a/src/include/globals.h b/src/include/globals.h index df5c7d7d..a3c79d10 100644 --- a/src/include/globals.h +++ b/src/include/globals.h @@ -51,13 +51,13 @@ enum { MODE_CW, - MODE_DEX4, - MODE_DEX5, - MODE_DEX8, - MODE_DEX11, - MODE_DSX11, - MODE_DEX16, - MODE_DEX22, + MODE_THOR4, + MODE_THOR5, + MODE_THOR8, + MODE_THOR11, + MODE_TSOR11, + MODE_THOR16, + MODE_THOR22, MODE_DOMINOEX4, MODE_DOMINOEX5, diff --git a/src/include/modem.h b/src/include/modem.h index 821e79c0..92d68ea6 100644 --- a/src/include/modem.h +++ b/src/include/modem.h @@ -194,13 +194,13 @@ extern modem *qpsk125_modem; extern modem *qpsk250_modem; extern modem *rtty_modem; extern modem *olivia_modem; -extern modem *dex4_modem; -extern modem *dex5_modem; -extern modem *dex8_modem; -extern modem *dex11_modem; -extern modem *dsx11_modem; -extern modem *dex16_modem; -extern modem *dex22_modem; +extern modem *thor4_modem; +extern modem *thor5_modem; +extern modem *thor8_modem; +extern modem *thor11_modem; +extern modem *tsor11_modem; +extern modem *thor16_modem; +extern modem *thor22_modem; extern modem *dominoex4_modem; extern modem *dominoex5_modem; extern modem *dominoex8_modem; diff --git a/src/include/qrunner.h b/src/include/qrunner.h index c0373a83..40256ef7 100644 --- a/src/include/qrunner.h +++ b/src/include/qrunner.h @@ -33,13 +33,19 @@ #if HAVE_STD_BIND # include +namespace qrbind { using std::bind; +}; #elif HAVE_STD_TR1_BIND # include +namespace qrbind { using std::tr1::bind; +}; #else # include +namespace qrbind { using boost::bind; +}; #endif #include "threads.h" @@ -158,16 +164,16 @@ extern qrunner *cbq[NUM_QRUNNER_THREADS]; #define REQ_ASYNC(...) \ do { \ if (GET_THREAD_ID() != FLMAIN_TID) \ - cbq[GET_THREAD_ID()]->request(bind(__VA_ARGS__)); \ + cbq[GET_THREAD_ID()]->request(qrbind::bind(__VA_ARGS__)); \ else \ - bind(__VA_ARGS__)(); \ + qrbind::bind(__VA_ARGS__)(); \ } while (0) #define REQ_SYNC(...) \ do { \ if (GET_THREAD_ID() != FLMAIN_TID) \ - cbq[GET_THREAD_ID()]->request_sync(bind(__VA_ARGS__)); \ + cbq[GET_THREAD_ID()]->request_sync(qrbind::bind(__VA_ARGS__)); \ else \ - bind(__VA_ARGS__)(); \ + qrbind::bind(__VA_ARGS__)(); \ } while (0) #define REQ_ASYNC_DROP(...) \ @@ -175,20 +181,20 @@ extern qrunner *cbq[NUM_QRUNNER_THREADS]; if (GET_THREAD_ID() != FLMAIN_TID) { \ if (unlikely(cbq[GET_THREAD_ID()]->drop_flag)) \ break; \ - cbq[GET_THREAD_ID()]->request(bind(__VA_ARGS__)); \ + cbq[GET_THREAD_ID()]->request(qrbind::bind(__VA_ARGS__)); \ } \ else \ - bind(__VA_ARGS__)(); \ + qrbind::bind(__VA_ARGS__)(); \ } while (0) #define REQ_SYNC_DROP(...) \ do { \ if (GET_THREAD_ID() != FLMAIN_TID) { \ if (unlikely(cbq[GET_THREAD_ID()]->drop_flag)) \ break; \ - cbq[GET_THREAD_ID()]->request_sync(bind(__VA_ARGS__)); \ + cbq[GET_THREAD_ID()]->request_sync(qrbind::bind(__VA_ARGS__)); \ } \ else \ - bind(__VA_ARGS__)(); \ + qrbind::bind(__VA_ARGS__)(); \ } while (0) #define REQ_FLUSH() \ diff --git a/src/include/status.h b/src/include/status.h index fe54dbc9..ebeaed36 100644 --- a/src/include/status.h +++ b/src/include/status.h @@ -13,6 +13,8 @@ struct status { bool rigShown; int rigX; int rigY; + int rigW; + int rigH; int carrier; int mag; int speed; diff --git a/src/include/dex.h b/src/include/thor.h similarity index 85% rename from src/include/dex.h rename to src/include/thor.h index ff99fc47..766b1a92 100644 --- a/src/include/dex.h +++ b/src/include/thor.h @@ -1,5 +1,5 @@ // -// dex.h -- dex modem +// thor.h -- thor modem // // Copyright (C) 2008 // David Freese (w1hkj@w1hkj.com) @@ -19,8 +19,8 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // ---------------------------------------------------------------------------- -#ifndef _dex_H -#define _dex_H +#ifndef _thor_H +#define _thor_H #include @@ -33,9 +33,9 @@ #include "mbuffer.h" // NASA coefficients for viterbi encode/decode algorithms -#define DEX_K 7 -#define DEX_POLY1 0x6d -#define DEX_POLY2 0x4f +#define THOR_K 7 +#define THOR_POLY1 0x6d +#define THOR_POLY2 0x4f //#include "mfskvaricode.h" #include "interleave.h" @@ -44,18 +44,18 @@ using namespace std; -#define DEXNUMMTONES 18 -#define DEXMAXFFTS 8 -#define DEXBASEFREQ 500.0 -#define DEXFIRSTIF 1000.0 +#define THORNUMMTONES 18 +#define THORMAXFFTS 8 +#define THORBASEFREQ 500.0 +#define THORFIRSTIF 1000.0 -#define DEXSCOPESIZE 64 +#define THORSCOPESIZE 64 -struct DEXrxpipe { - complex vector[DEXMAXFFTS * DEXNUMMTONES * 6]; +struct THORrxpipe { + complex vector[THORMAXFFTS * THORNUMMTONES * 6]; }; -class dex : public modem { +class thor : public modem { public: enum { TX_STATE_PREAMBLE, @@ -66,7 +66,7 @@ public: }; protected: // common variables - double phase[DEXMAXFFTS + 1]; + double phase[THORMAXFFTS + 1]; double txphase; int symlen; int doublespaced; @@ -77,12 +77,12 @@ protected: // rx variables C_FIR_filter *hilbert; - sfft *binsfft[DEXMAXFFTS]; + sfft *binsfft[THORMAXFFTS]; fftfilt *fft; - Cmovavg *vidfilter[DEXSCOPESIZE]; + Cmovavg *vidfilter[THORSCOPESIZE]; Cmovavg *syncfilter; - DEXrxpipe *pipe; + THORrxpipe *pipe; unsigned int pipeptr; unsigned int datashreg; mbuffer scopedata; @@ -153,8 +153,8 @@ private: void Clearbits(); public: - dex (trx_mode md); - ~dex (); + thor (trx_mode md); + ~thor (); void init(); void rx_init(); void tx_init(SoundBase *sc); diff --git a/src/include/dexvaricode.h b/src/include/thorvaricode.h similarity index 87% rename from src/include/dexvaricode.h rename to src/include/thorvaricode.h index e7461839..0f5a0c56 100644 --- a/src/include/dexvaricode.h +++ b/src/include/thorvaricode.h @@ -1,5 +1,5 @@ // -// dexvaricode.h -- DEX Varicode +// thorvaricode.h -- DEX Varicode // // Copyright (C) 2008 // Dave Freese, W1HKJ @@ -24,7 +24,7 @@ #ifndef _DEXVARICODE_H #define _DEXVARICODE_H -extern const char *dexvarienc(int c, int secondary); -extern int dexvaridec(unsigned int symbol); +extern const char *thorvarienc(int c, int secondary); +extern int thorvaridec(unsigned int symbol); #endif diff --git a/src/include/threads.h b/src/include/threads.h index a5ab2979..4657baff 100644 --- a/src/include/threads.h +++ b/src/include/threads.h @@ -61,8 +61,11 @@ extern int fl_join(Fl_Thread t); // we have 4 threads, only 3 of which will use qrunner -enum { UNKNOWN_TID = -1, TRX_TID, QRZ_TID, RIGCTL_TID, FLMAIN_TID, - NUM_THREADS, NUM_QRUNNER_THREADS = NUM_THREADS - 1 }; +enum { UNKNOWN_TID = -1, TRX_TID, QRZ_TID, RIGCTL_TID, +#if USE_XMLRPC + XMLRPC_TID, +#endif + FLMAIN_TID, NUM_THREADS, NUM_QRUNNER_THREADS = NUM_THREADS - 1 }; #if USE_TLS extern __thread int thread_id_; diff --git a/src/include/waterfall.h b/src/include/waterfall.h index 10d8fdda..1f2ffb9b 100644 --- a/src/include/waterfall.h +++ b/src/include/waterfall.h @@ -364,6 +364,13 @@ public: /* */ Fl_Button *btnRev; + Fl_Counter *wfcarrier; + Fl_Counter *wfRefLevel; + Fl_Counter *wfAmpSpan; + Fl_Light_Button *xmtrcv; + Fl_Light_Button *xmtlock; + Fl_Button *qsy; + private: Fl_Box *bezel; WFdisp *wfdisp; @@ -373,13 +380,7 @@ private: Fl_Button *left; Fl_Button *center; Fl_Button *right; - Fl_Counter *wfcarrier; - Fl_Counter *wfRefLevel; - Fl_Counter *wfAmpSpan; - Fl_Button *qsy; Fl_Button *wfrate; - Fl_Light_Button *xmtrcv; - Fl_Light_Button *xmtlock; Fl_Button *btnMem; Fl_Menu_Button *mbtnMem; int buttonrow; diff --git a/src/include/xmlrpc.h b/src/include/xmlrpc.h new file mode 100644 index 00000000..f10170c9 --- /dev/null +++ b/src/include/xmlrpc.h @@ -0,0 +1,25 @@ +#ifndef XMLRPC_H +#define XMLRPC_H + +class XML_RPC_Server +{ +public: + static void start(const char* node, const char* service); + static void stop(void); +private: + XML_RPC_Server(int sfd_); + XML_RPC_Server(); + ~XML_RPC_Server(); + XML_RPC_Server(const XML_RPC_Server&); + XML_RPC_Server operator=(const XML_RPC_Server&); + void add_methods(void); + static int get_socket(const char* node, const char* service, int& fd); + static void* thread_func(void* arg); + +private: + static XML_RPC_Server* inst; + bool run; + unsigned short sfd; +}; + +#endif // XMLRPC_H diff --git a/src/main.cxx b/src/main.cxx index 04ecd1a0..9c146feb 100644 --- a/src/main.cxx +++ b/src/main.cxx @@ -61,6 +61,7 @@ #include "configuration.h" #include "macros.h" #include "status.h" +#include "fileselect.h" #if USE_HAMLIB #include "rigclass.h" @@ -72,6 +73,10 @@ #include "qrunner.h" #include "stacktrace.h" +#if USE_XMLRPC + #include "xmlrpc.h" +#endif + using namespace std; string appname; @@ -209,6 +214,7 @@ int main(int argc, char ** argv) progStatus.loadLastState(); create_fl_digi_main(); + FSEL::create(); createConfig(); inpTTYdev->tooltip(progdefaults.strCommPorts.c_str()); @@ -239,11 +245,22 @@ int main(int argc, char ** argv) Fl::add_timeout(1.0, pskmail_loop); +#if USE_XMLRPC + if (progdefaults.xmlrpc_server) + XML_RPC_Server::start(progdefaults.xmlrpc_address.c_str(), progdefaults.xmlrpc_port.c_str()); +#endif + int ret = Fl::run(); + +#if USE_XMLRPC + XML_RPC_Server::stop(); +#endif + for (int i = 0; i < NUM_QRUNNER_THREADS; i++) { cbq[i]->detach(); delete cbq[i]; } + FSEL::destroy(); return ret; } @@ -290,6 +307,15 @@ void generate_option_help(void) { << " --resample CONVERTER **DEPRECATED**\n" << " This option has been deprecated and will be removed in a future release\n\n" + << " --xmlrpc-server\n" + << " Start the XML-RPC server\n\n" + << " --xmlrpc-server-address HOSTNAME\n" + << " Set the XML-RPC server address\n" + << " The default is: " << progdefaults.xmlrpc_address << "\n\n" + << " --xmlrpc-server-port PORT\n" + << " Set the XML-RPC server port\n" + << " The default is: " << progdefaults.xmlrpc_port << "\n\n" + << " --version\n" << " Print version information\n\n" @@ -373,6 +399,9 @@ int parse_args(int argc, char **argv, int& idx) OPT_RX_IPC_KEY, OPT_TX_IPC_KEY, #endif OPT_CONFIG_DIR, +#if USE_XMLRPC + OPT_CONFIG_XMLRPC, OPT_CONFIG_XMLRPC_ADDRESS, OPT_CONFIG_XMLRPC_PORT, +#endif OPT_FONT, OPT_WFALL_WIDTH, OPT_WFALL_HEIGHT, OPT_WINDOW_WIDTH, OPT_WINDOW_HEIGHT, OPT_PROFILE, @@ -392,6 +421,12 @@ int parse_args(int argc, char **argv, int& idx) { "tx-ipc-key", 1, 0, OPT_TX_IPC_KEY }, #endif { "config-dir", 1, 0, OPT_CONFIG_DIR }, + +#if USE_XMLRPC + { "xmlrpc-server", 0, 0, OPT_CONFIG_XMLRPC }, + { "xmlrpc-server-address", 1, 0, OPT_CONFIG_XMLRPC_ADDRESS }, + { "xmlrpc-server-port", 1, 0, OPT_CONFIG_XMLRPC_PORT }, +#endif { "font", 1, 0, OPT_FONT }, { "wfall-width", 1, 0, OPT_WFALL_WIDTH }, @@ -446,6 +481,18 @@ int parse_args(int argc, char **argv, int& idx) HomeDir += '/'; break; +#if USE_XMLRPC + case OPT_CONFIG_XMLRPC: + progdefaults.xmlrpc_server = true; + break; + case OPT_CONFIG_XMLRPC_ADDRESS: + progdefaults.xmlrpc_address = optarg; + break; + case OPT_CONFIG_XMLRPC_PORT: + progdefaults.xmlrpc_port = optarg; + break; +#endif + case OPT_FONT: { char *p; diff --git a/src/mfsk/mfsk.cxx b/src/mfsk/mfsk.cxx index 3d01b714..cb5f0ae9 100644 --- a/src/mfsk/mfsk.cxx +++ b/src/mfsk/mfsk.cxx @@ -919,7 +919,7 @@ void cb_picRxSave( Fl_Widget *w, void *who) ; int fsel; - const char *fn = file_saveas("Save image as:", ffilter, dfname, &fsel); + const char *fn = FSEL::saveas("Save image as:", ffilter, dfname, &fsel); if (!fn) return; // selected filter determines format switch (fsel) { @@ -1054,7 +1054,7 @@ void updateTxPic(unsigned char data, mfsk *me) void cb_picTxLoad(Fl_Widget *,void *who) { // mfsk *TxWho = (mfsk *)who; const char *fn = - file_select("Load image file", "Portable Network Graphics\t*.png\n" + FSEL::select("Load image file", "Portable Network Graphics\t*.png\n" "Independent JPEG Group\t*.{jpg,jif,jpeg,jpe}\n" "Graphics Interchange Format\t*.gif"); if (!fn) return; diff --git a/src/misc/configuration.cxx b/src/misc/configuration.cxx index 42305b11..02e6c5f6 100644 --- a/src/misc/configuration.cxx +++ b/src/misc/configuration.cxx @@ -73,18 +73,23 @@ configuration progdefaults = { // FELD-HELL false, // bool FELD_IDLE; 150.0, // double HELL_BW; + false, // bool HellRcvWidth; + false, // bool HellBlackboard; + false, // bool HellXmtWidth; + true, // bool HellXmtIdle; + false, // bool HellPulseFast; // OLIVIA 2, // int oliviatones; 2, // int oliviabw; 8, // int oliviasmargin 4, // int oliviasinteg false, // bool olivia8bit -// DEX - 2.0, // double DEX_BW; - true, // bool DEX_FILTER; - "fldigi-dex ", // string DEXsecText; - 5, // int DEX_PATHS; - false, // bool DEX_SOFT; +// THOR + 2.0, // double THOR_BW; + true, // bool THOR_FILTER; + "fldigi-thor ", // string THORsecText; + 5, // int THOR_PATHS; + false, // bool THOR_SOFT; // DOMINOEX 2.0, // double DOMINOEX_BW; true, // bool DOMINOEX_FILTER @@ -115,6 +120,7 @@ configuration progdefaults = { "CQ", // string strTextid; false, // bool macroCWid; 1, // int videowidth; + true, // bool ID_SMALL; false, // bool macrotextid; 0, // int QRZ; "", // string QRZusername; @@ -215,6 +221,9 @@ configuration progdefaults = { 20, // int VIEWERchannels 20.0, // double VIEWERsquelch 15, // int VIEWERtimeout + false, // bool xmlrpc_server + "localhost", // string xmlrpc_address + "7362", // string xmlrpc_port }; const char *szBaudRates[] = { @@ -252,15 +261,16 @@ enum TAG { \ CWTRACK, CWRISETIME, CWDASH2DOT, XQSK, CWPRE, CWPOST, CWID, CWIDWPM, OLIVIATONES, OLIVIABW, OLIVIASMARGIN, OLIVIASINTEG, OLIVIA8BIT, - DEXBW, DEXFILTER, DEXSECTEXT, DEXPATHS, DEXSOFT, + THORBW, THORFILTER, THORSECTEXT, THORPATHS, THORSOFT, DOMINOEXBW, DOMINOEXFILTER, DOMINOEXFEC, DOMINOEXPATHS, FELDFONTNBR, FELDIDLE, + HELLRCVWIDTH, HELLXMTWIDTH, HELLBLACKBOARD, HELLPULSEFAST, HELLXMTIDLE, WFPREFILTER, LATENCY, USECURSORLINES, USECURSORCENTERLINE, USEBWTRACKS, CLCOLORS, CCCOLORS, BWTCOLORS, - VIEWXMTSIGNAL, SENDID, MACROID, SENDTEXTID, STRTEXTID, VIDEOWIDTH, + VIEWXMTSIGNAL, SENDID, MACROID, SENDTEXTID, STRTEXTID, VIDEOWIDTH, IDSMALL, QRZTYPE, QRZUSER, QRZPASSWORD, BTNUSB, BTNPTTIS, RTSPTT, DTRPTT, RTSPLUS, DTRPLUS, @@ -269,7 +279,7 @@ enum TAG { \ HAMRIGNAME, HAMRIGDEVICE, HAMRIGBAUDRATE, PTTDEV, SECONDARYTEXT, - AUDIOIO, OSSDEVICE, PADEVICE, PORTINDEVICE, PORTININDEX, PORTOUTDEVICE, PORTOUTINDEX, PULSESERVER, + AUDIOIO, OSSDEVICE, PADEVICE, PORTINDEVICE, PORTININTHOR, PORTOUTDEVICE, PORTOUTINTHOR, PULSESERVER, SAMPLERATE, INSAMPLERATE, OUTSAMPLERATE, SAMPLECONVERTER, RXCORR, TXCORR, TXOFFSET, USELEADINGZEROS, CONTESTSTART, CONTESTDIGITS, USETIMER, MACRONUMBER, TIMEOUT, @@ -393,11 +403,11 @@ void configuration::writeDefaultsXML() writeXMLint(f, "OLIVIASINTEG", oliviasinteg); writeXMLbool(f, "OLIVIA8BIT", olivia8bit); - writeXMLdbl(f, "DEXBW", DEX_BW); - writeXMLbool(f, "DEXFILTER", DEX_FILTER); - writeXMLstr(f, "DEXSECTEXT", DEXsecText); - writeXMLint(f, "DEXPATHS", DEX_PATHS); - writeXMLbool(f, "DEXSOFT", DEX_SOFT); + writeXMLdbl(f, "THORBW", THOR_BW); + writeXMLbool(f, "THORFILTER", THOR_FILTER); + writeXMLstr(f, "THORSECTEXT", THORsecText); + writeXMLint(f, "THORPATHS", THOR_PATHS); + writeXMLbool(f, "THORSOFT", THOR_SOFT); writeXMLdbl(f, "DOMINOEXBW", DOMINOEX_BW); writeXMLbool(f, "DOMINOEXFILTER", DOMINOEX_FILTER); @@ -406,6 +416,11 @@ void configuration::writeDefaultsXML() writeXMLint(f, "FELDFONTNBR", feldfontnbr); writeXMLbool(f, "FELDIDLE", FELD_IDLE); + writeXMLbool(f, "HELLRCVWIDTH", HellRcvWidth); + writeXMLbool(f, "HELLXMTWIDTH", HellXmtWidth); + writeXMLbool(f, "HELLBLACKBOARD", HellBlackboard); + writeXMLbool(f, "HELLPULSEFAST", HellPulseFast); + writeXMLbool(f, "HELLXMTIDLE", HellXmtIdle); writeXMLint(f, "WFPREFILTER", wfPreFilter); writeXMLint(f, "LATENCY", latency); @@ -430,6 +445,7 @@ void configuration::writeDefaultsXML() writeXMLbool(f, "SENDTEXTID", sendtextid); writeXMLstr(f, "STRTEXTID", strTextid); writeXMLint(f, "VIDEOWIDTH", videowidth); + writeXMLbool(f, "IDSMALL", ID_SMALL); writeXMLint(f, "QRZTYPE", QRZ); writeXMLstr(f, "QRZUSER", QRZusername); writeXMLstr(f, "QRZPASSWORD", QRZuserpassword); @@ -453,9 +469,9 @@ void configuration::writeDefaultsXML() writeXMLstr(f, "OSSDEVICE", OSSdevice); writeXMLstr(f, "PADEVICE", PAdevice); writeXMLstr(f, "PORTINDEVICE", PortInDevice); - writeXMLint(f, "PORTININDEX", PortInIndex); + writeXMLint(f, "PORTININTHOR", PortInIndex); writeXMLstr(f, "PORTOUTDEVICE", PortOutDevice); - writeXMLint(f, "PORTOUTINDEX", PortOutIndex); + writeXMLint(f, "PORTOUTINTHOR", PortOutIndex); writeXMLstr(f, "PULSESERVER", PulseServer); writeXMLint(f, "SAMPLERATE", sample_rate); writeXMLint(f, "INSAMPLERATE", in_sample_rate); @@ -691,20 +707,20 @@ bool configuration::readDefaultsXML() case OLIVIA8BIT : olivia8bit = atoi(xml->getNodeData()); break; - case DEXBW : - DEX_BW = atof(xml->getNodeData()); + case THORBW : + THOR_BW = atof(xml->getNodeData()); break; - case DEXFILTER : - DEX_FILTER = atoi(xml->getNodeData()); + case THORFILTER : + THOR_FILTER = atoi(xml->getNodeData()); break; - case DEXSECTEXT : - DEXsecText = xml->getNodeData(); + case THORSECTEXT : + THORsecText = xml->getNodeData(); break; - case DEXPATHS : - DEX_PATHS = atoi(xml->getNodeData()); + case THORPATHS : + THOR_PATHS = atoi(xml->getNodeData()); break; - case DEXSOFT : - DEX_SOFT = atoi(xml->getNodeData()); + case THORSOFT : + THOR_SOFT = atoi(xml->getNodeData()); break; case DOMINOEXBW : DOMINOEX_BW = atof(xml->getNodeData()); @@ -724,6 +740,21 @@ bool configuration::readDefaultsXML() case FELDIDLE : FELD_IDLE = atoi(xml->getNodeData()); break; + case HELLRCVWIDTH : + HellRcvWidth = atoi(xml->getNodeData()); + break; + case HELLXMTWIDTH : + HellXmtWidth = atoi(xml->getNodeData()); + break; + case HELLBLACKBOARD : + HellBlackboard = atoi(xml->getNodeData()); + break; + case HELLPULSEFAST : + HellPulseFast = atoi(xml->getNodeData()); + break; + case HELLXMTIDLE : + HellXmtIdle = atoi(xml->getNodeData()); + break; case WFPREFILTER : wfPreFilter = atoi(xml->getNodeData()); break; @@ -773,6 +804,8 @@ bool configuration::readDefaultsXML() strTextid = xml->getNodeData(); case VIDEOWIDTH : videowidth = atoi(xml->getNodeData()); + case IDSMALL : + ID_SMALL = atoi(xml->getNodeData()); case QRZTYPE : QRZ = atoi(xml->getNodeData()); break; @@ -839,13 +872,13 @@ bool configuration::readDefaultsXML() case PORTINDEVICE : PortInDevice = xml->getNodeData(); break; - case PORTININDEX : + case PORTININTHOR : PortInIndex = atoi(xml->getNodeData()); break; case PORTOUTDEVICE : PortOutDevice = xml->getNodeData(); break; - case PORTOUTINDEX : + case PORTOUTINTHOR : PortOutIndex = atoi(xml->getNodeData()); break; case PULSESERVER : @@ -1068,17 +1101,22 @@ bool configuration::readDefaultsXML() else if (!strcmp("OLIVIASMARGIN", nodeName)) tag = OLIVIASMARGIN; else if (!strcmp("OLIVIASINTEG", nodeName)) tag = OLIVIASINTEG; else if (!strcmp("OLIVIA8BIT", nodeName)) tag = OLIVIA8BIT; - else if (!strcmp("DEXBW", nodeName)) tag = DEXBW; - else if (!strcmp("DEXFILTER", nodeName)) tag = DEXFILTER; - else if (!strcmp("DEXSECTEXT", nodeName)) tag = DEXSECTEXT; - else if (!strcmp("DEXPATHS", nodeName)) tag = DEXPATHS; - else if (!strcmp("DEXSOFT", nodeName)) tag = DEXSOFT; + else if (!strcmp("THORBW", nodeName)) tag = THORBW; + else if (!strcmp("THORFILTER", nodeName)) tag = THORFILTER; + else if (!strcmp("THORSECTEXT", nodeName)) tag = THORSECTEXT; + else if (!strcmp("THORPATHS", nodeName)) tag = THORPATHS; + else if (!strcmp("THORSOFT", nodeName)) tag = THORSOFT; else if (!strcmp("DOMINOEXBW", nodeName)) tag = DOMINOEXBW; else if (!strcmp("DOMINOEXFILTER", nodeName)) tag = DOMINOEXFILTER; else if (!strcmp("DOMINOEXFEC", nodeName)) tag = DOMINOEXFEC; else if (!strcmp("DOMINOEXPATHS", nodeName)) tag = DOMINOEXPATHS; else if (!strcmp("FELDFONTNBR", nodeName)) tag = FELDFONTNBR; else if (!strcmp("FELDIDLE", nodeName)) tag = FELDIDLE; + else if (!strcmp("HELLRCVWIDTH", nodeName)) tag = HELLRCVWIDTH; + else if (!strcmp("HELLXMTWIDTH", nodeName)) tag = HELLXMTWIDTH; + else if (!strcmp("HELLBLACKBOARD", nodeName)) tag = HELLBLACKBOARD; + else if (!strcmp("HELLPULSEFAST", nodeName)) tag = HELLPULSEFAST; + else if (!strcmp("HELLXMTIDLE", nodeName)) tag = HELLXMTIDLE; else if (!strcmp("WFPREFILTER", nodeName)) tag = WFPREFILTER; else if (!strcmp("LATENCY", nodeName)) tag = LATENCY; else if (!strcmp("USECURSORLINES", nodeName)) tag = USECURSORLINES; @@ -1093,6 +1131,7 @@ bool configuration::readDefaultsXML() else if (!strcmp("SENDTEXTID", nodeName)) tag = SENDTEXTID; else if (!strcmp("STRTEXTID", nodeName)) tag = STRTEXTID; else if (!strcmp("VIDEOWIDTH", nodeName)) tag = VIDEOWIDTH; + else if (!strcmp("IDSMALL", nodeName)) tag = IDSMALL; else if (!strcmp("QRZUSER", nodeName)) tag = QRZUSER; else if (!strcmp("QRZPASSWORD", nodeName)) tag = QRZPASSWORD; else if (!strcmp("QRZTYPE", nodeName)) tag = QRZTYPE; @@ -1115,9 +1154,9 @@ bool configuration::readDefaultsXML() else if (!strcmp("OSSDEVICE", nodeName)) tag = OSSDEVICE; else if (!strcmp("PADEVICE", nodeName)) tag = PADEVICE; else if (!strcmp("PORTINDEVICE", nodeName)) tag = PORTINDEVICE; - else if (!strcmp("PORTININDEX", nodeName)) tag = PORTININDEX; + else if (!strcmp("PORTININTHOR", nodeName)) tag = PORTININTHOR; else if (!strcmp("PORTOUTDEVICE", nodeName)) tag = PORTOUTDEVICE; - else if (!strcmp("PORTOUTINDEX", nodeName)) tag = PORTOUTINDEX; + else if (!strcmp("PORTOUTINTHOR", nodeName)) tag = PORTOUTINTHOR; else if (!strcmp("SAMPLERATE", nodeName)) tag = SAMPLERATE; else if (!strcmp("INSAMPLERATE", nodeName)) tag = INSAMPLERATE; else if (!strcmp("OUTSAMPLERATE", nodeName)) tag = OUTSAMPLERATE; @@ -1258,7 +1297,7 @@ void configuration::saveDefaults() { myQth = inpMyQth->value(); myLocator = inpMyLocator->value(); secText = txtSecondary->value(); - DEXsecText = txtDEXSecondary->value(); + THORsecText = txtTHORSecondary->value(); PTTdev = inpTTYdev->value(); for (int i = 0; i < 9; i++) { @@ -1287,11 +1326,11 @@ int configuration::setDefaults() { txtSecondary->value(secText.c_str()); - txtDEXSecondary->value(DEXsecText.c_str()); - valDEX_BW->value(DEX_BW); - valDEX_FILTER->value(DEX_FILTER); - valDEX_PATHS->value(DEX_PATHS); - valDEX_SOFT->value(DEX_SOFT); + txtTHORSecondary->value(THORsecText.c_str()); + valTHOR_BW->value(THOR_BW); + valTHOR_FILTER->value(THOR_FILTER); + valTHOR_PATHS->value(THOR_PATHS); + valTHOR_SOFT->value(THOR_SOFT); valDominoEX_BW->value(DOMINOEX_BW); valDominoEX_FILTER->value(DOMINOEX_FILTER); @@ -1426,7 +1465,8 @@ int configuration::setDefaults() { btnRTTY_USB->value(RTTY_USB); btnsendid->value(sendid); btnsendvideotext->value(sendtextid); - + chkID_SMALL->value(ID_SMALL); + FL_UNLOCK(); ReceiveText->setFont((Fl_Font)RxFontnbr); diff --git a/src/misc/macros.cxx b/src/misc/macros.cxx index 22e642ee..82d7a224 100644 --- a/src/misc/macros.cxx +++ b/src/misc/macros.cxx @@ -592,7 +592,7 @@ void MACROTEXT::openMacroFile() { string deffilename = HomeDir; deffilename.append("/macros.mdf"); - const char *p = file_select("Open macro file", "Fldigi macro definition file\t*.mdf", deffilename.c_str()); + const char *p = FSEL::select("Open macro file", "Fldigi macro definition file\t*.mdf", deffilename.c_str()); if (p) loadMacros(p); } @@ -601,7 +601,7 @@ void MACROTEXT::saveMacroFile() { string deffilename = HomeDir; deffilename.append("/macros.mdf"); - const char *p = file_saveas("Save macro file", "Fldigi macro definition file\t*.mdf", deffilename.c_str()); + const char *p = FSEL::saveas("Save macro file", "Fldigi macro definition file\t*.mdf", deffilename.c_str()); if (p) saveMacros(p); } diff --git a/src/misc/status.cxx b/src/misc/status.cxx index 3db69fe3..9b80f58e 100644 --- a/src/misc/status.cxx +++ b/src/misc/status.cxx @@ -44,6 +44,8 @@ status progStatus = { false, // bool rigShown; 50, // int rigX; 50, // int rigY; + 560, // int rigW + 80, // int rigH 1000, // int carrier; 1, // int mag; NORMAL, // WFdisp::WFspeed @@ -97,6 +99,8 @@ void status::saveLastState() if (rigcontrol && rigcontrol->visible()) { rigX = rigcontrol->x(); rigY = rigcontrol->y(); + rigW = rigcontrol->w(); + rigH = rigcontrol->h(); rigShown = true; } @@ -137,6 +141,8 @@ void status::saveLastState() spref.set("rigctl_visible", rigShown); spref.set("rigctl_x", rigX); spref.set("rigctl_y", rigY); + spref.set("rigctl_w", rigW); + spref.set("rigctl_h", rigH); spref.set("viewer_visible", VIEWERvisible); spref.set("viewer_x", static_cast(VIEWERxpos)); @@ -192,6 +198,8 @@ void status::loadLastState() spref.get("rigctl_visible", i, i); rigShown = i; spref.get("rigctl_x", rigX, rigX); spref.get("rigctl_y", rigY, rigY); + spref.get("rigctl_w", rigW, rigW); + spref.get("rigctl_h", rigH, rigH); spref.get("viewer_visible", i, i); VIEWERvisible = i; spref.get("viewer_x", i, i); VIEWERxpos = i; @@ -255,9 +263,7 @@ void status::initLastState() if (rigShown == true) { if (!rigcontrol) createRigDialog(); - int rdW = rigcontrol->w(); - int rdH = rigcontrol->h(); - rigcontrol->resize(rigX, rigY, rdW, rdH); + rigcontrol->resize(rigX, rigY, rigW, rigH); rigcontrol->show(); } if (VIEWERvisible == true) diff --git a/src/misc/xmlrpc.cxx b/src/misc/xmlrpc.cxx new file mode 100644 index 00000000..9e1fb48e --- /dev/null +++ b/src/misc/xmlrpc.cxx @@ -0,0 +1,1485 @@ +// ---------------------------------------------------------------------------- +// xmlrpc.cxx +// +// Copyright (C) 2008 +// Stelios Bounanos, M0GLD +// +// This file is part of fldigi. +// +// fldigi 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 3 of the License, or +// (at your option) any later version. +// +// fldigi 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, see . +// ---------------------------------------------------------------------------- + +#include + +#include "xmlrpc.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "globals.h" +#include "threads.h" +#include "modem.h" +#include "trx.h" +#include "fl_digi.h" +#include "configuration.h" +#include "main.h" +#include "waterfall.h" +#include "qrunner.h" + +#if USE_HAMLIB + #include "hamlib.h" +#endif +#include "rigMEM.h" +#include "rigio.h" + +using namespace std; + +struct rpc_method +{ + rpc_method(const xmlrpc_c::methodPtr& m, const char* n) + : method(m), name(n) { } + xmlrpc_c::methodPtr method; + const char* name; +}; +vector* methods; + +static Fl_Thread* server_thread; + +XML_RPC_Server* XML_RPC_Server::inst = 0; + +XML_RPC_Server::XML_RPC_Server(int sfd_) +{ + sfd = sfd_; + methods = new vector; + add_methods(); + + server_thread = new Fl_Thread; + run = true; + fl_create_thread(*server_thread, thread_func, this); +} +XML_RPC_Server::~XML_RPC_Server() +{ + run = false; + pthread_join(*server_thread, NULL); + delete server_thread; + delete methods; +} + + +void XML_RPC_Server::start(const char* node, const char* service) +{ + if (inst) + return; + + int sfd = -1, err; + if ((err = get_socket(node, service, sfd)) == -1) { +#if HAVE_GETADDRINFO + if (err < 0) + cerr << gai_strerror(err) << '\n'; + else +#endif + cerr << strerror(err) << '\n'; + + return; + } + + inst = new XML_RPC_Server(sfd); +} +void XML_RPC_Server::stop(void) +{ + if (!inst) + return; + delete inst; + inst = 0; +} + +int XML_RPC_Server::get_socket(const char* node, const char* service, int& fd) +{ + int res = 0; + +#if HAVE_GETADDRINFO + struct addrinfo hints, *ai, *aip; + + memset(&hints, 0, sizeof(hints)); +# ifdef AI_ADDRCONFIG + hints.ai_flags = AI_ADDRCONFIG; +# endif + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + bool num_service = service; + if (num_service) { // check + const char* p = service; + while (*p) + if (!isdigit(*p++)) + num_service = false; + } + if (num_service) + hints.ai_flags |= AI_NUMERICSERV; + + if ((res = getaddrinfo(node, service, &hints, &ai)) < 0) + return res; + for (aip = ai; aip; aip = ai->ai_next) { // use the first one that works + if ((fd = socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol)) == -1) + continue; + if (bind(fd, aip->ai_addr, aip->ai_addrlen) == 0) + break; + } + if (!aip) { // no usable address found + res = errno; + if (fd >= 0) + close(fd); + } + + freeaddrinfo(ai); +#else + struct sockaddr_in server_addr; + struct hostent* server_entry; + struct servent* service_entry; + + memset(&server_addr, 0, sizeof(server_addr)); + if ((service_entry = getservbyname(service, NULL)) == NULL) { + bool num_service = service; + if (num_service) { // check + const char* p = service; + while (*p) + if (!isdigit(*p++)) + num_service = false; + } + if (!num_service) + return errno; + if ((service_entry = getservbyport(atoi(service), NULL)) == NULL) + server_addr.sin_port = htons(atoi(service)); + } + else + server_addr.sin_port = service_entry->s_port; + if ((server_entry = gethostbyname(node)) == NULL) + return errno; + + server_addr.sin_family = AF_INET; + server_addr.sin_addr = *((struct in_addr *)server_entry->h_addr_list[0]); + + if ((fd = socket(server_addr.sin_family, SOCK_STREAM, 0)) == -1) + return errno; + if (bind(fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) + return errno; + + res = 0; +#endif // HAVE_GETADDRINFO + + int v = 1; + if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &v, sizeof(v)) == -1) + perror("setsockopt TCP_NODELAY"); + + return res; +} + + +void* XML_RPC_Server::thread_func(void* arg) +{ + SET_THREAD_ID(XMLRPC_TID); + + xmlrpc_c::registry reg; + for (vector::iterator i = methods->begin(); i != methods->end(); i++) + reg.addMethod(i->name, i->method); + + string logfile = +#ifndef NDEBUG + string(HomeDir).append("xmlrpc.log") +#else + "" +#endif + ; + + xmlrpc_c::serverAbyss server(xmlrpc_c::serverAbyss::constrOpt().registryP(®).logFileName(logfile)); + + int v = 1; + if (setsockopt(inst->sfd, SOL_SOCKET, SO_REUSEADDR, &v, sizeof(v))== -1) + perror("setsockopt SO_REUSEADDR"); + listen(inst->sfd, SOMAXCONN); + + int cfd = -1; + fd_set rset; + ssize_t r; + struct timeval timeout; + + while (inst->run) { + timeout.tv_sec = 0; + timeout.tv_usec = 200000; + FD_ZERO(&rset); + FD_SET(inst->sfd, &rset); + r = select(inst->sfd + 1, &rset, 0, 0, &timeout); + if (r == -1) { + perror("select"); + goto ret; + } + else if (r == 0) + continue; + + if ((cfd = accept(inst->sfd, NULL, 0)) == -1) { + perror("accept"); + goto ret; + } + server.runConn(cfd); + close(cfd); + } + +ret: + close(cfd); + close(inst->sfd); + inst->sfd = -1; + + return NULL; +} + + +// ============================================================================= +// helper functions + +static void frob(Fl_Widget* widget) +{ + REQ(static_cast(&Fl_Widget::do_callback), widget); +} + +static void set_button(Fl_Button* button, bool value) +{ + REQ(static_cast(&Fl_Button::value), button, value); + frob(button); +} +static void set_valuator(Fl_Valuator* valuator, double value) +{ + REQ(static_cast(&Fl_Valuator::value), valuator, value); + frob(valuator); +} + +// ============================================================================= + +// XML-RPC interface definition + +// ============================================================================= + +class Fldigi_list : public xmlrpc_c::method +{ +public: + Fldigi_list() + { + _signature = "A:n"; + _help = "Returns the list of methods."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + vector help; + for (vector::const_iterator i = methods->begin(); i != methods->end(); i++) { + map item; + item["name"] = xmlrpc_c::value_string(i->name); + item["signature"] = xmlrpc_c::value_string(i->method->signature()); + item["help"] = xmlrpc_c::value_string(i->method->help()); + help.push_back(xmlrpc_c::value_struct(item)); + } + + *retval = xmlrpc_c::value_array(help); + } +}; + +class Fldigi_name : public xmlrpc_c::method +{ +public: + Fldigi_name() + { + _signature = "s:n"; + _help = "Returns the program name."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + *retval = xmlrpc_c::value_string(PACKAGE_TARNAME); + } +}; + +class Fldigi_version_struct : public xmlrpc_c::method +{ +public: + Fldigi_version_struct() + { + _signature = "S:n"; + _help = "Returns the program version as a struct."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + map vstruct; + vstruct["major"] = xmlrpc_c::value_int(FLDIGI_VERSION_MAJOR); + vstruct["minor"] = xmlrpc_c::value_int(FLDIGI_VERSION_MINOR); + vstruct["patch"] = xmlrpc_c::value_string(FLDIGI_VERSION_PATCH); + *retval = xmlrpc_c::value_struct(vstruct); + } +}; + +class Fldigi_version_string : public xmlrpc_c::method +{ +public: + Fldigi_version_string() + { + _signature = "s:n"; + _help = "Returns the program version as a string."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + *retval = xmlrpc_c::value_string(PACKAGE_VERSION); + } +}; + +class Fldigi_name_version : public xmlrpc_c::method +{ +public: + Fldigi_name_version() + { + _signature = "s:n"; + _help = "Returns the program name and version."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + *retval = xmlrpc_c::value_string(PACKAGE_STRING); + } +}; + +// ============================================================================= + +class Modem_get_name : public xmlrpc_c::method +{ +public: + Modem_get_name() + { + _signature = "s:n"; + _help = "Returns the name of the current modem"; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + *retval = xmlrpc_c::value_string(mode_info[active_modem->get_mode()].sname); + } +}; + +class Modem_get_id : public xmlrpc_c::method +{ +public: + Modem_get_id() + { + _signature = "i:n"; + _help = "Returns the ID of the current modem"; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + *retval = xmlrpc_c::value_int(active_modem->get_mode()); + } +}; + +class Modem_get_max_id : public xmlrpc_c::method +{ +public: + Modem_get_max_id() + { + _signature = "i:n"; + _help = "Returns the maximum modem ID number"; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + *retval = xmlrpc_c::value_int(NUM_MODES - 1); + } +}; + +class Modem_set_by_name : public xmlrpc_c::method +{ +public: + Modem_set_by_name() + { + _signature = "s:s"; + _help = "Sets the current modem. Returns old name."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + const char* cur = mode_info[active_modem->get_mode()].sname; + + bool found = false; + string s = params.getString(0); + for (size_t i = 0; i < NUM_MODES; i++) { + if (!strcmp(mode_info[i].sname, s.c_str())) { + init_modem_sync(i); + found = true; + break; + } + } + if (!found) + throw xmlrpc_c::fault("No such modem", xmlrpc_c::fault::code_t(0)); + + *retval = xmlrpc_c::value_string(cur); + } +}; + +class Modem_set_by_id : public xmlrpc_c::method +{ +public: + Modem_set_by_id() + { + _signature = "i:i"; + _help = "Sets the current modem. Returns old ID."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + int cur = active_modem->get_mode(); + + int i = params.getInt(0, 0, NUM_MODES-1); + init_modem_sync(i); + + *retval = xmlrpc_c::value_int(cur); + } +}; + +// ============================================================================= + +class Modem_set_carrier : public xmlrpc_c::method +{ +public: + Modem_set_carrier() + { + _signature = "i:i"; + _help = "Sets modem carrier. Returns old carrier."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + int cur = active_modem->get_freq(); + active_modem->set_freq(params.getInt(0, 1)); + *retval = xmlrpc_c::value_int(cur); + } +}; + +class Modem_inc_carrier : public xmlrpc_c::method +{ +public: + Modem_inc_carrier() + { + _signature = "i:i"; + _help = "Increments the modem carrier frequency. Returns the new carrier."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + int cur = active_modem->get_freq(); + active_modem->set_freq(cur + params.getInt(0)); + *retval = xmlrpc_c::value_int(active_modem->get_freq()); + } +}; + +class Modem_get_carrier : public xmlrpc_c::method +{ +public: + Modem_get_carrier() + { + _signature = "i:n"; + _help = "Returns the modem carrier frequency."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + *retval = xmlrpc_c::value_int(active_modem->get_freq()); + } +}; + +// ============================================================================= + +class Fl_Counter; +extern Fl_Counter* cntSearchRange; // FIXME: export in header + +class Modem_get_afc_sr : public xmlrpc_c::method +{ +public: + Modem_get_afc_sr() + { + _signature = "i:n"; + _help = "Returns the modem AFC search range."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + *retval = xmlrpc_c::value_int(cntSearchRange->value()); + } +}; + +class Modem_set_afc_sr : public xmlrpc_c::method +{ +public: + Modem_set_afc_sr() + { + _signature = "n:i"; + _help = "Sets the modem AFC search range. Returns the old value."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + int v = cntSearchRange->value(); + set_valuator(cntSearchRange, params.getInt(0, cntSearchRange->minimum(), cntSearchRange->maximum())); + *retval = xmlrpc_c::value_int(v); + } +}; + +class Modem_inc_afc_sr : public xmlrpc_c::method +{ +public: + Modem_inc_afc_sr() + { + _signature = "n:i"; + _help = "Increments the modem AFC search range. Returns the new value."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + int v = cntSearchRange->value() + params.getInt(0); + set_valuator(cntSearchRange, v); + *retval = xmlrpc_c::value_int(v); + } +}; + +// ============================================================================= + +extern Fl_Value_Slider* sldrHellBW; // FIXME: export in header +extern Fl_Value_Slider* sldrCWbandwidth; // FIXME: export in header + +class Modem_get_bw : public xmlrpc_c::method +{ +public: + Modem_get_bw() + { + _signature = "i:n"; + _help = "Returns the modem bandwidth."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + Fl_Valuator* val; + switch (active_modem->get_mode()) { + case MODE_FELDHELL: + val = sldrHellBW; + break; + case MODE_CW: + val = sldrCWbandwidth; + break; + default: + throw xmlrpc_c::fault("Operation not supported by modem", xmlrpc_c::fault::code_t(0)); + } + + *retval = xmlrpc_c::value_int(val->value()); + } +}; + +class Modem_set_bw : public xmlrpc_c::method +{ +public: + Modem_set_bw() + { + _signature = "n:i"; + _help = "Sets the modem bandwidth. Returns the old value."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + Fl_Valuator* val; + switch (active_modem->get_mode()) { + case MODE_FELDHELL: + val = sldrHellBW; + break; + case MODE_CW: + val = sldrCWbandwidth; + break; + default: + throw xmlrpc_c::fault("Operation not supported by modem", xmlrpc_c::fault::code_t(0)); + } + + int v = val->value(); + set_valuator(val, params.getInt(0, val->minimum(), val->maximum())); + *retval = xmlrpc_c::value_int(v); + } +}; + +class Modem_inc_bw : public xmlrpc_c::method +{ +public: + Modem_inc_bw() + { + _signature = "n:i"; + _help = "Increments the modem bandwidth. Returns the new value."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + Fl_Valuator* val; + switch (active_modem->get_mode()) { + case MODE_FELDHELL: + val = sldrHellBW; + break; + case MODE_CW: + val = sldrCWbandwidth; + break; + default: + throw xmlrpc_c::fault("Operation not supported by modem", xmlrpc_c::fault::code_t(0)); + } + + int v = val->value() + params.getInt(0); + set_valuator(val, v); + *retval = xmlrpc_c::value_int(v); + } +}; + +// ============================================================================= + +class Modem_get_quality : public xmlrpc_c::method +{ +public: + Modem_get_quality() + { + _signature = "d:n"; + _help = "Returns the modem signal quality in the range [0:100]."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + *retval = xmlrpc_c::value_double(pgrsSquelch->value()); + } +}; + +class Modem_search_up : public xmlrpc_c::method +{ +public: + Modem_search_up() + { + _signature = "n:n"; + _help = "Searches upward in frequency."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + REQ(&modem::searchUp, active_modem); + *retval = xmlrpc_c::value_nil(); + } +}; + +class Modem_search_down : public xmlrpc_c::method +{ +public: + Modem_search_down() + { + _signature = "n:n"; + _help = "Searches downward in frequency."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + REQ(&modem::searchDown, active_modem); + *retval = xmlrpc_c::value_nil(); + } +}; + +// ============================================================================= + +class Main_get_status1 : public xmlrpc_c::method +{ +public: + Main_get_status1() + { + _signature = "s:n"; + _help = "Returns the contents of the first status field (typically s/n)."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + *retval = xmlrpc_c::value_string(Status1->label()); + } +}; + +class Main_get_status2 : public xmlrpc_c::method +{ +public: + Main_get_status2() + { + _signature = "s:n"; + _help = "Returns the contents of the second status field."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + *retval = xmlrpc_c::value_string(Status2->label()); + } +}; + +class Main_get_sb : public xmlrpc_c::method +{ +public: + Main_get_sb() + { + _signature = "s:n"; + _help = "Returns the current sideband."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + *retval = xmlrpc_c::value_string(wf->USB() ? "USB" : "LSB"); + } +}; + +class Main_get_freq : public xmlrpc_c::method +{ +public: + Main_get_freq() + { + _signature = "d:n"; + _help = "Returns the RF carrier frequency."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + *retval = xmlrpc_c::value_double(wf->rfcarrier()); + } +}; + +class Main_set_freq : public xmlrpc_c::method +{ +public: + Main_set_freq() + { + _signature = "d:d"; + _help = "Sets the RF carrier frequency. Returns the old value"; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + double d = wf->rfcarrier(); + double rfc = params.getDouble(0, 0.0); + int mc = active_modem->get_freq(); + rigCAT_set_qsy(rfc, mc); + rigMEM_set_qsy(rfc, mc); +#if USE_HAMLIB + hamlib_set_qsy(rfc, mc); +#endif + *retval = xmlrpc_c::value_double(d); + } +}; + +class Main_inc_freq : public xmlrpc_c::method +{ +public: + Main_inc_freq() + { + _signature = "d:d"; + _help = "Increments the RF carrier frequency. Returns the new value."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + double rfc = wf->rfcarrier() + params.getDouble(0); + int mc = active_modem->get_freq(); + rigCAT_set_qsy(rfc, mc); + rigMEM_set_qsy(rfc, mc); +#if USE_HAMLIB + hamlib_set_qsy(rfc, mc); +#endif + *retval = xmlrpc_c::value_double(rfc); + } +}; + + +// ============================================================================= + +class Main_get_afc : public xmlrpc_c::method +{ +public: + Main_get_afc() + { + _signature = "b:n"; + _help = "Returns the AFC state."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + *retval = xmlrpc_c::value_boolean(useCheckButtons ? chk_afconoff->value() : btn_afconoff->value()); + } +}; + +class Main_set_afc : public xmlrpc_c::method +{ +public: + Main_set_afc() + { + _signature = "b:b"; + _help = "Sets the AFC state. Returns the old state."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + Fl_Button* b = useCheckButtons ? chk_afconoff : btn_afconoff; + bool v = b->value(); + set_button(b, params.getBoolean(0)); + *retval = xmlrpc_c::value_boolean(v); + } +}; + +class Main_toggle_afc : public xmlrpc_c::method +{ +public: + Main_toggle_afc() + { + _signature = "b:n"; + _help = "Toggles the AFC state. Returns the new state."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + Fl_Button* b = useCheckButtons ? chk_afconoff : btn_afconoff; + bool v = b->value(); + set_button(b, !v); + *retval = xmlrpc_c::value_boolean(!v); + } +}; + +// ============================================================================= + +class Main_get_sql : public xmlrpc_c::method +{ +public: + Main_get_sql() + { + _signature = "b:n"; + _help = "Returns the squelch state."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + *retval = xmlrpc_c::value_boolean(useCheckButtons ? chk_sqlonoff->value() : btn_sqlonoff->value()); + } +}; + +class Main_set_sql : public xmlrpc_c::method +{ +public: + Main_set_sql() + { + _signature = "b:b"; + _help = "Sets the squelch state. Returns the old state."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + Fl_Button* b = useCheckButtons ? chk_sqlonoff : btn_sqlonoff; + bool v = b->value(); + set_button(b, params.getBoolean(0)); + *retval = xmlrpc_c::value_boolean(v); + } +}; + +class Main_toggle_sql : public xmlrpc_c::method +{ +public: + Main_toggle_sql() + { + _signature = "b:n"; + _help = "Toggles the squelch state. Returns the new state."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + Fl_Button* b = useCheckButtons ? chk_sqlonoff : btn_sqlonoff; + bool v = b->value(); + set_button(b, !v); + *retval = xmlrpc_c::value_boolean(!v); + } +}; + +// ============================================================================= + +class Main_get_sql_level : public xmlrpc_c::method +{ +public: + Main_get_sql_level() + { + _signature = "d:n"; + _help = "Returns the squelch level"; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + *retval = xmlrpc_c::value_double(sldrSquelch->value()); + } +}; + +class Main_set_sql_level : public xmlrpc_c::method +{ +public: + Main_set_sql_level() + { + _signature = "d:d"; + _help = "Sets the squelch level. Returns the old level."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + double v = sldrSquelch->value(); + // Squelch slider min/max are reversed when !twoscopes. Argh. + if (twoscopes) + set_valuator(sldrSquelch, params.getDouble(0, sldrSquelch->minimum(), sldrSquelch->maximum())); + else + set_valuator(sldrSquelch, params.getDouble(0, sldrSquelch->maximum(), sldrSquelch->minimum())); + *retval = xmlrpc_c::value_double(v); + } +}; + +class Main_inc_sql_level : public xmlrpc_c::method +{ +public: + Main_inc_sql_level() + { + _signature = "d:d"; + _help = "Increments the squelch level. Returns the new level."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + double v = sldrSquelch->value(); + set_valuator(sldrSquelch, v + params.getDouble(0)); // FIXME: check range + *retval = xmlrpc_c::value_double(sldrSquelch->value()); + } +}; + +// ============================================================================= + +class Main_get_rev : public xmlrpc_c::method +{ +public: + Main_get_rev() + { + _signature = "b:n"; + _help = "Returns the Reverse Sideband state."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + *retval = xmlrpc_c::value_boolean(wf->btnRev->value()); + } +}; + +class Main_set_rev : public xmlrpc_c::method +{ +public: + Main_set_rev() + { + _signature = "b:b"; + _help = "Sets the Reverse Sideband state. Returns the old state."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + bool v = wf->btnRev->value(); + set_button(wf->btnRev, params.getBoolean(0)); + *retval = xmlrpc_c::value_boolean(v); + } +}; + +class Main_toggle_rev : public xmlrpc_c::method +{ +public: + Main_toggle_rev() + { + _signature = "b:n"; + _help = "Toggles the Reverse Sideband state. Returns the new state."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + bool v = wf->btnRev->value(); + set_button(wf->btnRev, !v); + *retval = xmlrpc_c::value_boolean(!v); + } +}; + +// ============================================================================= + +class Main_get_lock : public xmlrpc_c::method +{ +public: + Main_get_lock() + { + _signature = "b:n"; + _help = "Returns the Transmit Lock state."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + *retval = xmlrpc_c::value_boolean(wf->xmtlock->value()); + } +}; + +class Main_set_lock : public xmlrpc_c::method +{ +public: + Main_set_lock() + { + _signature = "b:b"; + _help = "Sets the Transmit Lock state. Returns the old state."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + bool v = wf->xmtlock->value(); + set_button(wf->xmtlock, params.getBoolean(0)); + *retval = xmlrpc_c::value_boolean(v); + } +}; + +class Main_toggle_lock : public xmlrpc_c::method +{ +public: + Main_toggle_lock() + { + _signature = "b:n"; + _help = "Toggles the Reverse Sideband state. Returns the new state."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + bool v = wf->xmtlock->value(); + set_button(wf->xmtlock, !v); + *retval = xmlrpc_c::value_boolean(!v); + } +}; + +// ============================================================================= + +extern Fl_Button* btnTune; // FIXME: export in fl_digi.h + +class Main_get_tx_status : public xmlrpc_c::method +{ +public: + Main_get_tx_status() + { + _signature = "s:n"; + _help = "Returns transmit/tune/receive status"; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + if (btnTune->value()) + *retval = xmlrpc_c::value_string("tune"); + else if (wf->xmtrcv->value()) + *retval = xmlrpc_c::value_string("tx"); + else + *retval = xmlrpc_c::value_string("rx"); + } +}; + +class Main_tx : public xmlrpc_c::method +{ +public: + Main_tx() + { + _signature = "n:n"; + _help = "Transmits."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + set_button(wf->xmtrcv, true); + *retval = xmlrpc_c::value_nil(); + } +}; + +class Main_tune : public xmlrpc_c::method +{ +public: + Main_tune() + { + _signature = "n:n"; + _help = "Toggles tuning."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + set_button(btnTune, !btnTune->value()); + *retval = xmlrpc_c::value_nil(); + } +}; + +class Main_rx : public xmlrpc_c::method +{ +public: + Main_rx() + { + _signature = "n:n"; + _help = "Receives."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + set_button(wf->xmtrcv, false); + *retval = xmlrpc_c::value_nil(); + } +}; + +// ============================================================================= + +class Log_get_freq : public xmlrpc_c::method +{ +public: + Log_get_freq() + { + _signature = "s:n"; + _help = "Returns the Frequency field contents."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + *retval = xmlrpc_c::value_string(inpFreq->value()); + } +}; + +class Log_get_time : public xmlrpc_c::method +{ +public: + Log_get_time() + { + _signature = "s:n"; + _help = "Returns the Time field contents."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + *retval = xmlrpc_c::value_string(inpTime->value()); + } +}; + +class Log_get_call : public xmlrpc_c::method +{ +public: + Log_get_call() + { + _signature = "s:n"; + _help = "Returns the Call field contents."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + *retval = xmlrpc_c::value_string(inpCall->value()); + } +}; + +class Log_get_name : public xmlrpc_c::method +{ +public: + Log_get_name() + { + _signature = "s:n"; + _help = "Returns the Name field contents."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + *retval = xmlrpc_c::value_string(inpName->value()); + } +}; + +class Log_get_rst_in : public xmlrpc_c::method +{ +public: + Log_get_rst_in() + { + _signature = "s:n"; + _help = "Returns the RST(r) field contents."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + *retval = xmlrpc_c::value_string(inpRstIn->value()); + } +}; + +class Log_get_rst_out : public xmlrpc_c::method +{ +public: + Log_get_rst_out() + { + _signature = "s:n"; + _help = "Returns the RST(s) field contents."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + *retval = xmlrpc_c::value_string(inpRstOut->value()); + } +}; + +class Log_get_qth : public xmlrpc_c::method +{ +public: + Log_get_qth() + { + _signature = "s:n"; + _help = "Returns the QTH field contents."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + *retval = xmlrpc_c::value_string(inpQth->value()); + } +}; + +class Log_get_band : public xmlrpc_c::method +{ +public: + Log_get_band() + { + _signature = "s:n"; + _help = "Returns the Band selection."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + *retval = xmlrpc_c::value_string(cboBand->value()); + } +}; + +class Log_get_sb : public xmlrpc_c::method +{ +public: + Log_get_sb() + { + _signature = "s:n"; + _help = "Returns the sideband button label."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + *retval = xmlrpc_c::value_string(btnSideband->label()); + } +}; + +class Log_get_notes : public xmlrpc_c::method +{ +public: + Log_get_notes() + { + _signature = "s:n"; + _help = "Returns the Notes field contents."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + *retval = xmlrpc_c::value_string(inpNotes->value()); + } +}; + +class Log_get_locator : public xmlrpc_c::method +{ +public: + Log_get_locator() + { + _signature = "s:n"; + _help = "Returns the Locator field contents."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + *retval = xmlrpc_c::value_string(inpLoc->value()); + } +}; + +class Log_get_az : public xmlrpc_c::method +{ +public: + Log_get_az() + { + _signature = "s:n"; + _help = "Returns the AZ field contents."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + *retval = xmlrpc_c::value_string(inpAZ->value()); + } +}; + +// ============================================================================= + +class Text_get_rx_length : public xmlrpc_c::method +{ +public: + Text_get_rx_length() + { + _signature = "i:n"; + _help = "Returns the number of characters in the RX widget."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + *retval = xmlrpc_c::value_int(ReceiveText->buffer()->length()); + } +}; + +class Text_get_rx : public xmlrpc_c::method +{ +public: + Text_get_rx() + { + _signature = "6:ii"; + _help = "Returns a range of characters (start, length) from the RX text widget."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + params.verifyEnd(2); + + Fl_Text_Buffer* tbuf = ReceiveText->buffer(); + int len = tbuf->length(); + int start = params.getInt(0, 0, len - 1); + int n = params.getInt(1, 0, len - start); + + REQ_SYNC(&Fl_Text_Buffer::select, tbuf, start, start + n); + char *text = tbuf->selection_text(); + REQ(&Fl_Text_Buffer::unselect, tbuf); + + vector bytes(text, text + n); + *retval = xmlrpc_c::value_bytestring(bytes); + free(text); + } +}; + +class Text_clear_rx : public xmlrpc_c::method +{ +public: + Text_clear_rx() + { + _signature = "n:n"; + _help = "Clears the RX text widget."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + REQ(&FTextBase::clear, ReceiveText); + *retval = xmlrpc_c::value_nil(); + } +}; + +class Text_add_tx : public xmlrpc_c::method +{ +public: + Text_add_tx() + { + _signature = "i:s"; + _help = "Adds a string to the TX text widget."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + REQ_SYNC(&FTextBase::addstr, TransmitText, params.getString(0).c_str(), FTextBase::RECV); + *retval = xmlrpc_c::value_int(0); + } +}; + +class Text_add_tx_bytes : public xmlrpc_c::method +{ +public: + Text_add_tx_bytes() + { + _signature = "i:6"; + _help = "Adds a byte string to the TX text widget."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + vector bytes = params.getBytestring(0); + size_t len = bytes.size(); + char* chars = new char[len + 1]; + memcpy(chars, &bytes[0], len); + chars[len] = '\0'; + REQ_SYNC(&FTextBase::addstr, TransmitText, chars, FTextBase::RECV); + delete [] chars; + + *retval = xmlrpc_c::value_int(0); + } +}; + +class Text_clear_tx : public xmlrpc_c::method +{ +public: + Text_clear_tx() + { + _signature = "n:n"; + _help = "Clears the TX text widget."; + } + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + { + REQ(&FTextBase::clear, TransmitText); + *retval = xmlrpc_c::value_nil(); + } +}; + +// ============================================================================= + +// End XML-RPC interface + +void XML_RPC_Server::add_methods(void) +{ + methods->clear(); + methods->reserve(64); + + methods->push_back(rpc_method(new Fldigi_list, "fldigi.list")); + methods->push_back(rpc_method(new Fldigi_name, "fldigi.name")); + methods->push_back(rpc_method(new Fldigi_version_struct, "fldigi.version_struct")); + methods->push_back(rpc_method(new Fldigi_version_string, "fldigi.version")); + methods->push_back(rpc_method(new Fldigi_name_version, "fldigi.name_version")); + + methods->push_back(rpc_method(new Modem_get_name, "modem.get_name")); + methods->push_back(rpc_method(new Modem_get_id, "modem.get_id")); + methods->push_back(rpc_method(new Modem_get_max_id, "modem.get_max_id")); + methods->push_back(rpc_method(new Modem_set_by_name, "modem.set_by_name")); + methods->push_back(rpc_method(new Modem_set_by_id, "modem.set_by_id")); + + methods->push_back(rpc_method(new Modem_set_carrier, "modem.set_carrier")); + methods->push_back(rpc_method(new Modem_inc_carrier, "modem.inc_carrier")); + methods->push_back(rpc_method(new Modem_get_carrier, "modem.get_carrier")); + + methods->push_back(rpc_method(new Modem_get_afc_sr, "modem.get_afc_search_range")); + methods->push_back(rpc_method(new Modem_set_afc_sr, "modem.set_afc_search_range")); + methods->push_back(rpc_method(new Modem_inc_afc_sr, "modem.inc_afc_search_range")); + + methods->push_back(rpc_method(new Modem_get_bw, "modem.get_bandwidth")); + methods->push_back(rpc_method(new Modem_set_bw, "modem.set_bandwidth")); + methods->push_back(rpc_method(new Modem_inc_bw, "modem.inc_bandwidth")); + + methods->push_back(rpc_method(new Modem_get_quality, "modem.get_quality")); + methods->push_back(rpc_method(new Modem_search_up, "modem.search_up")); + methods->push_back(rpc_method(new Modem_search_down, "modem.search_down")); + + methods->push_back(rpc_method(new Main_get_status1, "main.get_status1")); + methods->push_back(rpc_method(new Main_get_status2, "main.get_status2")); + + methods->push_back(rpc_method(new Main_get_sb, "main.get_sideband")); + methods->push_back(rpc_method(new Main_get_freq, "main.get_frequency")); + methods->push_back(rpc_method(new Main_set_freq, "main.set_frequency")); + methods->push_back(rpc_method(new Main_inc_freq, "main.inc_frequency")); + + methods->push_back(rpc_method(new Main_get_afc, "main.get_afc")); + methods->push_back(rpc_method(new Main_set_afc, "main.set_afc")); + methods->push_back(rpc_method(new Main_toggle_afc, "main.toggle_afc")); + + methods->push_back(rpc_method(new Main_get_sql, "main.get_squelch")); + methods->push_back(rpc_method(new Main_set_sql, "main.set_squelch")); + methods->push_back(rpc_method(new Main_toggle_sql, "main.toggle_squelch")); + + methods->push_back(rpc_method(new Main_get_sql_level, "main.get_squelch_level")); + methods->push_back(rpc_method(new Main_set_sql_level, "main.set_squelch_level")); + methods->push_back(rpc_method(new Main_inc_sql_level, "main.inc_squelch_level")); + + methods->push_back(rpc_method(new Main_get_rev, "main.get_reverse")); + methods->push_back(rpc_method(new Main_set_rev, "main.set_reverse")); + methods->push_back(rpc_method(new Main_toggle_rev, "main.toggle_reverse")); + + methods->push_back(rpc_method(new Main_get_lock, "main.get_lock")); + methods->push_back(rpc_method(new Main_set_lock, "main.set_lock")); + methods->push_back(rpc_method(new Main_toggle_lock, "main.toggle_lock")); + + methods->push_back(rpc_method(new Main_get_tx_status, "main.get_tx_status")); + methods->push_back(rpc_method(new Main_tx, "main.tx")); + methods->push_back(rpc_method(new Main_tune, "main.tune")); + methods->push_back(rpc_method(new Main_rx, "main.rx")); + + methods->push_back(rpc_method(new Log_get_freq, "log.get_frequency")); + methods->push_back(rpc_method(new Log_get_time, "log.get_time")); + methods->push_back(rpc_method(new Log_get_call, "log.get_call")); + methods->push_back(rpc_method(new Log_get_name, "log.get_name")); + methods->push_back(rpc_method(new Log_get_rst_in, "log.get_rst_in")); + methods->push_back(rpc_method(new Log_get_rst_out, "log.get_rst_out")); + methods->push_back(rpc_method(new Log_get_qth, "log.get_qth")); + methods->push_back(rpc_method(new Log_get_band, "log.get_band")); + methods->push_back(rpc_method(new Log_get_sb, "log.get_sideband")); + methods->push_back(rpc_method(new Log_get_notes, "log.get_notes")); + methods->push_back(rpc_method(new Log_get_locator, "log.get_locator")); + methods->push_back(rpc_method(new Log_get_az, "log.get_az")); + + methods->push_back(rpc_method(new Text_get_rx_length, "text.get_rx_length")); + methods->push_back(rpc_method(new Text_get_rx, "text.get_rx")); + methods->push_back(rpc_method(new Text_clear_rx, "text.clear_rx")); + methods->push_back(rpc_method(new Text_add_tx, "text.add_tx")); + methods->push_back(rpc_method(new Text_add_tx_bytes, "text.add_tx_bytes")); + methods->push_back(rpc_method(new Text_clear_tx, "text.clear_tx")); +} diff --git a/src/soundcard/sound.cxx b/src/soundcard/sound.cxx index 19f519cd..2291cb8a 100644 --- a/src/soundcard/sound.cxx +++ b/src/soundcard/sound.cxx @@ -103,9 +103,9 @@ void SoundBase::get_file_params(const char* def_fname, const char** fname, int* int fsel; if (strstr(def_fname, "playback")) - *fname = file_select("Audio file", filters.c_str(), def_fname, &fsel); + *fname = FSEL::select("Audio file", filters.c_str(), def_fname, &fsel); else - *fname = file_saveas("Audio file", filters.c_str(), def_fname, &fsel); + *fname = FSEL::saveas("Audio file", filters.c_str(), def_fname, &fsel); if (!*fname) return; diff --git a/src/dex/dex.cxx b/src/thor/thor.cxx similarity index 72% rename from src/dex/dex.cxx rename to src/thor/thor.cxx index 5611c0bf..03df4533 100644 --- a/src/dex/dex.cxx +++ b/src/thor/thor.cxx @@ -1,5 +1,5 @@ // -// dex.cxx -- dex modem +// thor.cxx -- thor modem // // Copyright (C) 2008 // David Freese (w1hkj@w1hkj.com) @@ -28,19 +28,19 @@ #include "confdialog.h" #include "status.h" -#include "dex.h" +#include "thor.h" #include "trx.h" #include "fft.h" #include "filters.h" #include "misc.h" #include "sound.h" -#include "dexvaricode.h" +#include "thorvaricode.h" using namespace std; -char dexmsg[80]; +char thormsg[80]; -void dex::tx_init(SoundBase *sc) +void thor::tx_init(SoundBase *sc) { scard = sc; txstate = TX_STATE_PREAMBLE; @@ -49,13 +49,13 @@ void dex::tx_init(SoundBase *sc) counter = 0; txphase = 0; videoText(); - strSecXmtText = progdefaults.DEXsecText; + strSecXmtText = progdefaults.THORsecText; if (strSecXmtText.length() == 0) strSecXmtText = "fldigi "PACKAGE_VERSION" "; cptr = 0; } -void dex::rx_init() +void thor::rx_init() { synccounter = 0; symcounter = 0; @@ -64,7 +64,7 @@ void dex::rx_init() counter = 0; phase[0] = 0.0; currmag = prev1mag = prev2mag = 0.0; - for (int i = 0; i < DEXMAXFFTS; i++) + for (int i = 0; i < THORMAXFFTS; i++) phase[i+1] = 0.0; put_MODEstatus(mode); put_sec_char(0); @@ -72,25 +72,25 @@ void dex::rx_init() datashreg = 1; } -void dex::reset_filters() +void thor::reset_filters() { // fft filter at first IF frequency - if (progdefaults.DEX_FILTER == false) { - fft->create_filter( (DEXFIRSTIF - 2.0 * bandwidth) / samplerate, - (DEXFIRSTIF + 2.0 * bandwidth)/ samplerate ); + if (progdefaults.THOR_FILTER == false) { + fft->create_filter( (THORFIRSTIF - 2.0 * bandwidth) / samplerate, + (THORFIRSTIF + 2.0 * bandwidth)/ samplerate ); } else { - fft->create_filter( (DEXFIRSTIF - 0.5 * progdefaults.DEX_BW * bandwidth) / samplerate, - (DEXFIRSTIF + 0.5 * progdefaults.DEX_BW * bandwidth)/ samplerate ); + fft->create_filter( (THORFIRSTIF - 0.5 * progdefaults.THOR_BW * bandwidth) / samplerate, + (THORFIRSTIF + 0.5 * progdefaults.THOR_BW * bandwidth)/ samplerate ); } filter_reset = false; } -void dex::restart() +void thor::restart() { filter_reset = true; } -void dex::init() +void thor::init() { modem::init(); reset_filters(); @@ -99,15 +99,15 @@ void dex::init() set_scope_mode(Digiscope::DOMDATA); } -dex::~dex() +thor::~thor() { if (hilbert) delete hilbert; - for (int i = 0; i < DEXMAXFFTS; i++) { + for (int i = 0; i < THORMAXFFTS; i++) { if (binsfft[i]) delete binsfft[i]; } - for (int i = 0; i < DEXSCOPESIZE; i++) { + for (int i = 0; i < THORSCOPESIZE; i++) { if (vidfilter[i]) delete vidfilter[i]; } if (syncfilter) delete syncfilter; @@ -122,7 +122,7 @@ dex::~dex() } -dex::dex(trx_mode md) +thor::thor(trx_mode md) { int basetone, lotone, hitone; @@ -130,42 +130,42 @@ dex::dex(trx_mode md) switch (mode) { // 11.025 kHz modes - case MODE_DEX5: + case MODE_THOR5: symlen = 2048; doublespaced = 1; samplerate = 11025; break; - case MODE_DEX11: + case MODE_THOR11: symlen = 1024; doublespaced = 0; samplerate = 11025; break; - case MODE_DSX11: + case MODE_TSOR11: symlen = 1024; doublespaced = 1; samplerate = 11025; break; - case MODE_DEX22: + case MODE_THOR22: symlen = 512; doublespaced = 0; samplerate = 11025; break; // 8kHz modes - case MODE_DEX4: + case MODE_THOR4: symlen = 2048; doublespaced = 1; samplerate = 8000; break; - case MODE_DEX8: + case MODE_THOR8: symlen = 1024; doublespaced = 1; samplerate = 8000; break; - case MODE_DEX16: + case MODE_THOR16: default: symlen = 512; doublespaced = 0; @@ -173,37 +173,37 @@ dex::dex(trx_mode md) } - basetone = (int)floor(DEXBASEFREQ * symlen / samplerate + 0.5); - lotone = basetone - (DEXNUMMTONES/2) * (doublespaced ? 2 : 1); - hitone = basetone + 3 * (DEXNUMMTONES/2) * (doublespaced ? 2 : 1); + basetone = (int)floor(THORBASEFREQ * symlen / samplerate + 0.5); + lotone = basetone - (THORNUMMTONES/2) * (doublespaced ? 2 : 1); + hitone = basetone + 3 * (THORNUMMTONES/2) * (doublespaced ? 2 : 1); tonespacing = (double) (samplerate * ((doublespaced) ? 2 : 1)) / symlen; - bandwidth = DEXNUMMTONES * tonespacing; + bandwidth = THORNUMMTONES * tonespacing; hilbert = new C_FIR_filter(); hilbert->init_hilbert(37, 1); - paths = progdefaults.DEX_PATHS; + paths = progdefaults.THOR_PATHS; - for (int i = 0; i < DEXMAXFFTS; i++) + for (int i = 0; i < THORMAXFFTS; i++) binsfft[i] = new sfft (symlen, lotone, hitone); // fft filter at first if frequency - fft = new fftfilt( (DEXFIRSTIF - 0.5 * progdefaults.DEX_BW * bandwidth) / samplerate, - (DEXFIRSTIF + 0.5 * progdefaults.DEX_BW * bandwidth)/ samplerate, + fft = new fftfilt( (THORFIRSTIF - 0.5 * progdefaults.THOR_BW * bandwidth) / samplerate, + (THORFIRSTIF + 0.5 * progdefaults.THOR_BW * bandwidth)/ samplerate, 1024 ); - for (int i = 0; i < DEXSCOPESIZE; i++) + for (int i = 0; i < THORSCOPESIZE; i++) vidfilter[i] = new Cmovavg(16); syncfilter = new Cmovavg(8); twosym = 2 * symlen; - pipe = new DEXrxpipe[twosym]; + pipe = new THORrxpipe[twosym]; - scopedata.alloc(DEXSCOPESIZE); - videodata.alloc((DEXMAXFFTS * DEXNUMMTONES * 2 * (doublespaced?2:1) )); + scopedata.alloc(THORSCOPESIZE); + videodata.alloc((THORMAXFFTS * THORNUMMTONES * 2 * (doublespaced?2:1) )); pipeptr = 0; @@ -216,8 +216,8 @@ dex::dex(trx_mode md) prev1symbol = prev2symbol = 0; - Enc = new encoder (DEX_K, DEX_POLY1, DEX_POLY2); - Dec = new viterbi (DEX_K, DEX_POLY1, DEX_POLY2); + Enc = new encoder (THOR_K, THOR_POLY1, THOR_POLY2); + Dec = new viterbi (THOR_K, THOR_POLY1, THOR_POLY2); Dec->settraceback (45); Dec->setchunksize (1); Txinlv = new interleave (4, INTERLEAVE_FWD); // 4x4x10 @@ -232,17 +232,17 @@ dex::dex(trx_mode md) //===================================================================== // rx modules -complex dex::mixer(int n, complex in) +complex thor::mixer(int n, complex in) { complex z; double f; // first IF mixer (n == 0) plus -// DEXMAXFFTS mixers are supported each separated by 1/DEXMAXFFTS bin size -// n == 1, 2, 3, 4 ... DEXMAXFFTS +// THORMAXFFTS mixers are supported each separated by 1/THORMAXFFTS bin size +// n == 1, 2, 3, 4 ... THORMAXFFTS if (n == 0) - f = frequency - DEXFIRSTIF; + f = frequency - THORFIRSTIF; else - f = DEXFIRSTIF - DEXBASEFREQ - bandwidth/2 + (samplerate / symlen) * (1.0 * n / paths ); + f = THORFIRSTIF - THORBASEFREQ - bandwidth/2 + (samplerate / symlen) * (1.0 * n / paths ); z.re = cos(phase[n]); z.im = sin(phase[n]); z = z * in; @@ -254,7 +254,7 @@ complex dex::mixer(int n, complex in) return z; } -void dex::recvchar(int c) +void thor::recvchar(int c) { if (c == -1) return; @@ -268,7 +268,7 @@ void dex::recvchar(int c) // Receive //============================================================================= -void dex::decodePairs(unsigned char symbol) +void thor::decodePairs(unsigned char symbol) { int c, ch, met; @@ -289,13 +289,13 @@ void dex::decodePairs(unsigned char symbol) datashreg = (datashreg << 1) | !!c; if ((datashreg & 7) == 1) { - ch = dexvaridec(datashreg >> 1); + ch = thorvaridec(datashreg >> 1); recvchar(ch); datashreg = 1; } } -void dex::decodeEX(int ch) +void thor::decodeEX(int ch) { unsigned char symbols[4]; int c = ch; @@ -312,7 +312,7 @@ void dex::decodeEX(int ch) } -void dex::decodesymbol() +void thor::decodesymbol() { int c; double fdiff; @@ -324,7 +324,7 @@ void dex::decodesymbol() if (doublespaced) fdiff /= 2 * paths; else fdiff /= paths; c = (int)floor(fdiff + .5) - 2; - if (c < 0) c += DEXNUMMTONES; + if (c < 0) c += THORNUMMTONES; // decodeEX(c); @@ -335,7 +335,7 @@ void dex::decodesymbol() for (int i = 0; i < 4; i++) { // hard symbol decode - if (progdefaults.DEX_SOFT == false) { + if (progdefaults.THOR_SOFT == false) { if ((c & 1) == 1) symbols[3-i] = 255; else symbols[3-i] = 1; // soft symbol decode @@ -351,11 +351,11 @@ void dex::decodesymbol() } -int dex::harddecode() +int thor::harddecode() { double x, max = 0.0; int symbol = 0; - for (int i = 0; i < (paths * DEXNUMMTONES * 2 * (doublespaced ? 2 : 1) ); i++) { + for (int i = 0; i < (paths * THORNUMMTONES * 2 * (doublespaced ? 2 : 1) ); i++) { x = pipe[pipeptr].vector[i].mag(); if (x > max) { max = x; @@ -365,22 +365,22 @@ int dex::harddecode() return symbol; } -void dex::update_syncscope() +void thor::update_syncscope() { double max = 0, min = 1e6, range, mag; // dom waterfall - memset(videodata, 0, (paths * DEXNUMMTONES * 2 * (doublespaced?2:1) ) * sizeof(double)); + memset(videodata, 0, (paths * THORNUMMTONES * 2 * (doublespaced?2:1) ) * sizeof(double)); if (!progStatus.sqlonoff || metric >= progStatus.sldrSquelchValue) { - for (int i = 0; i < (paths * DEXNUMMTONES * 2 * (doublespaced?2:1) ); i++ ) { + for (int i = 0; i < (paths * THORNUMMTONES * 2 * (doublespaced?2:1) ); i++ ) { mag = pipe[pipeptr].vector[i].mag(); if (max < mag) max = mag; if (min > mag) min = mag; } range = max - min; - for (int i = 0; i < (paths * DEXNUMMTONES * 2 * (doublespaced?2:1) ); i++ ) { + for (int i = 0; i < (paths * THORNUMMTONES * 2 * (doublespaced?2:1) ); i++ ) { if (range > 2) { mag = (pipe[pipeptr].vector[i].mag() - min) / range + 0.0001; mag = 1 + 2 * log10(mag); @@ -390,24 +390,24 @@ void dex::update_syncscope() videodata[i] = 255*mag; } } - set_video(videodata, (paths * DEXNUMMTONES * 2 * (doublespaced?2:1) ), false); + set_video(videodata, (paths * THORNUMMTONES * 2 * (doublespaced?2:1) ), false); videodata.next(); // set_scope(scopedata, twosym); // 64 data points is sufficient to show the signal progression through the // convolution filter. - memset(scopedata, 0, DEXSCOPESIZE * sizeof(double)); + memset(scopedata, 0, THORSCOPESIZE * sizeof(double)); if (!progStatus.sqlonoff || metric >= progStatus.sldrSquelchValue) { - for (unsigned int i = 0, j = 0; i < DEXSCOPESIZE; i++) { - j = (pipeptr + i * twosym / DEXSCOPESIZE + 1) % (twosym); + for (unsigned int i = 0, j = 0; i < THORSCOPESIZE; i++) { + j = (pipeptr + i * twosym / THORSCOPESIZE + 1) % (twosym); scopedata[i] = vidfilter[i]->run(pipe[j].vector[prev1symbol].mag()); } } - set_scope(scopedata, DEXSCOPESIZE); + set_scope(scopedata, THORSCOPESIZE); scopedata.next(); } -void dex::synchronize() +void thor::synchronize() { // int syn = -1; double syn = -1; @@ -428,20 +428,20 @@ void dex::synchronize() } syn = syncfilter->run(syn); - synccounter += (int) floor(1.0 * (syn - symlen) / DEXNUMMTONES + 0.5); + synccounter += (int) floor(1.0 * (syn - symlen) / THORNUMMTONES + 0.5); } -void dex::eval_s2n() +void thor::eval_s2n() { if (currsymbol != prev1symbol && prev1symbol != prev2symbol) { sig = pipe[pipeptr].vector[currsymbol].mag(); noise = 0.0; - for (int i = 0; i < paths * DEXNUMMTONES * 2 * (doublespaced?2:1); i++) { + for (int i = 0; i < paths * THORNUMMTONES * 2 * (doublespaced?2:1); i++) { if (i != currsymbol) noise += pipe[pipeptr].vector[i].mag(); } - noise /= (paths * DEXNUMMTONES * 2 * (doublespaced?2:1) - 1); + noise /= (paths * THORNUMMTONES * 2 * (doublespaced?2:1) - 1); if (noise) s2n = decayavg( s2n, sig / noise, 8); @@ -450,20 +450,20 @@ void dex::eval_s2n() display_metric(metric); - snprintf(dexmsg, sizeof(dexmsg), "s/n %3.0f dB", metric / 3.0 - 2.0); - put_Status1(dexmsg); + snprintf(thormsg, sizeof(thormsg), "s/n %3.0f dB", metric / 3.0 - 2.0); + put_Status1(thormsg); } } -int dex::rx_process(const double *buf, int len) +int thor::rx_process(const double *buf, int len) { complex zref, z, *zp, *bins = 0; int n; if (filter_reset) reset_filters(); - if (paths != progdefaults.DEX_PATHS) { - paths = progdefaults.DEX_PATHS; + if (paths != progdefaults.THOR_PATHS) { + paths = progdefaults.THOR_PATHS; reset_filters(); } @@ -477,14 +477,14 @@ int dex::rx_process(const double *buf, int len) if (n) { for (int i = 0; i < n; i++) { -// process DEXMAXFFTS sets of sliding FFTs spaced at 1/DEXMAXFFTS bin intervals each of which +// process THORMAXFFTS sets of sliding FFTs spaced at 1/THORMAXFFTS bin intervals each of which // is a matched filter for the current symbol length for (int n = 0; n < paths; n++) { // shift in frequency to base band for the sliding DFTs z = mixer(n + 1, zp[i]); bins = binsfft[n]->run(z); // copy current vector to the pipe interleaving the FFT vectors - for (int i = 0; i < DEXNUMMTONES * 2 * (doublespaced ? 2 : 1); i++) { + for (int i = 0; i < THORNUMMTONES * 2 * (doublespaced ? 2 : 1); i++) { pipe[pipeptr].vector[n + paths * i] = bins[i]; } } @@ -516,7 +516,7 @@ int dex::rx_process(const double *buf, int len) // Transmit methods //============================================================================= -int dex::get_secondary_char() +int thor::get_secondary_char() { char chr; if (cptr > strSecXmtText.length()) cptr = 0; @@ -525,7 +525,7 @@ int dex::get_secondary_char() return chr; } -void dex::sendtone(int tone, int duration) +void thor::sendtone(int tone, int duration) { double f, phaseincr; f = (tone + 0.5) * tonespacing + get_txfreq_woffset() - bandwidth / 2; @@ -543,25 +543,25 @@ void dex::sendtone(int tone, int duration) } } -void dex::sendsymbol(int sym) +void thor::sendsymbol(int sym) { complex z; int tone; - tone = (txprevtone + 2 + sym) % DEXNUMMTONES; + tone = (txprevtone + 2 + sym) % THORNUMMTONES; txprevtone = tone; if (reverse) - tone = (DEXNUMMTONES - 1) - tone; + tone = (THORNUMMTONES - 1) - tone; sendtone(tone, 1); } -// Send DEX FEC varicode +// Send THOR FEC varicode -void dex::sendchar(unsigned char c, int secondary) +void thor::sendchar(unsigned char c, int secondary) { const char *code; - code = dexvarienc(c, secondary); + code = thorvarienc(c, secondary); while (*code) { int data = Enc->encode(*code++ - '0'); @@ -580,18 +580,18 @@ void dex::sendchar(unsigned char c, int secondary) put_echo_char(c); } -void dex::sendidle() +void thor::sendidle() { sendchar(0, 0); // } -void dex::sendsecondary() +void thor::sendsecondary() { int c = get_secondary_char(); sendchar(c & 0xFF, 1); } -void dex::Clearbits() +void thor::Clearbits() { int data = Enc->encode(0); for (int k = 0; k < 100; k++) { @@ -607,7 +607,7 @@ void dex::Clearbits() } } -void dex::flushtx() +void thor::flushtx() { // flush the varicode decoder at the other end // flush the convolutional encoder and interleaver @@ -616,7 +616,7 @@ void dex::flushtx() bitstate = 0; } -int dex::tx_process() +int thor::tx_process() { int i; @@ -624,12 +624,12 @@ int dex::tx_process() case TX_STATE_PREAMBLE: Clearbits(); for (int j = 0; j < 16; j++) sendsymbol(0); -// sendtone(DEXNUMMTONES/2, 4); +// sendtone(THORNUMMTONES/2, 4); // for (int k = 0; k < 3; k++) { -// sendtone(DEXNUMMTONES, 3); +// sendtone(THORNUMMTONES, 3); // sendtone(0, 3); // } -// sendtone(DEXNUMMTONES/2, 4); +// sendtone(THORNUMMTONES/2, 4); sendidle(); txstate = TX_STATE_START; diff --git a/src/dex/dexvaricode.cxx b/src/thor/thorvaricode.cxx similarity index 93% rename from src/dex/dexvaricode.cxx rename to src/thor/thorvaricode.cxx index 108edce1..7f069050 100644 --- a/src/dex/dexvaricode.cxx +++ b/src/thor/thorvaricode.cxx @@ -1,6 +1,6 @@ // ---------------------------------------------------------------------------- // -// dexvaricode.cxx -- DEX Varicode +// thorvaricode.cxx -- THOR Varicode // // Copyright (C) 2009 // Dave Freese, W1HKJ @@ -25,9 +25,9 @@ #include #include "mfskvaricode.h" -#include "dexvaricode.h" +#include "thorvaricode.h" -// DEX varicode is an extended set of the IZ8BLY MFSK varicode that uses the +// THOR varicode is an extended set of the IZ8BLY MFSK varicode that uses the // unallocated remaining 12 bit codes for a secondary character set. // Primary character set (same as MFSK) @@ -37,7 +37,7 @@ // encoding table -static const char *dex_varicode[] = { +static const char *thor_varicode[] = { "101110000000", /* 032 - */ "101110100000", /* 033 - ! */ "101110101000", /* 034 - '"' */ @@ -152,7 +152,7 @@ static char *unused[] = { // decoding table -static const unsigned int dex_varidecode[] = { +static const unsigned int thor_varidecode[] = { 0xB80, 0xBA0, 0xBA8, 0xBAC, 0xBB0, 0xBB4, 0xBB8, 0xBBC, 0xBC0, 0xBD0, 0xBD4, 0xBD8, 0xBDC, 0xBE0, 0xBE8, 0xBEC, 0xBF0, 0xBF4, 0xBF8, 0xBFC, 0xC00, 0xD00, 0xD40, 0xD54, @@ -167,18 +167,18 @@ static const unsigned int dex_varidecode[] = { 0xFA8, 0xFAC, 0xFB0 }; -const char *dexvarienc(int c, int sec) +const char *thorvarienc(int c, int sec) { if (sec == 0) return varienc(c); // mfsk varicode else if (c >= ' ' && c <= 'z') - return dex_varicode[c - ' ']; + return thor_varicode[c - ' ']; return varienc(0); // return code for NULL if not in tables } -int dexvaridec(unsigned int symbol) +int thorvaridec(unsigned int symbol) { int i; @@ -186,7 +186,7 @@ int dexvaridec(unsigned int symbol) return varidec(symbol); // find in the MFSK decode table for (i = 0; i < 92; i++) - if (symbol == dex_varidecode[i]) + if (symbol == thor_varidecode[i]) return (' ' + i + 0x100); // found in the extended decode table return -1; // not found diff --git a/src/trx/modem.cxx b/src/trx/modem.cxx index f3ed9b46..aac51f81 100644 --- a/src/trx/modem.cxx +++ b/src/trx/modem.cxx @@ -37,13 +37,13 @@ modem *qpsk125_modem = 0; modem *qpsk250_modem = 0; modem *olivia_modem = 0; modem *rtty_modem = 0; -modem *dex4_modem = 0; -modem *dex5_modem = 0; -modem *dex8_modem = 0; -modem *dex11_modem = 0; -modem *dsx11_modem = 0; -modem *dex16_modem = 0; -modem *dex22_modem = 0; +modem *thor4_modem = 0; +modem *thor5_modem = 0; +modem *thor8_modem = 0; +modem *thor11_modem = 0; +modem *tsor11_modem = 0; +modem *thor16_modem = 0; +modem *thor22_modem = 0; modem *dominoex4_modem = 0; modem *dominoex5_modem = 0; modem *dominoex8_modem = 0; @@ -278,263 +278,6 @@ void modem::videoText() } } -//===================================================================== -// transmit processing of waterfall video id -//===================================================================== -#define MAXCHARS 4 - -#define NUMCOLS 8 -#define NUMROWS 14 -#define CHARSPACE 2 -#define TONESPACING 8 - -#define IDSYMLEN 2048 -#define RISETIME 20 - -struct mfntchr { char c; int byte[14];};//NUMROWS]; }; -extern mfntchr idch[]; - -C_FIR_filter vidfilt; - -void modem::wfid_make_pulse() -{ - double risetime = (samplerate / 1000) * RISETIME; - for (int i = 0; i < IDSYMLEN; i++) - wfid_txpulse[i] = 1.0; - for (int i = 0; i < risetime; i++) - wfid_txpulse[i] = wfid_txpulse[IDSYMLEN - 1 - i] = - 0.5 * (1 - cos(M_PI * i / risetime)); -} - -void modem::wfid_make_tones() -{ - double f, flo, fhi; - f = TONESPACING * ( progdefaults.videowidth * (NUMCOLS - 1) + (progdefaults.videowidth) * CHARSPACE) / 2.0; - f = 2.0 * floor((frequency + f)/2.0); - fhi = f + 2 * TONESPACING; - flo = f - (progdefaults.videowidth * (NUMCOLS + CHARSPACE) + 2) * TONESPACING; - for (int i = 0; i < NUMCOLS * progdefaults.videowidth; i++) { - wfid_w[i] = f * 2.0 * M_PI / samplerate; - f -= TONESPACING; - if ( (i > 0) && (i % NUMCOLS == 0) ) - f -= TONESPACING * CHARSPACE; - } - vidfilt.init_bandpass( 1024, 1, flo/samplerate, fhi/samplerate) ; -} - -void modem::wfid_send(long int symbol) -{ - int i, j; - int sym; - double val; - - for (i = 0; i < IDSYMLEN; i++) { - wfid_outbuf[i] = 0.0; - val = 0.0; - sym = symbol; - for (j = 0; j < NUMCOLS * progdefaults.videowidth; j++) { - if ((sym & 1) == 1) - val += sin(wfid_w[j] * i); - sym = sym >> 1; - } -// soft limit the signal - wfid_outbuf[i] = 0.707 * (1.0 - exp(fabs(val)/-3.0)) * (val >= 0.0 ? 1 : -1); - } - -// band pass filter the hard limited signal - - for (i = 0; i < IDSYMLEN; i++) { - val = wfid_outbuf[i]; - vidfilt.Irun (val, val); - wfid_outbuf[i] = val * wfid_txpulse[i]; - } - - ModulateXmtr(wfid_outbuf, IDSYMLEN); -} - -void modem::wfid_sendchar(char c) -{ -// send rows from bottom to top so they appear to scroll down the waterfall correctly - long int symbol; - unsigned int n; - if (c < ' ' || c > '~') return; - n = c - ' '; - for (int row = 0; row < NUMROWS; row++) { - symbol = (idch[n].byte[NUMROWS - 1 - row]) >> (16 - NUMCOLS); - wfid_send (symbol); - if (stopflag) - return; - } -} - -void modem::wfid_sendchars(string s) -{ - long int symbol; - int len; - unsigned int n[progdefaults.videowidth]; - int c; - - while (s[0] == ' ') s.erase(0); - len = s.length(); - - for (int i = 0; i < len; i++) { //progdefaults.videowidth; i++) { - c = s[i]; - if (c > '~' || c < ' ') c = ' '; - c -= ' '; - n[i] = c; - } - -// send rows from bottom to top so they appear to scroll down the waterfall correctly - for (int row = 0; row < NUMROWS; row++) { - symbol = 0; - for (int i = 0; i < len; i++) {//progdefaults.videowidth; i++) { - symbol |= (idch[n[i]].byte[NUMROWS - 1 -row] >> (16 - NUMCOLS)); - if (i != (len - 1) ) - symbol = symbol << NUMCOLS; - } - - if (len < progdefaults.videowidth) - symbol = symbol << NUMCOLS * (progdefaults.videowidth - len) / 2; - - wfid_send (symbol); - if (stopflag) - return; - } -} - -void modem::wfid_text(string s) -{ - int len = s.length(); - string video = "Video text: "; - video += s; - - wfid_make_pulse(); - wfid_make_tones(); - - put_status(video.c_str()); - - if (progdefaults.videowidth == 1) { - for (int i = len - 1; i >= 0; i--) { - wfid_sendchar(s[i]); - } - } else { - int numlines = 0; - string tosend; - while (numlines < len) numlines += progdefaults.videowidth; - numlines -= progdefaults.videowidth; - while (numlines >= 0) { - tosend = s.substr(numlines, progdefaults.videowidth); - wfid_sendchars(tosend); - numlines -= progdefaults.videowidth; - if (stopflag) - break; - } - } - put_status(""); -} - -double modem::wfid_txpulse[IDSYMLEN]; -double modem::wfid_outbuf[IDSYMLEN]; -double modem::wfid_w[NUMCOLS * MAXCHARS]; - -mfntchr idch[] = { -{' ', { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, }, -{'!', { 0x0000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0x0000, 0x0000, 0xC000, 0xC000, 0x0000, 0x0000, 0x0000 }, }, -{'"', { 0x0000, 0xD800, 0xD800, 0xD800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, }, -{'#', { 0x0000, 0x5000, 0x5000, 0xF800, 0xF800, 0x5000, 0x5000, 0xF800, 0xF800, 0x5000, 0x5000, 0x0000, 0x0000, 0x0000 }, }, -{'$', { 0x0000, 0x2000, 0x2000, 0x7800, 0xF800, 0xA000, 0xF000, 0x7800, 0x2800, 0xF800, 0xF000, 0x2000, 0x2000, 0x0000 }, }, -{'%', { 0x0000, 0x4000, 0xE400, 0xE400, 0x4C00, 0x1800, 0x3000, 0x6000, 0xC800, 0x9C00, 0x9C00, 0x8800, 0x0000, 0x0000 }, }, -{'&', { 0x0000, 0x3000, 0x7800, 0x4800, 0x4800, 0x7000, 0xF400, 0x8C00, 0x8800, 0xFC00, 0x7400, 0x0000, 0x0000, 0x0000 }, }, -{ 39, { 0x0000, 0x4000, 0x4000, 0xC000, 0x8000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, }, -{'(', { 0x0000, 0x0000, 0x2000, 0x6000, 0xC000, 0x8000, 0x8000, 0x8000, 0x8000, 0xC000, 0x6000, 0x2000, 0x0000, 0x0000 }, }, -{')', { 0x0000, 0x0000, 0x8000, 0xC000, 0x6000, 0x2000, 0x2000, 0x2000, 0x2000, 0x6000, 0xC000, 0x8000, 0x0000, 0x0000 }, }, -{'*', { 0x0000, 0x0000, 0x0000, 0x1000, 0x1000, 0xFE00, 0x7C00, 0x3800, 0x6C00, 0x4400, 0x0000, 0x0000, 0x0000, 0x0000 }, }, -{'+', { 0x0000, 0x0000, 0x0000, 0x2000, 0x2000, 0x2000, 0xF800, 0xF800, 0x2000, 0x2000, 0x2000, 0x0000, 0x0000, 0x0000 }, }, -{',', { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xC000, 0xC000, 0xC000, 0x4000, 0xC000, 0x8000 }, }, -{'-', { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF800, 0xF800, 0x0000, 0x0000 }, }, -{'.', { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xC000, 0xC000, 0xC000, 0x0000, 0x0000 }, }, -{'/', { 0x0000, 0x0800, 0x0800, 0x1800, 0x1000, 0x3000, 0x2000, 0x6000, 0x4000, 0xC000, 0x8000, 0x8000, 0x0000, 0x0000 }, }, -{'0', { 0x0000, 0x0000, 0x7800, 0xFC00, 0x8C00, 0x9C00, 0xB400, 0xE400, 0xC400, 0x8400, 0xFC00, 0x7800, 0x0000, 0x0000 }, }, -{'1', { 0x0000, 0x0000, 0x1000, 0x3000, 0x7000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000 }, }, -{'2', { 0x0000, 0x0000, 0x7800, 0xFC00, 0x8400, 0x0C00, 0x1800, 0x3000, 0x6000, 0xC000, 0xFC00, 0xFC00, 0x0000, 0x0000 }, }, -{'3', { 0x0000, 0x0000, 0xFC00, 0xFC00, 0x0400, 0x0C00, 0x1800, 0x1C00, 0x0400, 0x8400, 0xFC00, 0x7800, 0x0000, 0x0000 }, }, -{'4', { 0x0000, 0x0000, 0x3800, 0x7800, 0x4800, 0xC800, 0x8800, 0xFC00, 0xFC00, 0x0800, 0x0800, 0x0800, 0x0000, 0x0000 }, }, -{'5', { 0x0000, 0x0000, 0xFC00, 0xFC00, 0x8000, 0x8000, 0xF800, 0xFC00, 0x0400, 0x0400, 0xFC00, 0xF800, 0x0000, 0x0000 }, }, -{'6', { 0x0000, 0x0000, 0x7800, 0xF800, 0x8000, 0x8000, 0xF800, 0xFC00, 0x8400, 0x8400, 0xFC00, 0x7800, 0x0000, 0x0000 }, }, -{'7', { 0x0000, 0x0000, 0xFC00, 0xFC00, 0x0400, 0x0400, 0x0C00, 0x1800, 0x3000, 0x2000, 0x2000, 0x2000, 0x0000, 0x0000 }, }, -{'8', { 0x0000, 0x0000, 0x7800, 0xFC00, 0x8400, 0x8400, 0x7800, 0xFC00, 0x8400, 0x8400, 0xFC00, 0x7800, 0x0000, 0x0000 }, }, -{'9', { 0x0000, 0x0000, 0x7800, 0xFC00, 0x8400, 0x8400, 0xFC00, 0x7C00, 0x0400, 0x0400, 0x7C00, 0x7800, 0x0000, 0x0000 }, }, -{':', { 0x0000, 0xC000, 0xC000, 0xC000, 0x0000, 0x0000, 0x0000, 0xC000, 0xC000, 0xC000, 0x0000, 0x0000, 0x0000, 0x0000 }, }, -{';', { 0x0000, 0x6000, 0x6000, 0x6000, 0x0000, 0x0000, 0x6000, 0x6000, 0x2000, 0x2000, 0xE000, 0xC000, 0x0000, 0x0000 }, }, -{'<', { 0x0000, 0x0000, 0x0800, 0x1800, 0x3000, 0x6000, 0xC000, 0xC000, 0x6000, 0x3000, 0x1800, 0x0800, 0x0000, 0x0000 }, }, -{'=', { 0x0000, 0x0000, 0x0000, 0x0000, 0xF800, 0xF800, 0x0000, 0x0000, 0xF800, 0xF800, 0x0000, 0x0000, 0x0000, 0x0000 }, }, -{'>', { 0x0000, 0x0000, 0x8000, 0xC000, 0x6000, 0x3000, 0x1800, 0x1800, 0x3000, 0x6000, 0xC000, 0x8000, 0x0000, 0x0000 }, }, -{'?', { 0x0000, 0x0000, 0x7000, 0xF800, 0x8800, 0x0800, 0x1800, 0x3000, 0x2000, 0x0000, 0x2000, 0x2000, 0x0000, 0x0000 }, }, -{'@', { 0x0000, 0x0000, 0x7C00, 0xFE00, 0x8200, 0x8200, 0xB200, 0xBE00, 0xBC00, 0x8000, 0xFC00, 0x7C00, 0x0000, 0x0000 }, }, -{'A', { 0x0000, 0x0000, 0x3000, 0x7800, 0xCC00, 0x8400, 0x8400, 0xFC00, 0xFC00, 0x8400, 0x8400, 0x8400, 0x0000, 0x0000 }, }, -{'B', { 0x0000, 0x0000, 0xF800, 0xFC00, 0x8400, 0x8400, 0xF800, 0xF800, 0x8400, 0x8400, 0xFC00, 0xF800, 0x0000, 0x0000 }, }, -{'C', { 0x0000, 0x0000, 0x3800, 0x7C00, 0xC400, 0x8000, 0x8000, 0x8000, 0x8000, 0xC400, 0x7C00, 0x3800, 0x0000, 0x0000 }, }, -{'D', { 0x0000, 0x0000, 0xF000, 0xF800, 0x8C00, 0x8400, 0x8400, 0x8400, 0x8400, 0x8C00, 0xF800, 0xF000, 0x0000, 0x0000 }, }, -{'E', { 0x0000, 0x0000, 0xFC00, 0xFC00, 0x8000, 0x8000, 0xF000, 0xF000, 0x8000, 0x8000, 0xFC00, 0xFC00, 0x0000, 0x0000 }, }, -{'F', { 0x0000, 0x0000, 0xFC00, 0xFC00, 0x8000, 0x8000, 0xF000, 0xF000, 0x8000, 0x8000, 0x8000, 0x8000, 0x0000, 0x0000 }, }, -{'G', { 0x0000, 0x0000, 0x3C00, 0x7C00, 0xC000, 0x8000, 0x8C00, 0x8C00, 0x8400, 0xC400, 0x7C00, 0x3800, 0x0000, 0x0000 }, }, -{'H', { 0x0000, 0x0000, 0x8400, 0x8400, 0x8400, 0x8400, 0xFC00, 0xFC00, 0x8400, 0x8400, 0x8400, 0x8400, 0x0000, 0x0000 }, }, -{'I', { 0x0000, 0x0000, 0xF800, 0xF800, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0xF800, 0xF800, 0x0000, 0x0000 }, }, -{'J', { 0x0000, 0x0000, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x8400, 0x8400, 0xFC00, 0x7800, 0x0000, 0x0000 }, }, -{'K', { 0x0000, 0x0000, 0x8400, 0x8400, 0x8C00, 0x9800, 0xF000, 0xF000, 0x9800, 0x8C00, 0x8400, 0x8400, 0x0000, 0x0000 }, }, -{'L', { 0x0000, 0x0000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0xFC00, 0xFC00, 0x0000, 0x0000 }, }, -{'M', { 0x0000, 0x0000, 0x8200, 0xC600, 0xEE00, 0xBA00, 0x9200, 0x8200, 0x8200, 0x8200, 0x8200, 0x8200, 0x0000, 0x0000 }, }, -{'N', { 0x0000, 0x0000, 0x8400, 0xC400, 0xE400, 0xB400, 0x9C00, 0x8C00, 0x8400, 0x8400, 0x8400, 0x8400, 0x0000, 0x0000 }, }, -{'O', { 0x0000, 0x0000, 0x3000, 0x7800, 0xCC00, 0x8400, 0x8400, 0x8400, 0x8400, 0xCC00, 0x7800, 0x3000, 0x0000, 0x0000 }, }, -{'P', { 0x0000, 0x0000, 0xF800, 0xFC00, 0x8400, 0x8400, 0xFC00, 0xF800, 0x8000, 0x8000, 0x8000, 0x8000, 0x0000, 0x0000 }, }, -{'Q', { 0x0000, 0x0000, 0x7800, 0xFC00, 0x8400, 0x8400, 0x8400, 0x8400, 0x9400, 0x9400, 0xFC00, 0x7800, 0x0800, 0x0800 }, }, -{'R', { 0x0000, 0x0000, 0xF800, 0xFC00, 0x8400, 0x8400, 0xFC00, 0xF800, 0x8800, 0x8C00, 0x8400, 0x8400, 0x0000, 0x0000 }, }, -{'S', { 0x0000, 0x0000, 0x7800, 0xFC00, 0x8400, 0x8000, 0xF800, 0x7C00, 0x0400, 0x8400, 0xFC00, 0x7800, 0x0000, 0x0000 }, }, -{'T', { 0x0000, 0x0000, 0xF800, 0xF800, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x0000, 0x0000 }, }, -{'U', { 0x0000, 0x0000, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0xFC00, 0x7800, 0x0000, 0x0000 }, }, -{'V', { 0x0000, 0x0000, 0x8200, 0x8200, 0x8200, 0xC600, 0x4400, 0x6C00, 0x2800, 0x3800, 0x1000, 0x1000, 0x0000, 0x0000 }, }, -{'W', { 0x0000, 0x0000, 0x8200, 0x8200, 0x8200, 0x8200, 0x8200, 0x9200, 0x9200, 0x9200, 0xFE00, 0x6C00, 0x0000, 0x0000 }, }, -{'X', { 0x0000, 0x0000, 0x8200, 0x8200, 0xC600, 0x6C00, 0x3800, 0x3800, 0x6C00, 0xC600, 0x8200, 0x8200, 0x0000, 0x0000 }, }, -{'Y', { 0x0000, 0x0000, 0x8200, 0x8200, 0xC600, 0x6C00, 0x3800, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000 }, }, -{'Z', { 0x0000, 0x0000, 0xFC00, 0xFC00, 0x0C00, 0x1800, 0x3000, 0x6000, 0xC000, 0x8000, 0xFC00, 0xFC00, 0x0000, 0x0000 }, }, -{'[', { 0x0000, 0x0000, 0xE000, 0xE000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0xE000, 0xE000, 0x0000, 0x0000 }, }, -{'\\', { 0x0000, 0x8000, 0x8000, 0xC000, 0x4000, 0x6000, 0x2000, 0x3000, 0x1000, 0x1800, 0x0800, 0x0800, 0x0000, 0x0000 }, }, -{']', { 0x0000, 0x0000, 0xE000, 0xE000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0xE000, 0xE000, 0x0000, 0x0000 }, }, -{'^', { 0x0000, 0x2000, 0x2000, 0x7000, 0x5000, 0xD800, 0x8800, 0x8800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, }, -{'_', { 0x0000, 0xF800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF800, 0x0000, 0x0000 }, }, -{'`', { 0x0000, 0xC000, 0xC000, 0xC000, 0xC000, 0x6000, 0x6000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, }, -{'a', { 0x0000, 0x0000, 0x0000, 0x0000, 0x7800, 0x7C00, 0x0400, 0x7C00, 0xFC00, 0x8400, 0xFC00, 0x7C00, 0x0000, 0x0000 }, }, -{'b', { 0x0000, 0x0000, 0x8000, 0x8000, 0xB800, 0xFC00, 0xC400, 0x8400, 0x8400, 0x8400, 0xFC00, 0xF800, 0x0000, 0x0000 }, }, -{'c', { 0x0000, 0x0000, 0x0000, 0x0000, 0x7800, 0xF800, 0x8000, 0x8000, 0x8000, 0x8000, 0xF800, 0x7800, 0x0000, 0x0000 }, }, -{'d', { 0x0000, 0x0000, 0x0400, 0x0400, 0x7400, 0xFC00, 0x8C00, 0x8400, 0x8400, 0x8400, 0xFC00, 0x7C00, 0x0000, 0x0000 }, }, -{'e', { 0x0000, 0x0000, 0x0000, 0x0000, 0x7800, 0xFC00, 0x8400, 0xFC00, 0xFC00, 0x8000, 0xF800, 0x7800, 0x0000, 0x0000 }, }, -{'f', { 0x0000, 0x0000, 0x3C00, 0x7C00, 0x4000, 0x4000, 0xF800, 0xF800, 0x4000, 0x4000, 0x4000, 0x4000, 0x0000, 0x0000 }, }, -{'g', { 0x0000, 0x0000, 0x0000, 0x7C00, 0xFC00, 0x8400, 0x8400, 0x8C00, 0xFC00, 0x7400, 0x0400, 0x7C00, 0x7800, 0x0000 }, }, -{'h', { 0x0000, 0x0000, 0x8000, 0x8000, 0xB800, 0xFC00, 0xC400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x0000, 0x0000 }, }, -{'i', { 0x0000, 0x2000, 0x2000, 0x0000, 0xE000, 0xE000, 0x2000, 0x2000, 0x2000, 0x2000, 0xF800, 0xF800, 0x0000, 0x0000 }, }, -{'j', { 0x0000, 0x0800, 0x0800, 0x0000, 0x3800, 0x3800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x8800, 0xF800, 0x7000 }, }, -{'k', { 0x0000, 0x0000, 0x8000, 0x8800, 0x9800, 0xB000, 0xE000, 0xE000, 0xB000, 0x9800, 0x8800, 0x8800, 0x0000, 0x0000 }, }, -{'l', { 0x0000, 0x0000, 0xE000, 0xE000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0xF800, 0xF800, 0x0000, 0x0000 }, }, -{'m', { 0x0000, 0x0000, 0x0000, 0x0000, 0xEC00, 0xFE00, 0x9200, 0x9200, 0x8200, 0x8200, 0x8200, 0x8200, 0x0000, 0x0000 }, }, -{'n', { 0x0000, 0x0000, 0x0000, 0x0000, 0xB800, 0xFC00, 0xC400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x0000, 0x0000 }, }, -{'o', { 0x0000, 0x0000, 0x0000, 0x0000, 0x7800, 0xFC00, 0x8400, 0x8400, 0x8400, 0x8400, 0xFC00, 0x7800, 0x0000, 0x0000 }, }, -{'p', { 0x0000, 0x0000, 0x0000, 0x0000, 0xF800, 0xFC00, 0x8400, 0x8400, 0xC400, 0xFC00, 0xB800, 0x8000, 0x8000, 0x8000 }, }, -{'q', { 0x0000, 0x0000, 0x0000, 0x0000, 0x7C00, 0xFC00, 0x8400, 0x8400, 0x8C00, 0xFC00, 0x7400, 0x0400, 0x0400, 0x0400 }, }, -{'r', { 0x0000, 0x0000, 0x0000, 0x0000, 0xB800, 0xFC00, 0xC400, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x0000, 0x0000 }, }, -{'s', { 0x0000, 0x0000, 0x0000, 0x0000, 0x7C00, 0xFC00, 0x8000, 0xF800, 0x7C00, 0x0400, 0xFC00, 0xF800, 0x0000, 0x0000 }, }, -{'t', { 0x0000, 0x0000, 0x4000, 0x4000, 0xF000, 0xF000, 0x4000, 0x4000, 0x4000, 0x4000, 0x7800, 0x3800, 0x0000, 0x0000 }, }, -{'u', { 0x0000, 0x0000, 0x0000, 0x0000, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8C00, 0xFC00, 0x7400, 0x0000, 0x0000 }, }, -{'v', { 0x0000, 0x0000, 0x0000, 0x0000, 0x8200, 0x8200, 0x8200, 0x8200, 0xC600, 0x6C00, 0x3800, 0x1000, 0x0000, 0x0000 }, }, -{'w', { 0x0000, 0x0000, 0x0000, 0x0000, 0x8200, 0x8200, 0x8200, 0x9200, 0x9200, 0x9200, 0xFE00, 0x6C00, 0x0000, 0x0000 }, }, -{'x', { 0x0000, 0x0000, 0x0000, 0x0000, 0x8200, 0xC600, 0x6C00, 0x3800, 0x3800, 0x6C00, 0xC600, 0x8200, 0x0000, 0x0000 }, }, -{'y', { 0x0000, 0x0000, 0x0000, 0x0000, 0x8400, 0x8400, 0x8400, 0x8400, 0x8C00, 0xFC00, 0x7400, 0x0400, 0x7C00, 0x7800 }, }, -{'z', { 0x0000, 0x0000, 0x0000, 0x0000, 0xFC00, 0xFC00, 0x1800, 0x3000, 0x6000, 0xC000, 0xFC00, 0xFC00, 0x0000, 0x0000 }, }, -{'{', { 0x0000, 0x2000, 0x6000, 0x4000, 0x4000, 0x4000, 0xC000, 0xC000, 0x4000, 0x4000, 0x4000, 0x6000, 0x2000, 0x0000 }, }, -{'|', { 0x0000, 0x8000, 0x8000, 0xC000, 0x4000, 0x6000, 0x2000, 0x3000, 0x1000, 0x1800, 0x0800, 0x0800, 0x0000, 0x0000 }, }, -{'}', { 0x0000, 0x8000, 0xC000, 0x4000, 0x4000, 0x4000, 0x6000, 0x6000, 0x4000, 0x4000, 0x4000, 0xC000, 0x8000, 0x0000 }, }, -{'~', { 0x0000, 0x9800, 0xFC00, 0x6400, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, } -}; - // CW ID transmit routines //=========================================================================== @@ -672,3 +415,498 @@ void modem::cwid() progdefaults.macroCWid = false; } } + +//===================================================================== +// transmit processing of waterfall video id +//===================================================================== + +int NUMROWS; +int NUMCOLS; +int NUMTONES; +int TONESPACING; +int IDSYMLEN; +int RISETIME; +int CHARSPACE; +int MAXCHARS; +int NUMCHARS; + +bool useIDSMALL = true; + +#define MAXROWS 14 +#define MAXIDSYMLEN 4096 +#define MAXTONES 32 + +struct mfntchr { char c; int byte[MAXROWS]; }; +extern mfntchr idch1[]; // original id font definition +extern mfntchr idch2[]; // extended id font definition +extern int mask[1024]; + +C_FIR_filter vidfilt; + +void modem::wfid_make_pulse() +{ + double risetime = (samplerate / 1000) * RISETIME; + for (int i = 0; i < IDSYMLEN; i++) + wfid_txpulse[i] = 1.0; + for (int i = 0; i < risetime; i++) { + wfid_txpulse[i] = wfid_txpulse[IDSYMLEN - 1 - i] = + 0.5 * (1 - cos(M_PI * i / risetime)); + } +} + +void modem::wfid_make_tones() +{ + if (useIDSMALL) { + double f; + double frequency = get_txfreq_woffset(); + for (int j = 0; j < NUMCHARS; j++) + for (int i = 0; i < NUMTONES; i++) { + f = frequency + TONESPACING * (NUMTONES - i - j * (NUMTONES + 3)); + wfid_w[i + NUMTONES * j] = 2 * M_PI * f / samplerate; + } + } else { + double f, flo, fhi; + f = TONESPACING * ( progdefaults.videowidth * (NUMCOLS - 1) + (progdefaults.videowidth) * CHARSPACE) / 2.0; + f = 2.0 * floor((frequency + f)/2.0); + fhi = f + 2 * TONESPACING; + flo = f - (progdefaults.videowidth * (NUMCOLS + CHARSPACE) + 2) * TONESPACING; + for (int i = 0; i < NUMCOLS * progdefaults.videowidth; i++) { + wfid_w[i] = f * 2.0 * M_PI / samplerate; + f -= TONESPACING; + if ( (i > 0) && (i % NUMCOLS == 0) ) + f -= TONESPACING * CHARSPACE; + } + vidfilt.init_bandpass( 1024, 1, flo/samplerate, fhi/samplerate) ; + } +} + +void modem::wfid_send(long int symbol) +{ + if (useIDSMALL) { + int i, j; + int sym; + int msk; + double maximum = 0.0; + + for (i = 0; i < IDSYMLEN; i++) { + wfid_outbuf[i] = 0.0; + sym = symbol; + msk = mask[symbol]; + for (j = 0; j < NUMTONES * NUMCHARS; j++) { + if (sym & 1 == 1) + wfid_outbuf[i] += ((msk & 1 == 1 ? -1 : 1 ) * sin(wfid_w[j] * i) * wfid_txpulse[i]); + sym = sym >> 1; + msk = msk >> 1; + } + if (fabs(wfid_outbuf[i]) > maximum) + maximum = fabs(wfid_outbuf[i]); + } + if (maximum > 0.0) + for (i = 0; i < IDSYMLEN; i++) + wfid_outbuf[i] = 0.9 * wfid_outbuf[i] / maximum; + + ModulateXmtr(wfid_outbuf, IDSYMLEN); + } else { + int i, j; + int sym; + double val; + + for (i = 0; i < IDSYMLEN; i++) { + wfid_outbuf[i] = 0.0; + val = 0.0; + sym = symbol; + for (j = 0; j < NUMCOLS * progdefaults.videowidth; j++) { + if ((sym & 1) == 1) + val += sin(wfid_w[j] * i); + sym = sym >> 1; + } +// soft limit the signal + wfid_outbuf[i] = 0.707 * (1.0 - exp(fabs(val)/-3.0)) * (val >= 0.0 ? 1 : -1); + } + +// band pass filter the hard limited signal + + for (i = 0; i < IDSYMLEN; i++) { + val = wfid_outbuf[i]; + vidfilt.Irun (val, val); + wfid_outbuf[i] = val * wfid_txpulse[i]; + } + + ModulateXmtr(wfid_outbuf, IDSYMLEN); + } +} + +void modem::wfid_sendchar(char c) +{ +// send rows from bottom to top so they appear to scroll down the waterfall correctly + long int symbol; + unsigned int n; + if (c < ' ' || c > '~') return; + n = c - ' '; + for (int row = 0; row < NUMROWS; row++) { + symbol = (idch2[n].byte[NUMROWS - 1 - row]) >> (16 - NUMCOLS); + wfid_send (symbol); + if (stopflag) + return; + } +} + +void modem::wfid_sendchars(string s) +{ + if (useIDSMALL) { + long int symbol; + int len = s.length(); + int n[NUMCHARS]; + int c; + while (len++ < NUMCHARS) s.insert(0," "); + + for (int i = 0; i < NUMCHARS; i++) { + c = s[i]; + if (c > 'z' || c < ' ') c = ' '; + c = toupper(c) - ' '; + n[i] = c; + } + for (int row = 0; row < NUMROWS; row++) { + symbol = 0; + for (int i = 0; i < NUMCHARS; i++) { + symbol |= (idch1[n[i]].byte[NUMROWS - 1 -row] >> 3); + if (i != (NUMCHARS - 1) ) + symbol = symbol << 5; + } + wfid_send (symbol); + } + wfid_send (0); // row of no tones + } else { + long int symbol; + int len; + unsigned int n[progdefaults.videowidth]; + int c; + + while (s[0] == ' ') s.erase(0); + len = s.length(); + + for (int i = 0; i < len; i++) { //progdefaults.videowidth; i++) { + c = s[i]; + if (c > '~' || c < ' ') c = ' '; + c -= ' '; + n[i] = c; + } + +// send rows from bottom to top so they appear to scroll down the waterfall correctly + for (int row = 0; row < NUMROWS; row++) { + symbol = 0; + for (int i = 0; i < len; i++) {//progdefaults.videowidth; i++) { + symbol |= (idch2[n[i]].byte[NUMROWS - 1 -row] >> (16 - NUMCOLS)); + if (i != (len - 1) ) + symbol = symbol << NUMCOLS; + } + + if (len < progdefaults.videowidth) + symbol = symbol << NUMCOLS * (progdefaults.videowidth - len) / 2; + + wfid_send (symbol); + if (stopflag) + return; + } + } +} + +void modem::wfid_text(string s) +{ + int len = s.length(); + string video = "Video text: "; + video += s; + + if (progdefaults.ID_SMALL) { + NUMROWS = 5; + NUMCHARS = 2; + NUMTONES = 5; + TONESPACING = 6; + IDSYMLEN = 3072; + RISETIME =20; + useIDSMALL = true; + } else { + NUMROWS = 14; + NUMCOLS = 8; + TONESPACING = 8; + IDSYMLEN = 2048; + RISETIME = 20; + CHARSPACE = 2; + MAXCHARS = 4; + useIDSMALL = false; + } + + wfid_make_pulse(); + wfid_make_tones(); + + put_status(video.c_str()); + + if (useIDSMALL) { + int numlines = 0; + string tosend; + while (numlines < len) numlines += NUMCHARS; + numlines -= NUMCHARS; + while (numlines >= 0) { + tosend = s.substr(numlines, NUMCHARS); + wfid_sendchars(tosend); + numlines -= NUMCHARS; + if (stopflag) + break; + } + put_status(""); + } else { + if (progdefaults.videowidth == 1) { + for (int i = len - 1; i >= 0; i--) { + wfid_sendchar(s[i]); + } + } else { + int numlines = 0; + string tosend; + while (numlines < len) numlines += progdefaults.videowidth; + numlines -= progdefaults.videowidth; + while (numlines >= 0) { + tosend = s.substr(numlines, progdefaults.videowidth); + wfid_sendchars(tosend); + numlines -= progdefaults.videowidth; + if (stopflag) + break; + } + } + put_status(""); + } +} + +double modem::wfid_txpulse[MAXIDSYMLEN]; +double modem::wfid_outbuf[MAXIDSYMLEN]; +double modem::wfid_w[MAXTONES]; + +mfntchr idch1[] = { +{' ', { 0x00, 0x00, 0x00, 0x00, 0x00 }, }, +{'!', { 0x80, 0x80, 0x80, 0x00, 0x80 }, }, +{'"', { 0xA0, 0x00, 0x00, 0x00, 0x00 }, }, +{'#', { 0x50, 0xF8, 0x50, 0xF8, 0x50 }, }, +{'$', { 0x78, 0xA0, 0x70, 0x28, 0xF0 }, }, +{'%', { 0xC8, 0x10, 0x20, 0x40, 0x98 }, }, +{'&', { 0x40, 0xE0, 0x68, 0x90, 0x78 }, }, +{ 39, { 0xC0, 0x40, 0x80, 0x00, 0x00 }, }, +{'(', { 0x60, 0x80, 0x80, 0x80, 0x60 }, }, +{')', { 0xC0, 0x20, 0x20, 0x20, 0xC0 }, }, +{'*', { 0xA8, 0x70, 0xF8, 0x70, 0xA8 }, }, +{'+', { 0x00, 0x20, 0xF8, 0x20, 0x00 }, }, +{',', { 0x00, 0x00, 0x00, 0xC0, 0x40 }, }, +{'-', { 0x00, 0x00, 0xF8, 0x00, 0x00 }, }, +{'.', { 0x00, 0x00, 0x00, 0x00, 0xC0 }, }, +{'/', { 0x08, 0x10, 0x20, 0x40, 0x80 }, }, +{'0', { 0x70, 0x98, 0xA8, 0xC8, 0x70 }, }, +{'1', { 0x60, 0xA0, 0x20, 0x20, 0x20 }, }, +{'2', { 0xE0, 0x10, 0x20, 0x40, 0xF8 }, }, +{'3', { 0xF0, 0x08, 0x30, 0x08, 0xF0 }, }, +{'4', { 0x90, 0x90, 0xF8, 0x10, 0x10 }, }, +{'5', { 0xF8, 0x80, 0xF0, 0x08, 0xF0 }, }, +{'6', { 0x70, 0x80, 0xF0, 0x88, 0x70 }, }, +{'7', { 0xF8, 0x08, 0x10, 0x20, 0x40 }, }, +{'8', { 0x70, 0x88, 0x70, 0x88, 0x70 }, }, +{'9', { 0x70, 0x88, 0x78, 0x08, 0x70 }, }, +{':', { 0x00, 0xC0, 0x00, 0xC0, 0x00 }, }, +{';', { 0xC0, 0x00, 0xC0, 0x40, 0x80 }, }, +{'<', { 0x08, 0x30, 0xC0, 0x30, 0x08 }, }, +{'=', { 0x00, 0xF8, 0x00, 0xF8, 0x00 }, }, +{'>', { 0x80, 0x60, 0x18, 0x60, 0x80 }, }, +{'?', { 0xE0, 0x10, 0x20, 0x00, 0x20 }, }, +{'@', { 0x70, 0x88, 0xB0, 0x80, 0x78 }, }, +{'A', { 0x70, 0x88, 0xF8, 0x88, 0x88 }, }, +{'B', { 0xF0, 0x48, 0x70, 0x48, 0xF0 }, }, +{'C', { 0x78, 0x80, 0x80, 0x80, 0x78 }, }, +{'D', { 0xF0, 0x88, 0x88, 0x88, 0xF0 }, }, +{'E', { 0xF8, 0x80, 0xE0, 0x80, 0xF8 }, }, +{'F', { 0xF8, 0x80, 0xE0, 0x80, 0x80 }, }, +{'G', { 0x78, 0x80, 0x98, 0x88, 0x78 }, }, +{'H', { 0x88, 0x88, 0xF8, 0x88, 0x88 }, }, +{'I', { 0xE0, 0x40, 0x40, 0x40, 0xE0 }, }, +{'J', { 0x08, 0x08, 0x08, 0x88, 0x70 }, }, +{'K', { 0x88, 0x90, 0xE0, 0x90, 0x88 }, }, +{'L', { 0x80, 0x80, 0x80, 0x80, 0xF8 }, }, +{'M', { 0x88, 0xD8, 0xA8, 0x88, 0x88 }, }, +{'N', { 0x88, 0xC8, 0xA8, 0x98, 0x88 }, }, +{'O', { 0x70, 0x88, 0x88, 0x88, 0x70 }, }, +{'P', { 0xF0, 0x88, 0xF0, 0x80, 0x80 }, }, +{'Q', { 0x70, 0x88, 0x88, 0xA8, 0x70 }, }, +{'R', { 0xF0, 0x88, 0xF0, 0x90, 0x88 }, }, +{'S', { 0x78, 0x80, 0x70, 0x08, 0xF0 }, }, +{'T', { 0xF8, 0x20, 0x20, 0x20, 0x20 }, }, +{'U', { 0x88, 0x88, 0x88, 0x88, 0x70 }, }, +{'V', { 0x88, 0x90, 0xA0, 0xC0, 0x80 }, }, +{'W', { 0x88, 0x88, 0xA8, 0xA8, 0x50 }, }, +{'X', { 0x88, 0x50, 0x20, 0x50, 0x88 }, }, +{'Y', { 0x88, 0x50, 0x20, 0x20, 0x20 }, }, +{'Z', { 0xF8, 0x10, 0x20, 0x40, 0xF8 }, } +}; + +// MASK for optimizing power in Waterfall ID signal + +int mask[1024] = { +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x03, 0x00, 0x01, 0x02, 0x02, 0x04, 0x04, 0x06, 0x04, +0x00, 0x01, 0x02, 0x01, 0x00, 0x01, 0x06, 0x03, 0x00, 0x01, 0x02, 0x01, 0x04, 0x05, 0x0e, 0x02, +0x00, 0x00, 0x02, 0x03, 0x04, 0x04, 0x04, 0x04, 0x00, 0x09, 0x02, 0x03, 0x04, 0x05, 0x0c, 0x01, +0x00, 0x10, 0x12, 0x13, 0x04, 0x04, 0x14, 0x04, 0x18, 0x01, 0x1a, 0x02, 0x0c, 0x05, 0x08, 0x1d, +0x00, 0x01, 0x02, 0x03, 0x04, 0x04, 0x06, 0x04, 0x00, 0x08, 0x0a, 0x03, 0x08, 0x0d, 0x08, 0x02, +0x10, 0x01, 0x12, 0x02, 0x04, 0x05, 0x06, 0x16, 0x18, 0x10, 0x1a, 0x01, 0x18, 0x05, 0x02, 0x1b, +0x20, 0x20, 0x02, 0x02, 0x04, 0x04, 0x04, 0x05, 0x28, 0x20, 0x02, 0x20, 0x08, 0x09, 0x04, 0x0d, +0x10, 0x11, 0x22, 0x02, 0x04, 0x34, 0x02, 0x27, 0x38, 0x39, 0x20, 0x21, 0x14, 0x09, 0x2e, 0x28, +0x00, 0x01, 0x02, 0x01, 0x00, 0x01, 0x04, 0x01, 0x08, 0x01, 0x08, 0x08, 0x0c, 0x04, 0x02, 0x0d, +0x10, 0x11, 0x12, 0x01, 0x10, 0x01, 0x04, 0x01, 0x10, 0x11, 0x1a, 0x01, 0x10, 0x05, 0x0e, 0x1d, +0x00, 0x21, 0x20, 0x22, 0x20, 0x25, 0x22, 0x01, 0x20, 0x09, 0x2a, 0x2a, 0x24, 0x20, 0x08, 0x09, +0x10, 0x11, 0x10, 0x33, 0x04, 0x04, 0x34, 0x13, 0x38, 0x11, 0x20, 0x19, 0x18, 0x19, 0x06, 0x0c, +0x40, 0x01, 0x40, 0x43, 0x04, 0x04, 0x40, 0x05, 0x40, 0x41, 0x42, 0x4b, 0x40, 0x4d, 0x0a, 0x41, +0x50, 0x11, 0x02, 0x12, 0x44, 0x41, 0x40, 0x41, 0x08, 0x10, 0x12, 0x53, 0x40, 0x5c, 0x16, 0x4f, +0x20, 0x61, 0x20, 0x01, 0x60, 0x25, 0x46, 0x05, 0x28, 0x28, 0x6a, 0x43, 0x40, 0x09, 0x42, 0x4c, +0x70, 0x31, 0x70, 0x33, 0x60, 0x25, 0x12, 0x50, 0x58, 0x39, 0x2a, 0x09, 0x5c, 0x60, 0x0c, 0x0d, +0x00, 0x01, 0x02, 0x02, 0x04, 0x01, 0x02, 0x06, 0x00, 0x09, 0x02, 0x08, 0x08, 0x09, 0x02, 0x0e, +0x10, 0x10, 0x12, 0x02, 0x04, 0x01, 0x04, 0x14, 0x08, 0x19, 0x08, 0x13, 0x10, 0x10, 0x0e, 0x1d, +0x20, 0x01, 0x02, 0x22, 0x20, 0x20, 0x22, 0x02, 0x28, 0x08, 0x2a, 0x29, 0x08, 0x0c, 0x0c, 0x0e, +0x10, 0x30, 0x32, 0x10, 0x14, 0x34, 0x06, 0x36, 0x28, 0x01, 0x02, 0x1a, 0x0c, 0x2d, 0x1c, 0x1d, +0x00, 0x41, 0x42, 0x41, 0x44, 0x04, 0x44, 0x06, 0x08, 0x09, 0x02, 0x41, 0x44, 0x48, 0x02, 0x06, +0x40, 0x01, 0x12, 0x12, 0x10, 0x11, 0x54, 0x13, 0x58, 0x01, 0x50, 0x5a, 0x04, 0x19, 0x12, 0x57, +0x60, 0x41, 0x40, 0x02, 0x20, 0x24, 0x02, 0x47, 0x08, 0x41, 0x08, 0x6a, 0x4c, 0x68, 0x6a, 0x47, +0x10, 0x71, 0x42, 0x43, 0x10, 0x55, 0x26, 0x50, 0x10, 0x58, 0x72, 0x28, 0x2c, 0x39, 0x1a, 0x4f, +0x80, 0x80, 0x82, 0x02, 0x04, 0x84, 0x02, 0x02, 0x88, 0x88, 0x08, 0x01, 0x08, 0x05, 0x04, 0x0d, +0x10, 0x01, 0x12, 0x90, 0x84, 0x94, 0x02, 0x90, 0x10, 0x98, 0x9a, 0x98, 0x14, 0x9c, 0x16, 0x0b, +0x20, 0x20, 0x80, 0xa3, 0x80, 0xa1, 0xa6, 0x87, 0x28, 0x29, 0xa8, 0xa8, 0x08, 0x09, 0x2a, 0x87, +0x10, 0x80, 0x82, 0x11, 0xb0, 0xa5, 0x32, 0x32, 0xb8, 0xa0, 0x2a, 0x11, 0x9c, 0x81, 0x8e, 0xa4, +0x40, 0xc0, 0xc2, 0x01, 0x40, 0xc5, 0x80, 0x05, 0xc0, 0x80, 0x4a, 0x09, 0x8c, 0x09, 0x0a, 0x09, +0x50, 0x41, 0xc0, 0x41, 0x40, 0xc0, 0x12, 0x87, 0x80, 0xc0, 0x82, 0x83, 0x9c, 0xd8, 0x98, 0x16, +0x20, 0x41, 0x82, 0x83, 0x80, 0xc0, 0x46, 0xc7, 0x48, 0xe0, 0x6a, 0x29, 0x4c, 0x29, 0xc0, 0x8e, +0x40, 0xc0, 0x50, 0x21, 0x74, 0xf4, 0x32, 0x25, 0x28, 0x98, 0x9a, 0x32, 0x74, 0x58, 0x8e, 0x83, +0x00, 0x00, 0x02, 0x01, 0x04, 0x05, 0x04, 0x06, 0x00, 0x09, 0x02, 0x02, 0x0c, 0x01, 0x06, 0x04, +0x00, 0x10, 0x12, 0x13, 0x14, 0x14, 0x12, 0x16, 0x10, 0x19, 0x12, 0x01, 0x04, 0x18, 0x16, 0x17, +0x20, 0x20, 0x22, 0x03, 0x04, 0x24, 0x24, 0x26, 0x20, 0x20, 0x20, 0x21, 0x0c, 0x2c, 0x2c, 0x24, +0x20, 0x10, 0x30, 0x20, 0x04, 0x10, 0x04, 0x31, 0x10, 0x28, 0x08, 0x33, 0x0c, 0x05, 0x0c, 0x3d, +0x40, 0x01, 0x40, 0x02, 0x04, 0x01, 0x44, 0x03, 0x40, 0x08, 0x0a, 0x08, 0x0c, 0x44, 0x4e, 0x44, +0x10, 0x50, 0x40, 0x11, 0x54, 0x14, 0x06, 0x56, 0x58, 0x49, 0x52, 0x49, 0x18, 0x4d, 0x56, 0x49, +0x20, 0x41, 0x02, 0x01, 0x44, 0x65, 0x64, 0x05, 0x20, 0x69, 0x6a, 0x23, 0x68, 0x0c, 0x0c, 0x27, +0x70, 0x50, 0x72, 0x71, 0x54, 0x54, 0x14, 0x56, 0x40, 0x21, 0x22, 0x33, 0x44, 0x79, 0x2e, 0x57, +0x00, 0x01, 0x80, 0x81, 0x84, 0x85, 0x84, 0x01, 0x88, 0x81, 0x8a, 0x8b, 0x80, 0x80, 0x02, 0x06, +0x10, 0x90, 0x12, 0x80, 0x94, 0x80, 0x80, 0x11, 0x88, 0x09, 0x90, 0x19, 0x0c, 0x11, 0x06, 0x13, +0xa0, 0x21, 0xa2, 0x21, 0xa4, 0x04, 0xa6, 0x24, 0x20, 0xa8, 0x8a, 0xa8, 0xa4, 0x85, 0x06, 0x06, +0x10, 0x20, 0xb2, 0xa0, 0x10, 0xb4, 0x12, 0xb6, 0xb8, 0xa0, 0x18, 0x81, 0x24, 0x85, 0xb6, 0x0c, +0xc0, 0xc1, 0xc0, 0x01, 0xc0, 0x44, 0x04, 0xc5, 0x08, 0xc0, 0x02, 0x0a, 0x4c, 0xc4, 0x8e, 0x03, +0x10, 0xd0, 0x82, 0x90, 0x50, 0x11, 0xd4, 0x11, 0x98, 0x88, 0x12, 0x53, 0xd4, 0x81, 0xc4, 0xd4, +0x20, 0x20, 0x62, 0xe2, 0x24, 0x85, 0xa6, 0xe5, 0x68, 0x69, 0xc0, 0xe9, 0xa0, 0xe9, 0x6c, 0x43, +0x70, 0x71, 0x60, 0xf1, 0x94, 0x31, 0xf2, 0xc5, 0xf0, 0xc9, 0x8a, 0x79, 0x18, 0x25, 0x68, 0xf6, +0x100, 0x01, 0x02, 0x100, 0x04, 0x01, 0x02, 0x05, 0x100, 0x08, 0x08, 0x100, 0x10c, 0x05, 0x04, 0x107, +0x110, 0x11, 0x110, 0x12, 0x10, 0x105, 0x100, 0x12, 0x100, 0x119, 0x0a, 0x119, 0x11c, 0x14, 0x1a, 0x10f, +0x20, 0x01, 0x02, 0x22, 0x24, 0x04, 0x24, 0x05, 0x100, 0x01, 0x120, 0x128, 0x28, 0x12c, 0x126, 0x2d, +0x110, 0x10, 0x122, 0x130, 0x104, 0x14, 0x14, 0x117, 0x100, 0x09, 0x138, 0x39, 0x0c, 0x09, 0x12e, 0x13c, +0x100, 0x40, 0x40, 0x02, 0x40, 0x141, 0x04, 0x107, 0x48, 0x108, 0x08, 0x140, 0x04, 0x140, 0x10e, 0x42, +0x50, 0x141, 0x102, 0x52, 0x150, 0x114, 0x54, 0x45, 0x10, 0x101, 0x12, 0x153, 0x54, 0x101, 0x44, 0x5a, +0x160, 0x161, 0x42, 0x101, 0x164, 0x105, 0x64, 0x65, 0x20, 0x121, 0x168, 0x10b, 0x10c, 0x10d, 0x120, 0x6a, +0x100, 0x101, 0x22, 0x103, 0x54, 0x31, 0x14, 0x33, 0x158, 0x101, 0x50, 0x72, 0x74, 0x105, 0x7a, 0x150, +0x80, 0x180, 0x82, 0x103, 0x184, 0x85, 0x100, 0x107, 0x80, 0x89, 0x8a, 0x09, 0x04, 0x101, 0x10e, 0x103, +0x180, 0x90, 0x100, 0x11, 0x194, 0x190, 0x12, 0x107, 0x118, 0x11, 0x12, 0x09, 0x14, 0x09, 0x118, 0x11c, +0x1a0, 0xa0, 0x1a2, 0x120, 0x1a4, 0x185, 0x126, 0x127, 0x1a0, 0x1a8, 0x8a, 0x123, 0x1a4, 0x18d, 0x2a, 0x22, +0x80, 0x81, 0x1b0, 0x11, 0x94, 0x1b4, 0x32, 0x25, 0x120, 0xa0, 0x28, 0x8b, 0x120, 0x39, 0x12e, 0x13c, +0x1c0, 0x1c0, 0x82, 0x41, 0x44, 0x180, 0x106, 0xc5, 0x100, 0x88, 0x180, 0x42, 0x1c4, 0xcd, 0xc4, 0x1c4, +0x90, 0x90, 0x1c0, 0x103, 0xd4, 0x180, 0x110, 0x52, 0x50, 0x49, 0x52, 0x158, 0x180, 0xd5, 0x1c4, 0x4d, +0x40, 0x101, 0x102, 0x21, 0x44, 0xc5, 0x1e4, 0xe2, 0x88, 0x1a1, 0x42, 0x22, 0x24, 0xac, 0x1a0, 0x127, +0x50, 0x41, 0x112, 0xf2, 0x180, 0xc0, 0x1d6, 0x1b0, 0x50, 0x51, 0x32, 0x160, 0x74, 0x1bc, 0x1b0, 0x16f +}; + +mfntchr idch2[] = { +{' ', { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, }, +{'!', { 0x0000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0x0000, 0x0000, 0xC000, 0xC000, 0x0000, 0x0000, 0x0000 }, }, +{'"', { 0x0000, 0xD800, 0xD800, 0xD800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, }, +{'#', { 0x0000, 0x5000, 0x5000, 0xF800, 0xF800, 0x5000, 0x5000, 0xF800, 0xF800, 0x5000, 0x5000, 0x0000, 0x0000, 0x0000 }, }, +{'$', { 0x0000, 0x2000, 0x2000, 0x7800, 0xF800, 0xA000, 0xF000, 0x7800, 0x2800, 0xF800, 0xF000, 0x2000, 0x2000, 0x0000 }, }, +{'%', { 0x0000, 0x4000, 0xE400, 0xE400, 0x4C00, 0x1800, 0x3000, 0x6000, 0xC800, 0x9C00, 0x9C00, 0x8800, 0x0000, 0x0000 }, }, +{'&', { 0x0000, 0x3000, 0x7800, 0x4800, 0x4800, 0x7000, 0xF400, 0x8C00, 0x8800, 0xFC00, 0x7400, 0x0000, 0x0000, 0x0000 }, }, +{ 39, { 0x0000, 0x4000, 0x4000, 0xC000, 0x8000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, }, +{'(', { 0x0000, 0x0000, 0x2000, 0x6000, 0xC000, 0x8000, 0x8000, 0x8000, 0x8000, 0xC000, 0x6000, 0x2000, 0x0000, 0x0000 }, }, +{')', { 0x0000, 0x0000, 0x8000, 0xC000, 0x6000, 0x2000, 0x2000, 0x2000, 0x2000, 0x6000, 0xC000, 0x8000, 0x0000, 0x0000 }, }, +{'*', { 0x0000, 0x0000, 0x0000, 0x1000, 0x1000, 0xFE00, 0x7C00, 0x3800, 0x6C00, 0x4400, 0x0000, 0x0000, 0x0000, 0x0000 }, }, +{'+', { 0x0000, 0x0000, 0x0000, 0x2000, 0x2000, 0x2000, 0xF800, 0xF800, 0x2000, 0x2000, 0x2000, 0x0000, 0x0000, 0x0000 }, }, +{',', { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xC000, 0xC000, 0xC000, 0x4000, 0xC000, 0x8000 }, }, +{'-', { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF800, 0xF800, 0x0000, 0x0000 }, }, +{'.', { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xC000, 0xC000, 0xC000, 0x0000, 0x0000 }, }, +{'/', { 0x0000, 0x0800, 0x0800, 0x1800, 0x1000, 0x3000, 0x2000, 0x6000, 0x4000, 0xC000, 0x8000, 0x8000, 0x0000, 0x0000 }, }, +{'0', { 0x0000, 0x0000, 0x7800, 0xFC00, 0x8C00, 0x9C00, 0xB400, 0xE400, 0xC400, 0x8400, 0xFC00, 0x7800, 0x0000, 0x0000 }, }, +{'1', { 0x0000, 0x0000, 0x1000, 0x3000, 0x7000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000 }, }, +{'2', { 0x0000, 0x0000, 0x7800, 0xFC00, 0x8400, 0x0C00, 0x1800, 0x3000, 0x6000, 0xC000, 0xFC00, 0xFC00, 0x0000, 0x0000 }, }, +{'3', { 0x0000, 0x0000, 0xFC00, 0xFC00, 0x0400, 0x0C00, 0x1800, 0x1C00, 0x0400, 0x8400, 0xFC00, 0x7800, 0x0000, 0x0000 }, }, +{'4', { 0x0000, 0x0000, 0x3800, 0x7800, 0x4800, 0xC800, 0x8800, 0xFC00, 0xFC00, 0x0800, 0x0800, 0x0800, 0x0000, 0x0000 }, }, +{'5', { 0x0000, 0x0000, 0xFC00, 0xFC00, 0x8000, 0x8000, 0xF800, 0xFC00, 0x0400, 0x0400, 0xFC00, 0xF800, 0x0000, 0x0000 }, }, +{'6', { 0x0000, 0x0000, 0x7800, 0xF800, 0x8000, 0x8000, 0xF800, 0xFC00, 0x8400, 0x8400, 0xFC00, 0x7800, 0x0000, 0x0000 }, }, +{'7', { 0x0000, 0x0000, 0xFC00, 0xFC00, 0x0400, 0x0400, 0x0C00, 0x1800, 0x3000, 0x2000, 0x2000, 0x2000, 0x0000, 0x0000 }, }, +{'8', { 0x0000, 0x0000, 0x7800, 0xFC00, 0x8400, 0x8400, 0x7800, 0xFC00, 0x8400, 0x8400, 0xFC00, 0x7800, 0x0000, 0x0000 }, }, +{'9', { 0x0000, 0x0000, 0x7800, 0xFC00, 0x8400, 0x8400, 0xFC00, 0x7C00, 0x0400, 0x0400, 0x7C00, 0x7800, 0x0000, 0x0000 }, }, +{':', { 0x0000, 0xC000, 0xC000, 0xC000, 0x0000, 0x0000, 0x0000, 0xC000, 0xC000, 0xC000, 0x0000, 0x0000, 0x0000, 0x0000 }, }, +{';', { 0x0000, 0x6000, 0x6000, 0x6000, 0x0000, 0x0000, 0x6000, 0x6000, 0x2000, 0x2000, 0xE000, 0xC000, 0x0000, 0x0000 }, }, +{'<', { 0x0000, 0x0000, 0x0800, 0x1800, 0x3000, 0x6000, 0xC000, 0xC000, 0x6000, 0x3000, 0x1800, 0x0800, 0x0000, 0x0000 }, }, +{'=', { 0x0000, 0x0000, 0x0000, 0x0000, 0xF800, 0xF800, 0x0000, 0x0000, 0xF800, 0xF800, 0x0000, 0x0000, 0x0000, 0x0000 }, }, +{'>', { 0x0000, 0x0000, 0x8000, 0xC000, 0x6000, 0x3000, 0x1800, 0x1800, 0x3000, 0x6000, 0xC000, 0x8000, 0x0000, 0x0000 }, }, +{'?', { 0x0000, 0x0000, 0x7000, 0xF800, 0x8800, 0x0800, 0x1800, 0x3000, 0x2000, 0x0000, 0x2000, 0x2000, 0x0000, 0x0000 }, }, +{'@', { 0x0000, 0x0000, 0x7C00, 0xFE00, 0x8200, 0x8200, 0xB200, 0xBE00, 0xBC00, 0x8000, 0xFC00, 0x7C00, 0x0000, 0x0000 }, }, +{'A', { 0x0000, 0x0000, 0x3000, 0x7800, 0xCC00, 0x8400, 0x8400, 0xFC00, 0xFC00, 0x8400, 0x8400, 0x8400, 0x0000, 0x0000 }, }, +{'B', { 0x0000, 0x0000, 0xF800, 0xFC00, 0x8400, 0x8400, 0xF800, 0xF800, 0x8400, 0x8400, 0xFC00, 0xF800, 0x0000, 0x0000 }, }, +{'C', { 0x0000, 0x0000, 0x3800, 0x7C00, 0xC400, 0x8000, 0x8000, 0x8000, 0x8000, 0xC400, 0x7C00, 0x3800, 0x0000, 0x0000 }, }, +{'D', { 0x0000, 0x0000, 0xF000, 0xF800, 0x8C00, 0x8400, 0x8400, 0x8400, 0x8400, 0x8C00, 0xF800, 0xF000, 0x0000, 0x0000 }, }, +{'E', { 0x0000, 0x0000, 0xFC00, 0xFC00, 0x8000, 0x8000, 0xF000, 0xF000, 0x8000, 0x8000, 0xFC00, 0xFC00, 0x0000, 0x0000 }, }, +{'F', { 0x0000, 0x0000, 0xFC00, 0xFC00, 0x8000, 0x8000, 0xF000, 0xF000, 0x8000, 0x8000, 0x8000, 0x8000, 0x0000, 0x0000 }, }, +{'G', { 0x0000, 0x0000, 0x3C00, 0x7C00, 0xC000, 0x8000, 0x8C00, 0x8C00, 0x8400, 0xC400, 0x7C00, 0x3800, 0x0000, 0x0000 }, }, +{'H', { 0x0000, 0x0000, 0x8400, 0x8400, 0x8400, 0x8400, 0xFC00, 0xFC00, 0x8400, 0x8400, 0x8400, 0x8400, 0x0000, 0x0000 }, }, +{'I', { 0x0000, 0x0000, 0xF800, 0xF800, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0xF800, 0xF800, 0x0000, 0x0000 }, }, +{'J', { 0x0000, 0x0000, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x8400, 0x8400, 0xFC00, 0x7800, 0x0000, 0x0000 }, }, +{'K', { 0x0000, 0x0000, 0x8400, 0x8400, 0x8C00, 0x9800, 0xF000, 0xF000, 0x9800, 0x8C00, 0x8400, 0x8400, 0x0000, 0x0000 }, }, +{'L', { 0x0000, 0x0000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0xFC00, 0xFC00, 0x0000, 0x0000 }, }, +{'M', { 0x0000, 0x0000, 0x8200, 0xC600, 0xEE00, 0xBA00, 0x9200, 0x8200, 0x8200, 0x8200, 0x8200, 0x8200, 0x0000, 0x0000 }, }, +{'N', { 0x0000, 0x0000, 0x8400, 0xC400, 0xE400, 0xB400, 0x9C00, 0x8C00, 0x8400, 0x8400, 0x8400, 0x8400, 0x0000, 0x0000 }, }, +{'O', { 0x0000, 0x0000, 0x3000, 0x7800, 0xCC00, 0x8400, 0x8400, 0x8400, 0x8400, 0xCC00, 0x7800, 0x3000, 0x0000, 0x0000 }, }, +{'P', { 0x0000, 0x0000, 0xF800, 0xFC00, 0x8400, 0x8400, 0xFC00, 0xF800, 0x8000, 0x8000, 0x8000, 0x8000, 0x0000, 0x0000 }, }, +{'Q', { 0x0000, 0x0000, 0x7800, 0xFC00, 0x8400, 0x8400, 0x8400, 0x8400, 0x9400, 0x9400, 0xFC00, 0x7800, 0x0800, 0x0800 }, }, +{'R', { 0x0000, 0x0000, 0xF800, 0xFC00, 0x8400, 0x8400, 0xFC00, 0xF800, 0x8800, 0x8C00, 0x8400, 0x8400, 0x0000, 0x0000 }, }, +{'S', { 0x0000, 0x0000, 0x7800, 0xFC00, 0x8400, 0x8000, 0xF800, 0x7C00, 0x0400, 0x8400, 0xFC00, 0x7800, 0x0000, 0x0000 }, }, +{'T', { 0x0000, 0x0000, 0xF800, 0xF800, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x0000, 0x0000 }, }, +{'U', { 0x0000, 0x0000, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0xFC00, 0x7800, 0x0000, 0x0000 }, }, +{'V', { 0x0000, 0x0000, 0x8200, 0x8200, 0x8200, 0xC600, 0x4400, 0x6C00, 0x2800, 0x3800, 0x1000, 0x1000, 0x0000, 0x0000 }, }, +{'W', { 0x0000, 0x0000, 0x8200, 0x8200, 0x8200, 0x8200, 0x8200, 0x9200, 0x9200, 0x9200, 0xFE00, 0x6C00, 0x0000, 0x0000 }, }, +{'X', { 0x0000, 0x0000, 0x8200, 0x8200, 0xC600, 0x6C00, 0x3800, 0x3800, 0x6C00, 0xC600, 0x8200, 0x8200, 0x0000, 0x0000 }, }, +{'Y', { 0x0000, 0x0000, 0x8200, 0x8200, 0xC600, 0x6C00, 0x3800, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000 }, }, +{'Z', { 0x0000, 0x0000, 0xFC00, 0xFC00, 0x0C00, 0x1800, 0x3000, 0x6000, 0xC000, 0x8000, 0xFC00, 0xFC00, 0x0000, 0x0000 }, }, +{'[', { 0x0000, 0x0000, 0xE000, 0xE000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0xE000, 0xE000, 0x0000, 0x0000 }, }, +{'\\', { 0x0000, 0x8000, 0x8000, 0xC000, 0x4000, 0x6000, 0x2000, 0x3000, 0x1000, 0x1800, 0x0800, 0x0800, 0x0000, 0x0000 }, }, +{']', { 0x0000, 0x0000, 0xE000, 0xE000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0xE000, 0xE000, 0x0000, 0x0000 }, }, +{'^', { 0x0000, 0x2000, 0x2000, 0x7000, 0x5000, 0xD800, 0x8800, 0x8800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, }, +{'_', { 0x0000, 0xF800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF800, 0x0000, 0x0000 }, }, +{'`', { 0x0000, 0xC000, 0xC000, 0xC000, 0xC000, 0x6000, 0x6000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, }, +{'a', { 0x0000, 0x0000, 0x0000, 0x0000, 0x7800, 0x7C00, 0x0400, 0x7C00, 0xFC00, 0x8400, 0xFC00, 0x7C00, 0x0000, 0x0000 }, }, +{'b', { 0x0000, 0x0000, 0x8000, 0x8000, 0xB800, 0xFC00, 0xC400, 0x8400, 0x8400, 0x8400, 0xFC00, 0xF800, 0x0000, 0x0000 }, }, +{'c', { 0x0000, 0x0000, 0x0000, 0x0000, 0x7800, 0xF800, 0x8000, 0x8000, 0x8000, 0x8000, 0xF800, 0x7800, 0x0000, 0x0000 }, }, +{'d', { 0x0000, 0x0000, 0x0400, 0x0400, 0x7400, 0xFC00, 0x8C00, 0x8400, 0x8400, 0x8400, 0xFC00, 0x7C00, 0x0000, 0x0000 }, }, +{'e', { 0x0000, 0x0000, 0x0000, 0x0000, 0x7800, 0xFC00, 0x8400, 0xFC00, 0xFC00, 0x8000, 0xF800, 0x7800, 0x0000, 0x0000 }, }, +{'f', { 0x0000, 0x0000, 0x3C00, 0x7C00, 0x4000, 0x4000, 0xF800, 0xF800, 0x4000, 0x4000, 0x4000, 0x4000, 0x0000, 0x0000 }, }, +{'g', { 0x0000, 0x0000, 0x0000, 0x7C00, 0xFC00, 0x8400, 0x8400, 0x8C00, 0xFC00, 0x7400, 0x0400, 0x7C00, 0x7800, 0x0000 }, }, +{'h', { 0x0000, 0x0000, 0x8000, 0x8000, 0xB800, 0xFC00, 0xC400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x0000, 0x0000 }, }, +{'i', { 0x0000, 0x2000, 0x2000, 0x0000, 0xE000, 0xE000, 0x2000, 0x2000, 0x2000, 0x2000, 0xF800, 0xF800, 0x0000, 0x0000 }, }, +{'j', { 0x0000, 0x0800, 0x0800, 0x0000, 0x3800, 0x3800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x8800, 0xF800, 0x7000 }, }, +{'k', { 0x0000, 0x0000, 0x8000, 0x8800, 0x9800, 0xB000, 0xE000, 0xE000, 0xB000, 0x9800, 0x8800, 0x8800, 0x0000, 0x0000 }, }, +{'l', { 0x0000, 0x0000, 0xE000, 0xE000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0xF800, 0xF800, 0x0000, 0x0000 }, }, +{'m', { 0x0000, 0x0000, 0x0000, 0x0000, 0xEC00, 0xFE00, 0x9200, 0x9200, 0x8200, 0x8200, 0x8200, 0x8200, 0x0000, 0x0000 }, }, +{'n', { 0x0000, 0x0000, 0x0000, 0x0000, 0xB800, 0xFC00, 0xC400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x0000, 0x0000 }, }, +{'o', { 0x0000, 0x0000, 0x0000, 0x0000, 0x7800, 0xFC00, 0x8400, 0x8400, 0x8400, 0x8400, 0xFC00, 0x7800, 0x0000, 0x0000 }, }, +{'p', { 0x0000, 0x0000, 0x0000, 0x0000, 0xF800, 0xFC00, 0x8400, 0x8400, 0xC400, 0xFC00, 0xB800, 0x8000, 0x8000, 0x8000 }, }, +{'q', { 0x0000, 0x0000, 0x0000, 0x0000, 0x7C00, 0xFC00, 0x8400, 0x8400, 0x8C00, 0xFC00, 0x7400, 0x0400, 0x0400, 0x0400 }, }, +{'r', { 0x0000, 0x0000, 0x0000, 0x0000, 0xB800, 0xFC00, 0xC400, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x0000, 0x0000 }, }, +{'s', { 0x0000, 0x0000, 0x0000, 0x0000, 0x7C00, 0xFC00, 0x8000, 0xF800, 0x7C00, 0x0400, 0xFC00, 0xF800, 0x0000, 0x0000 }, }, +{'t', { 0x0000, 0x0000, 0x4000, 0x4000, 0xF000, 0xF000, 0x4000, 0x4000, 0x4000, 0x4000, 0x7800, 0x3800, 0x0000, 0x0000 }, }, +{'u', { 0x0000, 0x0000, 0x0000, 0x0000, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8C00, 0xFC00, 0x7400, 0x0000, 0x0000 }, }, +{'v', { 0x0000, 0x0000, 0x0000, 0x0000, 0x8200, 0x8200, 0x8200, 0x8200, 0xC600, 0x6C00, 0x3800, 0x1000, 0x0000, 0x0000 }, }, +{'w', { 0x0000, 0x0000, 0x0000, 0x0000, 0x8200, 0x8200, 0x8200, 0x9200, 0x9200, 0x9200, 0xFE00, 0x6C00, 0x0000, 0x0000 }, }, +{'x', { 0x0000, 0x0000, 0x0000, 0x0000, 0x8200, 0xC600, 0x6C00, 0x3800, 0x3800, 0x6C00, 0xC600, 0x8200, 0x0000, 0x0000 }, }, +{'y', { 0x0000, 0x0000, 0x0000, 0x0000, 0x8400, 0x8400, 0x8400, 0x8400, 0x8C00, 0xFC00, 0x7400, 0x0400, 0x7C00, 0x7800 }, }, +{'z', { 0x0000, 0x0000, 0x0000, 0x0000, 0xFC00, 0xFC00, 0x1800, 0x3000, 0x6000, 0xC000, 0xFC00, 0xFC00, 0x0000, 0x0000 }, }, +{'{', { 0x0000, 0x2000, 0x6000, 0x4000, 0x4000, 0x4000, 0xC000, 0xC000, 0x4000, 0x4000, 0x4000, 0x6000, 0x2000, 0x0000 }, }, +{'|', { 0x0000, 0x8000, 0x8000, 0xC000, 0x4000, 0x6000, 0x2000, 0x3000, 0x1000, 0x1800, 0x0800, 0x0800, 0x0000, 0x0000 }, }, +{'}', { 0x0000, 0x8000, 0xC000, 0x4000, 0x4000, 0x4000, 0x6000, 0x6000, 0x4000, 0x4000, 0x4000, 0xC000, 0x8000, 0x0000 }, }, +{'~', { 0x0000, 0x9800, 0xFC00, 0x6400, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, } +}; + + diff --git a/src/waterfall/colorbox.cxx b/src/waterfall/colorbox.cxx index 26b6af59..f9f73eea 100644 --- a/src/waterfall/colorbox.cxx +++ b/src/waterfall/colorbox.cxx @@ -58,7 +58,7 @@ void loadPalette() palfilename = HomeDir; palfilename.append ("/fldigi.pal"); } - const char *p = file_select("Open palette", "Fldigi palette\t*.pal", palfilename.c_str()); + const char *p = FSEL::select("Open palette", "Fldigi palette\t*.pal", palfilename.c_str()); if (!p) return; if ((clrfile = fopen(p, "r")) != NULL) { for (int i = 0; i < 9; i++) { @@ -94,7 +94,7 @@ void savePalette() palfilename = HomeDir; palfilename.append ("/fldigi.pal"); } - const char *p = file_saveas("Save palette", "Fldigi palette\t*.pal", palfilename.c_str()); + const char *p = FSEL::saveas("Save palette", "Fldigi palette\t*.pal", palfilename.c_str()); if (!p) return; if ((clrfile = fopen(p, "w")) != NULL) { for (int i = 0; i < 9; i++) { diff --git a/src/waterfall/digiscope.cxx b/src/waterfall/digiscope.cxx index c3ea6849..32092fa9 100644 --- a/src/waterfall/digiscope.cxx +++ b/src/waterfall/digiscope.cxx @@ -168,6 +168,12 @@ void Digiscope::rtty(double flo, double fhi, double amp) void Digiscope::mode(scope_mode md) { + if (md == PHASE) { + if (phase_mode >= PHASE1 && phase_mode <= PHASE3) + md = phase_mode; + else + md = phase_mode = PHASE1; + } int W = w() - 4; int H = h() - 4; FL_LOCK_D(); @@ -219,7 +225,7 @@ void Digiscope::draw_phase() fl_end_line(); if (_highlight) { - if (_mode > PHASE) { + if (_mode > PHASE1) { if (pszn == psz - 1) memmove(pvecstack, pvecstack + 1, (psz - 1) * sizeof(*pvecstack)); else @@ -407,7 +413,7 @@ void Digiscope::draw() else { switch (_mode) { case SCOPE : draw_scope(); break; - case PHASE: case PHASE2: case PHASE3: draw_phase(); break; + case PHASE1: case PHASE2: case PHASE3: draw_phase(); break; case RTTY : draw_rtty(); break; // case XHAIRS : draw_crosshairs(); break; case XHAIRS : draw_xy(); break; @@ -433,11 +439,13 @@ int Digiscope::handle(int event) switch (event) { case FL_RELEASE: switch (_mode) { - case PHASE: case PHASE2: + case PHASE1: case PHASE2: _mode = (scope_mode)((int)_mode + 1); + phase_mode = _mode; break; case PHASE3: - _mode = PHASE; + _mode = PHASE1; + phase_mode = _mode; break; case RTTY: _mode = XHAIRS; diff --git a/src/widgets/FTextView.cxx b/src/widgets/FTextView.cxx index 6903c858..a0f504c4 100644 --- a/src/widgets/FTextView.cxx +++ b/src/widgets/FTextView.cxx @@ -24,6 +24,7 @@ #include #include +#include #include "FTextView.h" #include "main.h" @@ -185,17 +186,16 @@ void FTextBase::set_style(int attr, Fl_Font f, int s, Fl_Color c, int set) /// void FTextBase::readFile(void) { - const char *fn = file_select("Append text", "Text\t*.txt"); + const char *fn = FSEL::select("Append text", "Text\t*.txt"); if (fn) { -#ifdef WIN32 - string text; - ifstream tfile(fn); - char ch; - while (tfile) { - tfile.get(ch); - if (ch != '\r') text += ch; - } - tbuf->append(text.c_str()); +#ifdef __CYGWIN__ + FILE* tfile = fopen(fn, "rt"); + if (!tfile) + return; + char buf[BUFSIZ+1]; + while (fgets(buf, sizeof(buf), tfile)) + tbuf->append(buf); + fclose(tfile); #else tbuf->appendfile(fn); #endif @@ -209,9 +209,31 @@ void FTextBase::readFile(void) /// void FTextBase::saveFile(void) { - const char *fn = file_saveas("Save text as", "Text\t*.txt"); - if (fn) + const char *fn = FSEL::saveas("Save text as", "Text\t*.txt"); + if (fn) { +#ifdef __CYGWIN__ + ofstream tfile(fn); + if (!tfile) + return; + + char *p1, *p2, *text = tbuf->text(); + for (p1 = p2 = text; *p1; p1 = p2) { + while (*p2 != '\0' && *p2 != '\n') + p2++; + if (*p2 == '\n') { + *p2 = '\0'; + tfile << p1 << "\r\n"; + p2++; + + } + else + tfile << p1; + } + free(text); +#else tbuf->outputfile(fn, 0, tbuf->length()); +#endif + } } /// Returns a character string containing the selected text, if any,