kopia lustrzana https://github.com/jamescoxon/dl-fldigi
598 wiersze
14 KiB
C++
598 wiersze
14 KiB
C++
// ----------------------------------------------------------------------------
|
|
// rigsupport.cxx - support functions file
|
|
//
|
|
// Copyright (C) 2007-2009
|
|
// Dave Freese, W1HKJ
|
|
// Copyright (C) 2008-2009
|
|
// Stelios Bounanos, M0GLD
|
|
//
|
|
// This file is part of fldigi.
|
|
//
|
|
// Fldigi is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// Fldigi is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with fldigi. If not, see <http://www.gnu.org/licenses/>.
|
|
// ----------------------------------------------------------------------------
|
|
|
|
#include <config.h>
|
|
|
|
#include <fstream>
|
|
#include <sstream>
|
|
#include <vector>
|
|
#include <list>
|
|
#include <map>
|
|
#include <algorithm>
|
|
#include <iterator>
|
|
#include <cstring>
|
|
|
|
#include "rigsupport.h"
|
|
#include "rigxml.h"
|
|
#include "rigio.h"
|
|
|
|
#include "threads.h"
|
|
#include "main.h"
|
|
#include "fl_digi.h"
|
|
#include "trx.h"
|
|
|
|
#include "configuration.h"
|
|
|
|
#include "globals.h"
|
|
|
|
#include "debug.h"
|
|
|
|
#include "gettext.h"
|
|
|
|
LOG_FILE_SOURCE(debug::LOG_RIGCONTROL);
|
|
|
|
using namespace std;
|
|
|
|
string windowTitle;
|
|
|
|
vector<qrg_mode_t> freqlist;
|
|
|
|
const unsigned char nfields = 5;//4;
|
|
int fwidths[nfields];
|
|
enum { max_rfcarrier, max_rmode, max_mode, max_carrier };
|
|
|
|
#if !USE_HAMLIB
|
|
|
|
typedef enum {
|
|
RIG_MODE_NONE = 0, /*!< '' -- None */
|
|
RIG_MODE_AM = (1<<0), /*!< \c AM -- Amplitude Modulation */
|
|
RIG_MODE_CW = (1<<1), /*!< \c CW -- CW "normal" sideband */
|
|
RIG_MODE_USB = (1<<2), /*!< \c USB -- Upper Side Band */
|
|
RIG_MODE_LSB = (1<<3), /*!< \c LSB -- Lower Side Band */
|
|
RIG_MODE_RTTY = (1<<4), /*!< \c RTTY -- Radio Teletype */
|
|
RIG_MODE_FM = (1<<5), /*!< \c FM -- "narrow" band FM */
|
|
RIG_MODE_WFM = (1<<6), /*!< \c WFM -- broadcast wide FM */
|
|
RIG_MODE_CWR = (1<<7), /*!< \c CWR -- CW "reverse" sideband */
|
|
RIG_MODE_RTTYR = (1<<8), /*!< \c RTTYR -- RTTY "reverse" sideband */
|
|
RIG_MODE_AMS = (1<<9), /*!< \c AMS -- Amplitude Modulation Synchronous */
|
|
RIG_MODE_PKTLSB = (1<<10),/*!< \c PKTLSB -- Packet/Digital LSB mode (dedicated port) */
|
|
RIG_MODE_PKTUSB = (1<<11),/*!< \c PKTUSB -- Packet/Digital USB mode (dedicated port) */
|
|
RIG_MODE_PKTFM = (1<<12),/*!< \c PKTFM -- Packet/Digital FM mode (dedicated port) */
|
|
RIG_MODE_ECSSUSB = (1<<13),/*!< \c ECSSUSB -- Exalted Carrier Single Sideband USB */
|
|
RIG_MODE_ECSSLSB = (1<<14),/*!< \c ECSSLSB -- Exalted Carrier Single Sideband LSB */
|
|
RIG_MODE_FAX = (1<<15),/*!< \c FAX -- Facsimile Mode */
|
|
RIG_MODE_SAM = (1<<16),/*!< \c SAM -- Synchronous AM double sideband */
|
|
RIG_MODE_SAL = (1<<17),/*!< \c SAL -- Synchronous AM lower sideband */
|
|
RIG_MODE_SAH = (1<<18),/*!< \c SAH -- Synchronous AM upper (higher) sideband */
|
|
RIG_MODE_DSB = (1<<19), /*!< \c DSB -- Double sideband suppressed carrier */
|
|
} rmode_t;
|
|
|
|
#endif
|
|
|
|
struct rmode_name_t {
|
|
rmode_t mode;
|
|
const char *name;
|
|
} modes[] = {
|
|
{ RIG_MODE_NONE, "NONE" },
|
|
{ RIG_MODE_AM, "AM" },
|
|
{ RIG_MODE_CW, "CW" },
|
|
{ RIG_MODE_USB, "USB" },
|
|
{ RIG_MODE_LSB, "LSB" },
|
|
{ RIG_MODE_RTTY, "RTTY" },
|
|
{ RIG_MODE_FM, "FM" },
|
|
{ RIG_MODE_WFM, "WFM" },
|
|
{ RIG_MODE_CWR, "CWR" },
|
|
{ RIG_MODE_RTTYR, "RTTYR" },
|
|
{ RIG_MODE_AMS, "AMS" },
|
|
{ RIG_MODE_PKTLSB, "PKTLSB" },
|
|
{ RIG_MODE_PKTUSB, "PKTUSB" },
|
|
{ RIG_MODE_PKTFM, "PKTFM" }
|
|
//, // C99 trailing commas in enumerations not yet in the C++ standard
|
|
// { RIG_MODE_ECSSUSB, "ECSSUSB" },
|
|
// { RIG_MODE_ECSSLSB, "ECSSLSB" },
|
|
// { RIG_MODE_FAX, "FAX" }
|
|
// the above are covered by our requirement that hamlib be >= 1.2.4
|
|
#if (defined(RIG_MODE_SAM) && defined(RIG_MODE_SAL) && defined(RIG_MODE_SAH))
|
|
, // C99 trailing commas in enumerations not yet in the C++ standard
|
|
{ RIG_MODE_SAM, "SAM" },
|
|
{ RIG_MODE_SAL, "SAL" },
|
|
{ RIG_MODE_SAH, "SAH" }
|
|
#endif
|
|
};
|
|
|
|
map<string, rmode_t> mode_nums;
|
|
map<rmode_t, string> mode_names;
|
|
|
|
void qso_selMode(rmode_t m)
|
|
{
|
|
qso_opMODE->value(mode_names[m].c_str());
|
|
}
|
|
|
|
string modeString(rmode_t m)
|
|
{
|
|
return mode_names[m].c_str();
|
|
}
|
|
|
|
void initOptionMenus()
|
|
{
|
|
qso_opMODE->clear();
|
|
|
|
list<MODE>::iterator MD;
|
|
list<MODE> *pMD = 0;
|
|
|
|
if (lmodes.empty() == false)
|
|
pMD = &lmodes;
|
|
else if (lmodeCMD.empty() == false)
|
|
pMD = &lmodeCMD;
|
|
printf("initOptionMenus()\n");
|
|
if (pMD) {
|
|
MD = pMD->begin();
|
|
while (MD != pMD->end()) {
|
|
printf("adding mode: %s\n", (*MD).SYMBOL.c_str());
|
|
qso_opMODE->add( (*MD).SYMBOL.c_str());
|
|
MD++;
|
|
}
|
|
qso_opMODE->activate();
|
|
qso_opMODE->index(0);
|
|
}
|
|
else {
|
|
qso_opMODE->deactivate();
|
|
}
|
|
|
|
qso_opBW->clear();
|
|
list<BW>::iterator bw;
|
|
list<BW> *pBW = 0;
|
|
if (lbws.empty() == false)
|
|
pBW = &lbws;
|
|
else if (lbwCMD.empty() == false)
|
|
pBW = &lbwCMD;
|
|
|
|
if (pBW) {
|
|
bw = pBW->begin();
|
|
while (bw != pBW->end()) {
|
|
printf("adding BW: %s\n", (*bw).SYMBOL.c_str());
|
|
qso_opBW->add( (*bw).SYMBOL.c_str());
|
|
bw++;
|
|
}
|
|
qso_opBW->activate();
|
|
qso_opBW->index(0);
|
|
}
|
|
else {
|
|
qso_opBW->deactivate();
|
|
}
|
|
}
|
|
|
|
void clearList()
|
|
{
|
|
freqlist.clear();
|
|
qso_opBrowser->clear();
|
|
}
|
|
|
|
void updateSelect()
|
|
{
|
|
if (freqlist.empty())
|
|
return;
|
|
for (size_t i = 0; i < freqlist.size(); i++) {
|
|
qso_opBrowser->add(freqlist[i].str().c_str());
|
|
}
|
|
}
|
|
|
|
size_t updateList(long rf, int freq, string rmd, trx_mode md, string usage = "")
|
|
{
|
|
qrg_mode_t m;
|
|
m.rmode = rmd;
|
|
m.mode = md;
|
|
m.rfcarrier = rf;
|
|
m.carrier = freq;
|
|
m.usage = usage;
|
|
|
|
freqlist.push_back(m);
|
|
sort(freqlist.begin(), freqlist.end());
|
|
|
|
vector<qrg_mode_t>::const_iterator pos = find(freqlist.begin(), freqlist.end(), m);
|
|
if (pos != freqlist.end())
|
|
return pos - freqlist.begin();
|
|
else
|
|
return 0;
|
|
|
|
}
|
|
|
|
size_t addtoList(long val)
|
|
{
|
|
qrg_mode_t m;
|
|
|
|
m.rfcarrier = val;
|
|
|
|
if (strlen(qso_opMODE->value()))
|
|
m.rmode = qso_opMODE->value();
|
|
|
|
if (active_modem) {
|
|
m.carrier = active_modem->get_freq();
|
|
m.mode = active_modem->get_mode();
|
|
}
|
|
return updateList(val, m.carrier, m.rmode, m.mode);
|
|
}
|
|
|
|
bool readFreqList()
|
|
{
|
|
ifstream freqfile((HomeDir + "frequencies2.txt").c_str());
|
|
if (!freqfile) {
|
|
LOG_ERROR("Could not open %s", (HomeDir + "frequencies2.txt").c_str());
|
|
return false;
|
|
}
|
|
|
|
string line;
|
|
qrg_mode_t m;
|
|
while (!getline(freqfile, line).eof()) {
|
|
LOG_INFO("%s", line.c_str());
|
|
if (line[0] == '#')
|
|
continue;
|
|
istringstream is(line);
|
|
is >> m;
|
|
freqlist.push_back(m);
|
|
}
|
|
sort(freqlist.begin(), freqlist.end());
|
|
updateSelect();
|
|
|
|
freqfile.close();
|
|
|
|
return freqlist.size();
|
|
}
|
|
|
|
void saveFreqList()
|
|
{
|
|
if (freqlist.empty()) return;
|
|
|
|
ofstream freqfile((HomeDir + "frequencies2.txt").c_str());
|
|
if (!freqfile) {
|
|
LOG_ERROR("Could not open %s", (HomeDir + "frequencies2.txt").c_str());
|
|
return;
|
|
}
|
|
freqfile << "# rfcarrier rig_mode carrier mode usage\n";
|
|
|
|
copy( freqlist.begin(),
|
|
freqlist.end(),
|
|
ostream_iterator<qrg_mode_t>(freqfile, "\n") );
|
|
|
|
freqfile.close();
|
|
}
|
|
|
|
void build_frequencies2_list()
|
|
{
|
|
if (!freqlist.empty()) saveFreqList();
|
|
|
|
clearList();
|
|
// calculate the column widths
|
|
memset(fwidths, 0, sizeof(fwidths));
|
|
// these need to be a little wider than fl_width thinks
|
|
fwidths[max_rmode] = fwidths[max_mode] =
|
|
fwidths[max_carrier] = fwidths[max_rfcarrier]= 15;
|
|
|
|
fwidths[max_rfcarrier] += (int)ceil(fl_width("999999.999"));
|
|
|
|
fwidths[max_rmode] += (int)ceil(fl_width("XXXXXX"));
|
|
|
|
fwidths[max_carrier] += (int)ceil(fl_width("8888"));
|
|
|
|
// find mode with longest shortname
|
|
size_t s, smax = 0, mmax = 0;
|
|
for (size_t i = 0; i < NUM_MODES; i++) {
|
|
s = strlen(mode_info[i].sname);
|
|
if (smax < s) {
|
|
smax = s;
|
|
mmax = i;
|
|
}
|
|
}
|
|
fwidths[max_mode] += (int)ceil(fl_width(mode_info[mmax].sname));
|
|
|
|
if (readFreqList() == true)
|
|
return;
|
|
|
|
updateList (1807000L, 1000, "USB", MODE_PSK31 );
|
|
updateList (3505000L, 800, "USB", MODE_CW);
|
|
updateList (3580000L, 1000, "USB", MODE_PSK31 );
|
|
updateList (1000500L, 800, "USB", MODE_CW);
|
|
updateList (10135000L, 1000, "USB", MODE_PSK31 );
|
|
updateList (7005000L, 800, "USB", MODE_CW);
|
|
updateList (7030000L, 1000, "USB", MODE_PSK31 );
|
|
updateList (7070000L, 1000, "USB", MODE_PSK31 );
|
|
updateList (14005000L, 800, "USB", MODE_CW);
|
|
updateList (14070000L, 1000, "USB", MODE_PSK31 );
|
|
updateList (18100000L, 1000, "USB", MODE_PSK31 );
|
|
updateList (21005000L, 800, "USB", MODE_CW);
|
|
updateList (21070000L, 1000, "USB", MODE_PSK31 );
|
|
updateList (24920000L, 1000, "USB", MODE_PSK31 );
|
|
updateList (28005000L, 800, "USB", MODE_CW);
|
|
updateList (28120000, 1000, "USB", MODE_PSK31 );
|
|
updateSelect();
|
|
|
|
}
|
|
|
|
int cb_qso_opMODE()
|
|
{
|
|
if (connected_to_flrig) {
|
|
set_flrig_mode(qso_opMODE->value());
|
|
return 0;
|
|
}
|
|
#if USE_HAMLIB
|
|
if (progdefaults.chkUSEHAMLIBis)
|
|
hamlib_setmode(mode_nums[qso_opMODE->value()]);
|
|
else
|
|
#endif
|
|
if (progdefaults.chkUSERIGCATis)
|
|
rigCAT_setmode(qso_opMODE->value());
|
|
else
|
|
noCAT_setmode(qso_opMODE->value());
|
|
return 0;
|
|
}
|
|
|
|
int cb_qso_opBW()
|
|
{
|
|
if (connected_to_flrig)
|
|
set_flrig_bw(qso_opBW->index(), -1);
|
|
else if (progdefaults.chkUSERIGCATis)
|
|
rigCAT_setwidth(qso_opBW->value());
|
|
else
|
|
noCAT_setwidth(qso_opBW->value());
|
|
return 0;
|
|
}
|
|
|
|
int cb_qso_btnBW1()
|
|
{
|
|
qso_btnBW1->hide();
|
|
qso_opBW1->hide();
|
|
qso_btnBW2->show();
|
|
qso_opBW2->show();
|
|
return 0;
|
|
}
|
|
|
|
int cb_qso_btnBW2()
|
|
{
|
|
qso_btnBW2->hide();
|
|
qso_opBW2->hide();
|
|
qso_btnBW1->show();
|
|
qso_opBW1->show();
|
|
return 0;
|
|
}
|
|
|
|
int cb_qso_opBW1()
|
|
{
|
|
//printf("opBW1 %d:%s\n", qso_opBW1->index(), qso_opBW1->value());
|
|
set_flrig_bw(qso_opBW2->index(), qso_opBW1->index());
|
|
return 0;
|
|
}
|
|
|
|
int cb_qso_opBW2()
|
|
{
|
|
//printf("opBW2 %d:%s\n", qso_opBW2->index(), qso_opBW2->value());
|
|
set_flrig_bw(qso_opBW2->index(), qso_opBW1->index());
|
|
return 0;
|
|
}
|
|
|
|
void sendFreq(long int f)
|
|
{
|
|
if (connected_to_flrig)
|
|
set_flrig_freq(f);
|
|
#if USE_HAMLIB
|
|
else if (progdefaults.chkUSEHAMLIBis)
|
|
hamlib_setfreq(f);
|
|
#endif
|
|
else if (progdefaults.chkUSERIGCATis)
|
|
rigCAT_setfreq(f);
|
|
else
|
|
noCAT_setfreq(f);
|
|
}
|
|
|
|
void qso_movFreq(Fl_Widget* w, void *data)
|
|
{
|
|
cFreqControl *fc = (cFreqControl *)w;
|
|
long int f;
|
|
long restore = reinterpret_cast<long>(data);
|
|
f = fc->value();
|
|
if (fc == qsoFreqDisp1) {
|
|
qsoFreqDisp2->value(f);
|
|
qsoFreqDisp3->value(f);
|
|
} else if (fc == qsoFreqDisp2) {
|
|
qsoFreqDisp1->value(f);
|
|
qsoFreqDisp3->value(f);
|
|
} else {
|
|
qsoFreqDisp1->value(f);
|
|
qsoFreqDisp2->value(f);
|
|
}
|
|
|
|
sendFreq(f);
|
|
if (restore == 1)
|
|
restoreFocus();
|
|
return;
|
|
}
|
|
|
|
void qso_selectFreq(long int rfcarrier, int carrier)
|
|
{
|
|
if (rfcarrier > 0) {
|
|
qsoFreqDisp1->value(rfcarrier);
|
|
qsoFreqDisp2->value(rfcarrier);
|
|
qsoFreqDisp3->value(rfcarrier);
|
|
sendFreq(rfcarrier);
|
|
}
|
|
|
|
if (carrier > 0) {
|
|
active_modem->set_freq(carrier);
|
|
}
|
|
}
|
|
|
|
void qso_selectFreq()
|
|
{
|
|
int n = qso_opBrowser->value();
|
|
if (!n) return;
|
|
|
|
n -= 1;
|
|
// transceiver frequency
|
|
if (freqlist[n].rfcarrier > 0) {
|
|
qsoFreqDisp1->value(freqlist[n].rfcarrier);
|
|
qsoFreqDisp2->value(freqlist[n].rfcarrier);
|
|
qsoFreqDisp3->value(freqlist[n].rfcarrier);
|
|
sendFreq(freqlist[n].rfcarrier);
|
|
}
|
|
// transceiver mode
|
|
if (freqlist[n].rmode != "NONE") {
|
|
qso_opMODE->value(freqlist[n].rmode.c_str());
|
|
cb_qso_opMODE();
|
|
}
|
|
// modem type & audio sub carrier
|
|
if (freqlist[n].mode != NUM_MODES) {
|
|
if (freqlist[n].mode != active_modem->get_mode())
|
|
init_modem_sync(freqlist[n].mode);
|
|
if (freqlist[n].carrier > 0)
|
|
active_modem->set_freq(freqlist[n].carrier);
|
|
}
|
|
}
|
|
|
|
void qso_setFreq(long int f)
|
|
{
|
|
// transceiver frequency
|
|
if (f > 0) {
|
|
qsoFreqDisp->value(f);
|
|
sendFreq(f);
|
|
}
|
|
}
|
|
|
|
void qso_setFreq()
|
|
{
|
|
int n = qso_opBrowser->value();
|
|
if (!n) return;
|
|
|
|
n -= 1;
|
|
// transceiver frequency
|
|
qso_setFreq(freqlist[n].rfcarrier);
|
|
}
|
|
|
|
void qso_delFreq()
|
|
{
|
|
int v = qso_opBrowser->value() - 1;
|
|
|
|
if (v >= 0) {
|
|
freqlist.erase(freqlist.begin() + v);
|
|
qso_opBrowser->remove(v + 1);
|
|
}
|
|
}
|
|
|
|
void qso_addFreq()
|
|
{
|
|
long freq = qsoFreqDisp->value();
|
|
if (freq) {
|
|
size_t pos = addtoList(freq);
|
|
qso_opBrowser->insert(pos+1, freqlist[pos].str().c_str());
|
|
}
|
|
}
|
|
|
|
void qso_updateEntry(int i, std::string usage)
|
|
{
|
|
int v = i - 1;
|
|
int sz = (int)freqlist.size();
|
|
if ((v >= 0) && (v < sz)) {
|
|
freqlist[v].usage = usage;
|
|
}
|
|
}
|
|
|
|
void setTitle()
|
|
{
|
|
if (windowTitle.empty()) return;
|
|
size_t p = main_window_title.find(" / ");
|
|
if (p != string::npos) main_window_title.erase(p);
|
|
main_window_title.append(" / ").append(windowTitle);
|
|
update_main_title();
|
|
}
|
|
|
|
bool init_Xml_RigDialog()
|
|
{
|
|
LOG_DEBUG("xml rig");
|
|
initOptionMenus();
|
|
windowTitle = xmlrig.rigTitle;
|
|
setTitle();
|
|
return true;
|
|
}
|
|
|
|
bool init_NoRig_RigDialog()
|
|
{
|
|
LOG_DEBUG("no rig");
|
|
qso_opBW->deactivate();
|
|
qso_opMODE->clear();
|
|
|
|
printf("init_NoRig_RigDialog()\n");
|
|
for (size_t i = 0; i < sizeof(modes)/sizeof(modes[0]); i++) {
|
|
printf("adding %s\n", modes[i].name);
|
|
qso_opMODE->add(modes[i].name);
|
|
}
|
|
// list of LSB type modes that various xcvrs report via flrig
|
|
LSBmodes.clear();
|
|
LSBmodes.push_back("LSB");
|
|
LSBmodes.push_back("LSB-D");
|
|
LSBmodes.push_back("LSB-D1");
|
|
LSBmodes.push_back("LSB-D2");
|
|
LSBmodes.push_back("LSB-D3");
|
|
LSBmodes.push_back("CW");
|
|
LSBmodes.push_back("LCW");
|
|
LSBmodes.push_back("CW-N");
|
|
LSBmodes.push_back("CWL");
|
|
LSBmodes.push_back("RTTY");
|
|
LSBmodes.push_back("RTTY-L");
|
|
LSBmodes.push_back("PKTLSB");
|
|
LSBmodes.push_back("PKT-L");
|
|
LSBmodes.push_back("USER-L");
|
|
LSBmodes.push_back("DATA-L");
|
|
LSBmodes.push_back("DATA");
|
|
LSBmodes.push_back("D-LSB");
|
|
|
|
qso_opMODE->index(3);
|
|
qso_opMODE->activate();
|
|
|
|
windowTitle.clear();
|
|
setTitle();
|
|
|
|
return true;
|
|
}
|
|
|
|
#if USE_HAMLIB
|
|
bool init_Hamlib_RigDialog()
|
|
{
|
|
LOG_DEBUG("hamlib");
|
|
|
|
qso_opBW->deactivate();
|
|
qso_opMODE->clear();
|
|
|
|
for (size_t i = 0; i < sizeof(modes)/sizeof(modes[0]); i++) {
|
|
mode_nums[modes[i].name] = modes[i].mode;
|
|
mode_names[modes[i].mode] = modes[i].name;
|
|
qso_opMODE->add(modes[i].name);
|
|
}
|
|
|
|
windowTitle = "Hamlib ";
|
|
windowTitle.append(xcvr->getName());
|
|
|
|
setTitle();
|
|
|
|
return true;
|
|
}
|
|
#endif
|