Merge upstream fldigi 3.21.26

pull/2/head
Daniel Richman 2011-11-20 01:15:23 +00:00
commit a1cb30c6d4
60 zmienionych plików z 6388 dodań i 2931 usunięć

119
ChangeLog
Wyświetl plik

@ -1,7 +1,126 @@
=Version 3.21.26=
2011-11-14 David Freese <w1hkj@w1hkj.com>
77551e8: eQSL update
=Version 3.21.25=
50fa414: guard lock
2011-11-12 Remi Chateauneu <remi.chateauneu@gmail.com>
dae542e: Wefax enhancements.
e75cc0e: Use Logbook record
2011-11-12 David Freese <w1hkj@w1hkj.com>
c2ba559: eQSL
=Version 3.21.24=
16fc289: Exec macro
0859928: QRZ on-line lookup
=Version 3.21.23=
047543a: HamQTH
2ffb4a5: Auto-send
=Version 3.21.22=
2011-10-28 Pavel Milanes Costa <pavel@conas.co.cu>
b66a4d7: es.po update
2011-10-28 David Freese <w1hkj@w1hkj.com>
269ae3a: RSID defaults
1b3e852: NBEMS-FLMSG Directories
=Version 3.21.21=
3163fd2: Resize fault
=Version 3.21.20=
fba599c: RSID limit fault
c32fa63: DTMF debug
=Version 3.21.19=
7046d49: HamQTH lookup
=Version 3.21.18=
1247488: REV macro tag
9c13f6f: RTTY bandwidth
=Version 3.21.17=
4ac5f6b: MFSK soft decode
07baee2: MACRO code cleanup
4d13cb4: <EXEC>...</EXEC>
=Version 3.21.16=
3e554f8: !Queue reset
8ac0558: Timer delay
=Version 3.21.15=
d0e1c5f: Log Menu Items
cebc292: Macro Editor
960e580: WWV xmt mode
bb258cd: Inline macro tags
d2c33e4: RTTY baud
ab472e0: CW/RTTY init fault
5a9607a: Control-Z bug fix
c565815: CW QSK
405816e: Log Server lookup
2011-09-04 Remi Chateauneu <remi.chateauneu@gmail.com>
e0ee3a9: Added wefax::adjust_metric method.
261275e: modem::display_metric now sets the member modem::m
=Version 3.21.14=
2011-09-03 David Freese <w1hkj@w1hkj.com>
166fe59: DTMF decoder
49e2dd2: CW Prosign defaults
2011-08-30 Remi Chateauneu <remi.chateauneu@gmail.com>
ff18562: Macros code cleanup
2011-08-30 David Freese <w1hkj@w1hkj.com>
74364ee: DTMF class
5af9f3a: DTMF encoder
39fe31b: Wide Cursor Tracks
=Version 3.21.13=
2011-08-07 Pavel Milanes Costa <co7wt@frcuba.co.cu>
5f3c3da: Update to Spanish translation

Wyświetl plik

@ -9,7 +9,7 @@ dnl major and minor must be integers; patch may
dnl contain other characters or be empty
m4_define(FLDIGI_MAJOR, [3])
m4_define(FLDIGI_MINOR, [21])
m4_define(FLDIGI_PATCH, [.13])
m4_define(FLDIGI_PATCH, [.26])
m4_define(FLARQ_MAJOR, [4])
m4_define(FLARQ_MINOR, [3])
m4_define(FLARQ_PATCH, [.1])

2359
po/es.po

Plik diff jest za duży Load Diff

Wyświetl plik

@ -257,6 +257,7 @@ dl_fldigi_SOURCES += \
dialogs/Viewer.cxx \
dialogs/htmlstrings.cxx \
dialogs/notifydialog.cxx \
dtmf/dtmf.cxx \
thor/thor.cxx \
thor/thorvaricode.cxx \
dominoex/dominoex.cxx \
@ -274,6 +275,7 @@ dl_fldigi_SOURCES += \
include/htmlstrings.h \
include/arq_io.h \
include/confdialog.h \
include/dtmf.h \
include/FTextView.h \
include/FTextRXTX.h \
include/fileselect.h \
@ -373,6 +375,7 @@ dl_fldigi_SOURCES += \
include/rsid.h \
include/rtty.h \
include/view_rtty.h \
include/nullmodem.h \
include/rx_extract.h \
include/speak.h \
include/serial.h \
@ -502,6 +505,7 @@ dl_fldigi_SOURCES += \
ssb/ssb.cxx \
throb/throb.cxx \
trx/modem.cxx \
trx/nullmodem.cxx \
trx/trx.cxx \
waterfall/colorbox.cxx \
waterfall/digiscope.cxx \

Wyświetl plik

@ -95,6 +95,7 @@ void cw::init()
rx_init();
use_paren = progdefaults.CW_use_paren;
prosigns = progdefaults.CW_prosigns;
stopflag = false;
}
cw::~cw() {
@ -661,18 +662,23 @@ void cw::send_symbol(int bits, int len)
keydown = symlen + delta ;
keyup = symlen - delta;
kpre = (int)(progdefaults.CWpre * 8);
if (kpre > symlen) kpre = symlen;
if (progdefaults.QSK) {
kpre = (int)(progdefaults.CWpre * 8);
if (kpre > symlen) kpre = symlen;
if (progdefaults.CWnarrow) {
if (keydown - 2*knum < 0)
kpost = knum + (int)(progdefaults.CWpost * 8);
else
kpost = keydown - knum + (int)(progdefaults.CWpost * 8);
} else
kpost = keydown + (int)(progdefaults.CWpost * 8);
if (progdefaults.CWnarrow) {
if (keydown - 2*knum < 0)
kpost = knum + (int)(progdefaults.CWpost * 8);
else
kpost = keydown - knum + (int)(progdefaults.CWpost * 8);
} else
kpost = keydown + (int)(progdefaults.CWpost * 8);
if (kpost < 0) kpost = 0;
if (kpost < 0) kpost = 0;
} else {
kpre = 0;
kpost = 0;
}
if (firstelement) {
firstelement = false;

Wyświetl plik

@ -51,13 +51,13 @@ static CW_TABLE cw_table[] = {
/* Prosigns */
{'=', "<BT>", "-...-" }, // 0
{'~', "<AA>", ".-.-" }, // 1
{'%', "<AS>", ".-..." }, // 2
{'+', "<AR>", ".-.-." }, // 3
{'>', "<SK>", "...-.-" }, // 4
{'<', "<KN>", "-.--." }, // 5
{'<', "<AS>", ".-..." }, // 2
{'>', "<AR>", ".-.-." }, // 3
{'%', "<SK>", "...-.-" }, // 4
{'+', "<KN>", "-.--." }, // 5
{'&', "<INT>", "..-.-" }, // 6
{'}', "<HM>", "....--" }, // 7
{'{', "<VE>", "...-." }, // 8
{'{', "<HM>", "....--" }, // 7
{'}', "<VE>", "...-." }, // 8
/* ASCII 7bit letters */
{'A', "A", ".-" },
{'B', "B", "-..." },

Wyświetl plik

@ -125,6 +125,7 @@ void rtty::init()
bool wfrev = wf->Reverse();
bool wfsb = wf->USB();
reverse = wfrev ^ !wfsb;
stopflag = false;
if (progdefaults.StartAtSweetSpot)
set_freq(progdefaults.RTTYsweetspot);
@ -138,7 +139,10 @@ void rtty::init()
rx_init();
put_MODEstatus(mode);
snprintf(msg1, sizeof(msg1), "%-4.1f / %-4.0f", rtty_baud, rtty_shift);
if ((rtty_baud - (int)rtty_baud) == 0)
snprintf(msg1, sizeof(msg1), "%-3.0f / %-4.0f", rtty_baud, rtty_shift);
else
snprintf(msg1, sizeof(msg1), "%-4.2f / %-4.0f", rtty_baud, rtty_shift);
put_Status1(msg1);
if (progdefaults.PreferXhairScope)
set_scope_mode(Digiscope::XHAIRS);
@ -181,8 +185,9 @@ void rtty::restart()
symbollen = (int) (samplerate / rtty_baud + 0.5);
set_bandwidth(shift);
rtty_BW = 1.5 * rtty_baud;
progdefaults.RTTY_BW = rtty_BW;
if (progdefaults.RTTY_BW < rtty_baud)
progdefaults.RTTY_BW = rtty_baud;
rtty_BW = progdefaults.RTTY_BW;
sldrRTTYbandwidth->value(rtty_BW);
wf->redraw_marker();
@ -219,7 +224,10 @@ void rtty::restart()
metric = 0.0;
snprintf(msg1, sizeof(msg1), "%-4.1f / %-4.0f", rtty_baud, rtty_shift);
if ((rtty_baud - (int)rtty_baud) == 0)
snprintf(msg1, sizeof(msg1), "%-3.0f / %-4.0f", rtty_baud, rtty_shift);
else
snprintf(msg1, sizeof(msg1), "%-4.2f / %-4.0f", rtty_baud, rtty_shift);
put_Status1(msg1);
put_MODEstatus(mode);
for (int i = 0; i < 1024; i++) QI[i].re = QI[i].im = 0.0;
@ -756,9 +764,10 @@ void rtty::send_char(int c)
void rtty::send_idle()
{
if (nbits == 5)
if (nbits == 5) {
send_char(LETTERS);
else
txmode = LETTERS;
} else
send_char(0);
}
@ -769,13 +778,13 @@ int rtty::tx_process()
int c;
if (preamble > 0) {
preamble--;
send_symbol(1);
if (preamble == 0 && nbits == 5) {
for (int i = 0; i < preamble; i++)
send_symbol(1);
if (nbits == 5) {
send_char(LETTERS);
txmode = LETTERS;
}
return 0;
preamble = 0;
}
c = get_tx_char();
@ -798,16 +807,15 @@ int rtty::tx_process()
return -1;
}
// if NOT Baudot
if (nbits != 5) {
send_char(c);
return 0;
}
// send idle character if c == -1
if (c == -1) {
send_idle();
txmode = LETTERS;
return 0;
}
// if NOT Baudot
if (nbits != 5) {
send_char(c);
return 0;
}

Wyświetl plik

@ -4,6 +4,7 @@
#include "confdialog.h"
#include <config.h>
#include <FL/Fl_Tooltip.H>
#include <FL/Fl_Box.H>
#include <FL/filename.H>
#include <sstream>
#include <stdint.h>
@ -35,7 +36,7 @@ Mode_Browser* mode_browser;
void set_qrz_buttons(Fl_Button* b) {
Fl_Button* qrzb[] = { btnQRZnotavailable, btnQRZcdrom, btnQRZonline,
btnQRZsub, btnHamcall, btnHAMCALLonline,
btnCALLOOK};
btnCALLOOK, btnHamQTH};
for (size_t i = 0; i < sizeof(qrzb)/sizeof(*qrzb); i++)
qrzb[i]->value(b == qrzb[i]);
@ -881,6 +882,27 @@ progdefaults.changed = true;
};
}
Fl_Check_Button *btnUseWideTracks=(Fl_Check_Button *)0;
static void cb_btnUseWideTracks(Fl_Check_Button* o, void*) {
progdefaults.UseWideTracks = o->value();
progdefaults.changed = true;
}
Fl_Check_Button *btnUseWideCenter=(Fl_Check_Button *)0;
static void cb_btnUseWideCenter(Fl_Check_Button* o, void*) {
progdefaults.UseWideCenter = o->value();
progdefaults.changed = true;
}
Fl_Check_Button *btnUseWideCursor=(Fl_Check_Button *)0;
static void cb_btnUseWideCursor(Fl_Check_Button* o, void*) {
progdefaults.UseWideCursor = o->value();
progdefaults.changed = true;
}
Fl_Check_Button *chkShowAudioScale=(Fl_Check_Button *)0;
static void cb_chkShowAudioScale(Fl_Check_Button* o, void*) {
@ -2876,8 +2898,48 @@ static void cb_chkRxStream(Fl_Check_Button* o, void*) {
progdefaults.changed = true;
}
Fl_Group *tabDTMF=(Fl_Group *)0;
Fl_Check_Button *chkDTMFdecode=(Fl_Check_Button *)0;
static void cb_chkDTMFdecode(Fl_Check_Button* o, void*) {
progdefaults.DTMFdecode = o->value();
}
Fl_Group *tabQRZ=(Fl_Group *)0;
Fl_Round_Button *btnQRZnotavailable=(Fl_Round_Button *)0;
static void cb_btnQRZnotavailable(Fl_Round_Button* o, void*) {
set_qrz_buttons(o);
progdefaults.QRZ = QRZNONE;
progdefaults.changed = true;
}
Fl_Round_Button *btnQRZonline=(Fl_Round_Button *)0;
static void cb_btnQRZonline(Fl_Round_Button* o, void*) {
set_qrz_buttons(o);
progdefaults.QRZ = QRZHTML;
progdefaults.changed = true;
}
Fl_Round_Button *btnHAMCALLonline=(Fl_Round_Button *)0;
static void cb_btnHAMCALLonline(Fl_Round_Button* o, void*) {
set_qrz_buttons(o);
progdefaults.QRZ = HAMCALLHTML;
progdefaults.changed = true;
}
Fl_Round_Button *btnCALLOOK=(Fl_Round_Button *)0;
static void cb_btnCALLOOK(Fl_Round_Button* o, void*) {
set_qrz_buttons(o);
progdefaults.QRZ = CALLOOK;
progdefaults.changed = true;
}
Fl_Round_Button *btnQRZcdrom=(Fl_Round_Button *)0;
static void cb_btnQRZcdrom(Fl_Round_Button* o, void*) {
@ -2932,38 +2994,63 @@ inpQRZuserpassword->redraw();
o->label((inpQRZuserpassword->type() & FL_SECRET_INPUT) ? "Show" : "Hide");
}
Fl_Round_Button *btnQRZnotavailable=(Fl_Round_Button *)0;
Fl_Round_Button *btnHamQTH=(Fl_Round_Button *)0;
static void cb_btnQRZnotavailable(Fl_Round_Button* o, void*) {
static void cb_btnHamQTH(Fl_Round_Button* o, void*) {
set_qrz_buttons(o);
progdefaults.QRZ = QRZNONE;
progdefaults.QRZ = HAMQTH;
progdefaults.changed = true;
}
Fl_Round_Button *btnQRZonline=(Fl_Round_Button *)0;
Fl_Input2 *inpEQSL_id=(Fl_Input2 *)0;
static void cb_btnQRZonline(Fl_Round_Button* o, void*) {
set_qrz_buttons(o);
progdefaults.QRZ = QRZHTML;
static void cb_inpEQSL_id(Fl_Input2* o, void*) {
progdefaults.eqsl_id = o->value();
progdefaults.changed = true;
}
Fl_Round_Button *btnHAMCALLonline=(Fl_Round_Button *)0;
Fl_Input2 *inpEQSL_pwd=(Fl_Input2 *)0;
static void cb_btnHAMCALLonline(Fl_Round_Button* o, void*) {
set_qrz_buttons(o);
progdefaults.QRZ = HAMCALLHTML;
static void cb_inpEQSL_pwd(Fl_Input2* o, void*) {
progdefaults.eqsl_pwd = o->value();
progdefaults.changed = true;
}
Fl_Round_Button *btnCALLOOK=(Fl_Round_Button *)0;
Fl_Button *btnEQSL_pwd_show=(Fl_Button *)0;
static void cb_btnCALLOOK(Fl_Round_Button* o, void*) {
set_qrz_buttons(o);
progdefaults.QRZ = CALLOOK;
static void cb_btnEQSL_pwd_show(Fl_Button* o, void*) {
inpEQSL_pwd->type(inpEQSL_pwd->type() ^ FL_SECRET_INPUT);
inpEQSL_pwd->redraw();
o->label((inpEQSL_pwd->type() & FL_SECRET_INPUT) ? "Show" : "Hide");
}
Fl_Input2 *inpEQSL_nick=(Fl_Input2 *)0;
static void cb_inpEQSL_nick(Fl_Input2* o, void*) {
progdefaults.eqsl_nick = o->value();
progdefaults.changed = true;
}
Fl_Check_Button *btn_send_when_logged=(Fl_Check_Button *)0;
static void cb_btn_send_when_logged(Fl_Check_Button* o, void*) {
progdefaults.eqsl_when_logged = o->value();
progdefaults.changed = true;
}
Fl_Input2 *txt_eqsl_default_message=(Fl_Input2 *)0;
static void cb_txt_eqsl_default_message(Fl_Input2* o, void*) {
progdefaults.eqsl_default_message = o->value();
progdefaults.changed = true;
}
Fl_Box *eqsl_txt1=(Fl_Box *)0;
Fl_Box *eqsl_txt2=(Fl_Box *)0;
Fl_Box *eqsl_txt3=(Fl_Box *)0;
Fl_Group *tabDL=(Fl_Group *)0;
Fl_Tabs *tabsDL=(Fl_Tabs *)0;
@ -3944,17 +4031,17 @@ ab and newline are automatically included."));
} // Fl_Tabs* tabsUI
tabUI->end();
} // Fl_Group* tabUI
{ tabWaterfall = new Fl_Group(0, 25, 500, 347, _("Waterfall"));
{ tabWaterfall = new Fl_Group(0, 25, 501, 347, _("Waterfall"));
tabWaterfall->labelsize(12);
tabWaterfall->hide();
{ tabsWaterfall = new Fl_Tabs(0, 25, 500, 347);
{ tabsWaterfall = new Fl_Tabs(0, 25, 501, 347);
tabsWaterfall->color((Fl_Color)FL_LIGHT1);
tabsWaterfall->selection_color((Fl_Color)FL_LIGHT1);
{ Fl_Group* o = new Fl_Group(0, 50, 500, 320, _("Display"));
{ Fl_Group* o = new Fl_Group(5, 60, 490, 162, _("Colors and cursors"));
{ Fl_Group* o = new Fl_Group(0, 50, 501, 320, _("Display"));
{ Fl_Group* o = new Fl_Group(5, 60, 496, 162, _("Colors and cursors"));
o->box(FL_ENGRAVED_FRAME);
o->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE);
{ colorbox* o = WF_Palette = new colorbox(15, 98, 260, 24);
{ colorbox* o = WF_Palette = new colorbox(15, 93, 260, 24, _("aa"));
WF_Palette->box(FL_DOWN_BOX);
WF_Palette->color((Fl_Color)FL_FOREGROUND_COLOR);
WF_Palette->selection_color((Fl_Color)FL_BACKGROUND_COLOR);
@ -3968,89 +4055,107 @@ ab and newline are automatically included."));
o->label(progdefaults.PaletteName.c_str());
o->labelsize(FL_NORMAL_SIZE);
} // colorbox* WF_Palette
{ btnColor[0] = new Fl_Button(15, 128, 20, 24);
{ btnColor[0] = new Fl_Button(15, 120, 20, 24);
btnColor[0]->tooltip(_("Change color"));
btnColor[0]->callback((Fl_Callback*)cb_btnColor);
} // Fl_Button* btnColor[0]
{ btnColor[1] = new Fl_Button(45, 128, 20, 24);
{ btnColor[1] = new Fl_Button(45, 120, 20, 24);
btnColor[1]->tooltip(_("Change color"));
btnColor[1]->callback((Fl_Callback*)cb_btnColor1);
} // Fl_Button* btnColor[1]
{ btnColor[2] = new Fl_Button(75, 128, 20, 24);
{ btnColor[2] = new Fl_Button(75, 120, 20, 24);
btnColor[2]->tooltip(_("Change color"));
btnColor[2]->callback((Fl_Callback*)cb_btnColor2);
} // Fl_Button* btnColor[2]
{ btnColor[3] = new Fl_Button(105, 128, 20, 24);
{ btnColor[3] = new Fl_Button(105, 120, 20, 24);
btnColor[3]->tooltip(_("Change color"));
btnColor[3]->callback((Fl_Callback*)cb_btnColor3);
} // Fl_Button* btnColor[3]
{ btnColor[4] = new Fl_Button(135, 128, 20, 24);
{ btnColor[4] = new Fl_Button(135, 120, 20, 24);
btnColor[4]->tooltip(_("Change color"));
btnColor[4]->callback((Fl_Callback*)cb_btnColor4);
} // Fl_Button* btnColor[4]
{ btnColor[5] = new Fl_Button(165, 128, 20, 24);
{ btnColor[5] = new Fl_Button(165, 120, 20, 24);
btnColor[5]->tooltip(_("Change color"));
btnColor[5]->callback((Fl_Callback*)cb_btnColor5);
} // Fl_Button* btnColor[5]
{ btnColor[6] = new Fl_Button(195, 128, 20, 24);
{ btnColor[6] = new Fl_Button(195, 120, 20, 24);
btnColor[6]->tooltip(_("Change color"));
btnColor[6]->callback((Fl_Callback*)cb_btnColor6);
} // Fl_Button* btnColor[6]
{ btnColor[7] = new Fl_Button(225, 128, 20, 24);
{ btnColor[7] = new Fl_Button(225, 120, 20, 24);
btnColor[7]->tooltip(_("Change color"));
btnColor[7]->callback((Fl_Callback*)cb_btnColor7);
} // Fl_Button* btnColor[7]
{ btnColor[8] = new Fl_Button(256, 128, 20, 24);
{ btnColor[8] = new Fl_Button(256, 120, 20, 24);
btnColor[8]->tooltip(_("Change color"));
btnColor[8]->callback((Fl_Callback*)cb_btnColor8);
} // Fl_Button* btnColor[8]
{ btnLoadPalette = new Fl_Button(314, 96, 70, 24, _("Load..."));
{ btnLoadPalette = new Fl_Button(314, 93, 70, 24, _("Load..."));
btnLoadPalette->tooltip(_("Load a new palette"));
btnLoadPalette->callback((Fl_Callback*)cb_btnLoadPalette);
} // Fl_Button* btnLoadPalette
{ btnSavePalette = new Fl_Button(314, 128, 70, 24, _("Save..."));
{ btnSavePalette = new Fl_Button(314, 120, 70, 24, _("Save..."));
btnSavePalette->tooltip(_("Save this palette"));
btnSavePalette->callback((Fl_Callback*)cb_btnSavePalette);
} // Fl_Button* btnSavePalette
{ Fl_Check_Button* o = btnUseCursorLines = new Fl_Check_Button(15, 161, 150, 20, _("Bandwidth cursor"));
{ Fl_Check_Button* o = btnUseCursorLines = new Fl_Check_Button(15, 149, 150, 20, _("Bandwidth cursor"));
btnUseCursorLines->tooltip(_("Show cursor with bandwidth lines"));
btnUseCursorLines->down_box(FL_DOWN_BOX);
btnUseCursorLines->callback((Fl_Callback*)cb_btnUseCursorLines);
o->value(progdefaults.UseCursorLines);
} // Fl_Check_Button* btnUseCursorLines
{ Fl_Button* o = btnCursorBWcolor = new Fl_Button(15, 191, 20, 20, _("Cursor color"));
{ Fl_Button* o = btnCursorBWcolor = new Fl_Button(15, 172, 20, 20, _("Cursor color"));
btnCursorBWcolor->tooltip(_("Change color"));
btnCursorBWcolor->color((Fl_Color)3);
btnCursorBWcolor->callback((Fl_Callback*)cb_btnCursorBWcolor);
btnCursorBWcolor->align(FL_ALIGN_RIGHT);
o->color(fl_rgb_color(progdefaults.cursorLineRGBI.R,progdefaults.cursorLineRGBI.G,progdefaults.cursorLineRGBI.B));
} // Fl_Button* btnCursorBWcolor
{ Fl_Check_Button* o = btnUseCursorCenterLine = new Fl_Check_Button(185, 161, 149, 20, _("Cursor center line"));
{ Fl_Check_Button* o = btnUseCursorCenterLine = new Fl_Check_Button(185, 149, 149, 20, _("Cursor center line"));
btnUseCursorCenterLine->tooltip(_("Show cursor with center line"));
btnUseCursorCenterLine->down_box(FL_DOWN_BOX);
btnUseCursorCenterLine->callback((Fl_Callback*)cb_btnUseCursorCenterLine);
o->value(progdefaults.UseCursorCenterLine);
} // Fl_Check_Button* btnUseCursorCenterLine
{ Fl_Button* o = btnCursorCenterLineColor = new Fl_Button(185, 191, 20, 20, _("Center line color"));
{ Fl_Button* o = btnCursorCenterLineColor = new Fl_Button(185, 172, 20, 20, _("Center line color"));
btnCursorCenterLineColor->tooltip(_("Change color"));
btnCursorCenterLineColor->color((Fl_Color)FL_BACKGROUND2_COLOR);
btnCursorCenterLineColor->callback((Fl_Callback*)cb_btnCursorCenterLineColor);
btnCursorCenterLineColor->align(FL_ALIGN_RIGHT);
o->color(fl_rgb_color(progdefaults.cursorCenterRGBI.R,progdefaults.cursorCenterRGBI.G,progdefaults.cursorCenterRGBI.B));
} // Fl_Button* btnCursorCenterLineColor
{ Fl_Check_Button* o = btnUseBWTracks = new Fl_Check_Button(346, 161, 145, 20, _("Bandwidth tracks"));
{ Fl_Check_Button* o = btnUseBWTracks = new Fl_Check_Button(346, 149, 145, 20, _("Bandwidth tracks"));
btnUseBWTracks->tooltip(_("Show bandwidth tracks on waterfall"));
btnUseBWTracks->down_box(FL_DOWN_BOX);
btnUseBWTracks->callback((Fl_Callback*)cb_btnUseBWTracks);
o->value(progdefaults.UseBWTracks);
} // Fl_Check_Button* btnUseBWTracks
{ Fl_Button* o = btnBwTracksColor = new Fl_Button(346, 191, 20, 20, _("Tracks color"));
{ Fl_Button* o = btnBwTracksColor = new Fl_Button(346, 172, 20, 20, _("Tracks color"));
btnBwTracksColor->tooltip(_("Change color"));
btnBwTracksColor->color((Fl_Color)1);
btnBwTracksColor->callback((Fl_Callback*)cb_btnBwTracksColor);
btnBwTracksColor->align(FL_ALIGN_RIGHT);
o->color(fl_rgb_color(progdefaults.bwTrackRGBI.R,progdefaults.bwTrackRGBI.G,progdefaults.bwTrackRGBI.B));
} // Fl_Button* btnBwTracksColor
{ Fl_Check_Button* o = btnUseWideTracks = new Fl_Check_Button(346, 196, 145, 20, _("Wide tracks"));
btnUseWideTracks->tooltip(_("Show bandwidth tracks on waterfall"));
btnUseWideTracks->down_box(FL_DOWN_BOX);
btnUseWideTracks->callback((Fl_Callback*)cb_btnUseWideTracks);
o->value(progdefaults.UseWideTracks);
} // Fl_Check_Button* btnUseWideTracks
{ Fl_Check_Button* o = btnUseWideCenter = new Fl_Check_Button(185, 197, 145, 20, _("Wide center line"));
btnUseWideCenter->tooltip(_("Show bandwidth tracks on waterfall"));
btnUseWideCenter->down_box(FL_DOWN_BOX);
btnUseWideCenter->callback((Fl_Callback*)cb_btnUseWideCenter);
o->value(progdefaults.UseWideCenter);
} // Fl_Check_Button* btnUseWideCenter
{ Fl_Check_Button* o = btnUseWideCursor = new Fl_Check_Button(15, 195, 145, 20, _("Wide cursor"));
btnUseWideCursor->tooltip(_("Show bandwidth tracks on waterfall"));
btnUseWideCursor->down_box(FL_DOWN_BOX);
btnUseWideCursor->callback((Fl_Callback*)cb_btnUseWideCursor);
o->value(progdefaults.UseWideCursor);
} // Fl_Check_Button* btnUseWideCursor
o->end();
} // Fl_Group* o
{ Fl_Group* o = new Fl_Group(5, 222, 490, 62, _("Frequency scale"));
@ -6731,122 +6836,240 @@ d frequency"));
} // Fl_Group* o
tabText_IO->end();
} // Fl_Group* tabText_IO
{ tabDTMF = new Fl_Group(0, 50, 500, 320, _("DTMF"));
tabDTMF->hide();
{ Fl_Check_Button* o = chkDTMFdecode = new Fl_Check_Button(175, 71, 175, 20, _("Decode DTMF tones"));
chkDTMFdecode->tooltip(_("Send rx text to file: textout.txt"));
chkDTMFdecode->down_box(FL_DOWN_BOX);
chkDTMFdecode->callback((Fl_Callback*)cb_chkDTMFdecode);
o->value(progdefaults.DTMFdecode);
} // Fl_Check_Button* chkDTMFdecode
tabDTMF->end();
} // Fl_Group* tabDTMF
tabsMisc->end();
} // Fl_Tabs* tabsMisc
tabMisc->end();
} // Fl_Group* tabMisc
{ tabQRZ = new Fl_Group(0, 25, 500, 345, _("Callsign DB"));
{ tabQRZ = new Fl_Group(0, 25, 500, 345, _("Web"));
tabQRZ->tooltip(_("Callsign database"));
tabQRZ->labelsize(12);
tabQRZ->hide();
{ Fl_Group* o = new Fl_Group(5, 180, 490, 75, _("CDROM"));
o->box(FL_ENGRAVED_FRAME);
o->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE);
{ Fl_Round_Button* o = btnQRZcdrom = new Fl_Round_Button(25, 215, 70, 20, _("QRZ"));
btnQRZcdrom->tooltip(_("Use CD or hard drive CD image"));
btnQRZcdrom->down_box(FL_DOWN_BOX);
btnQRZcdrom->callback((Fl_Callback*)cb_btnQRZcdrom);
o->value(progdefaults.QRZ == QRZCD);
} // Fl_Round_Button* btnQRZcdrom
{ Fl_Input2* o = txtQRZpathname = new Fl_Input2(104, 215, 300, 20, _("at:"));
txtQRZpathname->tooltip(_("ie: /home/dave/CALLBK/ or C:/CALLBK/\nLeave blank to search for database"));
txtQRZpathname->box(FL_DOWN_BOX);
txtQRZpathname->color((Fl_Color)FL_BACKGROUND2_COLOR);
txtQRZpathname->selection_color((Fl_Color)FL_SELECTION_COLOR);
txtQRZpathname->labeltype(FL_NORMAL_LABEL);
txtQRZpathname->labelfont(0);
txtQRZpathname->labelsize(14);
txtQRZpathname->labelcolor((Fl_Color)FL_FOREGROUND_COLOR);
txtQRZpathname->callback((Fl_Callback*)cb_txtQRZpathname);
txtQRZpathname->align(FL_ALIGN_LEFT);
txtQRZpathname->when(FL_WHEN_RELEASE);
o->value(progdefaults.QRZpathname.c_str());
txtQRZpathname->labelsize(FL_NORMAL_SIZE);
} // Fl_Input2* txtQRZpathname
{ Fl_Tabs* o = new Fl_Tabs(0, 25, 500, 345);
{ Fl_Group* o = new Fl_Group(0, 46, 500, 324, _("QRZ/etal"));
{ Fl_Group* o = new Fl_Group(5, 55, 490, 120);
o->box(FL_ENGRAVED_FRAME);
o->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE);
{ Fl_Round_Button* o = btnQRZnotavailable = new Fl_Round_Button(25, 64, 337, 20, _("Not available"));
btnQRZnotavailable->tooltip(_("Do not use callsign database"));
btnQRZnotavailable->down_box(FL_DOWN_BOX);
btnQRZnotavailable->value(1);
btnQRZnotavailable->callback((Fl_Callback*)cb_btnQRZnotavailable);
o->value(progdefaults.QRZ == QRZNONE);
} // Fl_Round_Button* btnQRZnotavailable
{ Fl_Round_Button* o = btnQRZonline = new Fl_Round_Button(25, 92, 337, 20, _("QRZ online via default Internet Browser"));
btnQRZonline->tooltip(_("Visit QRZ web site"));
btnQRZonline->down_box(FL_DOWN_BOX);
btnQRZonline->callback((Fl_Callback*)cb_btnQRZonline);
o->value(progdefaults.QRZ == QRZHTML);
} // Fl_Round_Button* btnQRZonline
{ Fl_Round_Button* o = btnHAMCALLonline = new Fl_Round_Button(25, 120, 337, 20, _("HamCall online via default Internet Browser"));
btnHAMCALLonline->tooltip(_("Visit Hamcall web site"));
btnHAMCALLonline->down_box(FL_DOWN_BOX);
btnHAMCALLonline->callback((Fl_Callback*)cb_btnHAMCALLonline);
o->value(progdefaults.QRZ == HAMCALLHTML);
} // Fl_Round_Button* btnHAMCALLonline
{ Fl_Round_Button* o = btnCALLOOK = new Fl_Round_Button(25, 148, 337, 20, _("Callook.info lookup (US callsigns only)"));
btnCALLOOK->tooltip(_("Visit Hamcall web site"));
btnCALLOOK->down_box(FL_DOWN_BOX);
btnCALLOOK->callback((Fl_Callback*)cb_btnCALLOOK);
o->value(progdefaults.QRZ == CALLOOK);
} // Fl_Round_Button* btnCALLOOK
o->end();
} // Fl_Group* o
{ Fl_Group* o = new Fl_Group(5, 176, 490, 55, _("CDROM"));
o->box(FL_ENGRAVED_FRAME);
o->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE);
{ Fl_Round_Button* o = btnQRZcdrom = new Fl_Round_Button(25, 196, 70, 20, _("QRZ"));
btnQRZcdrom->tooltip(_("Use CD or hard drive CD image"));
btnQRZcdrom->down_box(FL_DOWN_BOX);
btnQRZcdrom->callback((Fl_Callback*)cb_btnQRZcdrom);
o->value(progdefaults.QRZ == QRZCD);
} // Fl_Round_Button* btnQRZcdrom
{ Fl_Input2* o = txtQRZpathname = new Fl_Input2(104, 196, 300, 20, _("at:"));
txtQRZpathname->tooltip(_("ie: /home/dave/CALLBK/ or C:/CALLBK/\nLeave blank to search for database"));
txtQRZpathname->box(FL_DOWN_BOX);
txtQRZpathname->color((Fl_Color)FL_BACKGROUND2_COLOR);
txtQRZpathname->selection_color((Fl_Color)FL_SELECTION_COLOR);
txtQRZpathname->labeltype(FL_NORMAL_LABEL);
txtQRZpathname->labelfont(0);
txtQRZpathname->labelsize(14);
txtQRZpathname->labelcolor((Fl_Color)FL_FOREGROUND_COLOR);
txtQRZpathname->callback((Fl_Callback*)cb_txtQRZpathname);
txtQRZpathname->align(FL_ALIGN_LEFT);
txtQRZpathname->when(FL_WHEN_RELEASE);
o->value(progdefaults.QRZpathname.c_str());
txtQRZpathname->labelsize(FL_NORMAL_SIZE);
} // Fl_Input2* txtQRZpathname
o->end();
} // Fl_Group* o
{ Fl_Group* o = new Fl_Group(5, 232, 490, 134, _("Subscriber data"));
o->box(FL_ENGRAVED_FRAME);
o->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE);
{ Fl_Round_Button* o = btnQRZsub = new Fl_Round_Button(25, 263, 90, 20, _("QRZ.com"));
btnQRZsub->tooltip(_("You need a paid QRZ online\nsubscription to access"));
btnQRZsub->down_box(FL_DOWN_BOX);
btnQRZsub->callback((Fl_Callback*)cb_btnQRZsub);
o->value(progdefaults.QRZ == QRZNET);
} // Fl_Round_Button* btnQRZsub
{ Fl_Round_Button* o = btnHamcall = new Fl_Round_Button(25, 297, 105, 20, _("Hamcall.net"));
btnHamcall->tooltip(_("You need a paid Hamcall online\nsubscription to access"));
btnHamcall->down_box(FL_DOWN_BOX);
btnHamcall->callback((Fl_Callback*)cb_btnHamcall);
o->value(progdefaults.QRZ == HAMCALLNET);
} // Fl_Round_Button* btnHamcall
{ Fl_Input2* o = inpQRZusername = new Fl_Input2(235, 263, 150, 20, _("User name"));
inpQRZusername->tooltip(_("Your login name"));
inpQRZusername->box(FL_DOWN_BOX);
inpQRZusername->color((Fl_Color)FL_BACKGROUND2_COLOR);
inpQRZusername->selection_color((Fl_Color)FL_SELECTION_COLOR);
inpQRZusername->labeltype(FL_NORMAL_LABEL);
inpQRZusername->labelfont(0);
inpQRZusername->labelsize(14);
inpQRZusername->labelcolor((Fl_Color)FL_FOREGROUND_COLOR);
inpQRZusername->callback((Fl_Callback*)cb_inpQRZusername);
inpQRZusername->align(FL_ALIGN_LEFT);
inpQRZusername->when(FL_WHEN_RELEASE);
o->value(progdefaults.QRZusername.c_str());
inpQRZusername->labelsize(FL_NORMAL_SIZE);
} // Fl_Input2* inpQRZusername
{ Fl_Input2* o = inpQRZuserpassword = new Fl_Input2(235, 297, 150, 20, _("Password"));
inpQRZuserpassword->tooltip(_("Your login password"));
inpQRZuserpassword->box(FL_DOWN_BOX);
inpQRZuserpassword->color((Fl_Color)FL_BACKGROUND2_COLOR);
inpQRZuserpassword->selection_color((Fl_Color)FL_SELECTION_COLOR);
inpQRZuserpassword->labeltype(FL_NORMAL_LABEL);
inpQRZuserpassword->labelfont(0);
inpQRZuserpassword->labelsize(14);
inpQRZuserpassword->labelcolor((Fl_Color)FL_FOREGROUND_COLOR);
inpQRZuserpassword->callback((Fl_Callback*)cb_inpQRZuserpassword);
inpQRZuserpassword->align(FL_ALIGN_LEFT);
inpQRZuserpassword->when(FL_WHEN_RELEASE);
o->value(progdefaults.QRZuserpassword.c_str());
o->type(FL_SECRET_INPUT);
inpQRZuserpassword->labelsize(FL_NORMAL_SIZE);
} // Fl_Input2* inpQRZuserpassword
{ btnQRZpasswordShow = new Fl_Button(395, 297, 70, 20, _("Show"));
btnQRZpasswordShow->tooltip(_("Show password in plain text"));
btnQRZpasswordShow->callback((Fl_Callback*)cb_btnQRZpasswordShow);
} // Fl_Button* btnQRZpasswordShow
{ Fl_Round_Button* o = btnHamQTH = new Fl_Round_Button(26, 332, 121, 20, _("HamQTH.com (free service http://www.hamqth.com)"));
btnHamQTH->tooltip(_("You need a paid Hamcall online\nsubscription to access"));
btnHamQTH->down_box(FL_DOWN_BOX);
btnHamQTH->callback((Fl_Callback*)cb_btnHamQTH);
o->value(progdefaults.QRZ == HAMQTH);
} // Fl_Round_Button* btnHamQTH
o->end();
} // Fl_Group* o
o->end();
} // Fl_Group* o
{ Fl_Group* o = new Fl_Group(0, 50, 500, 320, _("eQSL"));
o->hide();
{ Fl_Input2* o = inpEQSL_id = new Fl_Input2(176, 75, 150, 20, _("User ID"));
inpEQSL_id->tooltip(_("Your login name"));
inpEQSL_id->box(FL_DOWN_BOX);
inpEQSL_id->color((Fl_Color)FL_BACKGROUND2_COLOR);
inpEQSL_id->selection_color((Fl_Color)FL_SELECTION_COLOR);
inpEQSL_id->labeltype(FL_NORMAL_LABEL);
inpEQSL_id->labelfont(0);
inpEQSL_id->labelsize(14);
inpEQSL_id->labelcolor((Fl_Color)FL_FOREGROUND_COLOR);
inpEQSL_id->callback((Fl_Callback*)cb_inpEQSL_id);
inpEQSL_id->align(FL_ALIGN_LEFT);
inpEQSL_id->when(FL_WHEN_RELEASE);
o->value(progdefaults.eqsl_id.c_str());
inpEQSL_id->labelsize(FL_NORMAL_SIZE);
} // Fl_Input2* inpEQSL_id
{ Fl_Input2* o = inpEQSL_pwd = new Fl_Input2(176, 106, 150, 20, _("Password"));
inpEQSL_pwd->tooltip(_("Your login password"));
inpEQSL_pwd->box(FL_DOWN_BOX);
inpEQSL_pwd->color((Fl_Color)FL_BACKGROUND2_COLOR);
inpEQSL_pwd->selection_color((Fl_Color)FL_SELECTION_COLOR);
inpEQSL_pwd->labeltype(FL_NORMAL_LABEL);
inpEQSL_pwd->labelfont(0);
inpEQSL_pwd->labelsize(14);
inpEQSL_pwd->labelcolor((Fl_Color)FL_FOREGROUND_COLOR);
inpEQSL_pwd->callback((Fl_Callback*)cb_inpEQSL_pwd);
inpEQSL_pwd->align(FL_ALIGN_LEFT);
inpEQSL_pwd->when(FL_WHEN_RELEASE);
o->value(progdefaults.eqsl_pwd.c_str());
o->type(FL_SECRET_INPUT);
inpEQSL_pwd->labelsize(FL_NORMAL_SIZE);
} // Fl_Input2* inpEQSL_pwd
{ btnEQSL_pwd_show = new Fl_Button(344, 106, 70, 20, _("Show"));
btnEQSL_pwd_show->tooltip(_("Show password in plain text"));
btnEQSL_pwd_show->callback((Fl_Callback*)cb_btnEQSL_pwd_show);
} // Fl_Button* btnEQSL_pwd_show
{ Fl_Input2* o = inpEQSL_nick = new Fl_Input2(176, 137, 150, 20, _("QTH Nickname"));
inpEQSL_nick->tooltip(_("Your login name"));
inpEQSL_nick->box(FL_DOWN_BOX);
inpEQSL_nick->color((Fl_Color)FL_BACKGROUND2_COLOR);
inpEQSL_nick->selection_color((Fl_Color)FL_SELECTION_COLOR);
inpEQSL_nick->labeltype(FL_NORMAL_LABEL);
inpEQSL_nick->labelfont(0);
inpEQSL_nick->labelsize(14);
inpEQSL_nick->labelcolor((Fl_Color)FL_FOREGROUND_COLOR);
inpEQSL_nick->callback((Fl_Callback*)cb_inpEQSL_nick);
inpEQSL_nick->align(FL_ALIGN_LEFT);
inpEQSL_nick->when(FL_WHEN_RELEASE);
o->value(progdefaults.eqsl_nick.c_str());
inpEQSL_nick->labelsize(FL_NORMAL_SIZE);
} // Fl_Input2* inpEQSL_nick
{ Fl_Group* o = new Fl_Group(4, 170, 492, 194, _("Options"));
o->box(FL_ENGRAVED_FRAME);
o->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE);
{ Fl_Check_Button* o = btn_send_when_logged = new Fl_Check_Button(29, 191, 70, 15, _("send when logged (log button, <LOG>, <LNW>)"));
btn_send_when_logged->tooltip(_("eQSL upload when record logged"));
btn_send_when_logged->down_box(FL_DOWN_BOX);
btn_send_when_logged->callback((Fl_Callback*)cb_btn_send_when_logged);
o->value(progdefaults.eqsl_when_logged);
} // Fl_Check_Button* btn_send_when_logged
{ Fl_Input2* o = txt_eqsl_default_message = new Fl_Input2(33, 226, 451, 40, _("Default message"));
txt_eqsl_default_message->tooltip(_("Default message sent with eQSL"));
txt_eqsl_default_message->type(4);
txt_eqsl_default_message->box(FL_DOWN_BOX);
txt_eqsl_default_message->color((Fl_Color)FL_BACKGROUND2_COLOR);
txt_eqsl_default_message->selection_color((Fl_Color)FL_SELECTION_COLOR);
txt_eqsl_default_message->labeltype(FL_NORMAL_LABEL);
txt_eqsl_default_message->labelfont(0);
txt_eqsl_default_message->labelsize(14);
txt_eqsl_default_message->labelcolor((Fl_Color)FL_FOREGROUND_COLOR);
txt_eqsl_default_message->callback((Fl_Callback*)cb_txt_eqsl_default_message);
txt_eqsl_default_message->align(FL_ALIGN_TOP_LEFT);
txt_eqsl_default_message->when(FL_WHEN_CHANGED);
o->value(progdefaults.eqsl_default_message.c_str());
} // Fl_Input2* txt_eqsl_default_message
{ Fl_Group* o = new Fl_Group(8, 270, 484, 90, _("Text Tags (tags use {} delimiters)"));
o->box(FL_THIN_DOWN_BOX);
o->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE);
{ eqsl_txt1 = new Fl_Box(14, 317, 220, 17, _("{CALL} other ops call sign"));
eqsl_txt1->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
} // Fl_Box* eqsl_txt1
{ eqsl_txt2 = new Fl_Box(12, 336, 220, 17, _("{MODE} full mode / submode"));
eqsl_txt2->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
} // Fl_Box* eqsl_txt2
{ eqsl_txt3 = new Fl_Box(260, 317, 220, 17, _("{NAME} other ops name"));
eqsl_txt3->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
} // Fl_Box* eqsl_txt3
{ new Fl_Box(28, 293, 440, 17, _("These tags can also be used in <EQSL:[message]>"));
} // Fl_Box* o
o->end();
} // Fl_Group* o
o->end();
} // Fl_Group* o
o->end();
} // Fl_Group* o
o->end();
} // Fl_Group* o
{ Fl_Group* o = new Fl_Group(5, 260, 490, 95, _("Paid online subscription"));
o->box(FL_ENGRAVED_FRAME);
o->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE);
{ Fl_Round_Button* o = btnQRZsub = new Fl_Round_Button(25, 291, 90, 20, _("QRZ.com"));
btnQRZsub->tooltip(_("You need a paid QRZ online\nsubscription to access"));
btnQRZsub->down_box(FL_DOWN_BOX);
btnQRZsub->callback((Fl_Callback*)cb_btnQRZsub);
o->value(progdefaults.QRZ == QRZNET);
} // Fl_Round_Button* btnQRZsub
{ Fl_Round_Button* o = btnHamcall = new Fl_Round_Button(25, 321, 105, 20, _("Hamcall.net"));
btnHamcall->tooltip(_("You need a paid Hamcall online\nsubscription to access"));
btnHamcall->down_box(FL_DOWN_BOX);
btnHamcall->callback((Fl_Callback*)cb_btnHamcall);
o->value(progdefaults.QRZ == HAMCALLNET);
} // Fl_Round_Button* btnHamcall
{ Fl_Input2* o = inpQRZusername = new Fl_Input2(235, 291, 90, 20, _("User name"));
inpQRZusername->tooltip(_("Your login name"));
inpQRZusername->box(FL_DOWN_BOX);
inpQRZusername->color((Fl_Color)FL_BACKGROUND2_COLOR);
inpQRZusername->selection_color((Fl_Color)FL_SELECTION_COLOR);
inpQRZusername->labeltype(FL_NORMAL_LABEL);
inpQRZusername->labelfont(0);
inpQRZusername->labelsize(14);
inpQRZusername->labelcolor((Fl_Color)FL_FOREGROUND_COLOR);
inpQRZusername->callback((Fl_Callback*)cb_inpQRZusername);
inpQRZusername->align(FL_ALIGN_LEFT);
inpQRZusername->when(FL_WHEN_RELEASE);
o->value(progdefaults.QRZusername.c_str());
inpQRZusername->labelsize(FL_NORMAL_SIZE);
} // Fl_Input2* inpQRZusername
{ Fl_Input2* o = inpQRZuserpassword = new Fl_Input2(236, 321, 90, 20, _("Password"));
inpQRZuserpassword->tooltip(_("Your login password"));
inpQRZuserpassword->box(FL_DOWN_BOX);
inpQRZuserpassword->color((Fl_Color)FL_BACKGROUND2_COLOR);
inpQRZuserpassword->selection_color((Fl_Color)FL_SELECTION_COLOR);
inpQRZuserpassword->labeltype(FL_NORMAL_LABEL);
inpQRZuserpassword->labelfont(0);
inpQRZuserpassword->labelsize(14);
inpQRZuserpassword->labelcolor((Fl_Color)FL_FOREGROUND_COLOR);
inpQRZuserpassword->callback((Fl_Callback*)cb_inpQRZuserpassword);
inpQRZuserpassword->align(FL_ALIGN_LEFT);
inpQRZuserpassword->when(FL_WHEN_RELEASE);
o->value(progdefaults.QRZuserpassword.c_str());
o->type(FL_SECRET_INPUT);
inpQRZuserpassword->labelsize(FL_NORMAL_SIZE);
} // Fl_Input2* inpQRZuserpassword
{ btnQRZpasswordShow = new Fl_Button(336, 321, 70, 20, _("Show"));
btnQRZpasswordShow->tooltip(_("Show password in plain text"));
btnQRZpasswordShow->callback((Fl_Callback*)cb_btnQRZpasswordShow);
} // Fl_Button* btnQRZpasswordShow
o->end();
} // Fl_Group* o
{ Fl_Group* o = new Fl_Group(5, 35, 490, 140);
o->box(FL_ENGRAVED_FRAME);
o->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE);
{ Fl_Round_Button* o = btnQRZnotavailable = new Fl_Round_Button(25, 45, 337, 20, _("Not available"));
btnQRZnotavailable->tooltip(_("Do not use callsign database"));
btnQRZnotavailable->down_box(FL_DOWN_BOX);
btnQRZnotavailable->value(1);
btnQRZnotavailable->callback((Fl_Callback*)cb_btnQRZnotavailable);
o->value(progdefaults.QRZ == QRZNONE);
} // Fl_Round_Button* btnQRZnotavailable
{ Fl_Round_Button* o = btnQRZonline = new Fl_Round_Button(25, 75, 337, 20, _("QRZ online via default Internet Browser"));
btnQRZonline->tooltip(_("Visit QRZ web site"));
btnQRZonline->down_box(FL_DOWN_BOX);
btnQRZonline->callback((Fl_Callback*)cb_btnQRZonline);
o->value(progdefaults.QRZ == QRZHTML);
} // Fl_Round_Button* btnQRZonline
{ Fl_Round_Button* o = btnHAMCALLonline = new Fl_Round_Button(25, 106, 337, 20, _("HamCall online via default Internet Browser"));
btnHAMCALLonline->tooltip(_("Visit Hamcall web site"));
btnHAMCALLonline->down_box(FL_DOWN_BOX);
btnHAMCALLonline->callback((Fl_Callback*)cb_btnHAMCALLonline);
o->value(progdefaults.QRZ == HAMCALLHTML);
} // Fl_Round_Button* btnHAMCALLonline
{ Fl_Round_Button* o = btnCALLOOK = new Fl_Round_Button(25, 137, 337, 20, _("Callook.info lookup (US callsigns only)"));
btnCALLOOK->tooltip(_("Visit Hamcall web site"));
btnCALLOOK->down_box(FL_DOWN_BOX);
btnCALLOOK->callback((Fl_Callback*)cb_btnCALLOOK);
o->value(progdefaults.QRZ == CALLOOK);
} // Fl_Round_Button* btnCALLOOK
o->end();
} // Fl_Group* o
} // Fl_Tabs* o
tabQRZ->end();
} // Fl_Group* tabQRZ
{ tabDL = new Fl_Group(0, 25, 500, 350, _("DL Client"));

Wyświetl plik

@ -9,6 +9,8 @@ decl {\#include <config.h>} {}
decl {\#include <FL/Fl_Tooltip.H>} {}
decl {\#include <FL/Fl_Box.H>} {}
decl {\#include <FL/filename.H>} {}
decl {\#include <sstream>} {}
@ -89,7 +91,7 @@ Function {set_qrz_buttons(Fl_Button* b)} {open return_type void
} {
code {Fl_Button* qrzb[] = { btnQRZnotavailable, btnQRZcdrom, btnQRZonline,
btnQRZsub, btnHamcall, btnHAMCALLonline,
btnCALLOOK};
btnCALLOOK, btnHamQTH};
for (size_t i = 0; i < sizeof(qrzb)/sizeof(*qrzb); i++)
qrzb[i]->value(b == qrzb[i]);} {}
@ -111,14 +113,14 @@ static const char szProsigns[] = "~|%|&|+|=|{|}|<|>|[|]| ";} {}
code {static const int flight_browser_columns[] = { 170, 150, 170 };} {}
Fl_Window {} {
label {Fldigi configuration} open
xywh {644 190 500 400} type Double color 45 selection_color 51 labelsize 18 align 80 non_modal visible
xywh {592 125 500 400} type Double color 45 selection_color 51 labelsize 18 align 80 non_modal visible
} {
Fl_Tabs tabsConfigure {open
xywh {-4 0 521 372} color 50 selection_color 50
} {
Fl_Group tabOperator {
label Operator
callback {progdefaults.changed = true;}
callback {progdefaults.changed = true;} open selected
tooltip {Operator information} xywh {0 25 500 345} labelsize 12 when 1
} {
Fl_Group {} {
@ -216,7 +218,7 @@ btnApplyConfig->activate();}
}
}
Fl_Group tabUI {
label UI open
label UI
xywh {0 25 502 346} labelsize 12 hide
} {
Fl_Tabs tabsUI {open
@ -935,22 +937,23 @@ connect_to_log_server();}
}
Fl_Group tabWaterfall {
label Waterfall
xywh {0 25 500 347} labelsize 12 hide
xywh {0 25 501 347} labelsize 12 hide
} {
Fl_Tabs tabsWaterfall {open
xywh {0 25 500 347} color 50 selection_color 50
xywh {0 25 501 347} color 50 selection_color 50
} {
Fl_Group {} {
label Display open
xywh {0 50 500 320}
xywh {0 50 501 320}
} {
Fl_Group {} {
label {Colors and cursors} open
xywh {5 60 490 162} box ENGRAVED_FRAME align 21
xywh {5 60 496 162} box ENGRAVED_FRAME align 21
} {
Fl_Button WF_Palette {
label aa
callback {progdefaults.changed = true;}
xywh {15 98 260 24} box DOWN_BOX color 0 labelsize 12 align 5
xywh {15 93 260 24} box DOWN_BOX color 0 labelsize 12 align 5
code0 {\#include "colorbox.h"}
code1 {o->label(progdefaults.PaletteName.c_str());}
code2 {o->labelsize(FL_NORMAL_SIZE);}
@ -959,59 +962,59 @@ connect_to_log_server();}
Fl_Button {btnColor[0]} {
callback {selectColor(0);
progdefaults.changed = true;}
tooltip {Change color} xywh {15 128 20 24}
tooltip {Change color} xywh {15 120 20 24}
}
Fl_Button {btnColor[1]} {
callback {selectColor(1);
progdefaults.changed = true;}
tooltip {Change color} xywh {45 128 20 24}
tooltip {Change color} xywh {45 120 20 24}
}
Fl_Button {btnColor[2]} {
callback {selectColor(2);
progdefaults.changed = true;}
tooltip {Change color} xywh {75 128 20 24}
tooltip {Change color} xywh {75 120 20 24}
}
Fl_Button {btnColor[3]} {
callback {selectColor(3);
progdefaults.changed = true;}
tooltip {Change color} xywh {105 128 20 24}
tooltip {Change color} xywh {105 120 20 24}
}
Fl_Button {btnColor[4]} {
callback {selectColor(4);
progdefaults.changed = true;}
tooltip {Change color} xywh {135 128 20 24}
tooltip {Change color} xywh {135 120 20 24}
}
Fl_Button {btnColor[5]} {
callback {selectColor(5);
progdefaults.changed = true;}
tooltip {Change color} xywh {165 128 20 24}
tooltip {Change color} xywh {165 120 20 24}
}
Fl_Button {btnColor[6]} {
callback {selectColor(6);
progdefaults.changed = true;}
tooltip {Change color} xywh {195 128 20 24}
tooltip {Change color} xywh {195 120 20 24}
}
Fl_Button {btnColor[7]} {
callback {selectColor(7);
progdefaults.changed = true;}
tooltip {Change color} xywh {225 128 20 24}
tooltip {Change color} xywh {225 120 20 24}
}
Fl_Button {btnColor[8]} {
callback {selectColor(8);
progdefaults.changed = true;}
tooltip {Change color} xywh {256 128 20 24}
tooltip {Change color} xywh {256 120 20 24}
}
Fl_Button btnLoadPalette {
label {Load...}
callback {loadPalette();
progdefaults.changed = true;}
tooltip {Load a new palette} xywh {314 96 70 24}
tooltip {Load a new palette} xywh {314 93 70 24}
code0 {\#include "colorbox.h"}
}
Fl_Button btnSavePalette {
label {Save...}
callback {savePalette();}
tooltip {Save this palette} xywh {314 128 70 24}
tooltip {Save this palette} xywh {314 120 70 24}
code0 {\#include "colorbox.h"}
}
Fl_Check_Button btnUseCursorLines {
@ -1022,7 +1025,7 @@ if (o->value())
else
btnCursorBWcolor->deactivate();
progdefaults.changed = true;}
tooltip {Show cursor with bandwidth lines} xywh {15 161 150 20} down_box DOWN_BOX
tooltip {Show cursor with bandwidth lines} xywh {15 149 150 20} down_box DOWN_BOX
code0 {o->value(progdefaults.UseCursorLines);}
}
Fl_Button btnCursorBWcolor {
@ -1035,7 +1038,7 @@ o->color(fl_rgb_color(progdefaults.cursorLineRGBI.R,progdefaults.cursorLineRGBI.
o->redraw();
progdefaults.changed = true;
}}
tooltip {Change color} xywh {15 191 20 20} color 3 align 8
tooltip {Change color} xywh {15 172 20 20} color 3 align 8
code0 {\#include <FL/Fl_Color_Chooser.H>}
code1 {o->color(fl_rgb_color(progdefaults.cursorLineRGBI.R,progdefaults.cursorLineRGBI.G,progdefaults.cursorLineRGBI.B));}
}
@ -1043,7 +1046,7 @@ progdefaults.changed = true;
label {Cursor center line}
callback {progdefaults.UseCursorCenterLine = o->value();
progdefaults.changed = true;}
tooltip {Show cursor with center line} xywh {185 161 149 20} down_box DOWN_BOX
tooltip {Show cursor with center line} xywh {185 149 149 20} down_box DOWN_BOX
code0 {o->value(progdefaults.UseCursorCenterLine);}
}
Fl_Button btnCursorCenterLineColor {
@ -1056,14 +1059,14 @@ o->color(fl_rgb_color(progdefaults.cursorCenterRGBI.R,progdefaults.cursorCenterR
o->redraw();
progdefaults.changed = true;
}}
tooltip {Change color} xywh {185 191 20 20} color 7 align 8
tooltip {Change color} xywh {185 172 20 20} color 7 align 8
code0 {o->color(fl_rgb_color(progdefaults.cursorCenterRGBI.R,progdefaults.cursorCenterRGBI.G,progdefaults.cursorCenterRGBI.B));}
}
Fl_Check_Button btnUseBWTracks {
label {Bandwidth tracks}
callback {progdefaults.UseBWTracks = o->value();
progdefaults.changed = true;}
tooltip {Show bandwidth tracks on waterfall} xywh {346 161 145 20} down_box DOWN_BOX
tooltip {Show bandwidth tracks on waterfall} xywh {346 149 145 20} down_box DOWN_BOX
code0 {o->value(progdefaults.UseBWTracks);}
}
Fl_Button btnBwTracksColor {
@ -1077,9 +1080,30 @@ o->redraw();
wf->redraw_marker();
progdefaults.changed = true;
}}
tooltip {Change color} xywh {346 191 20 20} color 1 align 8
tooltip {Change color} xywh {346 172 20 20} color 1 align 8
code0 {o->color(fl_rgb_color(progdefaults.bwTrackRGBI.R,progdefaults.bwTrackRGBI.G,progdefaults.bwTrackRGBI.B));}
}
Fl_Check_Button btnUseWideTracks {
label {Wide tracks}
callback {progdefaults.UseWideTracks = o->value();
progdefaults.changed = true;}
tooltip {Show bandwidth tracks on waterfall} xywh {346 196 145 20} down_box DOWN_BOX
code0 {o->value(progdefaults.UseWideTracks);}
}
Fl_Check_Button btnUseWideCenter {
label {Wide center line}
callback {progdefaults.UseWideCenter = o->value();
progdefaults.changed = true;}
tooltip {Show bandwidth tracks on waterfall} xywh {185 197 145 20} down_box DOWN_BOX
code0 {o->value(progdefaults.UseWideCenter);}
}
Fl_Check_Button btnUseWideCursor {
label {Wide cursor}
callback {progdefaults.UseWideCursor = o->value();
progdefaults.changed = true;}
tooltip {Show bandwidth tracks on waterfall} xywh {15 195 145 20} down_box DOWN_BOX
code0 {o->value(progdefaults.UseWideCursor);}
}
}
Fl_Group {} {
label {Frequency scale} open
@ -1247,7 +1271,7 @@ behaves inside the waterfall} xywh {15 196 150 22} down_box BORDER_BOX align 8
}
}
Fl_Group tabModems {
label Modems open
label Modems
xywh {-4 25 521 347} labelsize 12 hide
} {
Fl_Tabs tabsModems {open
@ -2184,7 +2208,7 @@ o->color(fl_rgb_color(progdefaults.rttymarkRGBI.R,progdefaults.rttymarkRGBI.G,pr
o->redraw();
wf->redraw_marker();
progdefaults.changed = true;
}} selected
}}
tooltip {Change color} xywh {403 208 18 18} color 2 align 8
code0 {o->color(fl_rgb_color(progdefaults.rttymarkRGBI.R,progdefaults.rttymarkRGBI.G,progdefaults.rttymarkRGBI.B));}
}
@ -3342,7 +3366,7 @@ progdefaults.changed = true;}
}
}
Fl_Group tabMisc {
label Misc open
label Misc
xywh {0 25 500 345} labelsize 12 hide
} {
Fl_Tabs tabsMisc {open
@ -3660,119 +3684,229 @@ progdefaults.changed = true;}
}
}
}
Fl_Group tabDTMF {
label DTMF open
xywh {0 50 500 320} hide
} {
Fl_Check_Button chkDTMFdecode {
label {Decode DTMF tones}
callback {progdefaults.DTMFdecode = o->value();}
tooltip {Send rx text to file: textout.txt} xywh {175 71 175 20} down_box DOWN_BOX
code0 {o->value(progdefaults.DTMFdecode);}
}
}
}
}
Fl_Group tabQRZ {
label {Callsign DB}
label Web open
tooltip {Callsign database} xywh {0 25 500 345} labelsize 12 hide
} {
Fl_Group {} {
label CDROM open
xywh {5 180 490 75} box ENGRAVED_FRAME align 21
} {
Fl_Tabs {} {open
xywh {0 25 500 345}
} {
Fl_Round_Button btnQRZcdrom {
label QRZ
callback {set_qrz_buttons(o);
progdefaults.QRZ = QRZCD;
progdefaults.changed = true;}
tooltip {Use CD or hard drive CD image} xywh {25 215 70 20} down_box DOWN_BOX
code0 {o->value(progdefaults.QRZ == QRZCD);}
}
Fl_Input txtQRZpathname {
label {at:}
callback {progdefaults.QRZpathname = o->value();
progdefaults.QRZchanged = true;
progdefaults.changed = true;}
tooltip {ie: /home/dave/CALLBK/ or C:/CALLBK/
Leave blank to search for database} xywh {104 215 300 20}
code0 {o->value(progdefaults.QRZpathname.c_str());}
code1 {txtQRZpathname->labelsize(FL_NORMAL_SIZE);}
class Fl_Input2
}
}
Fl_Group {} {
label {Paid online subscription} open
xywh {5 260 490 95} box ENGRAVED_FRAME align 21
} {
Fl_Round_Button btnQRZsub {
label {QRZ.com}
callback {set_qrz_buttons(o);
progdefaults.QRZ = QRZNET;
progdefaults.changed = true;}
tooltip {You need a paid QRZ online
subscription to access} xywh {25 291 90 20} down_box DOWN_BOX
code0 {o->value(progdefaults.QRZ == QRZNET);}
}
Fl_Round_Button btnHamcall {
label {Hamcall.net}
callback {set_qrz_buttons(o);
progdefaults.QRZ = HAMCALLNET;
progdefaults.changed = true;}
tooltip {You need a paid Hamcall online
subscription to access} xywh {25 321 105 20} down_box DOWN_BOX
code0 {o->value(progdefaults.QRZ == HAMCALLNET);}
}
Fl_Input inpQRZusername {
label {User name}
callback {progdefaults.QRZusername = o->value();
progdefaults.changed = true;}
tooltip {Your login name} xywh {235 291 90 20}
code0 {o->value(progdefaults.QRZusername.c_str());}
code1 {inpQRZusername->labelsize(FL_NORMAL_SIZE);}
class Fl_Input2
}
Fl_Input inpQRZuserpassword {
label Password
callback {progdefaults.QRZuserpassword = o->value();
progdefaults.changed = true;}
tooltip {Your login password} xywh {236 321 90 20}
code0 {o->value(progdefaults.QRZuserpassword.c_str());}
code1 {o->type(FL_SECRET_INPUT);}
code2 {inpQRZuserpassword->labelsize(FL_NORMAL_SIZE);}
class Fl_Input2
}
Fl_Button btnQRZpasswordShow {
label Show
callback {inpQRZuserpassword->type(inpQRZuserpassword->type() ^ FL_SECRET_INPUT);
inpQRZuserpassword->redraw();
o->label((inpQRZuserpassword->type() & FL_SECRET_INPUT) ? "Show" : "Hide");}
tooltip {Show password in plain text} xywh {336 321 70 20}
}
}
Fl_Group {} {open
xywh {5 35 490 140} box ENGRAVED_FRAME align 21
} {
Fl_Round_Button btnQRZnotavailable {
label {Not available}
callback {set_qrz_buttons(o);
Fl_Group {} {
label {QRZ/etal} open
xywh {0 46 500 324}
} {
Fl_Group {} {open
xywh {5 55 490 120} box ENGRAVED_FRAME align 21
} {
Fl_Round_Button btnQRZnotavailable {
label {Not available}
callback {set_qrz_buttons(o);
progdefaults.QRZ = QRZNONE;
progdefaults.changed = true;}
tooltip {Do not use callsign database} xywh {25 45 337 20} down_box DOWN_BOX value 1
code0 {o->value(progdefaults.QRZ == QRZNONE);}
}
Fl_Round_Button btnQRZonline {
label {QRZ online via default Internet Browser}
callback {set_qrz_buttons(o);
tooltip {Do not use callsign database} xywh {25 64 337 20} down_box DOWN_BOX value 1
code0 {o->value(progdefaults.QRZ == QRZNONE);}
}
Fl_Round_Button btnQRZonline {
label {QRZ online via default Internet Browser}
callback {set_qrz_buttons(o);
progdefaults.QRZ = QRZHTML;
progdefaults.changed = true;}
tooltip {Visit QRZ web site} xywh {25 75 337 20} down_box DOWN_BOX
code0 {o->value(progdefaults.QRZ == QRZHTML);}
}
Fl_Round_Button btnHAMCALLonline {
label {HamCall online via default Internet Browser}
callback {set_qrz_buttons(o);
tooltip {Visit QRZ web site} xywh {25 92 337 20} down_box DOWN_BOX
code0 {o->value(progdefaults.QRZ == QRZHTML);}
}
Fl_Round_Button btnHAMCALLonline {
label {HamCall online via default Internet Browser}
callback {set_qrz_buttons(o);
progdefaults.QRZ = HAMCALLHTML;
progdefaults.changed = true;}
tooltip {Visit Hamcall web site} xywh {25 106 337 20} down_box DOWN_BOX
code0 {o->value(progdefaults.QRZ == HAMCALLHTML);}
}
Fl_Round_Button btnCALLOOK {
label {Callook.info lookup (US callsigns only)}
callback {set_qrz_buttons(o);
tooltip {Visit Hamcall web site} xywh {25 120 337 20} down_box DOWN_BOX
code0 {o->value(progdefaults.QRZ == HAMCALLHTML);}
}
Fl_Round_Button btnCALLOOK {
label {Callook.info lookup (US callsigns only)}
callback {set_qrz_buttons(o);
progdefaults.QRZ = CALLOOK;
progdefaults.changed = true;}
tooltip {Visit Hamcall web site} xywh {25 137 337 20} down_box DOWN_BOX
code0 {o->value(progdefaults.QRZ == CALLOOK);}
tooltip {Visit Hamcall web site} xywh {25 148 337 20} down_box DOWN_BOX
code0 {o->value(progdefaults.QRZ == CALLOOK);}
}
}
Fl_Group {} {
label CDROM open
xywh {5 176 490 55} box ENGRAVED_FRAME align 21
} {
Fl_Round_Button btnQRZcdrom {
label QRZ
callback {set_qrz_buttons(o);
progdefaults.QRZ = QRZCD;
progdefaults.changed = true;}
tooltip {Use CD or hard drive CD image} xywh {25 196 70 20} down_box DOWN_BOX
code0 {o->value(progdefaults.QRZ == QRZCD);}
}
Fl_Input txtQRZpathname {
label {at:}
callback {progdefaults.QRZpathname = o->value();
progdefaults.QRZchanged = true;
progdefaults.changed = true;}
tooltip {ie: /home/dave/CALLBK/ or C:/CALLBK/
Leave blank to search for database} xywh {104 196 300 20}
code0 {o->value(progdefaults.QRZpathname.c_str());}
code1 {txtQRZpathname->labelsize(FL_NORMAL_SIZE);}
class Fl_Input2
}
}
Fl_Group {} {
label {Subscriber data} open
xywh {5 232 490 134} box ENGRAVED_FRAME align 21
} {
Fl_Round_Button btnQRZsub {
label {QRZ.com}
callback {set_qrz_buttons(o);
progdefaults.QRZ = QRZNET;
progdefaults.changed = true;}
tooltip {You need a paid QRZ online
subscription to access} xywh {25 263 90 20} down_box DOWN_BOX
code0 {o->value(progdefaults.QRZ == QRZNET);}
}
Fl_Round_Button btnHamcall {
label {Hamcall.net}
callback {set_qrz_buttons(o);
progdefaults.QRZ = HAMCALLNET;
progdefaults.changed = true;}
tooltip {You need a paid Hamcall online
subscription to access} xywh {25 297 105 20} down_box DOWN_BOX
code0 {o->value(progdefaults.QRZ == HAMCALLNET);}
}
Fl_Input inpQRZusername {
label {User name}
callback {progdefaults.QRZusername = o->value();
progdefaults.changed = true;}
tooltip {Your login name} xywh {235 263 150 20}
code0 {o->value(progdefaults.QRZusername.c_str());}
code1 {inpQRZusername->labelsize(FL_NORMAL_SIZE);}
class Fl_Input2
}
Fl_Input inpQRZuserpassword {
label Password
callback {progdefaults.QRZuserpassword = o->value();
progdefaults.changed = true;}
tooltip {Your login password} xywh {235 297 150 20}
code0 {o->value(progdefaults.QRZuserpassword.c_str());}
code1 {o->type(FL_SECRET_INPUT);}
code2 {inpQRZuserpassword->labelsize(FL_NORMAL_SIZE);}
class Fl_Input2
}
Fl_Button btnQRZpasswordShow {
label Show
callback {inpQRZuserpassword->type(inpQRZuserpassword->type() ^ FL_SECRET_INPUT);
inpQRZuserpassword->redraw();
o->label((inpQRZuserpassword->type() & FL_SECRET_INPUT) ? "Show" : "Hide");}
tooltip {Show password in plain text} xywh {395 297 70 20}
}
Fl_Round_Button btnHamQTH {
label {HamQTH.com (free service http://www.hamqth.com)}
callback {set_qrz_buttons(o);
progdefaults.QRZ = HAMQTH;
progdefaults.changed = true;}
tooltip {You need a paid Hamcall online
subscription to access} xywh {26 332 121 20} down_box DOWN_BOX
code0 {o->value(progdefaults.QRZ == HAMQTH);}
}
}
}
Fl_Group {} {
label eQSL open
xywh {0 50 500 320} hide
} {
Fl_Input inpEQSL_id {
label {User ID}
callback {progdefaults.eqsl_id = o->value();
progdefaults.changed = true;}
tooltip {Your login name} xywh {176 75 150 20}
code0 {o->value(progdefaults.eqsl_id.c_str());}
code1 {inpEQSL_id->labelsize(FL_NORMAL_SIZE);}
class Fl_Input2
}
Fl_Input inpEQSL_pwd {
label Password
callback {progdefaults.eqsl_pwd = o->value();
progdefaults.changed = true;}
tooltip {Your login password} xywh {176 106 150 20}
code0 {o->value(progdefaults.eqsl_pwd.c_str());}
code1 {o->type(FL_SECRET_INPUT);}
code2 {inpEQSL_pwd->labelsize(FL_NORMAL_SIZE);}
class Fl_Input2
}
Fl_Button btnEQSL_pwd_show {
label Show
callback {inpEQSL_pwd->type(inpEQSL_pwd->type() ^ FL_SECRET_INPUT);
inpEQSL_pwd->redraw();
o->label((inpEQSL_pwd->type() & FL_SECRET_INPUT) ? "Show" : "Hide");}
tooltip {Show password in plain text} xywh {344 106 70 20}
}
Fl_Input inpEQSL_nick {
label {QTH Nickname}
callback {progdefaults.eqsl_nick = o->value();
progdefaults.changed = true;}
tooltip {Your login name} xywh {176 137 150 20}
code0 {o->value(progdefaults.eqsl_nick.c_str());}
code1 {inpEQSL_nick->labelsize(FL_NORMAL_SIZE);}
class Fl_Input2
}
Fl_Group {} {
label Options open
xywh {4 170 492 194} box ENGRAVED_FRAME align 21
} {
Fl_Check_Button btn_send_when_logged {
label {send when logged (log button, <LOG>, <LNW>)}
callback {progdefaults.eqsl_when_logged = o->value();
progdefaults.changed = true;}
tooltip {eQSL upload when record logged} xywh {29 191 70 15} down_box DOWN_BOX
code0 {o->value(progdefaults.eqsl_when_logged);}
}
Fl_Input txt_eqsl_default_message {
label {Default message}
callback {progdefaults.eqsl_default_message = o->value();
progdefaults.changed = true;}
tooltip {Default message sent with eQSL} xywh {33 226 451 40} type Multiline align 5 when 1
code0 {o->value(progdefaults.eqsl_default_message.c_str());}
class Fl_Input2
}
Fl_Group {} {
label {Text Tags (tags use {} delimiters)} open
xywh {8 270 484 90} box THIN_DOWN_BOX align 21
} {
Fl_Box eqsl_txt1 {
label {{CALL} other ops call sign}
xywh {14 317 220 17} align 20
}
Fl_Box eqsl_txt2 {
label {{MODE} full mode / submode}
xywh {12 336 220 17} align 20
}
Fl_Box eqsl_txt3 {
label {{NAME} other ops name}
xywh {260 317 220 17} align 20
}
Fl_Box {} {
label {These tags can also be used in <EQSL:[message]>}
xywh {28 293 440 17}
}
}
}
}
}
}

Wyświetl plik

@ -77,6 +77,7 @@
#endif
#include "rigio.h"
#include "rigMEM.h"
#include "nullmodem.h"
#include "psk.h"
#include "cw.h"
#include "mfsk.h"
@ -1034,6 +1035,11 @@ void init_modem(trx_mode mode, int freq)
mode = NUM_MODES - 1;
return init_modem(mode, freq);
case MODE_NULL:
startup_modem(*mode_info[mode].modem ? *mode_info[mode].modem :
*mode_info[mode].modem = new NULLMODEM, freq);
break;
case MODE_CW:
startup_modem(*mode_info[mode].modem ? *mode_info[mode].modem :
*mode_info[mode].modem = new cw, freq);
@ -1856,6 +1862,19 @@ void cb_ShowNBEMS(Fl_Widget*, void*)
cb_mnuVisitURL(0, (void*)NBEMS_dir.c_str());
}
void cb_ShowFLMSG(Fl_Widget*, void*)
{
DIR *flmsg_dir;
flmsg_dir = opendir(FLMSG_dir.c_str());
if (!flmsg_dir) {
int ans = fl_choice2(_("Do not exist, create?"), _("No"), _("Yes"), 0);
if (!ans) return;
check_nbems_dirs();
}
closedir(flmsg_dir);
cb_mnuVisitURL(0, (void*)FLMSG_dir.c_str());
}
void cbTune(Fl_Widget *w, void *) {
Fl_Button *b = (Fl_Button *)w;
if (!(active_modem->get_cap() & modem::CAP_TX)) {
@ -2342,6 +2361,7 @@ void stopMacroTimer()
progStatus.timer = 0;
progStatus.repeatMacro = -1;
Fl::remove_timeout(macro_timer);
Fl::remove_timeout(macro_timed_execute);
btnMacroTimer->label(0);
btnMacroTimer->color(FL_BACKGROUND_COLOR);
@ -2362,6 +2382,32 @@ void macro_timer(void*)
Fl::repeat_timeout(1.0, macro_timer);
}
void macro_timed_execute(void *)
{
if (exec_date == zdate() && exec_time == ztime()) {
macros.timed_execute();
btnMacroTimer->label(0);
btnMacroTimer->color(FL_BACKGROUND_COLOR);
btnMacroTimer->set_output();
} else {
Fl::repeat_timeout(1.0, macro_timed_execute);
}
}
void startTimedExecute(std::string &title)
{
ENSURE_THREAD(FLMAIN_TID);
Fl::add_timeout(0.0, macro_timed_execute);
string txt = "Macro '";
txt.append(title).append("' scheduled at ");
txt.append(exec_time).append(", on ").append(exec_date).append("\n");
btnMacroTimer->label("SKED");
btnMacroTimer->color(fl_rgb_color(240, 240, 0));
btnMacroTimer->redraw_label();
ReceiveText->clear();
ReceiveText->add(txt.c_str(), FTextBase::CTRL);
}
void cbMacroTimerButton(Fl_Widget*, void*)
{
stopMacroTimer();
@ -2993,6 +3039,7 @@ Fl_Menu_Item menu_[] = {
{ make_icon_label(_("Folders")), 0, 0, 0, FL_SUBMENU, _FL_MULTI_LABEL, 0, 14, 0},
{ make_icon_label(_("Fldigi config..."), folder_open_icon), 0, cb_ShowConfig, 0, 0, _FL_MULTI_LABEL, 0, 14, 0},
{ make_icon_label(_("FLMSG files..."), folder_open_icon), 0, cb_ShowFLMSG, 0, 0, _FL_MULTI_LABEL, 0, 14, 0},
{ make_icon_label(_("NBEMS files..."), folder_open_icon), 0, cb_ShowNBEMS, 0, 0, _FL_MULTI_LABEL, 0, 14, 0},
{0,0,0,0,0,0,0,0,0},
@ -3142,6 +3189,7 @@ Fl_Menu_Item menu_[] = {
{ mode_info[MODE_PSK250].name, 0, cb_init_mode, (void *)MODE_PSK250, 0, FL_NORMAL_LABEL, 0, 14, 0},
{0,0,0,0,0,0,0,0,0},
{ mode_info[MODE_NULL].name, 0, cb_init_mode, (void *)MODE_NULL, 0, FL_NORMAL_LABEL, 0, 14, 0},
{ mode_info[MODE_SSB].name, 0, cb_init_mode, (void *)MODE_SSB, 0, FL_NORMAL_LABEL, 0, 14, 0},
{ mode_info[MODE_WWV].name, 0, cb_init_mode, (void *)MODE_WWV, 0, FL_NORMAL_LABEL, 0, 14, 0},
@ -3163,7 +3211,7 @@ Fl_Menu_Item menu_[] = {
{ make_icon_label(_("Misc")), 0, (Fl_Callback*)cb_mnuConfigMisc, 0, 0, _FL_MULTI_LABEL, 0, 14, 0},
{ make_icon_label(_("Notifications")), 0, (Fl_Callback*)cb_mnuConfigNotify, 0, 0, _FL_MULTI_LABEL, 0, 14, 0},
{ make_icon_label(CONTEST_MLABEL), 0, (Fl_Callback*)cb_mnuConfigContest, 0, 0, _FL_MULTI_LABEL, 0, 14, 0},
{ make_icon_label(_("QRZ"), net_icon), 0, (Fl_Callback*)cb_mnuConfigQRZ, 0, FL_MENU_DIVIDER, _FL_MULTI_LABEL, 0, 14, 0},
{ make_icon_label(_("QRZ/eQSL"), net_icon), 0, (Fl_Callback*)cb_mnuConfigQRZ, 0, FL_MENU_DIVIDER, _FL_MULTI_LABEL, 0, 14, 0},
{ make_icon_label(_("Save Config"), save_icon), 0, (Fl_Callback*)cb_mnuSaveConfig, 0, 0, _FL_MULTI_LABEL, 0, 14, 0},
{0,0,0,0,0,0,0,0,0},
@ -3194,23 +3242,24 @@ Fl_Menu_Item menu_[] = {
{0,0,0,0,0,0,0,0,0},
{_("&Logbook"), 0, 0, 0, FL_SUBMENU, FL_NORMAL_LABEL, 0, 14, 0},
{ LOG_CONNECT_SERVER, 0, cb_log_server, 0, FL_MENU_TOGGLE | FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0},
{ make_icon_label(_("View")), 'l', (Fl_Callback*)cb_mnuShowLogbook, 0, FL_MENU_DIVIDER, _FL_MULTI_LABEL, 0, 14, 0},
{ make_icon_label(_("New")), 0, (Fl_Callback*)cb_mnuNewLogbook, 0, 0, _FL_MULTI_LABEL, 0, 14, 0},
{ make_icon_label(_("Open...")), 0, (Fl_Callback*)cb_mnuOpenLogbook, 0, 0, _FL_MULTI_LABEL, 0, 14, 0},
{ make_icon_label(_("Save")), 0, (Fl_Callback*)cb_mnuSaveLogbook, 0, FL_MENU_DIVIDER, _FL_MULTI_LABEL, 0, 14, 0},
{"ADIF", 0, 0, 0, FL_SUBMENU, FL_NORMAL_LABEL, 0, 14, 0},
{ make_icon_label(_("Merge...")), 0, (Fl_Callback*)cb_mnuMergeADIF_log, 0, 0, _FL_MULTI_LABEL, 0, 14, 0},
{ make_icon_label(_("Export...")), 0, (Fl_Callback*)cb_mnuExportADIF_log, 0, 0, _FL_MULTI_LABEL, 0, 14, 0},
{0,0,0,0,0,0,0,0,0},
{"Reports", 0, 0, 0, FL_SUBMENU, FL_NORMAL_LABEL, 0, 14, 0},
{"Reports", 0, 0, 0, FL_SUBMENU | FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0},
{ make_icon_label(_("Text...")), 0, (Fl_Callback*)cb_mnuExportTEXT_log, 0, 0, _FL_MULTI_LABEL, 0, 14, 0},
{ make_icon_label(_("CSV...")), 0, (Fl_Callback*)cb_mnuExportCSV_log, 0, 0, _FL_MULTI_LABEL, 0, 14, 0},
{ make_icon_label(_("Cabrillo...")), 0, (Fl_Callback*)cb_Export_Cabrillo, 0, 0, _FL_MULTI_LABEL, 0, 14, 0},
{0,0,0,0,0,0,0,0,0},
{ make_icon_label(_("New")), 0, (Fl_Callback*)cb_mnuNewLogbook, 0, 0, _FL_MULTI_LABEL, 0, 14, 0},
{ make_icon_label(_("Open...")), 0, (Fl_Callback*)cb_mnuOpenLogbook, 0, 0, _FL_MULTI_LABEL, 0, 14, 0},
{ make_icon_label(_("Save")), 0, (Fl_Callback*)cb_mnuSaveLogbook, 0, FL_MENU_DIVIDER, _FL_MULTI_LABEL, 0, 14, 0},
{ LOG_CONNECT_SERVER, 0, cb_log_server, 0, FL_MENU_TOGGLE, FL_NORMAL_LABEL, 0, 14, 0},
{0,0,0,0,0,0,0,0,0},
{_("DL Client"), 0, 0, 0, FL_SUBMENU, FL_NORMAL_LABEL, 0, 14, 0},
@ -3673,6 +3722,12 @@ void showMacroSet() {
set_macroLabels();
}
void showDTMF(const string s) {
string dtmfstr = "\n<DTMF> ";
dtmfstr.append(s);
ReceiveText->add(dtmfstr.c_str());
}
void setwfrange() {
wf->opmode();
}
@ -3762,7 +3817,7 @@ void create_fl_digi_main_primary() {
int Hmacrobtn;
int xpos;
int ypos;
int wblank;
int wBLANK;
int fnt = fl_font();
int fsize = fl_size();
@ -4404,14 +4459,14 @@ void create_fl_digi_main_primary() {
Fl_Group *btngroup2 = new Fl_Group(0, Y + 1, progStatus.mainW - Hmacros, Hmacros - 1);
Wmacrobtn = (btngroup2->w()) / NUMMACKEYS;
Hmacrobtn = btngroup2->h() - 1;
wblank = (btngroup2->w() - NUMMACKEYS * Wmacrobtn) / 2;
wBLANK = (btngroup2->w() - NUMMACKEYS * Wmacrobtn) / 2;
xpos = 0;
ypos = btngroup2->y();
for (int i = 0; i < NUMMACKEYS; i++) {
if (i == 4 || i == 8) {
bx = new Fl_Box(xpos, ypos, wblank, Hmacrobtn);
bx = new Fl_Box(xpos, ypos, wBLANK, Hmacrobtn);
bx->box(FL_FLAT_BOX);
xpos += wblank;
xpos += wBLANK;
}
btnMacro[NUMMACKEYS + i] = new Fl_Button(xpos, ypos, Wmacrobtn, Hmacrobtn,
macros.name[NUMMACKEYS + i].c_str());
@ -4427,6 +4482,7 @@ void create_fl_digi_main_primary() {
btnAltMacros2->tooltip(_("Shift-key macro set"));
macroFrame2->resizable(btngroup2);
macroFrame2->end();
Y += Hmacros;
int Htext = progStatus.mainH - Hwfall - Hmenu - Hstatus - Hmacros*NUMKEYROWS - Hqsoframe - 4;
int Hrcvtxt = Htext / 2;
@ -4465,7 +4521,6 @@ void create_fl_digi_main_primary() {
text_panel->x(), text_panel->y(),
text_panel->w()/2, Htext, "");
// mainViewer = new pskBrowser(mvgroup->x(), mvgroup->y(), mvgroup->w(), Htext-22, "");
mainViewer = new pskBrowser(mvgroup->x(), mvgroup->y(), mvgroup->w(), Htext-42, "");
mainViewer->box(FL_DOWN_BOX);
mainViewer->has_scrollbar(Fl_Browser_::VERTICAL);
@ -4477,9 +4532,6 @@ void create_fl_digi_main_primary() {
Fl_Group* gseek = new Fl_Group(mvgroup->x(), mvgroup->y() + Htext - 42, mvgroup->w(), 20);
// search field
// const char* label = _("Find: ");
// fl_font(FL_HELVETICA, FL_NORMAL_SIZE);
// int label_w = static_cast<int>(fl_width(label));
int seek_x = mvgroup->x() + 2;
int seek_y = mvgroup->y() + Htext - 42;
int seek_w = mvgroup->w() - 4;
@ -4567,8 +4619,8 @@ void create_fl_digi_main_primary() {
TransmitText->align(FL_ALIGN_CLIP);
Fl_Box *minbox = new Fl_Box(
text_panel->x(), text_panel->y() + 66,
text_panel->w() - 100, text_panel->h() - 66 - 80);
text_panel->x(), text_panel->y() + 66, // fixed by Raster min height
text_panel->w() - 100, text_panel->h() - 66 - 60); // fixed by HMIN & Hwfall max
minbox->hide();
text_panel->resizable(minbox);
@ -4583,14 +4635,14 @@ void create_fl_digi_main_primary() {
Fl_Group *btngroup1 = new Fl_Group(0, Y+1, progStatus.mainW - Hmacros, Hmacros-1);
Wmacrobtn = (btngroup1->w()) / NUMMACKEYS;
Hmacrobtn = btngroup1->h() - 1;
wblank = (btngroup1->w() - NUMMACKEYS * Wmacrobtn) / 2;
wBLANK = (btngroup1->w() - NUMMACKEYS * Wmacrobtn) / 2;
xpos = 0;
ypos = btngroup1->y();
for (int i = 0; i < NUMMACKEYS; i++) {
if (i == 4 || i == 8) {
bx = new Fl_Box(xpos, ypos, wblank, Hmacrobtn);
bx = new Fl_Box(xpos, ypos, wBLANK, Hmacrobtn);
bx->box(FL_FLAT_BOX);
xpos += wblank;
xpos += wBLANK;
}
btnMacro[i] = new Fl_Button(xpos, ypos, Wmacrobtn, Hmacrobtn,
macros.name[i].c_str());
@ -4975,6 +5027,7 @@ Fl_Menu_Item alt_menu_[] = {
{ mode_info[MODE_PSK250].name, 0, cb_init_mode, (void *)MODE_PSK250, 0, FL_NORMAL_LABEL, 0, 14, 0},
{0,0,0,0,0,0,0,0,0},
{ mode_info[MODE_NULL].name, 0, cb_init_mode, (void *)MODE_NULL, 0, FL_NORMAL_LABEL, 0, 14, 0},
{ mode_info[MODE_SSB].name, 0, cb_init_mode, (void *)MODE_SSB, 0, FL_NORMAL_LABEL, 0, 14, 0},
{ mode_info[MODE_WWV].name, 0, cb_init_mode, (void *)MODE_WWV, 0, FL_NORMAL_LABEL, 0, 14, 0},
@ -5901,7 +5954,7 @@ void put_Bandwidth(int bandwidth)
wf->Bandwidth ((int)bandwidth);
}
static void set_metric(double metric)
static void callback_set_metric(double metric)
{
pgrsSquelch->value(metric);
if (!progStatus.sqlonoff)
@ -5913,10 +5966,10 @@ static void set_metric(double metric)
btnSQL->redraw_label();
}
void display_metric(double metric)
void global_display_metric(double metric)
{
FL_LOCK_D();
REQ_DROP(set_metric, metric);
REQ_DROP(callback_set_metric, metric);
FL_UNLOCK_D();
FL_AWAKE_D();
}
@ -6305,10 +6358,6 @@ void put_rx_data(int *data, int len)
FHdisp->data(data, len);
}
extern bool macro_idle_on;
extern string text2repeat;
extern size_t repeatchar;
bool idling = false;
void get_tx_char_idle(void *)
@ -6317,10 +6366,55 @@ void get_tx_char_idle(void *)
progStatus.repeatIdleTime = 0;
}
int Qwait_time = 0;
int Qidle_time = 0;
static int que_timeout = 0;
bool que_ok = true;
void post_queue_execute(void*)
{
if (!que_timeout) {
LOG_ERROR("%s", "timed out");
return;
}
while (!que_ok && trx_state != STATE_RX) {
que_timeout--;
Fl::repeat_timeout(0.05, post_queue_execute);
}
trx_transmit();
}
void queue_execute_after_rx(void*)
{
if (!que_timeout) {
LOG_ERROR("%s", "timed out");
return;
}
while (trx_state == STATE_TX) {
que_timeout--;
Fl::repeat_timeout(0.05, queue_execute_after_rx);
return;
}
que_ok = false;
que_timeout = 100; // 5 seconds
Fl::add_timeout(0.05, post_queue_execute);
queue_execute();
}
char szTestChar[] = "E|I|S|T|M|O|A|V";
int get_tx_char(void)
{
if (macro_idle_on) return -1;
int c;
static int pending = -1;
enum { STATE_CHAR, STATE_CTRL };
static int state = STATE_CHAR;
if (!que_ok) { return -1; }
if (Qwait_time) { return -1; }
if (Qidle_time) { return -1; }
if (macro_idle_on) { return -1; }
if (idling) { return -1; }
if (arq_text_available)
return arq_get_char();
@ -6328,24 +6422,19 @@ int get_tx_char(void)
if (active_modem == cw_modem && progdefaults.QSKadjust)
return szTestChar[2 * progdefaults.TestChar];
int c;
static int pending = -1;
if ( progStatus.repeatMacro && progStatus.repeatIdleTime > 0 &&
!idling ) {
Fl::add_timeout(progStatus.repeatIdleTime, get_tx_char_idle);
idling = true;
return -1;
}
if (pending >= 0) {
c = pending;
pending = -1;
return c;
}
enum { STATE_CHAR, STATE_CTRL };
static int state = STATE_CHAR;
if ( progStatus.repeatMacro && progStatus.repeatIdleTime > 0 &&
!idling ) {
Fl::add_timeout(progStatus.repeatIdleTime, get_tx_char_idle);
idling = true;
}
if (idling) return -1;
if (progStatus.repeatMacro > -1 && text2repeat.length()) {
c = text2repeat[repeatchar];
repeatchar++;
@ -6357,12 +6446,15 @@ int get_tx_char(void)
}
c = TransmitText->nextChar();
if (c == '^' && state == STATE_CHAR) {
state = STATE_CTRL;
c = TransmitText->nextChar();
}
switch (c) {
case -1: break; // no character available
case -1: // no character available
queue_reset();
break;
case '\n':
pending = '\n';
return '\r';
@ -6372,6 +6464,8 @@ int get_tx_char(void)
REQ_SYNC(&FTextTX::clear_sent, TransmitText);
state = STATE_CHAR;
c = 3; // ETX
// if (progStatus.timer)
// REQ(startMacroTimer);
break;
case 'R':
if (state != STATE_CTRL)
@ -6380,6 +6474,8 @@ int get_tx_char(void)
if (TransmitText->eot()) {
REQ_SYNC(&FTextTX::clear_sent, TransmitText);
c = 3; // ETX
// if (progStatus.timer)
// REQ(startMacroTimer);
} else
c = -1;
break;
@ -6397,6 +6493,19 @@ int get_tx_char(void)
c = -1;
REQ(clearQSO);
break;
case '!':
if (state != STATE_CTRL)
break;
state = STATE_CHAR;
if (queue_must_rx()) {
c = 3;
que_timeout = 400; // 20 seconds
Fl::add_timeout(0.0, queue_execute_after_rx);
} else {
c = -1;
queue_execute();
}
break;
case '^':
state = STATE_CHAR;
break;
@ -6580,7 +6689,6 @@ void start_tx()
if (!(active_modem->get_cap() & modem::CAP_TX))
return;
trx_transmit();
REQ(&waterfall::set_XmtRcvBtn, wf, true);
}
void abort_tx()
@ -6591,6 +6699,7 @@ void abort_tx()
return;
}
if (trx_state == STATE_TX) {
queue_reset();
trx_start_modem(active_modem);
}
}
@ -6832,6 +6941,12 @@ void set_rtty_bits(int bits)
}
}
void set_rtty_bw(float bw)
{
sldrRTTYbandwidth->value(bw);
sldrRTTYbandwidth->do_callback();
}
void set_menu_dl_online(bool val)
{
Fl_Menu_Item *m;

274
src/dtmf/dtmf.cxx 100644
Wyświetl plik

@ -0,0 +1,274 @@
// ----------------------------------------------------------------------------
//
// DTMF.cxx
//
// Copyright (C) 2011
// Dave Freese, W1HKJ
//
// 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 fldigi. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#include <config.h>
#include <cmath>
#include <cstring>
#include <float.h>
#include <samplerate.h>
#include "trx.h"
#include "dtmf.h"
#include "misc.h"
#include "fl_digi.h"
#include "configuration.h"
#include "qrunner.h"
#include "debug.h"
#include "status.h"
#include "main.h"
LOG_FILE_SOURCE(debug::LOG_MODEM);
// tones in 4x4 array
// 697 770 842 941 1209 1336 1447 1633
int cDTMF::row[] = {697, 770, 852, 941};
int cDTMF::col[] = {1209, 1336, 1477, 1633};
const char cDTMF::rc[] = "123A456B789C*0#D";
//======================================================================
// DTMF tone receive
//======================================================================
// tone #s and coefficients
// 8000 Hz sampling N == 240
// 11025 Hz sampling N == 331
/*
* calculate the power of each tone using Goertzel filters
*/
void cDTMF::calc_power()
{
double sr = active_modem->get_samplerate();
// reset row freq filters
for (int i = 0; i < 4; i++) filt[i]->reset(240, row[i], sr);
// reset col freq filters
for (int i = 0; i < 4; i++) filt[i+4]->reset(240, col[i], sr);
for (int i = 0; i < framesize; i++)
for (int j = 0; j < NUMTONES; j++)
filt[j]->run(data[i]);
for (int i = 0; i < NUMTONES; i++)
power[i] = filt[i]->mag();
maxpower = 0;
minpower = 1e6;
for (int i = 0; i < NUMTONES;i++) {
if (power[i] > maxpower)
maxpower = power[i];
if (power[i] < minpower)
minpower = power[i];
}
if ( minpower == 0 ) minpower = 1e-3;
}
/*
* detect which signals are present.
*
*/
int cDTMF::decode()
{
calc_power();
if (maxpower < (10 * progStatus.sldrSquelchValue))
return ' ';
int r = -1, c = -1;
double pwr = 0;
for (int i = 0; i < 4; i++)
if (power[i] > pwr) {
pwr = power[i];
r = i;
}
pwr = 0;
for (int i = 0; i < 4; i++)
if (power[i+4] > pwr) {
pwr = power[i+4];
c = i;
}
if (r == -1 || c == -1)
return ' ';
return rc[r*4 + c];
}
/*
* read in frames, output the decoded
* results
*/
void cDTMF::receive(const float* buf, size_t len)
{
int x;
static size_t dptr = 0;
size_t bufptr = 0;
if (!progdefaults.DTMFdecode) return;
framesize = (active_modem->get_samplerate() == 8000) ? 240 : 331;
while (1) {
int i;
for ( i = dptr; i < framesize; i++) {
data[i] = buf[bufptr];
bufptr++;
if (bufptr == len) break;
}
if (i < framesize) {
dptr = i + 1;
return;
}
dptr = 0;
x = decode();
if (x == ' ') {
silence_time++;
if (silence_time == 4 && !dtmfchars.empty()) dtmfchars += ' ';
if (silence_time == FLUSH_TIME) {
if (!dtmfchars.empty()) {
REQ(showDTMF, dtmfchars);
dtmfchars.clear();
}
silence_time = 0;
}
} else {
silence_time = 0;
if (x != last && last == ' ')
dtmfchars += x;
}
last = x;
}
}
//======================================================================
// DTMF tone transmit
//======================================================================
void cDTMF::makeshape()
{
for (int i = 0; i < 128; i++) shape[i] = 1.0;
for (int i = 0; i < RT; i++)
shape[i] = 0.5 * (1.0 - cos (M_PI * i / RT));
}
//----------------------------------------------------------------------
// transmit silence for specified time duration in milliseconds
//----------------------------------------------------------------------
void cDTMF::silence(int len)
{
double sr = active_modem->get_samplerate();
int length = len * sr / 1000;
if (length > 16384) length = 16384;
memset(outbuf, 0, length * sizeof(*outbuf));
active_modem->ModulateXmtr(outbuf, length);
}
//----------------------------------------------------------------------
// transmit DTMF tones for specific time interval
//----------------------------------------------------------------------
void cDTMF::two_tones(int ch)
{
if (!strchr(rc, ch)) return;
int pos = strchr(rc, ch) - rc;
int r = pos / 4;
int c = pos % 4;
double sr = active_modem->get_samplerate();
double phaseincr = 2.0 * M_PI * row[r] / sr;
double phase = 0;
int length = duration * sr / 1000;
if (length > 16384) length = 16384;
for (int i = 0; i < length; i++) {
outbuf[i] = 0.5 * sin(phase);
phase += phaseincr;
}
phaseincr = 2.0 * M_PI * col[c] / sr;
phase = 0;
for (int i = 0; i < length; i++) {
outbuf[i] += 0.5 * sin(phase);
phase += phaseincr;
}
for (int i = 0; i < RT; i++) {
outbuf[i] *= shape[i];
outbuf[length - 1 - i] *= shape[i];
}
active_modem->ModulateXmtr(outbuf, length);
}
//----------------------------------------------------------------------
// transmit the string contained in progdefaults.DTMFstr and output as
// dtmf valid characters, 0-9, *, #, A-D
// each pair of tones is separated by 50ms silence
// 500 msec silence for ' ', ',' or '-'
// 50 msec silence for invalid characters
//----------------------------------------------------------------------
void cDTMF::send()
{
int c = 0, delay = 0;
duration = 50;
RT = (int)(active_modem->get_samplerate() * 4 / 1000.0); // 4 msec edge
makeshape();
size_t colon = std::string::npos;
size_t modifier = progdefaults.DTMFstr.find("W");
if (modifier != std::string::npos) {
delay = atoi(&progdefaults.DTMFstr[modifier + 1]);
colon = progdefaults.DTMFstr.find(':', modifier);
progdefaults.DTMFstr.erase(modifier, colon - modifier + 1);
}
modifier = progdefaults.DTMFstr.find('L');
if (modifier != std::string::npos) {
duration = atoi(&progdefaults.DTMFstr[modifier + 1]);
colon = progdefaults.DTMFstr.find(':', modifier);
progdefaults.DTMFstr.erase(modifier, colon - modifier + 1);
}
while (delay > 50) { silence(50); delay -= 50;}
if (delay) silence(delay);
for(size_t i = 0; i < progdefaults.DTMFstr.length(); i++) {
c = progdefaults.DTMFstr[i];
if (c == ' ' || c == ',' || c == '-')
silence(duration);
else if ( (c >= '0' && c <= '9') ||
c == '*' ||
c == '#' ||
(c >= 'A' && c <= 'D') )
two_tones(c);
silence(duration);
}
progdefaults.DTMFstr.clear();
}

Wyświetl plik

@ -43,6 +43,8 @@ using namespace std;
// ... doing so will break the Fl_menu_item table 'menu_'. -Kamal
const struct mode_info_t mode_info[NUM_MODES] = {
{ MODE_NULL, &null_modem, "NULL", "NULL", "", "NULL", "" },
{ MODE_CW, &cw_modem, "CW", "CW", "CW", "CW", "CW" },
{ MODE_CONTESTIA, &contestia_modem, "CTSTIA", "Contestia", "", "CONTESTI", "CT" },

Wyświetl plik

@ -127,6 +127,9 @@ extern Fl_Check_Button *btnUseCursorCenterLine;
extern Fl_Button *btnCursorCenterLineColor;
extern Fl_Check_Button *btnUseBWTracks;
extern Fl_Button *btnBwTracksColor;
extern Fl_Check_Button *btnUseWideTracks;
extern Fl_Check_Button *btnUseWideCenter;
extern Fl_Check_Button *btnUseWideCursor;
extern Fl_Check_Button *chkShowAudioScale;
extern Fl_Button *btnWaterfallFont;
extern Fl_Check_Button *btnViewXmtSignal;
@ -400,7 +403,13 @@ extern void close_talker();
extern Fl_Light_Button *btnConnectTalker;
extern Fl_Check_Button *btn_auto_talk;
extern Fl_Check_Button *chkRxStream;
extern Fl_Group *tabDTMF;
extern Fl_Check_Button *chkDTMFdecode;
extern Fl_Group *tabQRZ;
extern Fl_Round_Button *btnQRZnotavailable;
extern Fl_Round_Button *btnQRZonline;
extern Fl_Round_Button *btnHAMCALLonline;
extern Fl_Round_Button *btnCALLOOK;
extern Fl_Round_Button *btnQRZcdrom;
extern Fl_Input2 *txtQRZpathname;
extern Fl_Round_Button *btnQRZsub;
@ -408,10 +417,16 @@ extern Fl_Round_Button *btnHamcall;
extern Fl_Input2 *inpQRZusername;
extern Fl_Input2 *inpQRZuserpassword;
extern Fl_Button *btnQRZpasswordShow;
extern Fl_Round_Button *btnQRZnotavailable;
extern Fl_Round_Button *btnQRZonline;
extern Fl_Round_Button *btnHAMCALLonline;
extern Fl_Round_Button *btnCALLOOK;
extern Fl_Round_Button *btnHamQTH;
extern Fl_Input2 *inpEQSL_id;
extern Fl_Input2 *inpEQSL_pwd;
extern Fl_Button *btnEQSL_pwd_show;
extern Fl_Input2 *inpEQSL_nick;
extern Fl_Check_Button *btn_send_when_logged;
extern Fl_Input2 *txt_eqsl_default_message;
extern Fl_Box *eqsl_txt1;
extern Fl_Box *eqsl_txt2;
extern Fl_Box *eqsl_txt3;
extern Fl_Group *tabDL;
extern Fl_Tabs *tabsDL;
extern Fl_Group *tabDLEnable;

Wyświetl plik

@ -70,7 +70,7 @@
+20.0) \
ELEM_(bool, rsidWideSearch, "RSIDWIDESEARCH", \
"RSID detector searches the entire passband", \
true) \
false) \
ELEM_(int, rsid_squelch, "RSIDSQUELCH", \
"RSID detection opens squelch for nn seconds", \
5) \
@ -88,8 +88,8 @@
"Trigger RSID notifications but do not change modem and frequency", \
false) \
ELEM_(bool, rsid_auto_disable, "RSIDAUTODISABLE", \
"Disable RSID detection when changing modem and/or frequency", \
true) \
"Disable RSID detection when RsID signal is detected", \
false) \
ELEM_(bool, rsid_post, "RSIDPOST", \
"Transmit an RSID signal when modem data is concluded", \
false) \
@ -239,9 +239,12 @@
ELEM_(int, rtty_custom_shift, "RTTYCUSTOMSHIFT", \
"Custom shift (Hz)", \
450) \
ELEM_(double, RTTY_BW, "RTTYBW", \
"Receive filter bandwidth (Hz)", \
68.0) \
ELEM_(int, rtty_baud, "RTTYBAUD", \
"Carrier baud rate. Values are as follows:\n" \
" 0: 45; 1: 45.45; 2: 50; 3: 56; 4: 75; 5: 100; 6: 110; 7: 150; \n" \
" 1: 45; 1: 45.45; 2: 50; 3: 56; 4: 75; 5: 100; 6: 110; 7: 150; \n" \
" 8: 200; 9: 300", \
0) /* 45 */ \
ELEM_(int, rtty_bits, "RTTYBITS", \
@ -293,13 +296,10 @@
true) \
ELEM_(bool, useMARKfreq, "USEMARKFREQ", \
"Use MARK frequency for logging", \
true) \
true) \
ELEM_(bool, Xagc, "XAGC", \
"This setting is currently unused", \
false) \
ELEM_(double, RTTY_BW, "RTTYBW", \
"Receive filter bandwidth (Hz)", \
400.0) \
/* CW */ \
ELEM_(bool, useCWkeylineRTS, "", "", false) \
ELEM_(bool, useCWkeylineDTR, "", "", false) \
@ -523,6 +523,15 @@
ELEM_(bool, UseBWTracks, "USEBWTRACKS", \
"Draw bandwidth marker with vertical lines", \
true) \
ELEM_(bool, UseWideTracks, "USEWIDETRACKS", \
"Draw bandwidth marker with 3x vertical lines", \
false) \
ELEM_(bool, UseWideCursor, "USEWIDECURSOR", \
"Draw cursor with 3x vertical lines", \
false) \
ELEM_(bool, UseWideCenter, "USEWIDECENTER", \
"Draw center line marker with 3x vertical lines", \
false) \
ELEM_(RGBI, cursorLineRGBI, "CLCOLORS", \
"Color of cursor lines (RGBI)", \
{255, 255, 0, 255}) \
@ -557,6 +566,10 @@
"Single tone at center of modem BW, carrier detect for amplifiers", \
0.0) \
ELEM_(bool, macroCWid, "", "", false) \
ELEM_(std::string, DTMFstr, "", "", "") \
ELEM_(bool, DTMFdecode, "DTMFDECODE", \
"Decode received DTMF tones", \
false) \
ELEM_(int, videowidth, "VIDEOWIDTH", \
"Video ID text width (characters per row)", \
1) \
@ -652,6 +665,22 @@
"QRZ or HamCall subscriber password", \
"") \
ELEM_(bool, QRZchanged, "", "", false) \
/* eQSL */ \
ELEM_(std::string, eqsl_id, "EQSL_ID", \
"eQSL login id", \
"") \
ELEM_(std::string, eqsl_pwd, "EQSL_PASSWORD", \
"eQSL login password", \
"") \
ELEM_(std::string, eqsl_nick, "EQSL_NICKNAME", \
"eQSL nickname", \
"") \
ELEM_(std::string, eqsl_default_message, "EQSL_DEF_MSG", \
"eQSl default message", \
"") \
ELEM_(bool, eqsl_when_logged, "EQSL_WHEN_LOGGED", \
"Send eQSL when other log action invoked", \
false) \
/* Rig control */ \
ELEM_(bool, btnusb, "BTNUSB", \
"This setting is currently unused", \

62
src/include/dtmf.h 100644
Wyświetl plik

@ -0,0 +1,62 @@
#include <string>
#include "filters.h"
class cDTMF {
public:
#define N 240 // 30 msec interval at 8000 sps
#define RANGE 0.5 /* any thing higher than RANGE*peak is "on" */
#define THRESH 1000 /* 6 dB s/n for detection */
#define FLUSH_TIME 10 /* 10 frames ~ 330 millisecond */
#define NUMTONES 8
private:
double power[NUMTONES];
double thresh;
double maxpower;
double minpower;
double data[350];
goertzel *filt[NUMTONES];
int framesize;
static double coef[];
static int k[];
static const char *dtran[];
static int row[];
static int col[];
static const char rc[];
double outbuf[16384];
double shape[128];
int RT;
int duration;
int silence_time;
int last;
std::string dtmfchars;
public:
cDTMF() {
for (int i = 0; i < 4; i++) filt[i] = new goertzel(240, row[i], 8000);
for (int i = 0; i < 4; i++) filt[i+4] = new goertzel(240, col[i], 8000);
for (int i = 0; i < N; i++) data[i] = 0;
dtmfchars.clear();
framesize = 240; // 8000 sr default
silence_time = 0;
last = ' ';
}
~cDTMF() {};
// receive
void calc_power();
int decode();
void receive(const float* buf, size_t len);
// transmit
void makeshape();
void silence(int);
void two_tones(int);
void send();
};

Wyświetl plik

@ -172,6 +172,9 @@ extern Digiscope *digiscope;
extern std::string main_window_title;
extern int Qwait_time;
extern int Qidle_time;
extern void toggleRSID();
extern void set_menus();
@ -190,7 +193,7 @@ extern void cb_mnuVisitURL(Fl_Widget*, void* arg);
extern void put_freq(double frequency);
extern void put_Bandwidth(int bandwidth);
extern void display_metric(double metric);
extern void global_display_metric(double metric);
extern void put_cwRcvWPM(double wpm);
extern void set_scope_mode(Digiscope::scope_mode md);
@ -224,6 +227,7 @@ extern void show_bw(const std::string& sWidth);
extern void show_spot(bool v);
extern void showMacroSet();
extern void setwfrange();
extern void showDTMF(const std::string s);
extern void xmtrcv_selection_color();
extern void rev_selection_color();
@ -239,6 +243,10 @@ extern void put_WARNstatus(double);
extern void qsoSave_cb(Fl_Widget *b, void *);
extern bool que_ok;
extern void post_queue_execute(void*);
extern void queue_execute_after_rx(void*);
extern void put_rx_data(int *data, int len);
extern int get_tx_char();
extern int get_secondary_char();
@ -284,6 +292,10 @@ extern void set_contestia_default_integ();
extern void startMacroTimer();
extern void stopMacroTimer();
extern void macro_timer(void *);
extern void macro_timed_execute(void *);
extern void startTimedExecute(std::string &);
extern void cb_ResetSerNbr();
extern void updateOutSerNo();
@ -314,6 +326,7 @@ void set_contestia_tones(int tones);
void set_rtty_shift(int shift);
void set_rtty_baud(float baud);
void set_rtty_bits(int bits);
void set_rtty_bw(float bw);
void sync_cw_parameters();

Wyświetl plik

@ -49,6 +49,8 @@ enum {
MODE_PREV = -2,
MODE_NEXT,
MODE_NULL,
MODE_CW,
MODE_CONTESTIA,

Wyświetl plik

@ -83,6 +83,8 @@ extern void cb_btnUpdateCancel(Fl_Button*, void*);
extern Fl_Button *bUpdateCancel;
extern void cb_btnDelete(Fl_Button*, void*);
extern Fl_Button *bDelete;
extern void cb_btnDialFreq(Fl_Button*, void*);
extern Fl_Button *bDialFreq;
extern Fl_Input2 *txtNbrRecs_log;
extern Fl_Input2 *inpSerNoOut_log;
extern Fl_Input2 *inpMyXchg_log;

Wyświetl plik

@ -52,6 +52,7 @@ extern void clearRecord ();
extern void updateRecord ();
extern void deleteRecord ();
extern void AddRecord ();
extern void DisplayRecord (int idxRec);
extern void SearchLastQSO (const char *);
extern cQsoRec* SearchLog(const char *callsign);
extern void DupCheck();

Wyświetl plik

@ -16,6 +16,9 @@ extern std::string lookup_country;
extern void clear_Lookup();
extern void CALLSIGNquery();
enum qrz_query_t { QRZ_EXIT = -1, QRZNONE, QRZNET, QRZCD, HAMCALLNET, QRZHTML, HAMCALLHTML, CALLOOK };
enum qrz_query_t { QRZ_EXIT = -1, QRZNONE, QRZNET, QRZCD, HAMCALLNET, QRZHTML, HAMCALLHTML, CALLOOK, HAMQTH };
extern void sendEQSL(const char *url);
extern void makeEQSL(const char *msg);
#endif

Wyświetl plik

@ -5,6 +5,10 @@
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Hold_Browser.H>
#include <FL/Fl_Pixmap.H>
#include <FL/Fl_Group.H>
#include <FL/Fl_Box.H>
#include "flinput2.h"
extern void loadBrowser(Fl_Widget *widget);

Wyświetl plik

@ -36,13 +36,14 @@ struct MACROTEXT {
void openMacroFile();
void saveMacroFile();
void saveMacros(const std::string& fname);
std::string expandMacro(int n);
std::string expandMacro(std::string &s);
void execute(int n);
void repeat(int n);
void timed_execute();
MACROTEXT();
private:
std::string expanded;
void loadnewMACROS(std::string& s, size_t &i);
void loadnewMACROS(std::string& s, size_t &i, size_t endbracket);
};
extern MACROTEXT macros;
@ -52,7 +53,20 @@ extern std::string info1msg;
extern std::string info2msg;
extern std::string qso_time;
extern std::string qso_exchange;
extern std::string exec_date;
extern std::string exec_time;
extern std::string exec_string;
extern std::string text2repeat;
extern bool macro_idle_on;
extern size_t repeatchar;
void set_macro_env(void);
void queue_reset();
void queue_execute();
bool queue_must_rx();
void idleTimer(void *);
#endif

Wyświetl plik

@ -38,6 +38,15 @@ extern std::string ICS_dir;
extern std::string ICS_msg_dir;
extern std::string ICS_tmp_dir;
extern std::string FLMSG_dir;
extern std::string FLMSG_WRAP_dir;
extern std::string FLMSG_WRAP_recv_dir;
extern std::string FLMSG_WRAP_send_dir;
extern std::string FLMSG_WRAP_auto_dir;
extern std::string FLMSG_ICS_dir;
extern std::string FLMSG_ICS_msg_dir;
extern std::string FLMSG_ICS_tmp_dir;
extern std::string xmlfname;
extern std::string scDevice[2];

Wyświetl plik

@ -87,17 +87,11 @@ public:
virtual void searchDown() {};
virtual void searchUp() {};
// void update_syncscope();
void HistoryON(bool val) {historyON = val;}
bool HistoryON() { return historyON;}
// void set_mode(trx_mode);
trx_mode get_mode();
const char *get_mode_name() { return mode_info[get_mode()].sname;}
// void set_state(state_t);
// void set_state_wait(state_t);
// state_t get_state();
virtual void set_freq(double);
int get_freq();
void init_freqlock();
@ -107,6 +101,7 @@ public:
double get_txfreq();
double get_txfreq_woffset();
void set_metric(double);
void display_metric(double);
double get_metric();
void set_reverse(bool on);
bool get_reverse() { return reverse; }
@ -157,8 +152,6 @@ private:
void wfid_make_tones(int numchars);
void wfid_send(int numchars);
// double peakval(int symbol, int mask);
// int findmask(int symbol);
void wfid_sendchars(std::string s);
@ -192,6 +185,8 @@ protected:
virtual void s2nreport(void);
};
extern modem *null_modem;
extern modem *cw_modem;
extern modem *mfsk8_modem;

Wyświetl plik

@ -0,0 +1,48 @@
// ----------------------------------------------------------------------------
// NULLMODEM.h -- BASIS FOR ALL MODEMS
//
// Copyright (C) 2006
// Dave Freese, W1HKJ
//
// 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 fldigi. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#ifndef _NULLMODEM_H
#define _NULLMODEM_H
#include "trx.h"
#include "modem.h"
#include "fft.h"
#include "filters.h"
#include "complex.h"
#define NULLMODEMSampleRate 8000
class NULLMODEM : public modem {
protected:
public:
NULLMODEM();
~NULLMODEM();
void init();
void rx_init();
void restart();
void tx_init(SoundBase *sc);
int rx_process(const double *buf, int len);
int tx_process();
};
#endif

Wyświetl plik

@ -30,7 +30,7 @@ public:
void putField (int, const char *);
void putField (int, const char *, int);
void addtoField (int, const char *);
const char *getField (int);
const char *getField (int) const;
void trimFields();
void clearRec ();
int validRec();

Wyświetl plik

@ -49,7 +49,7 @@ int pthread_cond_timedwait_rel(pthread_cond_t* cond, pthread_mutex_t* mutex, dou
//};
enum {
INVALID_TID = -1,
TRX_TID, QRZ_TID, RIGCTL_TID, NORIGCTL_TID,
TRX_TID, QRZ_TID, RIGCTL_TID, NORIGCTL_TID, EQSL_TID,
#if USE_XMLRPC
XMLRPC_TID,
#endif
@ -125,4 +125,28 @@ bool thread_in_list(int id, const int* list);
#include "fl_lock.h"
/// This ensures that a mutex is always unlocked when leaving a function or block.
class guard_lock
{
public:
guard_lock(pthread_mutex_t* m);
~guard_lock(void);
private:
pthread_mutex_t* mutex;
};
/// This wraps together a mutex and a condition variable which are used
/// together very often for queues etc...
class syncobj
{
pthread_mutex_t m_mutex ;
pthread_cond_t m_cond ;
public:
syncobj();
~syncobj();
pthread_mutex_t * mtxp(void) { return & m_mutex; }
void signal();
bool wait( double seconds );
};
#endif // !THREADS_H_

Wyświetl plik

@ -43,11 +43,8 @@ extern void trx_tune();
extern void trx_receive();
extern void trx_reset(void);
extern void trx_start_macro_timer();
extern void trx_wait_state(void);
extern void macro_timer(void *);
extern void trx_wait_state(void);
extern state_t trx_state;
extern modem *active_modem;

Wyświetl plik

@ -35,6 +35,8 @@ public:
static void setpicture_link(wefax *me);
static void save_image(const std::string & fil_name, const std::string & extra_comments);
static void power( double start, double phase, double image, double black, double stop );
static void send_image( const std::string & fil_name );
static void restore_max_lines(void);
};
#endif // _WEFAX_PIC_H

Wyświetl plik

@ -28,6 +28,11 @@ class wefax : public modem {
/// For updating the logbook when loading/saving an image file.
cQsoRec m_qso_rec ;
/// Non-copiable object.
wefax ();
wefax ( const wefax & );
wefax & operator=( const wefax & );
public:
wefax (trx_mode md);
virtual ~wefax ();
@ -103,6 +108,27 @@ public:
{
m_adif_log = the_flag ;
}
/// Helper string indicating the internal state of the wefax engine.
std::string state_string(void) const;
/// Maximum wait time when getting information about received and sent files.
static const int max_delay = 3600 * 24 * 365 ;
/// Called by the engine when a file is received.
void put_received_file(const std::string & filnam);
/// Used by XML-RPC to get the list of received files.
std::string get_received_file(double max_seconds=max_delay);
/// Called by XML-RPC to send a file which resides on the machine where fldigi runs.
std::string send_file( const std::string & filnam, double max_seconds=max_delay);
/// Called before sending a file. Transmitting is an exclusive process.
bool transmit_lock_acquire( const std::string & filnam, double max_seconds=max_delay);
/// Called after sending a file so another sending can take place.
void transmit_lock_release( const std::string & err_msg );
};
#endif

Wyświetl plik

@ -69,6 +69,15 @@ protected:
bool calc;
bool zoom;
double keyshape[32]; // 4 msec rise and fall time for pulse
double audio[400];
double quiet[400];
double play[400];
double nco(double freq);
void makeshape();
void makeaudio();
public:
wwv();
~wwv();
@ -77,7 +86,7 @@ public:
void tx_init(SoundBase *sc);
void restart() {};
int rx_process(const double *buf, int len);
int tx_process() {return -1;}
int tx_process();
void update_syncscope();
void set1(int x, int y);
void set2(int x, int y);

Wyświetl plik

@ -90,13 +90,13 @@ FIELD fields[] = {
{XCHG1, 0, &btnSelectXchgIn} // contest exchange #1 / free1 in xlog
};
void initfields()
static void initfields()
{
for (int i = 0; i < NUMFIELDS; i++)
fields[i].name = new string(fieldnames[i]);
}
int findfield( char *p )
static int findfield( const char *p )
{
int m;
int test;

Wyświetl plik

@ -261,6 +261,8 @@ Fl_Button *bUpdateCancel=(Fl_Button *)0;
Fl_Button *bDelete=(Fl_Button *)0;
Fl_Button *bDialFreq=(Fl_Button *)0;
Fl_Input2 *txtNbrRecs_log=(Fl_Input2 *)0;
Fl_Input2 *inpSerNoOut_log=(Fl_Input2 *)0;
@ -818,23 +820,33 @@ void create_logbook_dialogs() {
inpNotes_log->when(FL_WHEN_RELEASE);
} // Fl_Input2* inpNotes_log
{ bNewSave = new Fl_Button(163, 263, 55, 22, _("New"));
bNewSave->tooltip(_("New record / Save record"));
bNewSave->shortcut(0x8004e);
bNewSave->color((Fl_Color)FL_LIGHT1);
bNewSave->selection_color((Fl_Color)48);
bNewSave->callback((Fl_Callback*)cb_btnNewSave);
} // Fl_Button* bNewSave
{ bUpdateCancel = new Fl_Button(235, 263, 55, 22, _("Update"));
bUpdateCancel->tooltip(_("Update the current record"));
bUpdateCancel->shortcut(0x80055);
bUpdateCancel->color((Fl_Color)FL_LIGHT1);
bUpdateCancel->selection_color((Fl_Color)48);
bUpdateCancel->callback((Fl_Callback*)cb_btnUpdateCancel);
} // Fl_Button* bUpdateCancel
{ bDelete = new Fl_Button(307, 263, 55, 22, _("Delete"));
bDelete->tooltip(_("Delete the current record"));
bDelete->shortcut(0x80044);
bDelete->color((Fl_Color)FL_LIGHT1);
bDelete->selection_color((Fl_Color)48);
bDelete->callback((Fl_Callback*)cb_btnDelete);
} // Fl_Button* bDelete
{ bDialFreq = new Fl_Button(380, 263, 55, 22, _("Dial"));
bDialFreq->tooltip(_("Retrieve for active modem use"));
bDialFreq->shortcut(0x50066);
bDialFreq->color((Fl_Color)FL_LIGHT1);
bDialFreq->selection_color((Fl_Color)48);
bDialFreq->callback((Fl_Callback*)cb_btnDialFreq);
} // Fl_Button* bDialFreq
{ txtNbrRecs_log = new Fl_Input2(41, 263, 65, 22, _("Recs"));
txtNbrRecs_log->tooltip(_("# Records in logbook"));
txtNbrRecs_log->box(FL_DOWN_BOX);

Wyświetl plik

@ -20,7 +20,7 @@ Function {create_logbook_dialogs()} {open return_type void
} {
Fl_Window wExport {
label {Export Setup} open
xywh {588 534 655 385} type Double modal visible
xywh {588 534 655 385} type Double hide modal
} {
Fl_Group {} {
label {Select Records to Export} open
@ -283,7 +283,7 @@ btnSelectNotes->value(0);}
label Logbook open
xywh {574 55 585 410} type Double color 47 resizable visible
} {
Fl_Group editGroup {open selected
Fl_Group editGroup {open
xywh {2 2 602 290} box ENGRAVED_FRAME color 52
} {
Fl_Input inpDate_log {
@ -420,17 +420,22 @@ btnSelectNotes->value(0);}
Fl_Button bNewSave {
label New
callback cb_btnNewSave
xywh {163 263 55 22} shortcut 0x8004e color 50 selection_color 48
tooltip {New record / Save record} xywh {163 263 55 22} shortcut 0x8004e color 50 selection_color 48
}
Fl_Button bUpdateCancel {
label Update
callback cb_btnUpdateCancel
xywh {235 263 55 22} shortcut 0x80055 color 50 selection_color 48
tooltip {Update the current record} xywh {235 263 55 22} shortcut 0x80055 color 50 selection_color 48
}
Fl_Button bDelete {
label Delete
callback cb_btnDelete
xywh {307 263 55 22} shortcut 0x80044 color 50 selection_color 48
tooltip {Delete the current record} xywh {307 263 55 22} shortcut 0x80044 color 50 selection_color 48
}
Fl_Button bDialFreq {
label Dial
callback cb_btnDialFreq
tooltip {Retrieve for active modem use} xywh {380 263 55 22} shortcut 0x50066 color 50 selection_color 48
}
Fl_Input txtNbrRecs_log {
label Recs
@ -475,7 +480,7 @@ btnSelectNotes->value(0);}
code0 {bSearchPrev->image(new Fl_Pixmap(left_arrow_icon));}
}
Fl_Button bSearchNext {
callback cb_search
callback cb_search selected
tooltip {Find next} xywh {550 263 24 22} color 50 selection_color 48 align 16
code0 {bSearchNext->image(new Fl_Pixmap(right_arrow_icon));}
}

Wyświetl plik

@ -42,6 +42,7 @@
#include "adif_io.h"
#include "textio.h"
#include "logbook.h"
#include "rigsupport.h"
#include "logger.h"
#include "fl_digi.h"
@ -165,6 +166,9 @@ static void dxcc_entity_cache_rm(cQsoRec* r);
static void dxcc_entity_cache_add(cQsoDb& db);
void cb_mnuNewLogbook(Fl_Menu_* m, void* d){
if (!fl_choice2(_("Create New Logbook?"), _("No"), _("Yes"), NULL))
return;
saveLogbook();
logbook_filename = LogsDir;
@ -544,7 +548,51 @@ int log_search_handler(int)
return 1;
}
int editNbr = 0;
static int editNbr = 0;
void cb_btnDialFreq(Fl_Button* b, void* d)
{
double drf = atof(inpFreq_log->value());
if (!drf) return;
int rf1, rf, audio;
rf1 = drf * 1e6;
rf = rf1 / 10000;
rf *= 10000;
audio = rf1 - rf;
// try to keep within normal xcvr bw, 500 - 3000 Hz
while (audio > 3000) {
audio -= 3000;
rf += 3000;
}
if (audio < 500) {
audio += 500;
rf -= 500;
}
qsy(rf, audio);
std::string mode_name = inpMode_log->value();
trx_mode m;
for (m = 0; m < NUM_MODES; m++)
if (mode_name == mode_info[m].adif_name)
break;
// do we have a valid modem?
if (m < NUM_MODES && active_modem->get_mode() != mode_info[m].mode)
init_modem(mode_info[m].mode);
const cQsoRec *qsoPtr = qsodb.getRec(editNbr);
inpCall->value(qsoPtr->getField(CALL));
inpName->value (qsoPtr->getField(NAME));
inpTimeOn->value (inpTimeOff->value());
inpState->value (qsoPtr->getField(STATE));
inpCountry->value (qsoPtr->getField(COUNTRY));
inpXchgIn->value(qsoPtr->getField(XCHG1));
inpQth->value (qsoPtr->getField(QTH));
inpLoc->value (qsoPtr->getField(GRIDSQUARE));
inpNotes->value (qsoPtr->getField(NOTES));
wBrowser->take_focus();
}
void clearRecord() {
Date tdy;

Wyświetl plik

@ -106,7 +106,7 @@ void cQsoRec::trimFields () {
}
}
const char * cQsoRec::getField (int n) {
const char * cQsoRec::getField (int n) const {
if (n < 0 || n >= NUMFIELDS) return 0;
return (qsofield[n].c_str());
}

Wyświetl plik

@ -26,6 +26,8 @@
#include "util.h"
#include "date.h"
#include "logbook.h"
#include "logger.h"
#include "locator.h"
#include "fl_digi.h"
#include "adif_io.h"
#include "modem.h"
@ -119,6 +121,19 @@ bool xml_get_record(const char *callsign)
inpLoc->value("");
inpNotes->value("");
}
if (inpLoc->value()[0]) {
double lon1, lat1, lon2, lat2;
double azimuth, distance;
char szAZ[4];
if ( locator2longlat(&lon1, &lat1, progdefaults.myLocator.c_str()) == RIG_OK &&
locator2longlat(&lon2, &lat2, inpLoc->value()) == RIG_OK &&
qrb(lon1, lat1, lon2, lat2, &distance, &azimuth) == RIG_OK ) {
snprintf(szAZ,sizeof(szAZ),"%0.f", azimuth);
inpAZ->value(szAZ);
} else
inpAZ->value("");
} else
inpAZ->value("");
return true;
}

Wyświetl plik

@ -46,6 +46,7 @@
#include "configuration.h"
#include "logsupport.h"
#include "lookupcall.h"
#include <FL/fl_ask.H>
@ -215,6 +216,9 @@ void submit_log(void)
logmode = mode_info[active_modem->get_mode()].adif_name;
if (progdefaults.eqsl_when_logged)
makeEQSL("");
if (progdefaults.xml_logbook)
xml_add_record();
else

Wyświetl plik

@ -104,7 +104,7 @@ void rx_extract_add(int c)
gmtime_r(&t, &tim);
strftime(dttm, sizeof(dttm), "%Y%m%d-%H%M%S", &tim);
string outfilename = WRAP_recv_dir;
string outfilename = FLMSG_WRAP_recv_dir;
outfilename.append("extract-");
outfilename.append(dttm);
outfilename.append(".wrap");
@ -114,11 +114,11 @@ void rx_extract_add(int c)
extractstream.close();
}
rx_extract_msg = "File saved in ";
rx_extract_msg.append(WRAP_recv_dir);
rx_extract_msg.append(FLMSG_WRAP_recv_dir);
put_status(rx_extract_msg.c_str(), 20, STATUS_CLEAR);
if (progdefaults.open_nbems_folder)
open_recv_folder(WRAP_recv_dir.c_str());
open_recv_folder(FLMSG_WRAP_recv_dir.c_str());
if ((progdefaults.open_flmsg || progdefaults.open_flmsg_print) &&
(rx_buff.find(flmsg) != string::npos) &&

Wyświetl plik

@ -120,30 +120,41 @@ string appname;
string scDevice[2];
string HomeDir;
string RigsDir;
string ScriptsDir;
string PalettesDir;
string LogsDir;
string PicsDir;
string HelpDir;
string MacrosDir;
string WrapDir;
string TalkDir;
string TempDir;
string PskMailDir;
string NBEMS_dir;
string ARQ_dir;
string ARQ_files_dir;
string ARQ_recv_dir;
string ARQ_send;
string WRAP_dir;
string WRAP_recv_dir;
string WRAP_send_dir;
string WRAP_auto_dir;
string ICS_dir;
string ICS_msg_dir;
string ICS_tmp_dir;
string HomeDir = "";
string RigsDir = "";
string ScriptsDir = "";
string PalettesDir = "";
string LogsDir = "";
string PicsDir = "";
string HelpDir = "";
string MacrosDir = "";
string WrapDir = "";
string TalkDir = "";
string TempDir = "";
string PskMailDir = "";
string NBEMS_dir = "";
string ARQ_dir = "";
string ARQ_files_dir = "";
string ARQ_recv_dir = "";
string ARQ_send = "";
string WRAP_dir = "";
string WRAP_recv_dir = "";
string WRAP_send_dir = "";
string WRAP_auto_dir = "";
string ICS_dir = "";
string ICS_msg_dir = "";
string ICS_tmp_dir = "";
string FLMSG_dir = "";
string FLMSG_dir_default = "";
string FLMSG_WRAP_dir = "";
string FLMSG_WRAP_recv_dir = "";
string FLMSG_WRAP_send_dir = "";
string FLMSG_WRAP_auto_dir = "";
string FLMSG_ICS_dir = "";
string FLMSG_ICS_msg_dir = "";
string FLMSG_ICS_tmp_dir = "";
string PskMailFile;
string ArqFilename;
@ -223,6 +234,7 @@ int main(int argc, char ** argv)
NBEMS_dir = dirbuf;
fl_filename_expand(dirbuf, sizeof(dirbuf) - 1, "$USERPROFILE/");
PskMailDir = dirbuf;
FLMSG_dir_default = "$USERPROFILE/NBEMS.files/";
#else
fl_filename_expand(dirbuf, sizeof(dirbuf) - 1, "$HOME/.dl-fldigi/");
HomeDir = dirbuf;
@ -230,6 +242,7 @@ int main(int argc, char ** argv)
NBEMS_dir = dirbuf;
fl_filename_expand(dirbuf, sizeof(dirbuf) - 1, "$HOME/");
PskMailDir = dirbuf;
FLMSG_dir_default = "$HOME/.nbems/";
#endif
}
@ -245,6 +258,13 @@ int main(int argc, char ** argv)
if (main_window_title.empty())
main_window_title = PACKAGE_TARNAME;
{
char dirbuf[FL_PATH_MAX + 1];
if (FLMSG_dir_default[FLMSG_dir_default.length()-1] != '/')
FLMSG_dir_default += '/';
fl_filename_expand(dirbuf, sizeof(dirbuf) - 1, FLMSG_dir_default.c_str());
FLMSG_dir = dirbuf;
}
checkdirectories();
check_nbems_dirs();
@ -467,6 +487,12 @@ void generate_option_help(void) {
<< " --arq-server-port PORT\n"
<< " Set the ARQ TCP server port\n"
<< " The default is: " << progdefaults.arq_port << "\n\n"
<< " --flmsg-dir DIRECTORY\n"
<< " Look for flmsg files in DIRECTORY\n"
<< " The default is " << FLMSG_dir_default << "\n\n"
<< " --auto-dir DIRECTORY\n"
<< " Look for auto-send files in DIRECTORY\n"
<< " The default is " << HomeDir << "/autosend" << "\n\n"
#if USE_XMLRPC
<< " --xmlrpc-server-address HOSTNAME\n"
@ -619,6 +645,8 @@ int parse_args(int argc, char **argv, int& idx)
OPT_CONFIG_DIR,
OPT_ARQ_ADDRESS, OPT_ARQ_PORT,
OPT_SHOW_CPU_CHECK,
OPT_FLMSG_DIR,
OPT_AUTOSEND_DIR,
#if USE_XMLRPC
OPT_CONFIG_XMLRPC_ADDRESS, OPT_CONFIG_XMLRPC_PORT,
@ -651,6 +679,8 @@ int parse_args(int argc, char **argv, int& idx)
{ "arq-server-address", 1, 0, OPT_ARQ_ADDRESS },
{ "arq-server-port", 1, 0, OPT_ARQ_PORT },
{ "flmsg-dir", 1, 0, OPT_FLMSG_DIR },
{ "auto-dir", 1, 0, OPT_AUTOSEND_DIR },
{ "cpu-speed-test", 0, 0, OPT_SHOW_CPU_CHECK },
@ -740,6 +770,14 @@ int parse_args(int argc, char **argv, int& idx)
progdefaults.arq_port = optarg;
break;
case OPT_FLMSG_DIR:
FLMSG_dir_default = optarg;
break;
case OPT_AUTOSEND_DIR:
FLMSG_WRAP_auto_dir = optarg;
break;
#if USE_XMLRPC
case OPT_CONFIG_XMLRPC_ADDRESS:
progdefaults.xmlrpc_address = optarg;
@ -1164,6 +1202,31 @@ void check_nbems_dirs(void)
else if (r == 0 && NBEMS_dirs[i].new_dir_func)
NBEMS_dirs[i].new_dir_func();
}
DIRS FLMSG_dirs[] = {
{ FLMSG_dir, 0, 0 },
{ FLMSG_WRAP_dir, "WRAP", 0 },
{ FLMSG_WRAP_recv_dir, "WRAP/recv", 0 },
{ FLMSG_WRAP_send_dir, "WRAP/send", 0 },
{ FLMSG_WRAP_auto_dir, "WRAP/auto", 0 },
{ FLMSG_ICS_dir, "ICS", 0 },
{ FLMSG_ICS_msg_dir, "ICS/messages", 0 },
{ FLMSG_ICS_tmp_dir, "ICS/templates", 0 },
};
for (size_t i = 0; i < sizeof(FLMSG_dirs)/sizeof(*FLMSG_dirs); i++) {
if (FLMSG_dirs[i].dir.empty() && FLMSG_dirs[i].suffix)
FLMSG_dirs[i].dir.assign(FLMSG_dir).append(FLMSG_dirs[i].suffix).append("/");
if ((r = mkdir(FLMSG_dirs[i].dir.c_str(), 0777)) == -1 && errno != EEXIST) {
cerr << _("Could not make directory") << ' ' << FLMSG_dirs[i].dir
<< ": " << strerror(errno) << '\n';
exit(EXIT_FAILURE);
}
else if (r == 0 && FLMSG_dirs[i].new_dir_func)
FLMSG_dirs[i].new_dir_func();
}
nbems_dirs_checked = true;
}

Wyświetl plik

@ -517,7 +517,7 @@ void mfsk::softdecode(complex *bins)
// shift to range 0...255
for (i = 0; i < symbits; i++)
if (staticburst)
symbols[i] = 0; // puncturing
symbols[i] = 128; // puncturing 128 is neither 0 nor a 1
else
symbols[i] = (unsigned char)clamp(128.0 + (b[i] / sum * 128.0), 0, 255);

Wyświetl plik

@ -380,7 +380,7 @@ bool WRAP_auto_arqRx()
{
time_t start_time, prog_time;
static char mailline[1000];
string sAutoFile = WRAP_auto_dir;
string sAutoFile = FLMSG_WRAP_auto_dir;
sAutoFile += "wrap_auto_file";
ifstream autofile(sAutoFile.c_str());

Wyświetl plik

@ -654,6 +654,9 @@ int configuration::setDefaults()
case CALLOOK:
qrzb = btnCALLOOK;
break;
case HAMQTH:
qrzb = btnHamQTH;
break;
default :
break;
}

Wyświetl plik

@ -44,10 +44,12 @@
#include "configuration.h"
#include "lookupcall.h"
#include "logsupport.h"
#include "main.h"
#include "confdialog.h"
#include "fl_digi.h"
#include "qrzlib.h"
#include "trx.h"
#include "xmlreader.h"
@ -150,7 +152,7 @@ bool parseSessionKey(const string& sessionpage)
{
case EXN_TEXT:
case EXN_CDATA:
switch (tag)
switch (tag)
{
default:
break;
@ -188,7 +190,7 @@ bool parseSessionKey(const string& sessionpage)
}
delete xml;
return true;
}
}
bool parse_xml(const string& xmlpage)
@ -196,7 +198,7 @@ bool parse_xml(const string& xmlpage)
//printf("%s\n", xmlpage.c_str());
IrrXMLReader* xml = createIrrXMLReader(new IIrrXMLStringReader(xmlpage));
// If we got any result back, clear the session key so that it will be
// If we got any result back, clear the session key so that it will be
// refreshed by this response, or if not present, will be removed and we'll
// know to log in next time.
if (xml) {
@ -207,7 +209,7 @@ bool parse_xml(const string& xmlpage)
}
TAG tag = QRZ_IGNORE;
// parse the file until end reached
while(xml && xml->read()) {
switch(xml->getNodeType()) {
@ -269,12 +271,12 @@ bool parse_xml(const string& xmlpage)
break;
}
break;
case EXN_ELEMENT_END:
tag=QRZ_IGNORE;
break;
case EXN_ELEMENT:
case EXN_ELEMENT:
{
const char *nodeName = xml->getNodeName();
if (!strcmp("call", nodeName)) tag = QRZ_CALL;
@ -390,11 +392,11 @@ void QRZ_disp_result()
}
inpQth->value(lookup_qth.c_str());
inpState->value(lookup_state.c_str());
inpVEprov->value(lookup_province.c_str());
inpLoc->value(lookup_grid.c_str());
if (!lookup_country.empty())
@ -419,7 +421,7 @@ void QRZ_CD_query()
char srch[20];
size_t snip;
memset( srch, 0, sizeof(srch) );
strncpy( srch, callsign.c_str(), 6 );
for (size_t i = 0; i < strlen(srch); i ++ )
@ -652,36 +654,36 @@ void CALLOOKquery()
void parse_html(const string& htmlpage)
{
size_t p;
clear_Lookup();
if ((p = htmlpage.find(HAMCALL_FIRST)) != string::npos) {
p++;
while ((uchar)htmlpage[p] < 128 && p < htmlpage.length() )
lookup_fname += htmlpage[p++];
camel_case(lookup_fname);
}
if ((p = htmlpage.find(HAMCALL_CITY)) != string::npos) {
if ((p = htmlpage.find(HAMCALL_CITY)) != string::npos) {
p++;
while ((uchar)htmlpage[p] < 128 && p < htmlpage.length())
lookup_qth += htmlpage[p++];
}
if ((p = htmlpage.find(HAMCALL_STATE)) != string::npos) {
if ((p = htmlpage.find(HAMCALL_STATE)) != string::npos) {
p++;
while ((uchar)htmlpage[p] < 128 && p < htmlpage.length())
lookup_state += htmlpage[p++];
}
if ((p = htmlpage.find(HAMCALL_GRID)) != string::npos) {
if ((p = htmlpage.find(HAMCALL_GRID)) != string::npos) {
p++;
while ((uchar)htmlpage[p] < 128 && p < htmlpage.length())
lookup_grid += htmlpage[p++];
}
if ((p = htmlpage.find(HAMCALL_DOB)) != string::npos) {
if ((p = htmlpage.find(HAMCALL_DOB)) != string::npos) {
p++;
lookup_notes = "DOB: ";
while ((uchar)htmlpage[p] < 128 && p < htmlpage.length())
lookup_notes += htmlpage[p++];
}
}
}
bool HAMCALLget(string& htmlpage)
@ -713,11 +715,186 @@ void HAMCALLquery()
REQ(QRZ_disp_result);
}
// ---------------------------------------------------------------------
// Hamcall specific functions
// ---------------------------------------------------------------------
static string HAMQTH_session_id = "";
static string HAMQTH_reply = "";
#define HAMQTH_DEBUG 1
#undef HAMQTH_DEBUG
bool HAMQTH_get_session_id()
{
string url = "";
string retstr = "";
size_t p1 = string::npos;
size_t p2 = string::npos;
url.append("http://www.hamqth.com/xml.php?u=").append(progdefaults.QRZusername);
url.append("&p=").append(progdefaults.QRZuserpassword);
HAMQTH_session_id.clear();
if (!fetch_http(url, retstr, 5.0)) {
return false;
}
if ((p1 = retstr.find("<error>")) != string::npos) {
p2 = retstr.find("</error>");
lookup_notes = retstr.substr(p1 + 7, p2 - p1 - 7);
return false;
}
if ((p1 = retstr.find("<session_id>")) == string::npos) {
lookup_notes = "HamQTH not available";
return false;
}
p2 = retstr.find("</session_id>");
HAMQTH_session_id = retstr.substr(p1 + 12, p2 - p1 - 12);
//#ifdef HAMQTH_DEBUG
// printf("session id = %s\n", HAMQTH_session_id.c_str());
//#endif
return true;
}
void parse_HAMQTH_html(const string& htmlpage)
{
size_t p = string::npos;
size_t p1 = string::npos;
clear_Lookup();
lookup_fname.clear();
lookup_qth.clear();
lookup_state.clear();
lookup_grid.clear();
lookup_notes.clear();
lookup_country.clear();
if ((p = htmlpage.find("<error>")) != string::npos) {
p += 7;
p1 = htmlpage.find("</error>");
if (p1 != string::npos)
lookup_notes.append(htmlpage.substr(p, p1 - p));
return;
}
if ((p = htmlpage.find("<nick>")) != string::npos) {
p += 6;
p1 = htmlpage.find("</nick>", p);
if (p1 != string::npos) {
lookup_fname = htmlpage.substr(p, p1 - p);
camel_case(lookup_fname);
}
}
if ((p = htmlpage.find("<qth>")) != string::npos) {
p += 5;
p1 = htmlpage.find("</qth>", p);
if (p1 != string::npos)
lookup_qth = htmlpage.substr(p, p1 - p);
}
if ((p = htmlpage.find("<country>")) != string::npos) {
p += 9;
p1 = htmlpage.find("</country>", p);
if (p1 != string::npos)
lookup_country = htmlpage.substr(p, p1 - p);
}
if ((p = htmlpage.find("<us_state>")) != string::npos) {
p += 10;
p1 = htmlpage.find("</us_state>");
if (p1 != string::npos)
lookup_state = htmlpage.substr(p, p1 - p);
}
if ((p = htmlpage.find("<grid>")) != string::npos) {
p += 6;
p1 = htmlpage.find("</grid>");
if (p1 != string::npos)
lookup_grid = htmlpage.substr(p, p1 - p);
}
if ((p = htmlpage.find("<qsl_via>")) != string::npos) {
p += 9;
p1 = htmlpage.find("</qsl_via>");
if (p1 != string::npos)
lookup_notes.append("QSL via: ").append(htmlpage.substr(p, p1 - p)).append("\n");
}
if ((p = htmlpage.find("<adr_name>")) != string::npos) {
p += 10;
p1 = htmlpage.find("</adr_name>");
if (p1 != string::npos)
lookup_notes.append(htmlpage.substr(p, p1 - p)).append("\n");
}
if ((p = htmlpage.find("<adr_street1>")) != string::npos) {
p += 13;
p1 = htmlpage.find("</adr_street1>");
if (p1 != string::npos)
lookup_notes.append(htmlpage.substr(p, p1 - p)).append("\n");
}
if ((p = htmlpage.find("<adr_city>")) != string::npos) {
p += 10;
p1 = htmlpage.find("</adr_city>");
if (p1 != string::npos)
lookup_notes.append(htmlpage.substr(p, p1 - p)).append(", ").append(lookup_state);
}
if ((p = htmlpage.find("<adr_zip>")) != string::npos) {
p += 9;
p1 = htmlpage.find("</adr_zip>");
if (p1 != string::npos)
lookup_notes.append(" ").append(htmlpage.substr(p, p1 - p));
}
if ((p = htmlpage.find("<adr_country>")) != string::npos) {
p += 13;
p1 = htmlpage.find("</adr_country>");
if (p1 != string::npos)
lookup_notes.append(" ").append(htmlpage.substr(p, p1 - p));
}
}
bool HAMQTHget(string& htmlpage)
{
string url = "";
bool ret;
if (HAMQTH_session_id.empty()) {
if (!HAMQTH_get_session_id()) return false;
}
url.append("http://www.hamqth.com/xml.php?id=").append(HAMQTH_session_id);
url.append("&callsign=").append(callsign);
url.append("&prg=fldigi-").append(VERSION);
ret = fetch_http(url, htmlpage, 5.0);
if (htmlpage.find("<error>") != string::npos) {
htmlpage.clear();
if (!HAMQTH_get_session_id()) {
lookup_notes = "Get session id failed!\n";
return false;
}
ret = fetch_http(url, htmlpage, 5.0);
}
#ifdef HAMQTH_DEBUG
FILE *fetchit = fopen("fetchit.txt", "a");
fprintf(fetchit, "%s\n", htmlpage.c_str());
fclose(fetchit);
#endif
return ret;
}
void HAMQTHquery()
{
ENSURE_THREAD(QRZ_TID);
string htmlpage;
if (!HAMQTHget(htmlpage)) return;
parse_HAMQTH_html(htmlpage);
REQ(QRZ_disp_result);
}
// ----------------------------------------------------------------------------
void QRZ_DETAILS_query()
{
string qrzurl = "http://www.qrz.com/callsign.html?callsign=";
string qrzurl = "http://www.qrz.com/db/";
qrzurl.append(callsign);
cb_mnuVisitURL(0, (void*)qrzurl.c_str());
}
@ -725,7 +902,7 @@ void HAMCALL_DETAILS_query()
{
string hamcallurl = "http://www.hamcall.net/call?callsign=";
hamcallurl.append(callsign);
cb_mnuVisitURL(0, (void*)hamcallurl.c_str());
}
@ -762,6 +939,9 @@ static void *LOOKUP_loop(void *args)
case CALLOOK:
CALLOOKquery();
break;
case HAMQTH:
HAMQTHquery();
break;
case QRZ_EXIT:
return NULL;
default:
@ -815,6 +995,9 @@ void CALLSIGNquery()
case CALLOOK:
inpNotes->value("Request sent to\nhttp://callook.info...");
break;
case HAMQTH:
inpNotes->value("Request sent to \nhttp://hamqth.com...");
break;
default:
LOG_ERROR("Bad query type %d", DB_query);
return;
@ -824,3 +1007,201 @@ void CALLSIGNquery()
pthread_cond_signal(&qrz_cond);
pthread_mutex_unlock(&qrz_mutex);
}
//======================================================================
// thread to support sending log entry to eQSL
//======================================================================
pthread_t* EQSLthread = 0;
pthread_mutex_t EQSLmutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t EQSLcond = PTHREAD_COND_INITIALIZER;
static void *EQSL_loop(void *args);
static void EQSL_init(void);
void EQSL_close(void);
void EQSL_send();
static std::string EQSL_url = "";
static std::string EQSL_xmlpage = "";
static bool EQSLEXIT = false;
static void *EQSL_loop(void *args)
{
SET_THREAD_ID(EQSL_TID);
SET_THREAD_CANCEL();
for (;;) {
TEST_THREAD_CANCEL();
pthread_mutex_lock(&EQSLmutex);
pthread_cond_wait(&EQSLcond, &EQSLmutex);
pthread_mutex_unlock(&EQSLmutex);
if (EQSLEXIT)
return NULL;
size_t p;
if (fetch_http(EQSL_url, EQSL_xmlpage, 5.0) == -1)
LOG_ERROR("%s", "eQSL not available");
else if ((p = EQSL_xmlpage.find("Error:")) != std::string::npos) {
size_t p2 = EQSL_xmlpage.find('\n', p);
LOG_ERROR("%s\n%s", EQSL_xmlpage.substr(p, p2 - p - 1).c_str(), EQSL_url.c_str());
} else
LOG_INFO("eQSL logged %s", EQSL_url.c_str());
}
return NULL;
}
void EQSL_close(void)
{
ENSURE_THREAD(FLMAIN_TID);
if (!EQSLthread)
return;
CANCEL_THREAD(*EQSLthread);
pthread_mutex_lock(&qrz_mutex);
EQSLEXIT = true;
pthread_cond_signal(&qrz_cond);
pthread_mutex_unlock(&qrz_mutex);
pthread_join(*QRZ_thread, NULL);
delete QRZ_thread;
QRZ_thread = 0;
}
static void EQSL_init(void)
{
ENSURE_THREAD(FLMAIN_TID);
if (EQSLthread)
return;
EQSLthread = new pthread_t;
EQSLEXIT = false;
if (pthread_create(EQSLthread, NULL, EQSL_loop, NULL) != 0) {
LOG_PERROR("pthread_create");
return;
}
MilliSleep(10);
}
void sendEQSL(const char *url)
{
ENSURE_THREAD(FLMAIN_TID);
if (!EQSLthread)
EQSL_init();
pthread_mutex_lock(&EQSLmutex);
EQSL_url = url;
pthread_cond_signal(&EQSLcond);
pthread_mutex_unlock(&EQSLmutex);
}
// this function may be called from several places including macro
// expansion and execution
void makeEQSL(const char *message)
{
char sztemp[100];
std::string tempstr;
std::string eQSL_url;
std::string msg;
size_t p = 0;
msg = message;
if (msg.empty()) msg = progdefaults.eqsl_default_message;
// replace message tags {CALL}, {NAME}, {MODE}
while ((p = msg.find("{CALL}")) != std::string::npos)
msg.replace(p, 6, inpCall->value());
while ((p = msg.find("{NAME}")) != std::string::npos)
msg.replace(p, 6, inpName->value());
while ((p = msg.find("{MODE}")) != std::string::npos)
msg.replace(p, 6, mode_info[active_modem->get_mode()].adif_name);
// eqsl url header
eQSL_url = "http://www.eqsl.cc/qslcard/importADIF.cfm?ADIFdata=upload <adIF_ver:5>2.1.9";
snprintf(sztemp, sizeof(sztemp),"<EQSL_USER:%d>%s<EQSL_PSWD:%d>%s",
progdefaults.eqsl_id.length(), progdefaults.eqsl_id.c_str(),
progdefaults.eqsl_pwd.length(), progdefaults.eqsl_pwd.c_str());
eQSL_url.append(sztemp);
// eqsl nickname
if (!progdefaults.eqsl_nick.empty()) {
snprintf(sztemp, sizeof(sztemp), "<APP_EQSL_QTH_NICKNAME:%d>%s",
progdefaults.eqsl_nick.length(), progdefaults.eqsl_nick.c_str());
eQSL_url.append(sztemp);
}
eQSL_url.append("<PROGRAMID:6>FLDIGI<EOH>");
// eqsl record
// band
tempstr = band_name(band(wf->rfcarrier()));
snprintf(sztemp, sizeof(sztemp), "<BAND:%d>%s", tempstr.length(), tempstr.c_str());
eQSL_url.append(sztemp);
// call
tempstr = inpCall->value();
snprintf(sztemp, sizeof(sztemp), "<CALL:%d>%s", tempstr.length(), tempstr.c_str());
eQSL_url.append(sztemp);
// mode
tempstr = mode_info[active_modem->get_mode()].adif_name;
// test for modes not supported by eQSL
if ((tempstr.find("MFSK4") != std::string::npos) ||
(tempstr.find("MFSK11") != std::string::npos) ||
(tempstr.find("MFSK22") != std::string::npos) ||
(tempstr.find("MFSK31") != std::string::npos) ||
(tempstr.find("MFSK32") != std::string::npos) ||
(tempstr.find("MFSK64") != std::string::npos) )
tempstr = "MFSK16";
if ((tempstr.find("PSK250") != std::string::npos) ||
(tempstr.find("PSK500") != std::string::npos) ||
(tempstr.find("PSK125R") != std::string::npos) ||
(tempstr.find("PSK250R") != std::string::npos) ||
(tempstr.find("PSK500R") != std::string::npos))
tempstr = "PSK125";
if ((tempstr.find("QPSK250") != std::string::npos) ||
(tempstr.find("QPSK500") != std::string::npos) ||
(tempstr.find("QPSK125R") != std::string::npos) ||
(tempstr.find("QPSK250R") != std::string::npos) ||
(tempstr.find("QPSK500R") != std::string::npos))
tempstr = "QPSK125";
snprintf(sztemp, sizeof(sztemp), "<MODE:%d>%s", tempstr.length(), tempstr.c_str());
eQSL_url.append(sztemp);
// qso date
snprintf(sztemp, sizeof(sztemp), "<QSO_DATE:%d>%s", sDate_on.length(), sDate_on.c_str());
eQSL_url.append(sztemp);
// qso time
tempstr = inpTimeOn->value();
snprintf(sztemp, sizeof(sztemp), "<TIME_ON:%d>%s", tempstr.length(), tempstr.c_str());
eQSL_url.append(sztemp);
// rst sent
tempstr = inpRstOut->value();
snprintf(sztemp, sizeof(sztemp), "<RST_SENT:%d>%s", tempstr.length(), tempstr.c_str());
eQSL_url.append(sztemp);
// message
if (!msg.empty()) {
snprintf(sztemp, sizeof(sztemp), "<QSLMSG:%d>%s", msg.length(), msg.c_str());
eQSL_url.append(sztemp);
}
eQSL_url.append("<EOR>");
tempstr.clear();
for (size_t n = 0; n < eQSL_url.length(); n++) {
if (eQSL_url[n] == ' ') tempstr.append("%20");
else if (eQSL_url[n] == '<') tempstr.append("%3c");
else if (eQSL_url[n] == '>') tempstr.append("%3e");
else tempstr += eQSL_url[n];
}
sendEQSL(tempstr.c_str());
}

Wyświetl plik

@ -34,8 +34,6 @@
#include <cstring>
#include <cassert>
#include <FL/Fl_Pixmap.H>
#include "macros.h"
#include "macroedit.h"
#include "globals.h"
@ -52,12 +50,12 @@ using namespace std;
Fl_Double_Window *MacroEditDialog = (Fl_Double_Window *)0;
Fl_Button *btnMacroEditOK = (Fl_Button *)0;
Fl_Button *btnMacroEditCancel = (Fl_Button *)0;
Fl_Button *btnMacroEditApply = (Fl_Button *)0;
Fl_Button *btnMacroEditClose = (Fl_Button *)0;
Fl_Button *btnInsertMacro = (Fl_Button *)0;
Fl_Input2 *macrotext = (Fl_Input2 *)0;
Fl_Input2 *labeltext = (Fl_Input2 *)0;
static int widths[] = {130, 0};
static int widths[] = {150, 0};
Fl_Hold_Browser *macroDefs=(Fl_Hold_Browser *)0;
@ -106,6 +104,7 @@ void loadBrowser(Fl_Widget *widget) {
w->add(_("<LOG>\tsave QSO data"));
w->add(_("<LNW>\tlog at xmt time"));
w->add(_("<CLRLOG>\tclear log fields"));
w->add(_("<EQSL:[msg]>\tlog eQSL optional msg"));
w->add(LINE_SEP);
w->add(_("<QSOTIME>\tQSO time (HHMM))"));
@ -151,6 +150,7 @@ void loadBrowser(Fl_Widget *widget) {
w->add(_("<TUNE:NN>\ttune signal for NN sec"));
w->add(_("<WAIT:NN>\tdelay xmt for NN sec"));
w->add(_("<REPEAT>\trepeat macro continuously"));
w->add(_("<SKED:hhmm[:YYYYDDMM]>\tschedule execution"));
w->add(LINE_SEP);
w->add(_("<CWID>\tCW identifier"));
@ -158,6 +158,7 @@ void loadBrowser(Fl_Widget *widget) {
w->add(_("<TEXT>\tvideo text"));
w->add(_("<TXRSID:on|off|t>\tTx RSID on,off,toggle"));
w->add(_("<RXRSID:on|off|t>\tRx RSID on,off,toggle"));
w->add(_("<DTMF:[Wn:][Ln:]chrs>\t[Wait][Len](ms)"));
w->add(LINE_SEP);
w->add(_("<POST:+/-nn.n>\tCW QSK post-timing"));
@ -168,6 +169,7 @@ void loadBrowser(Fl_Widget *widget) {
w->add(LINE_SEP);
w->add(_("<AFC:on|off|t>\tAFC on,off,toggle"));
w->add(_("<LOCK:on|off|t>\tLOCK on,off,toggle"));
w->add(_("<REV:on|off|t>\tRev on,off,toggle"));
w->add(LINE_SEP);
w->add(_("<MACROS:>\tchange macro defs file"));
@ -201,7 +203,7 @@ void loadBrowser(Fl_Widget *widget) {
w->add(s);
}
// add some RTTY macros
const char* rtty[] = { "170:45.45:5", "170:50:5", "850:75:5" };
const char* rtty[] = { "170:45.45:5:90", "170:50:5:100", "850:75:5:150" };
for (size_t i = 0; i < sizeof(rtty)/sizeof(*rtty); i++) {
snprintf(s, sizeof(s), "<MODEM:%s:%s>", mode_info[MODE_RTTY].sname, rtty[i]);
w->add(s);
@ -239,8 +241,10 @@ void loadBrowser(Fl_Widget *widget) {
void cbMacroEditOK(Fl_Widget *w, void *)
{
if (w == btnMacroEditCancel)
goto ret;
if (w == btnMacroEditClose) {
MacroEditDialog->hide();
return;
}
if (iType == MACRO_EDIT_BUTTON) {
macros.text[iMacro] = macrotext->value();
@ -263,8 +267,6 @@ void cbMacroEditOK(Fl_Widget *w, void *)
}
else if (iType == MACRO_EDIT_INPUT)
iInput->value(macrotext->value());
ret:
MacroEditDialog->hide();
}
void cbInsertMacro(Fl_Widget *, void *)
@ -312,35 +314,65 @@ void cbInsertMacro(Fl_Widget *, void *)
macrotext->take_focus();
}
#include <FL/Fl_Tile.H>
Fl_Double_Window* make_macroeditor(void)
{
Fl_Double_Window* w = new Fl_Double_Window(768, 190, "");
Fl_Double_Window* w = new Fl_Double_Window(800, 190, "");
macrotext = new Fl_Input2(2, 22, 450, 140, _("Text:"));
macrotext->type(FL_MULTILINE_INPUT);
macrotext->textfont(FL_COURIER);
macrotext->align(FL_ALIGN_TOP_LEFT);
btnInsertMacro = new Fl_Button(454, 86, 20, 20);
Fl_Group *grpA = new Fl_Group(0, 0, 800, 22);
Fl_Group *grpB = new Fl_Group(450, 0, 350, 22);
btnInsertMacro = new Fl_Button(450, 2, 40, 20);
btnInsertMacro->image(new Fl_Pixmap(left_arrow_icon));
btnInsertMacro->callback(cbInsertMacro);
grpB->end();
grpA->end();
macroDefs = new Fl_Hold_Browser(476, 22, 290, 140, _("Select Tags:"));
Fl_Group *grpC = new Fl_Group(0, 22, 800, 140);
Fl_Tile *tile = new Fl_Tile(0,22,800,140);
macrotext = new Fl_Input2(0, 22, 450, 140, _("Macro Text"));
macrotext->type(FL_MULTILINE_INPUT);
macrotext->textfont(FL_COURIER);
macrotext->align(FL_ALIGN_TOP);
macroDefs = new Fl_Hold_Browser(450, 22, 350, 140, _("Select Tag"));
macroDefs->column_widths(widths);
macroDefs->align(FL_ALIGN_TOP_LEFT);
loadBrowser(macroDefs);
macroDefs->align(FL_ALIGN_TOP);
labeltext = new Fl_Input2(2 + 450 - 115, 164, 115, 24, _("Macro Button Label:"));
Fl_Box *minbox = new Fl_Box(200, 22, 400, 140);
minbox->hide();
tile->end();
tile->resizable(minbox);
grpC->end();
Fl_Group *grpD = new Fl_Group(0, 164, 452, 24);
Fl_Box *box3a = new Fl_Box(0, 164, 327, 24, "");
labeltext = new Fl_Input2(337, 164, 115, 24, _("Macro Button Label"));
labeltext->textfont(FL_COURIER);
grpD->end();
grpD->resizable(box3a);
btnMacroEditOK = new Fl_Button(476 + 145 - 80 - 1, 164, 80, 24, _("OK"));
btnMacroEditOK->callback(cbMacroEditOK);
Fl_Group *grpE = new Fl_Group(452, 164, 348, 24);
Fl_Box *box4a = new Fl_Box(452, 164, 92, 24, "");
btnMacroEditCancel = new Fl_Button(476 + 145 + 1 , 164, 80, 24, _("Cancel"));
btnMacroEditCancel->callback(cbMacroEditOK);
btnMacroEditApply = new Fl_Button(544, 164, 80, 24, _("Apply"));
btnMacroEditApply->callback(cbMacroEditOK);
btnMacroEditClose = new Fl_Button(626 , 164, 80, 24, _("Close"));
btnMacroEditClose->callback(cbMacroEditOK);
grpE->end();
grpE->resizable(box4a);
w->end();
w->resizable(grpC);
w->size_range( 600, 120);
w->xclass(PACKAGE_NAME);
loadBrowser(macroDefs);
return w;
}

Plik diff jest za duży Load Diff

Wyświetl plik

@ -21,6 +21,7 @@
// ----------------------------------------------------------------------------
#include <config.h>
#include <stdio.h>
#include <sys/time.h>
#include <cmath>

Wyświetl plik

@ -21,7 +21,9 @@
// ----------------------------------------------------------------------------
#include <config.h>
#include <stdexcept>
#include <string.h>
#include <errno.h>
#include "threads.h"
THREAD_ID_TYPE thread_id_;
@ -99,3 +101,50 @@ void linux_log_tid(void)
LOG_DEBUG(PACKAGE_TARNAME " thread %" PRIdPTR " is LWP %ld", GET_THREAD_ID(), syscall(SYS_gettid));
}
#endif
// Synchronization objects.
guard_lock::guard_lock(pthread_mutex_t* m) : mutex(m)
{
pthread_mutex_lock(mutex);
}
guard_lock::~guard_lock(void)
{
pthread_mutex_unlock(mutex);
}
syncobj::syncobj()
{
pthread_mutex_init( & m_mutex, NULL );
pthread_cond_init( & m_cond, NULL );
}
syncobj::~syncobj()
{
pthread_mutex_destroy( & m_mutex );
pthread_cond_destroy( & m_cond );
}
void syncobj::signal()
{
int rc = pthread_cond_signal( &m_cond );
if( rc )
{
throw std::runtime_error(strerror(rc));
}
}
bool syncobj::wait( double seconds )
{
int rc = pthread_cond_timedwait_rel( &m_cond, &m_mutex, seconds );
switch( rc )
{
case 0 : return true ;
default : throw std::runtime_error(strerror(rc));
case ETIMEDOUT: return false ;
}
}

Wyświetl plik

@ -57,6 +57,8 @@
#include "waterfall.h"
#include "macros.h"
#include "qrunner.h"
#include "wefax.h"
#include "wefax-pic.h"
#if USE_HAMLIB
#include "hamlib.h"
@ -189,16 +191,8 @@ ostream& XML_RPC_Server::list_methods(ostream& out)
// =============================================================================
// Methods that change the server state must call XMLRPC_LOCK
class xmlrpc_lock
{
public:
xmlrpc_lock(pthread_mutex_t* m) : mutex(m) { pthread_mutex_lock(mutex); }
~xmlrpc_lock(void) { pthread_mutex_unlock(mutex); }
private:
pthread_mutex_t* mutex;
};
#define XMLRPC_LOCK SET_THREAD_ID(XMLRPC_TID); xmlrpc_lock autolock_(server_mutex)
// guard_lock (include/threads.h) ensures that mutex are always unlocked.
#define XMLRPC_LOCK SET_THREAD_ID(XMLRPC_TID); guard_lock autolock_(server_mutex)
// =============================================================================
@ -2433,6 +2427,206 @@ public:
// =============================================================================
// Returns the current wefax modem pointer.
static wefax * get_wefax(void)
{
if( ( active_modem->get_mode() >= MODE_WEFAX_FIRST )
&& ( active_modem->get_mode() <= MODE_WEFAX_LAST ) )
{
wefax * ptr = dynamic_cast<wefax *>( active_modem );
if( ptr == NULL ) throw runtime_error("Inconsistent wefax object");
return ptr ;
}
throw runtime_error("Not in wefax mode");
}
struct Wefax_state_string : public xmlrpc_c::method
{
Wefax_state_string() {
_signature = "s:n";
_help = "Returns Wefax engine state (tx and rx) for information."; }
void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
try
{
*retval = xmlrpc_c::value_string( get_wefax()->state_string() );
}
catch( const exception & e )
{
*retval = xmlrpc_c::value_string( e.what());
}
};
struct Wefax_skip_apt : public xmlrpc_c::method
{
Wefax_skip_apt() {
_signature = "s:n";
_help = "Skip APT during Wefax reception"; }
void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
try
{
get_wefax()->skip_apt();
*retval = xmlrpc_c::value_string( "" );
}
catch( const exception & e )
{
*retval = xmlrpc_c::value_string( e.what() );
}
};
/// TODO: Refresh the screen with the new value.
struct Wefax_skip_phasing : public xmlrpc_c::method
{
Wefax_skip_phasing() {
_signature = "s:n";
_help = "Skip phasing during Wefax reception"; }
void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
try
{
get_wefax()->skip_phasing(true);
*retval = xmlrpc_c::value_string( "" );
}
catch( const exception & e )
{
*retval = xmlrpc_c::value_string( e.what() );
}
};
// TODO: The image should be reloaded just like cancelling from the GUI.
struct Wefax_set_tx_abort_flag : public xmlrpc_c::method
{
Wefax_set_tx_abort_flag() {
_signature = "s:n";
_help = "Cancels Wefax image transmission"; }
void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
try
{
get_wefax()->set_tx_abort_flag();
*retval = xmlrpc_c::value_string( "" );
}
catch( const exception & e )
{
*retval = xmlrpc_c::value_string( e.what() );
}
};
struct Wefax_end_reception : public xmlrpc_c::method
{
Wefax_end_reception() {
_signature = "s:n";
_help = "End Wefax image reception"; }
void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
try
{
get_wefax()->end_reception();
*retval = xmlrpc_c::value_string( "" );
}
catch( const exception & e )
{
*retval = xmlrpc_c::value_string( e.what() );
}
};
struct Wefax_start_manual_reception : public xmlrpc_c::method
{
Wefax_start_manual_reception() {
_signature = "s:n";
_help = "Starts fax image reception in manual mode"; }
void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
try
{
get_wefax()->set_rx_manual_mode(true);
get_wefax()->skip_apt();
get_wefax()->skip_phasing(true);
*retval = xmlrpc_c::value_string( "" );
}
catch( const exception & e )
{
*retval = xmlrpc_c::value_string( e.what() );
}
};
struct Wefax_set_adif_log : public xmlrpc_c::method
{
Wefax_set_adif_log() {
_signature = "s:b";
_help = "Set/reset logging to received/transmit images to ADIF log file"; }
void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
try
{
get_wefax()->set_adif_log( params.getBoolean(0));
*retval = xmlrpc_c::value_string( "" );
}
catch( const exception & e )
{
*retval = xmlrpc_c::value_string( e.what() );
}
};
struct Wefax_set_max_lines : public xmlrpc_c::method
{
Wefax_set_max_lines() {
_signature = "s:i";
_help = "Set maximum lines for fax image reception"; }
void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
try
{
get_wefax()->set_max_lines( params.getInt(0));
/// This updates the GUI.
REQ( wefax_pic::restore_max_lines );
*retval = xmlrpc_c::value_string( "" );
}
catch( const exception & e )
{
*retval = xmlrpc_c::value_string( e.what() );
}
};
struct Wefax_get_received_file : public xmlrpc_c::method
{
Wefax_get_received_file() {
_signature = "s:i";
_help = "Waits for next received fax file, returns its name with a delay. Empty string if timeout."; }
void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
try
{
std::string filename = get_wefax()->get_received_file( params.getInt(0));
*retval = xmlrpc_c::value_string( filename );
}
catch( const exception & e )
{
*retval = xmlrpc_c::value_string( e.what() );
}
};
struct Wefax_send_file : public xmlrpc_c::method
{
Wefax_send_file() {
_signature = "s:si";
_help = "Send file. returns an empty string if OK otherwise an error message."; }
void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
try
{
std::string status = get_wefax()->send_file( params.getString(0), params.getInt(1) );
*retval = xmlrpc_c::value_string( status );
}
catch( const exception & e )
{
*retval = xmlrpc_c::value_string( e.what() );
}
};
// =============================================================================
// End XML-RPC interface
// method list: ELEM_(class_name, "method_name")
@ -2586,7 +2780,18 @@ public:
ELEM_(Spot_get_auto, "spot.get_auto") \
ELEM_(Spot_set_auto, "spot.set_auto") \
ELEM_(Spot_toggle_auto, "spot.toggle_auto") \
ELEM_(Spot_pskrep_get_count, "spot.pskrep.get_count")
ELEM_(Spot_pskrep_get_count, "spot.pskrep.get_count") \
\
ELEM_(Wefax_state_string, "wefax.state_string") \
ELEM_(Wefax_skip_apt, "wefax.skip_apt") \
ELEM_(Wefax_skip_phasing, "wefax.skip_phasing") \
ELEM_(Wefax_set_tx_abort_flag, "wefax.set_tx_abort_flag") \
ELEM_(Wefax_end_reception, "wefax.end_reception") \
ELEM_(Wefax_start_manual_reception, "wefax.start_manual_reception") \
ELEM_(Wefax_set_adif_log, "wefax.set_adif_log") \
ELEM_(Wefax_set_max_lines, "wefax.set_max_lines") \
ELEM_(Wefax_get_received_file, "wefax.get_received_file") \
ELEM_(Wefax_send_file, "wefax.send_file") \
struct rm_pred

Wyświetl plik

@ -79,13 +79,22 @@ int mt63::tx_process()
if (c == 0x03) {
stopflag = true;
flush = Tx->DataInterleave;
c = 0;
}
if (c == -1 || stopflag == true) c = 0;
if (stopflag && flush-- == 0) {
if (stopflag) {
stopflag = false;
while (--flush) {
Tx->SendChar(0);
for (int i = 0; i < Tx->Comb.Output.Len; i++)
if (fabs(Tx->Comb.Output.Data[i]) > maxval)
maxval = fabs(Tx->Comb.Output.Data[i]);
for (int i = 0; i < Tx->Comb.Output.Len; i++) {
Tx->Comb.Output.Data[i] /= maxval;
}
ModulateXmtr((Tx->Comb.Output.Data), Tx->Comb.Output.Len);
}
Tx->SendJam();
for (int i = 0; i < Tx->Comb.Output.Len; i++)
if (fabs(Tx->Comb.Output.Data[i]) > maxval)

Wyświetl plik

@ -435,7 +435,9 @@ void cRsId::search(void)
else {
double centerfreq = active_modem->get_freq();
nBinLow = (int)((centerfreq - 100.0 * RSID_RESOL) * 2048.0 / RSID_SAMPLE_RATE);
if (nBinLow < RSID_RESOL + 1) nBinLow = RSID_RESOL + 1;
nBinHigh = (int)((centerfreq + 100.0 * RSID_RESOL) * 2048.0 / RSID_SAMPLE_RATE);
if (nBinHigh > RSID_FFT_SIZE -32) nBinHigh = RSID_FFT_SIZE;
}
bool bReverse = !(wf->Reverse() ^ wf->USB());

Wyświetl plik

@ -42,6 +42,7 @@
using namespace std;
modem *null_modem = 0;
modem *cw_modem = 0;
modem *mfsk8_modem = 0;
@ -248,6 +249,12 @@ void modem::set_metric(double m)
metric = m;
}
void modem::display_metric(double m)
{
set_metric(m);
::global_display_metric(m);
}
double modem::get_metric(void)
{
return metric;
@ -990,5 +997,3 @@ mfntchr idch2[] = {
{'}', { 0x00, 0x80, 0xC0, 0x40, 0x40, 0x40, 0x60, 0x60, 0x40, 0x40, 0x40, 0xC0, 0x80, 0x00 }, },
{'~', { 0x00, 0x98, 0xFC, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
};

Wyświetl plik

@ -0,0 +1,91 @@
// ----------------------------------------------------------------------------
// NULLMODEM.cxx -- NULLMODEM modem
//
// Copyright (C) 2006
// Dave Freese, W1HKJ
//
// This file is part of fldigi. Adapted from code contained in gMFSK source code
// distribution.
// gMFSK Copyright (C) 2001, 2002, 2003
// Tomi Manninen (oh2bns@sral.fi)
//
// 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 fldigi. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#include <config.h>
#include <stdlib.h>
#include <iostream>
#include "nullmodem.h"
#include "fl_digi.h"
#include "ascii.h"
#define null_bw 1
NULLMODEM:: NULLMODEM() : modem()
{
mode = MODE_NULL;
samplerate = 8000;
restart();
}
NULLMODEM::~NULLMODEM() {};
void NULLMODEM::tx_init(SoundBase *sc)
{
scard = sc;
}
void NULLMODEM::rx_init()
{
put_MODEstatus(mode);
}
void NULLMODEM::init()
{
modem::init();
rx_init();
digiscope->mode(Digiscope::SCOPE);
}
void NULLMODEM::restart()
{
set_bandwidth(null_bw);
}
//=====================================================================
// receive processing
//=====================================================================
int NULLMODEM::rx_process(const double *buf, int len)
{
return 0;
}
//=====================================================================
// transmit processing
//=====================================================================
int NULLMODEM::tx_process()
{
MilliSleep(10);
if ( get_tx_char() == 0x03 || stopflag) {
stopflag = false;
return -1;
}
return 0;
}

Wyświetl plik

@ -37,6 +37,7 @@
#include "misc.h"
#include "configuration.h"
#include "status.h"
#include "dtmf.h"
#include "soundconf.h"
#include "ringbuffer.h"
@ -68,6 +69,7 @@ state_t trx_state;
modem *active_modem = 0;
cRsId *ReedSolomon = 0;
cDTMF *dtmf = 0;
SoundBase *scard;
static int _trx_tune;
@ -156,7 +158,6 @@ static void trx_xmit_wfall_end(int samplerate)
void trx_xmit_wfall_queue(int samplerate, const double* buf, size_t len)
{
ENSURE_THREAD(TRX_TID);
ringbuffer<double>::vector_type wv[2];
wv[0].buf = wv[1].buf = 0;
@ -256,6 +257,7 @@ void trx_trx_receive_loop()
active_modem->rx_process(rbvec[0].buf, numread);
if (progdefaults.rsid)
ReedSolomon->receive(fbuf, numread);
dtmf->receive(fbuf, numread);
}
else {
bool afc = progStatus.afconoff;
@ -286,7 +288,6 @@ void trx_trx_transmit_loop()
MilliSleep(10);
return;
}
if (active_modem) {
try {
current_samplerate = active_modem->get_samplerate();
@ -299,13 +300,21 @@ void trx_trx_transmit_loop()
return;
}
push2talk->set(true);
if (active_modem != ssb_modem) {
push2talk->set(true);
REQ(&waterfall::set_XmtRcvBtn, wf, true);
}
active_modem->tx_init(scard);
if (progdefaults.TransmitRSid)
if ((active_modem != null_modem &&
active_modem != ssb_modem &&
active_modem != wwv_modem ) &&
progdefaults.TransmitRSid)
ReedSolomon->send(true);
while (trx_state == STATE_TX) {
if (active_modem != ssb_modem && !progdefaults.DTMFstr.empty())
dtmf->send();
try {
if (active_modem->tx_process() < 0)
trx_state = STATE_RX;
@ -321,9 +330,6 @@ void trx_trx_transmit_loop()
trx_xmit_wfall_end(current_samplerate);
// if (progdefaults.TransmitRSid)
// ReedSolomon->send(false);
scard->flush();
if (scard->must_close(O_WRONLY))
scard->Close(O_WRONLY);
@ -333,6 +339,8 @@ void trx_trx_transmit_loop()
push2talk->set(false);
REQ(&waterfall::set_XmtRcvBtn, wf, false);
if (progStatus.timer)
REQ(startMacroTimer);
}
//=============================================================================
@ -402,6 +410,17 @@ void *trx_loop(void *args)
trxrb.reset();
trx_signal_state();
}
/*
printf("trx state %s\n",
trx_state == STATE_ABORT ? "abort" :
trx_state == STATE_ENDED ? "ended" :
trx_state == STATE_RESTART ? "restart" :
trx_state == STATE_NEW_MODEM ? "new modem" :
trx_state == STATE_TX ? "tx" :
trx_state == STATE_TUNE ? "tune" :
trx_state == STATE_RX ? "rx" :
"unknown");
*/
switch (trx_state) {
case STATE_ABORT:
delete scard;
@ -421,8 +440,6 @@ void *trx_loop(void *args)
break;
case STATE_TX:
trx_trx_transmit_loop();
if (progStatus.timer)
REQ(startMacroTimer);
break;
case STATE_TUNE:
trx_tune_loop();
@ -527,6 +544,7 @@ void trx_start(void)
if (scard) delete scard;
if (ReedSolomon) delete ReedSolomon;
if (dtmf) delete dtmf;
switch (progdefaults.btnAudioIOis) {
@ -553,6 +571,8 @@ void trx_start(void)
}
ReedSolomon = new cRsId;
dtmf = new cDTMF;
#endif // !BENCHMARK_MODE
#if USE_NAMED_SEMAPHORES

Wyświetl plik

@ -857,13 +857,25 @@ void WFdisp::update_waterfall() {
if (active_modem->get_reverse()) {
*pos1 = progdefaults.rttymarkRGBI;
*pos2 = progdefaults.bwTrackRGBI;
if (progdefaults.UseWideTracks) {
*(pos1 + 1) = *pos1;
*(pos2 - 1) = *pos2;
}
} else {
*pos1 = progdefaults.bwTrackRGBI;
*pos2 = progdefaults.rttymarkRGBI;
if (progdefaults.UseWideTracks) {
*(pos1 + 1) = *pos1;
*(pos2 - 1) = *pos2;
}
}
} else {
*pos1 = progdefaults.bwTrackRGBI;
*pos2 = progdefaults.bwTrackRGBI;
if (progdefaults.UseWideTracks) {
*(pos1 + 1) = *pos1;
*(pos2 - 1) = *pos2;
}
}
pos1 += disp_width;
pos2 += disp_width;
@ -895,10 +907,16 @@ void WFdisp::drawcolorWF() {
RGBI *pos2 = (fft_img + cursorpos + bw_hi/step);
if (pos1 >= fft_img && pos2 < fft_img + disp_width)
for (int y = 0; y < image_height; y ++) {
if (progdefaults.UseCursorLines)
if (progdefaults.UseCursorLines) {
*pos1 = *pos2 = progdefaults.cursorLineRGBI;
if (progdefaults.UseCursorCenterLine)
if (progdefaults.UseWideCursor)
*(pos1 + 1) = *(pos2 - 1) = *pos1;
}
if (progdefaults.UseCursorCenterLine) {
*pos0 = progdefaults.cursorCenterRGBI;
if (progdefaults.UseWideCenter)
*(pos0 - 1) = *(pos0 + 1) = *pos0;
}
pos0 += disp_width;
pos1 += disp_width;
pos2 += disp_width;
@ -1059,9 +1077,14 @@ void WFdisp::drawspectrum() {
if (progdefaults.UseBWTracks) {
uchar *pos1 = pixmap + (carrierfreq - offset - bandwidth/2) / step;
uchar *pos2 = pixmap + (carrierfreq - offset + bandwidth/2) / step;
if (pos1 >= pixmap && pos2 < pixmap + disp_width)
if (pos1 >= pixmap &&
pos2 < pixmap + disp_width)
for (int y = 0; y < image_height; y ++) {
*pos1 = *pos2 = 255;
if (progdefaults.UseWideTracks) {
*(pos1 + 1) = 255;
*(pos2 - 1) = 255;
}
pos1 += IMAGE_WIDTH/step;
pos2 += IMAGE_WIDTH/step;
}
@ -1076,10 +1099,15 @@ void WFdisp::drawspectrum() {
uchar *pos1 = (pixmap + cursorpos - bw_lo/step);
uchar *pos2 = (pixmap + cursorpos + bw_hi/step);
for (int y = 0; y < h1; y ++) {
if (progdefaults.UseCursorLines)
if (progdefaults.UseCursorLines) {
*pos1 = *pos2 = 255;
if (progdefaults.UseCursorCenterLine)
if (progdefaults.UseWideCursor)
*(pos1 + 1) = *(pos2 - 1) = *pos1;
}
if (progdefaults.UseCursorCenterLine) {
*pos0 = 255;
if (progdefaults.UseWideCenter) *(pos0-1) = *(pos0+1) = *(pos0);
}
pos0 += IMAGE_WIDTH/step;
pos1 += IMAGE_WIDTH/step;
pos2 += IMAGE_WIDTH/step;

Wyświetl plik

@ -91,14 +91,20 @@ static Fl_Choice *wefax_choice_tx_lpm = (Fl_Choice *)0;
static Fl_Round_Button *wefax_round_tx_adif_log = (Fl_Round_Button *)0;
static Fl_Button *wefax_btn_tx_send_color = (Fl_Button *)0;
static Fl_Button *wefax_btn_tx_send_grey = (Fl_Button *)0;
static Fl_Output *wefax_out_tx_row_num = (Fl_Output *)0;
static Fl_Button *wefax_btn_tx_send_abort = (Fl_Button *)0;
static Fl_Button *wefax_btn_tx_load = (Fl_Button *)0;
static Fl_Button *wefax_btn_tx_clear = (Fl_Button *)0;
static Fl_Button *wefax_btn_tx_close = (Fl_Button *)0;
static Fl_Shared_Image *wefax_shared_tx_img = (Fl_Shared_Image *)0;
static unsigned char *wefax_xmtimg = (unsigned char *)0;
static unsigned char *wefax_xmtpicbuff = (unsigned char *)0;
/// This indicates whether an image to send is loaded in the GUI.
/// It allows to acquire twice when re-loading an image without sending.
static bool wefax_image_loaded_in_gui = false ;
/// Used for shifting the received image left and right.
static volatile int center_val_prev = 0 ;
@ -144,6 +150,43 @@ static const int mini_max_fax_lines = 1000 ;
/// However, when the printing resumes, the position is not altered.
static volatile bool reception_paused = false ;
/// Sets the label of the received or sent image.
static void set_win_label( Fl_Double_Window * wefax_pic, const std::string & lab)
{
char* label = strdup(lab.c_str());
wefax_pic->copy_label(label);
free(label);
wefax_pic->redraw();
}
/// Called when clearing the image to send.
static void clear_image(void)
{
if (wefax_xmtimg)
{
delete [] wefax_xmtimg;
wefax_xmtimg = NULL ;
}
if (wefax_shared_tx_img) {
wefax_shared_tx_img->release();
wefax_shared_tx_img = 0;
}
set_win_label(wefax_pic_tx_win,"");
}
/// Clears the loaded image. It allows XML-RPC clients to send an image.
static void wefax_cb_pic_tx_clear( Fl_Widget *, void *)
{
FL_LOCK_D();
wefax_image_loaded_in_gui = false ;
clear_image();
wefax_pic_tx_picture->clear();
wefax_pic::restart_tx_viewer();
/// Now the lock can be acquired by XML-RPC.
wefax_serviceme->transmit_lock_release( "Cleared" );
FL_UNLOCK_D();
}
static void wefax_cb_pic_tx_close( Fl_Widget *, void *)
{
FL_LOCK_D();
@ -386,8 +429,7 @@ void wefax_pic::update_rx_pic_bw(unsigned char data, int pix_pos )
/// Prints the row number sometimes only, to save CPU.
if( ( pix_pos % 1000 ) == 0 ) {
char row_num_buffer[20];
snprintf( row_num_buffer, sizeof(row_num_buffer),
"%d", row_number );
snprintf( row_num_buffer, sizeof(row_num_buffer), "%d", row_number );
wefax_out_rx_row_num->value( row_num_buffer );
}
@ -439,6 +481,15 @@ static void wefax_cb_pic_rx_resume( Fl_Widget *, void *)
wefax_serviceme->update_rx_label();
}
static void LocalSleep( int seconds )
{
#ifdef __MINGW32__
MilliSleep(seconds);
#else
usleep(100000*seconds);
#endif
}
/// Displays the latest image file saved.
static void add_to_files_list( const std::string & the_fil_nam )
{
@ -459,22 +510,21 @@ static void add_to_files_list( const std::string & the_fil_nam )
/// This window is hidden/shown to signal that a file was added.
static const int nb_blink = 5 ;
for( int ix_blink = 0 ; ix_blink < nb_blink ; ++ix_blink ) {
#ifdef __MINGW32__
wefax_browse_rx_events->hide();
wefax_browse_rx_events->redraw();
MilliSleep(1);
LocalSleep(1);
wefax_browse_rx_events->show();
wefax_browse_rx_events->redraw();
MilliSleep(1);
#else
wefax_browse_rx_events->hide();
wefax_browse_rx_events->redraw();
usleep(100000);
wefax_browse_rx_events->show();
wefax_browse_rx_events->redraw();
usleep(100000);
#endif
LocalSleep(1);
}
/// If there is not directory specification, adds the default dir.
if( the_fil_nam.empty() )
LOG_WARN("Empty file name");
else if( the_fil_nam[0] != '/' )
wefax_serviceme->put_received_file( progdefaults.wefax_save_dir + '/' + the_fil_nam );
else
wefax_serviceme->put_received_file( the_fil_nam );
};
static void wefax_cb_pic_rx_abort( Fl_Widget *, void *)
@ -628,7 +678,7 @@ static void wefax_cb_rx_set_filter( Fl_Widget *, void * )
wefax_serviceme->set_rx_filter(ix_filter);
}
static void restore_max_lines(void)
void wefax_pic::restore_max_lines(void)
{
char buf_max_lines[20];
snprintf( buf_max_lines, sizeof(buf_max_lines), "%d", wefax_serviceme->get_max_lines() );
@ -643,15 +693,15 @@ static void wefax_cb_pic_max_lines( Fl_Widget *, void * )
/// The value given by FLTK should be an integer, but better to be sure.
if( 1 != sscanf( ptr_val_gui, "%d", &max_val_gui ) ) {
LOG_ERROR( "Cannot parse: %s", ptr_val_gui ) ;
restore_max_lines();
LOG_ERROR( _("Cannot parse: %s"), ptr_val_gui ) ;
wefax_pic::restore_max_lines();
return ;
}
/// Faxes should not be too small otherwise we will spend all our time
/// saving automatic image files.
if( max_val_gui < mini_max_fax_lines ) {
restore_max_lines();
wefax_pic::restore_max_lines();
return ;
}
@ -952,7 +1002,7 @@ void wefax_pic::create_rx_viewer(void)
/// This buffer will never change so it does not matter if it is static.
static char tooltip_max_lines[256];
snprintf(tooltip_max_lines, sizeof(tooltip_max_lines),
"Maximum number of lines per image. Must be bigger than %d",
"Maximum number of lines per image. Minimum value is %d",
mini_max_fax_lines );
wefax_int_rx_max->tooltip(tooltip_max_lines);
@ -1068,11 +1118,7 @@ void wefax_pic::set_rx_label(const std::string & win_label)
}
/// This copy seems strange, but otherwise the label is not updated.
char* label = strdup(tmp_label.c_str());
wefax_pic_rx_win->copy_label(label);
free(label);
wefax_pic_rx_win->redraw_label();
set_win_label(wefax_pic_rx_win, tmp_label);
FL_UNLOCK_D();
}
@ -1090,33 +1136,31 @@ void wefax_pic::save_image(const std::string & fil_name, const std::string & ext
wefax_serviceme->qso_rec_save();
}
static void wefax_load_image(const char *fil_name)
/// Protected by an exclusive mutex.
static std::string wefax_load_image_after_acquire(const char * fil_name)
{
if (wefax_serviceme != active_modem) return;
if (wefax_serviceme != active_modem) return "Not in WEFAX mode";
wefax_serviceme->qso_rec_init();
qso_notes( "TX:", fil_name );
if (wefax_shared_tx_img) {
wefax_shared_tx_img->release();
wefax_shared_tx_img = 0;
}
clear_image();
wefax_shared_tx_img = Fl_Shared_Image::get(fil_name);
if (!wefax_shared_tx_img) {
LOG_ERROR("Could not Fl_Shared_Image::get %s", fil_name);
return;
std::string err_msg("Cannot call Fl_Shared_Image::get on file:" + std::string(fil_name) );
LOG_ERROR("%s",err_msg.c_str());
return err_msg;
}
if (wefax_shared_tx_img->count() > 1) { // we only handle rgb images
LOG_ERROR("Handle only RGB images: %s", fil_name );
wefax_shared_tx_img->release();
wefax_shared_tx_img = 0;
return;
std::string err_msg("Handle only RGB images: " + std::string(fil_name) );
LOG_ERROR("%s",err_msg.c_str());
clear_image();
return err_msg;
}
unsigned char * img_data = (unsigned char *)wefax_shared_tx_img->data()[0];
int img_wid = wefax_shared_tx_img->w();
int img_hei = wefax_shared_tx_img->h();
int img_depth = wefax_shared_tx_img->d();
if (wefax_xmtimg) delete [] wefax_xmtimg;
wefax_xmtimg = new unsigned char [img_wid * img_hei * bytes_per_pix];
if (img_depth == bytes_per_pix)
memcpy(wefax_xmtimg, img_data, img_wid*img_hei*bytes_per_pix);
@ -1135,22 +1179,23 @@ static void wefax_load_image(const char *fil_name)
wefax_xmtimg[j] = wefax_xmtimg[j+1] = wefax_xmtimg[j+2] = img_data[i];
}
} else {
LOG_ERROR( "Inconsistent img_depth=%d\n", img_depth );
exit(EXIT_FAILURE);
std::stringstream err_strm ;
err_strm << "Inconsistent img_depth=" << img_depth << " for " << fil_name ;
std::string err_msg = err_strm.str();
LOG_ERROR("%s",err_msg.c_str());
return err_msg ;
};
wefax_pic::tx_viewer_resize(img_wid, img_hei);
char* label = strdup(fil_name);
wefax_pic_tx_win->copy_label(basename(label));
free(label);
set_win_label(wefax_pic_tx_win, fil_name);
wefax_pic_tx_box->label(0);
// load the picture widget with the rgb image
FL_LOCK_D();
wefax_pic_tx_picture->show();
wefax_pic_tx_picture->clear();
wefax_pic_tx_win->redraw();
wefax_pic_tx_picture->video(wefax_xmtimg, img_wid * img_hei * bytes_per_pix);
int tim_color = wefax_serviceme->tx_time( img_wid * img_hei * bytes_per_pix );
@ -1167,7 +1212,22 @@ static void wefax_load_image(const char *fil_name)
wefax_btn_tx_send_grey->tooltip(wefax_txgry_tooltip);
wefax_btn_tx_send_grey->activate();
wefax_btn_tx_clear->activate();
FL_UNLOCK_D();
return std::string();
}
static void wefax_load_image(const char * fil_name)
{
if (wefax_serviceme != active_modem) return;
if( false == wefax_image_loaded_in_gui )
{
/// So we do not re-acquire the exclusive access to wefax transmission.
wefax_serviceme->transmit_lock_acquire(fil_name);
wefax_image_loaded_in_gui = true ;
}
wefax_load_image_after_acquire(fil_name);
}
void wefax_pic::set_tx_pic(unsigned char data, int col, int row, int tx_img_col, bool is_color )
@ -1190,6 +1250,15 @@ void wefax_pic::set_tx_pic(unsigned char data, int col, int row, int tx_img_col,
wefax_pic_tx_picture->pixel( data, tripleOffset + 1 );
wefax_pic_tx_picture->pixel( data, tripleOffset + 2 );
}
static int previous_row = -1 ;
if( row != previous_row )
{
previous_row = row ;
char row_num_buffer[20];
snprintf( row_num_buffer, sizeof(row_num_buffer), "%d", row );
wefax_out_tx_row_num->value( row_num_buffer );
}
}
static void wefax_cb_pic_tx_load(Fl_Widget *, void *)
@ -1218,13 +1287,18 @@ static void wefax_pic_tx_send_common(
FL_LOCK_D();
wefax_choice_tx_lpm->hide();
wefax_round_tx_adif_log->hide();
wefax_btn_tx_send_color->hide();
wefax_btn_tx_send_grey->hide();
wefax_btn_tx_load->hide();
wefax_btn_tx_clear->hide();
wefax_btn_tx_close->hide();
wefax_out_tx_row_num->show();
wefax_btn_tx_send_abort->show();
wefax_pic_tx_picture->clear();
wefax_out_tx_row_num->value( "Init" );
wefax_serviceme->set_tx_parameters(
get_choice_lpm_value( wefax_choice_tx_lpm ),
wefax_xmtpicbuff,
@ -1306,12 +1380,27 @@ static void wefax_cb_pic_tx_adif_log( Fl_Widget *, void *)
void wefax_pic::restart_tx_viewer(void)
{
wefax_out_tx_row_num->hide();
wefax_btn_tx_send_abort->hide();
wefax_choice_tx_lpm->show();
wefax_btn_tx_send_color->show();
wefax_btn_tx_send_grey->show();
wefax_round_tx_adif_log->show();
wefax_btn_tx_load->show();
wefax_btn_tx_close->show();
if( wefax_image_loaded_in_gui )
{
// If the image was loaded from the GUI.
wefax_choice_tx_lpm->show();
wefax_btn_tx_send_color->show();
wefax_btn_tx_send_grey->show();
wefax_btn_tx_clear->show();
}
else
{
/// If the image was loaded and sent from XML-RPC, or no image present.
wefax_choice_tx_lpm->deactivate();
wefax_btn_tx_send_color->deactivate();
wefax_btn_tx_send_grey->deactivate();
wefax_btn_tx_clear->deactivate();
}
}
void wefax_pic::create_tx_viewer(void)
@ -1351,7 +1440,7 @@ void wefax_pic::create_tx_viewer(void)
static const int hei_tx_btn = 24 ;
int width_btn = 0;
int width_offset = 35;
int width_offset = 30;
width_btn = 70 ;
wefax_choice_tx_lpm = make_lpm_choice( width_offset, y_btn, width_btn, hei_tx_btn );
@ -1366,33 +1455,46 @@ void wefax_pic::create_tx_viewer(void)
wefax_round_tx_adif_log->align(FL_ALIGN_LEFT);
width_offset += width_btn ;
width_btn = 60 ;
wefax_btn_tx_send_color = new Fl_Button(width_offset, y_btn, width_btn, hei_tx_btn, "Xmt Color");
width_btn = 50 ;
wefax_btn_tx_send_color = new Fl_Button(width_offset, y_btn, width_btn, hei_tx_btn, "Tx Color");
wefax_btn_tx_send_color->callback(wefax_cb_pic_tx_send_color, 0);
width_offset += width_btn ;
width_btn = 60 ;
wefax_btn_tx_send_grey = new Fl_Button(width_offset, y_btn, width_btn, hei_tx_btn, "Xmt Grey");
width_btn = 50 ;
wefax_btn_tx_send_grey = new Fl_Button(width_offset, y_btn, width_btn, hei_tx_btn, "Tx B/W");
wefax_btn_tx_send_grey->callback( wefax_cb_pic_tx_send_grey, 0);
width_offset += width_btn ;
width_btn = 40 ;
width_btn = 35 ;
wefax_btn_tx_load = new Fl_Button(width_offset, y_btn, width_btn, hei_tx_btn, _("Load"));
wefax_btn_tx_load->callback(wefax_cb_pic_tx_load, 0);
wefax_btn_tx_load->tooltip("Load image to send");
width_offset += width_btn ;
width_btn = 40 ;
width_btn = 35 ;
wefax_btn_tx_clear = new Fl_Button(width_offset, y_btn, width_btn, hei_tx_btn, _("Clear"));
wefax_btn_tx_clear->callback(wefax_cb_pic_tx_clear, 0);
width_offset += width_btn ;
width_btn = 35 ;
wefax_btn_tx_close = new Fl_Button(width_offset, y_btn, width_btn, hei_tx_btn, _("Close"));
wefax_btn_tx_close->callback(wefax_cb_pic_tx_close, 0);
wefax_btn_tx_send_abort = new Fl_Button(84, y_btn, 122, hei_tx_btn, "Abort Xmt");
static const char * title_row_num = "" ;
width_offset += fl_width( title_row_num );
wefax_out_tx_row_num = new Fl_Output(20, y_btn, 100, hei_tx_btn, _(title_row_num));
wefax_out_tx_row_num->align(FL_ALIGN_LEFT);
wefax_out_tx_row_num->tooltip("Fax line number being sent.");
wefax_btn_tx_send_abort = new Fl_Button(180, y_btn, 122, hei_tx_btn, "Abort Xmt");
wefax_btn_tx_send_abort->callback(wefax_cb_pic_tx_send_abort, 0);
wefax_btn_tx_send_abort->tooltip("Abort transmission");
wefax_out_tx_row_num->hide();
wefax_btn_tx_send_abort->hide();
wefax_btn_tx_send_color->deactivate();
wefax_btn_tx_send_grey->deactivate();
wefax_btn_tx_clear->deactivate();
wefax_pic_tx_win->end();
FL_UNLOCK_D();
@ -1511,4 +1613,21 @@ void wefax_pic::cb_mnu_pic_viewer(Fl_Menu_ *, void *) {
}
}
/// Called from XML-RPC thread.
void wefax_pic::send_image( const std::string & fil_nam )
{
LOG_INFO("%s", fil_nam.c_str() );
/// Here, transmit_lock_acquire is called by the XML-RPC client.
std::string err_msg = wefax_load_image_after_acquire( fil_nam.c_str() );
if( ! err_msg.empty() )
{
if (wefax_serviceme == active_modem)
{
/// Allows another XML-RPC client or the GUI to send an image.
wefax_serviceme->transmit_lock_release( err_msg );
}
return ;
}
wefax_cb_pic_tx_send_grey( NULL, NULL );
}

Plik diff jest za duży Load Diff

Wyświetl plik

@ -273,6 +273,7 @@ void Fl_Text_Buffer_mod::replace( int start, int end, const char *s ) {
// Range check...
if (!s) return;
if (start < 0) start = 0;
if (end < 0) end = 0;
if (end > mLength) end = mLength;
call_predelete_callbacks( start, end-start );

Wyświetl plik

@ -335,6 +335,8 @@ void Fl_Text_Buffer_mod::replace(int start, int end, const char *text)
return;
if (start < 0)
start = 0;
if (end < 0)
end = 0;
if (end > mLength)
end = mLength;

Wyświetl plik

@ -46,8 +46,6 @@ void wwv::rx_init()
phaseacc = 0.0;
smpl_ctr = 0; // sample counter for timing wwv rx
agc = 0.0; // threshold for tick detection
// sync = 0;
// sync0 = 0;
ticks = 0;
calc = false;
zoom = false;
@ -87,8 +85,8 @@ wwv::wwv() : modem()
lpfilter->init_lowpass (FIRLEN_1, DEC_1, lp);
vidfilter = new Cmovavg(16);
cap &= ~CAP_TX;
makeaudio();
}
@ -165,3 +163,58 @@ void wwv::set2(int x, int y)
zoom = !zoom;
}
//======================================================================
// transmit time tick
//======================================================================
void wwv::makeshape()
{
for (int i = 0; i < 32; i++)
keyshape[i] = 0.5 * (1.0 - cos (M_PI * i / 32));
}
double wwv::nco(double freq)
{
phaseacc += 2.0 * M_PI * freq / samplerate;
if (phaseacc > M_PI)
phaseacc -= 2.0 * M_PI;
return sin(phaseacc);
}
void wwv::makeaudio()
{
phaseacc = 0.0;
makeshape();
for (int i = 0; i < 400; i++) {
audio[i] = (i < 200 ? nco(1000) : 0);
quiet[i] = 0;
}
for (int i = 0; i < 32; i++) {
audio[i] *= keyshape[i];
audio[199 - i] *= keyshape[i];
}
}
int wwv::tx_process()
{
static int cycle = 4;
int c = get_tx_char();
if (c == 0x03 || stopflag) {
stopflag = false;
return -1;
}
if (--cycle == 0) {
memcpy(play, audio, 400 * sizeof(double));
ModulateXmtr(play, 400);
cycle = 4;
} else
ModulateXmtr(quiet, 400);
ModulateXmtr(quiet, 400);
ModulateXmtr(quiet, 400);
ModulateXmtr(quiet, 400);
ModulateXmtr(quiet, 400);
return 0;
}