2007-06-22 22:10:49 +00:00
|
|
|
//
|
|
|
|
// Digital Modem Program for the Fast Light Toolkit
|
|
|
|
//
|
|
|
|
// Copyright W1HKJ, Dave Freese 2006
|
|
|
|
//
|
|
|
|
// This library is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU Library General Public
|
|
|
|
// License as published by the Free Software Foundation; either
|
|
|
|
// version 2 of the License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This library 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
|
|
|
|
// Library General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Library General Public
|
|
|
|
// License along with this library; if not, write to the Free Software
|
|
|
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
|
|
|
// USA.
|
|
|
|
//
|
|
|
|
// Please report all bugs and problems to "w1hkj@w1hkj.com".
|
|
|
|
//
|
2007-07-21 12:15:41 +00:00
|
|
|
|
2007-11-28 22:32:50 +00:00
|
|
|
#include <config.h>
|
|
|
|
|
2007-10-08 06:59:57 +00:00
|
|
|
#include <iostream>
|
|
|
|
#include <iomanip>
|
|
|
|
#include <sstream>
|
|
|
|
#include <cstdlib>
|
|
|
|
#include <getopt.h>
|
2007-07-21 12:15:41 +00:00
|
|
|
#include <sys/types.h>
|
2008-03-30 13:38:05 +00:00
|
|
|
#ifndef __CYGWIN__
|
|
|
|
# include <sys/ipc.h>
|
|
|
|
# include <sys/msg.h>
|
|
|
|
#endif
|
2007-10-16 17:18:03 +00:00
|
|
|
#include <sys/utsname.h>
|
2007-11-01 03:22:20 +00:00
|
|
|
#include <unistd.h>
|
|
|
|
#include <dirent.h>
|
2007-12-11 03:36:51 +00:00
|
|
|
#include <exception>
|
|
|
|
#include <signal.h>
|
2007-12-20 08:21:04 +00:00
|
|
|
#include <locale.h>
|
2007-07-21 12:15:41 +00:00
|
|
|
|
2008-04-01 17:47:24 +00:00
|
|
|
#include <FL/Fl.H>
|
|
|
|
#include <FL/Enumerations.H>
|
|
|
|
#include <FL/Fl_Window.H>
|
2007-06-22 22:10:49 +00:00
|
|
|
#include <FL/Fl_Shared_Image.H>
|
2008-04-01 17:47:24 +00:00
|
|
|
#include <FL/x.H>
|
2008-01-09 04:19:08 +00:00
|
|
|
|
2008-11-25 00:14:59 +00:00
|
|
|
#include "gettext.h"
|
2007-06-22 22:04:50 +00:00
|
|
|
#include "main.h"
|
|
|
|
#include "waterfall.h"
|
2007-06-22 22:10:49 +00:00
|
|
|
#include "fft.h"
|
2008-03-30 13:38:05 +00:00
|
|
|
#include "soundconf.h"
|
2007-06-22 22:04:50 +00:00
|
|
|
#include "complex.h"
|
|
|
|
#include "fl_digi.h"
|
|
|
|
#include "rigio.h"
|
|
|
|
#include "globals.h"
|
|
|
|
#include "psk.h"
|
|
|
|
#include "cw.h"
|
|
|
|
#include "mfsk.h"
|
2008-02-15 19:36:53 +00:00
|
|
|
#include "confdialog.h"
|
2008-11-29 19:20:54 +00:00
|
|
|
#include "colorsfonts.h"
|
2007-06-22 22:04:50 +00:00
|
|
|
#include "configuration.h"
|
|
|
|
#include "macros.h"
|
|
|
|
#include "status.h"
|
2008-05-17 03:24:15 +00:00
|
|
|
#include "fileselect.h"
|
2008-06-30 00:20:03 +00:00
|
|
|
#include "timeops.h"
|
2008-08-26 22:33:34 +00:00
|
|
|
#include "debug.h"
|
2008-11-22 01:32:17 +00:00
|
|
|
#include "pskrep.h"
|
2008-11-26 05:21:34 +00:00
|
|
|
#include "logbook.h"
|
2008-12-10 22:48:53 +00:00
|
|
|
#include "dxcc.h"
|
2008-12-23 00:08:43 +00:00
|
|
|
#include "newinstall.h"
|
2007-06-22 22:04:50 +00:00
|
|
|
|
2007-11-28 22:32:50 +00:00
|
|
|
#if USE_HAMLIB
|
2007-06-22 22:04:50 +00:00
|
|
|
#include "rigclass.h"
|
|
|
|
#endif
|
|
|
|
#include "rigsupport.h"
|
|
|
|
|
|
|
|
#include "log.h"
|
|
|
|
|
2007-09-19 00:45:42 +00:00
|
|
|
#include "qrunner.h"
|
2007-12-11 03:36:51 +00:00
|
|
|
#include "stacktrace.h"
|
2007-09-19 00:45:42 +00:00
|
|
|
|
2008-05-17 03:24:15 +00:00
|
|
|
#if USE_XMLRPC
|
|
|
|
#include "xmlrpc.h"
|
|
|
|
#endif
|
|
|
|
|
2009-02-04 05:20:24 +00:00
|
|
|
#if BENCHMARK_MODE
|
|
|
|
#include "benchmark.h"
|
|
|
|
#endif
|
|
|
|
|
2007-06-22 22:04:50 +00:00
|
|
|
using namespace std;
|
|
|
|
|
2008-05-10 23:59:51 +00:00
|
|
|
string appname;
|
|
|
|
|
2008-02-27 02:58:09 +00:00
|
|
|
string scDevice[2];
|
2007-11-07 17:42:47 +00:00
|
|
|
|
2008-12-23 00:08:43 +00:00
|
|
|
string HomeDir;
|
|
|
|
string RigsDir;
|
|
|
|
string ScriptsDir;
|
|
|
|
string PalettesDir;
|
|
|
|
string LogsDir;
|
|
|
|
string PicsDir;
|
|
|
|
string HelpDir;
|
|
|
|
string MacrosDir;
|
2009-02-05 21:09:58 +00:00
|
|
|
string WrapDir;
|
|
|
|
string TalkDir;
|
2008-12-23 00:08:43 +00:00
|
|
|
string TempDir;
|
2007-06-22 22:10:49 +00:00
|
|
|
string PskMailDir;
|
2008-12-23 00:08:43 +00:00
|
|
|
|
2007-06-22 22:10:49 +00:00
|
|
|
string PskMailFile;
|
2007-07-21 12:15:41 +00:00
|
|
|
string ArqFilename;
|
2007-06-22 22:04:50 +00:00
|
|
|
string xmlfname;
|
|
|
|
|
|
|
|
PTT *push2talk = (PTT *)0;
|
2007-11-28 22:32:50 +00:00
|
|
|
#if USE_HAMLIB
|
2007-06-22 22:04:50 +00:00
|
|
|
Rig *xcvr = (Rig *)0;
|
|
|
|
#endif
|
|
|
|
|
2008-09-14 14:00:49 +00:00
|
|
|
bool tlfio = false;
|
2008-11-26 05:21:34 +00:00
|
|
|
cLogfile *logfile = 0;
|
2007-06-22 22:04:50 +00:00
|
|
|
cLogfile *Maillogfile = (cLogfile *)0;
|
|
|
|
FILE *server;
|
|
|
|
FILE *client;
|
2007-07-21 12:15:41 +00:00
|
|
|
bool mailserver = false, mailclient = false, arqmode = false;
|
2007-06-22 22:04:50 +00:00
|
|
|
|
2007-07-21 12:15:41 +00:00
|
|
|
RXMSGSTRUC rxmsgst;
|
|
|
|
int rxmsgid = -1;
|
2007-06-22 22:04:50 +00:00
|
|
|
|
2007-07-21 12:15:41 +00:00
|
|
|
TXMSGSTRUC txmsgst;
|
|
|
|
int txmsgid = -1;
|
2007-06-22 22:25:46 +00:00
|
|
|
|
2008-01-25 23:11:48 +00:00
|
|
|
string option_help, version_text;
|
2007-06-22 22:04:50 +00:00
|
|
|
|
2007-11-28 22:32:50 +00:00
|
|
|
qrunner *cbq[NUM_QRUNNER_THREADS];
|
2007-08-14 13:44:14 +00:00
|
|
|
|
2007-10-08 06:59:57 +00:00
|
|
|
void arqchecks(void);
|
|
|
|
void generate_option_help(void);
|
|
|
|
int parse_args(int argc, char **argv, int& idx);
|
2008-01-25 23:11:48 +00:00
|
|
|
void generate_version_text(void);
|
2008-01-15 03:16:59 +00:00
|
|
|
void debug_exec(char** argv);
|
2008-06-30 00:20:03 +00:00
|
|
|
void set_platform_ui(void);
|
|
|
|
double speed_test(int converter, unsigned repeat);
|
2008-10-12 06:35:04 +00:00
|
|
|
static void setup_signal_handlers(void);
|
2008-12-23 00:08:43 +00:00
|
|
|
static void checkdirectories(void);
|
2007-07-21 12:15:41 +00:00
|
|
|
|
2007-09-19 00:45:42 +00:00
|
|
|
int main(int argc, char ** argv)
|
|
|
|
{
|
2008-05-10 23:59:51 +00:00
|
|
|
appname = argv[0];
|
2008-01-15 03:16:59 +00:00
|
|
|
debug_exec(argv);
|
2007-09-19 00:45:42 +00:00
|
|
|
CREATE_THREAD_ID(); // only call this once
|
|
|
|
SET_THREAD_ID(FLMAIN_TID);
|
|
|
|
|
2007-10-06 15:04:10 +00:00
|
|
|
for (int i = 0; i < NUM_QRUNNER_THREADS; i++) {
|
2008-06-12 22:15:17 +00:00
|
|
|
cbq[i] = new qrunner;
|
2007-09-19 00:45:42 +00:00
|
|
|
cbq[i]->attach();
|
|
|
|
}
|
2007-07-21 12:15:41 +00:00
|
|
|
|
2007-12-11 03:36:51 +00:00
|
|
|
set_unexpected(handle_unexpected);
|
|
|
|
set_terminate(diediedie);
|
2008-09-26 19:17:45 +00:00
|
|
|
setup_signal_handlers();
|
2007-12-11 03:36:51 +00:00
|
|
|
|
2008-11-25 00:14:59 +00:00
|
|
|
#ifndef ENABLE_NLS
|
2008-01-10 18:02:24 +00:00
|
|
|
setlocale(LC_TIME, "");
|
2008-11-25 00:14:59 +00:00
|
|
|
#endif
|
2007-12-20 08:21:04 +00:00
|
|
|
|
2009-01-01 17:03:36 +00:00
|
|
|
{
|
|
|
|
char dirbuf[FL_PATH_MAX + 1];
|
2008-04-14 22:18:15 +00:00
|
|
|
#ifdef __CYGWIN__
|
2009-01-01 17:03:36 +00:00
|
|
|
fl_filename_expand(dirbuf, sizeof(dirbuf) - 1, "$USERPROFILE/fldigi.files/");
|
2008-07-24 12:22:53 +00:00
|
|
|
#else
|
2009-01-01 17:03:36 +00:00
|
|
|
fl_filename_expand(dirbuf, sizeof(dirbuf) - 1, "$HOME/.fldigi/");
|
2008-07-25 12:08:44 +00:00
|
|
|
#endif
|
2009-01-01 17:03:36 +00:00
|
|
|
HomeDir = dirbuf;
|
|
|
|
fl_filename_expand(dirbuf, sizeof(dirbuf) - 1, "$HOME/");
|
|
|
|
PskMailDir = dirbuf;
|
|
|
|
}
|
2008-04-14 22:18:15 +00:00
|
|
|
|
2008-07-24 12:22:53 +00:00
|
|
|
set_platform_ui();
|
2008-06-16 02:17:11 +00:00
|
|
|
|
2007-10-08 06:59:57 +00:00
|
|
|
generate_option_help();
|
2008-01-25 23:11:48 +00:00
|
|
|
generate_version_text();
|
2007-10-08 06:59:57 +00:00
|
|
|
int arg_idx;
|
2007-10-27 14:57:10 +00:00
|
|
|
if (Fl::args(argc, argv, arg_idx, parse_args) != argc) {
|
2007-11-28 22:32:50 +00:00
|
|
|
cerr << PACKAGE_NAME << ": unrecognized option `" << argv[arg_idx]
|
|
|
|
<< "'\nTry `" << PACKAGE_NAME
|
2007-10-27 14:57:10 +00:00
|
|
|
<< " --help' for more information.\n";
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
2008-12-23 00:08:43 +00:00
|
|
|
checkdirectories();
|
2008-11-13 00:13:14 +00:00
|
|
|
bool have_config = progdefaults.readDefaultsXML();
|
2008-08-26 22:33:34 +00:00
|
|
|
try {
|
|
|
|
debug::start(string(HomeDir).append("status_log.txt").c_str());
|
|
|
|
time_t t = time(NULL);
|
2009-01-05 16:00:01 +00:00
|
|
|
LOG(debug::QUIET_LEVEL, debug::LOG_OTHER, _("%s log started on %s"), PACKAGE_STRING, ctime(&t));
|
2008-08-26 22:33:34 +00:00
|
|
|
}
|
|
|
|
catch (const char* error) {
|
|
|
|
cerr << error << '\n';
|
|
|
|
debug::stop();
|
|
|
|
}
|
|
|
|
|
2007-07-21 12:15:41 +00:00
|
|
|
xmlfname = HomeDir;
|
|
|
|
xmlfname.append("rig.xml");
|
|
|
|
|
2008-12-06 22:57:55 +00:00
|
|
|
Date tdy;
|
2007-07-21 12:15:41 +00:00
|
|
|
string lfname = HomeDir;
|
2008-12-06 22:57:55 +00:00
|
|
|
lfname.append("fldigi");
|
|
|
|
lfname.append(tdy.szDate(2));
|
|
|
|
lfname.append(".log");
|
2007-07-21 12:15:41 +00:00
|
|
|
logfile = new cLogfile(lfname);
|
|
|
|
logfile->log_to_file_start();
|
|
|
|
|
2008-03-30 13:38:05 +00:00
|
|
|
#ifndef __CYGWIN__
|
2007-10-29 03:15:22 +00:00
|
|
|
txmsgid = msgget( (key_t) progdefaults.tx_msgid, 0666 );
|
2008-03-30 13:38:05 +00:00
|
|
|
#else
|
|
|
|
txmsgid = -1;
|
|
|
|
#endif
|
2008-09-14 14:00:49 +00:00
|
|
|
|
|
|
|
checkTLF();
|
2007-10-29 03:15:22 +00:00
|
|
|
|
2009-01-01 17:03:36 +00:00
|
|
|
|
2008-11-29 06:36:17 +00:00
|
|
|
Fl::lock(); // start the gui thread!!
|
2007-08-14 01:18:58 +00:00
|
|
|
Fl::visual(FL_RGB); // insure 24 bit color operation
|
2007-08-14 01:17:50 +00:00
|
|
|
|
2007-06-22 22:04:50 +00:00
|
|
|
fl_register_images();
|
2007-06-22 22:19:01 +00:00
|
|
|
Fl::set_fonts(0);
|
2007-06-22 22:25:46 +00:00
|
|
|
|
2007-06-22 22:04:50 +00:00
|
|
|
rigcontrol = createRigDialog();
|
2008-06-30 00:20:03 +00:00
|
|
|
|
2008-11-13 00:13:14 +00:00
|
|
|
if (!have_config) {
|
2008-06-30 00:20:03 +00:00
|
|
|
double speed = speed_test(SRC_SINC_FASTEST, 8);
|
2008-08-26 22:33:34 +00:00
|
|
|
|
2008-06-30 00:20:03 +00:00
|
|
|
if (speed > 150.0) { // fast
|
|
|
|
progdefaults.slowcpu = false;
|
|
|
|
progdefaults.sample_converter = SRC_SINC_BEST_QUALITY;
|
|
|
|
}
|
|
|
|
else if (speed > 60.0) { // ok
|
|
|
|
progdefaults.slowcpu = false;
|
|
|
|
progdefaults.sample_converter = SRC_SINC_MEDIUM_QUALITY;
|
|
|
|
}
|
|
|
|
else if (speed > 20.0) { // slow
|
|
|
|
progdefaults.slowcpu = true;
|
|
|
|
progdefaults.sample_converter = SRC_SINC_FASTEST;
|
|
|
|
}
|
|
|
|
else { // recycle me
|
|
|
|
progdefaults.slowcpu = true;
|
|
|
|
progdefaults.sample_converter = SRC_LINEAR;
|
|
|
|
}
|
2008-08-26 22:33:34 +00:00
|
|
|
|
|
|
|
LOG_INFO("speed factor=%f, slowcpu=%d, sample_converter=\"%s\"", speed,
|
|
|
|
progdefaults.slowcpu, src_get_name(progdefaults.sample_converter));
|
2008-06-30 00:20:03 +00:00
|
|
|
}
|
2008-10-25 01:11:49 +00:00
|
|
|
if (progdefaults.XmlRigFilename.empty())
|
|
|
|
progdefaults.XmlRigFilename = xmlfname;
|
2008-06-30 00:20:03 +00:00
|
|
|
|
2008-03-08 23:24:42 +00:00
|
|
|
progStatus.loadLastState();
|
2008-08-31 14:10:22 +00:00
|
|
|
|
|
|
|
Fl::scheme(progdefaults.ui_scheme.c_str());
|
2008-11-26 05:21:34 +00:00
|
|
|
|
2007-06-22 22:04:50 +00:00
|
|
|
create_fl_digi_main();
|
2009-02-04 05:20:24 +00:00
|
|
|
|
|
|
|
#if BENCHMARK_MODE
|
|
|
|
return setup_benchmark();
|
|
|
|
#endif
|
|
|
|
|
2008-05-17 03:24:15 +00:00
|
|
|
FSEL::create();
|
2007-06-22 22:24:50 +00:00
|
|
|
|
2007-06-22 22:04:50 +00:00
|
|
|
createConfig();
|
2008-11-29 19:20:54 +00:00
|
|
|
make_colorsfonts();
|
|
|
|
setTabColors();
|
2008-11-26 05:21:34 +00:00
|
|
|
|
|
|
|
start_logbook();
|
|
|
|
|
2008-09-08 16:48:25 +00:00
|
|
|
progdefaults.testCommPorts();
|
|
|
|
|
2007-06-22 22:04:50 +00:00
|
|
|
macros.loadDefault();
|
|
|
|
|
2007-11-28 22:32:50 +00:00
|
|
|
#if USE_HAMLIB
|
2007-06-22 22:04:50 +00:00
|
|
|
xcvr = new Rig();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
push2talk = new PTT();
|
|
|
|
|
2008-03-08 23:19:46 +00:00
|
|
|
progdefaults.setDefaults();
|
2008-02-09 23:07:10 +00:00
|
|
|
|
2008-03-30 13:38:05 +00:00
|
|
|
atexit(sound_close);
|
2008-02-09 23:07:10 +00:00
|
|
|
sound_init();
|
2008-02-27 02:58:09 +00:00
|
|
|
trx_start();
|
2008-02-09 23:07:10 +00:00
|
|
|
|
2008-04-01 17:47:24 +00:00
|
|
|
progdefaults.initInterface();
|
2008-04-14 22:18:15 +00:00
|
|
|
|
2008-10-31 03:47:24 +00:00
|
|
|
// OS X will prevent the main window from being resized if we change its
|
|
|
|
// size *after* it has been shown. With some X11 window managers, OTOH,
|
|
|
|
// the main window will not be restored at its exact saved position if
|
|
|
|
// we move it *after* it has been shown.
|
|
|
|
#ifndef __APPLE__
|
2008-02-09 23:07:10 +00:00
|
|
|
fl_digi_main->show(argc, argv);
|
|
|
|
progStatus.initLastState();
|
2008-10-31 03:47:24 +00:00
|
|
|
#else
|
|
|
|
progStatus.initLastState();
|
|
|
|
fl_digi_main->show(argc, argv);
|
|
|
|
#endif
|
|
|
|
|
2008-08-03 00:04:18 +00:00
|
|
|
arq_init();
|
2008-02-09 23:07:10 +00:00
|
|
|
|
2008-05-17 03:24:15 +00:00
|
|
|
#if USE_XMLRPC
|
2008-09-11 01:35:48 +00:00
|
|
|
XML_RPC_Server::start(progdefaults.xmlrpc_address.c_str(), progdefaults.xmlrpc_port.c_str());
|
2008-05-17 03:24:15 +00:00
|
|
|
#endif
|
|
|
|
|
2008-11-23 06:20:16 +00:00
|
|
|
if (progdefaults.usepskrep)
|
|
|
|
if (!pskrep_start())
|
|
|
|
LOG_ERROR("Could not start PSK reporter: %s", pskrep_error());
|
2008-11-22 01:32:17 +00:00
|
|
|
|
2008-12-18 00:01:59 +00:00
|
|
|
if (progdefaults.rxtext_tooltips || progdefaults.autofill_qso_fields)
|
|
|
|
dxcc_open(string(HomeDir).append("cty.dat").c_str());
|
2009-02-04 05:20:24 +00:00
|
|
|
if (progdefaults.rxtext_tooltips) {
|
|
|
|
qsl_open(string(HomeDir).append("lotw1.txt").c_str(), QSL_LOTW);
|
|
|
|
if (!qsl_open(string(HomeDir).append("eqsl.txt").c_str(), QSL_EQSL))
|
|
|
|
qsl_open(string(HomeDir).append("AGMemberList.txt").c_str(), QSL_EQSL);
|
|
|
|
}
|
2008-12-10 22:48:53 +00:00
|
|
|
|
2008-02-09 23:07:10 +00:00
|
|
|
int ret = Fl::run();
|
2008-05-17 03:24:15 +00:00
|
|
|
|
2008-08-13 15:41:18 +00:00
|
|
|
arq_close();
|
|
|
|
|
2008-05-17 03:24:15 +00:00
|
|
|
#if USE_XMLRPC
|
|
|
|
XML_RPC_Server::stop();
|
|
|
|
#endif
|
|
|
|
|
2008-11-23 06:20:16 +00:00
|
|
|
if (progdefaults.usepskrep)
|
|
|
|
pskrep_stop();
|
2008-11-22 01:32:17 +00:00
|
|
|
|
2008-04-29 21:07:44 +00:00
|
|
|
for (int i = 0; i < NUM_QRUNNER_THREADS; i++) {
|
2008-02-09 23:07:10 +00:00
|
|
|
cbq[i]->detach();
|
2008-04-29 21:07:44 +00:00
|
|
|
delete cbq[i];
|
|
|
|
}
|
2008-05-17 03:24:15 +00:00
|
|
|
FSEL::destroy();
|
2008-08-26 22:33:34 +00:00
|
|
|
debug::stop();
|
2008-02-09 23:07:10 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2007-06-22 22:10:49 +00:00
|
|
|
|
2007-10-08 06:59:57 +00:00
|
|
|
void generate_option_help(void) {
|
|
|
|
ostringstream help;
|
2008-01-29 15:58:15 +00:00
|
|
|
help << "Usage:\n"
|
2008-01-25 23:11:48 +00:00
|
|
|
<< " " << PACKAGE_NAME << " [option...]\n\n";
|
|
|
|
|
|
|
|
help << PACKAGE_NAME << " options:\n\n"
|
2008-01-29 15:58:15 +00:00
|
|
|
<< " --config-dir DIRECTORY\n"
|
2008-01-25 23:11:48 +00:00
|
|
|
<< " Look for configuration files in DIRECTORY\n"
|
|
|
|
<< " The default is: " << HomeDir << "\n\n"
|
2008-01-29 15:58:15 +00:00
|
|
|
|
2008-03-30 13:38:05 +00:00
|
|
|
#ifndef __CYGWIN__
|
2008-01-29 15:58:15 +00:00
|
|
|
<< " --rx-ipc-key KEY\n"
|
|
|
|
<< " Set the receive message queue key\n"
|
2008-01-25 23:11:48 +00:00
|
|
|
<< " May be given in hex if prefixed with \"0x\"\n"
|
|
|
|
<< " The default is: " << progdefaults.rx_msgid
|
|
|
|
<< " or 0x" << hex << progdefaults.rx_msgid << dec << "\n\n"
|
|
|
|
|
2008-01-29 15:58:15 +00:00
|
|
|
<< " --tx-ipc-key KEY\n"
|
|
|
|
<< " Set the transmit message queue key\n"
|
2008-01-25 23:11:48 +00:00
|
|
|
<< " May be given in hex if prefixed with \"0x\"\n"
|
|
|
|
<< " The default is: " << progdefaults.tx_msgid
|
|
|
|
<< " or 0x" << hex << progdefaults.tx_msgid << dec << "\n\n"
|
2008-03-30 13:38:05 +00:00
|
|
|
#endif
|
2008-01-25 23:11:48 +00:00
|
|
|
|
2008-08-13 15:41:18 +00:00
|
|
|
<< " --arq-server-address HOSTNAME\n"
|
|
|
|
<< " Set the ARQ TCP server address\n"
|
|
|
|
<< " The default is: " << progdefaults.arq_address << "\n\n"
|
|
|
|
<< " --arq-server-port PORT\n"
|
|
|
|
<< " Set the ARQ TCP server port\n"
|
|
|
|
<< " The default is: " << progdefaults.arq_port << "\n\n"
|
|
|
|
|
2008-06-13 13:23:46 +00:00
|
|
|
#if USE_XMLRPC
|
2008-05-17 03:24:15 +00:00
|
|
|
<< " --xmlrpc-server-address HOSTNAME\n"
|
|
|
|
<< " Set the XML-RPC server address\n"
|
|
|
|
<< " The default is: " << progdefaults.xmlrpc_address << "\n\n"
|
|
|
|
<< " --xmlrpc-server-port PORT\n"
|
|
|
|
<< " Set the XML-RPC server port\n"
|
|
|
|
<< " The default is: " << progdefaults.xmlrpc_port << "\n\n"
|
2008-09-26 19:17:45 +00:00
|
|
|
<< " --xmlrpc-allow REGEX\n"
|
|
|
|
<< " Allow only the methods whose names match REGEX\n\n"
|
|
|
|
<< " --xmlrpc-deny REGEX\n"
|
|
|
|
<< " Allow only the methods whose names don't match REGEX\n\n"
|
|
|
|
<< " --xmlrpc-list\n"
|
|
|
|
<< " List all available methods\n\n"
|
2008-06-13 13:23:46 +00:00
|
|
|
#endif
|
2008-05-17 03:24:15 +00:00
|
|
|
|
2009-02-04 05:20:24 +00:00
|
|
|
#if BENCHMARK_MODE
|
|
|
|
<< " --benchmark-modem ID\n"
|
|
|
|
<< " Specify the modem\n"
|
|
|
|
<< " Default: " << mode_info[benchmark.modem].sname << "\n\n"
|
|
|
|
<< " --benchmark-frequency FREQ\n"
|
|
|
|
<< " Specify the modem frequency\n"
|
|
|
|
<< " Default: " << benchmark.freq << "\n\n"
|
|
|
|
<< " --benchmark-afc BOOLEAN\n"
|
|
|
|
<< " Set modem AFC\n"
|
|
|
|
<< " Default: " << benchmark.afc
|
|
|
|
<< " (" << boolalpha << benchmark.afc << noboolalpha << ")\n\n"
|
|
|
|
<< " --benchmark-squelch BOOLEAN\n"
|
|
|
|
<< " Set modem squelch\n"
|
|
|
|
<< " Default: " << benchmark.sql
|
|
|
|
<< " (" << boolalpha << benchmark.sql << noboolalpha << ")\n\n"
|
|
|
|
<< " --benchmark-squelch-level LEVEL\n"
|
|
|
|
<< " Set modem squelch level\n"
|
|
|
|
<< " Default: " << benchmark.sqlevel << " (%)\n\n"
|
|
|
|
<< " --benchmark-input INPUT\n"
|
|
|
|
<< " Specify the input\n"
|
|
|
|
<< " Must be a positive integer indicating the number of samples\n"
|
|
|
|
" of silence to generate as the input"
|
|
|
|
# if USE_SNDFILE
|
|
|
|
", or a filename containing\n"
|
|
|
|
" non-digit characters"
|
|
|
|
#endif
|
|
|
|
"\n\n"
|
|
|
|
|
|
|
|
<< " --benchmark-output FILE\n"
|
|
|
|
<< " Specify the output data file\n"
|
|
|
|
<< " Default: decoder output is discarded\n\n"
|
|
|
|
<< " --benchmark-src-ratio RATIO\n"
|
|
|
|
<< " Specify the sample rate conversion ratio\n"
|
|
|
|
<< " Default: 1.0 (input is not resampled)\n\n"
|
|
|
|
<< " --benchmark-src-type TYPE\n"
|
|
|
|
<< " Specify the sample rate conversion type\n"
|
|
|
|
<< " Default: " << benchmark.src_type << " (" << src_get_name(benchmark.src_type) << ")\n\n"
|
|
|
|
#endif
|
|
|
|
|
2008-08-26 22:33:34 +00:00
|
|
|
<< " --debug-level LEVEL\n"
|
|
|
|
<< " Set the event log verbosity\n\n"
|
|
|
|
|
2008-01-29 15:58:15 +00:00
|
|
|
<< " --version\n"
|
2008-01-25 23:11:48 +00:00
|
|
|
<< " Print version information\n\n"
|
|
|
|
|
2008-01-29 15:58:15 +00:00
|
|
|
<< " --help\n"
|
2008-01-25 23:11:48 +00:00
|
|
|
<< " Print this option help\n\n";
|
|
|
|
|
|
|
|
// Fl::help looks ugly so we'll write our own
|
|
|
|
|
|
|
|
help << "Standard FLTK options:\n\n"
|
|
|
|
|
|
|
|
<< " -bg COLOR, -background COLOR\n"
|
|
|
|
<< " Set the background color\n"
|
|
|
|
|
|
|
|
<< " -bg2 COLOR, -background2 COLOR\n"
|
|
|
|
<< " Set the secondary (text) background color\n\n"
|
|
|
|
|
|
|
|
<< " -di DISPLAY, -display DISPLAY\n"
|
|
|
|
<< " Set the X display to use DISPLAY,\n"
|
|
|
|
<< " format is ``host:n.n''\n\n"
|
|
|
|
|
|
|
|
<< " -dn, -dnd or -nodn, -nodnd\n"
|
2008-01-29 15:58:15 +00:00
|
|
|
<< " Enable or disable drag and drop copy and paste in text fields\n\n"
|
2008-01-25 23:11:48 +00:00
|
|
|
|
|
|
|
<< " -fg COLOR, -foreground COLOR\n"
|
|
|
|
<< " Set the foreground color\n\n"
|
|
|
|
|
|
|
|
<< " -g GEOMETRY, -geometry GEOMETRY\n"
|
|
|
|
<< " Set the initial window size and position\n"
|
|
|
|
<< " GEOMETRY format is ``WxH+X+Y''\n"
|
2008-11-19 20:17:40 +00:00
|
|
|
<< " ** " << PACKAGE_NAME << " may override this setting **\n\n"
|
2008-01-25 23:11:48 +00:00
|
|
|
|
|
|
|
<< " -i, -iconic\n"
|
|
|
|
<< " Start " << PACKAGE_NAME << " in iconified state\n\n"
|
|
|
|
|
|
|
|
<< " -k, -kbd or -nok, -nokbd\n"
|
|
|
|
<< " Enable or disable visible keyboard focus in non-text widgets\n\n"
|
|
|
|
|
|
|
|
<< " -na CLASSNAME, -name CLASSNAME\n"
|
|
|
|
<< " Set the window class to CLASSNAME\n\n"
|
|
|
|
|
|
|
|
<< " -ti WINDOWTITLE, -title WINDOWTITLE\n"
|
2008-11-19 20:17:40 +00:00
|
|
|
<< " Set the window title\n\n";
|
2008-01-25 23:11:48 +00:00
|
|
|
|
|
|
|
help << "Additional UI options:\n\n"
|
2007-10-16 17:18:03 +00:00
|
|
|
|
2008-01-25 23:11:48 +00:00
|
|
|
<< " --font FONT[:SIZE]\n"
|
|
|
|
<< " Set the widget font and (optionally) size\n"
|
|
|
|
<< " The default is: " << Fl::get_font(FL_HELVETICA)
|
|
|
|
<< ':' << FL_NORMAL_SIZE << "\n\n"
|
2007-10-12 23:15:06 +00:00
|
|
|
|
2008-10-16 10:11:28 +00:00
|
|
|
;
|
2007-10-12 09:14:02 +00:00
|
|
|
|
2007-10-08 06:59:57 +00:00
|
|
|
option_help = help.str();
|
|
|
|
}
|
|
|
|
|
2008-06-11 17:36:06 +00:00
|
|
|
void exit_cb(void*) { fl_digi_main->do_callback(); }
|
2008-02-09 23:07:10 +00:00
|
|
|
|
2007-10-08 06:59:57 +00:00
|
|
|
int parse_args(int argc, char **argv, int& idx)
|
|
|
|
{
|
2007-10-12 09:14:02 +00:00
|
|
|
// Only handle long options
|
|
|
|
if ( !(strlen(argv[idx]) >= 2 && strncmp(argv[idx], "--", 2) == 0) )
|
2007-10-08 06:59:57 +00:00
|
|
|
return 0;
|
|
|
|
|
2008-03-30 13:38:05 +00:00
|
|
|
enum { OPT_ZERO,
|
|
|
|
#ifndef __CYGWIN__
|
|
|
|
OPT_RX_IPC_KEY, OPT_TX_IPC_KEY,
|
|
|
|
#endif
|
2008-10-12 06:35:04 +00:00
|
|
|
OPT_CONFIG_DIR,
|
|
|
|
OPT_ARQ_ADDRESS, OPT_ARQ_PORT,
|
2008-05-17 03:24:15 +00:00
|
|
|
#if USE_XMLRPC
|
2008-10-12 06:35:04 +00:00
|
|
|
OPT_CONFIG_XMLRPC_ADDRESS, OPT_CONFIG_XMLRPC_PORT,
|
2008-09-26 19:17:45 +00:00
|
|
|
OPT_CONFIG_XMLRPC_ALLOW, OPT_CONFIG_XMLRPC_DENY, OPT_CONFIG_XMLRPC_LIST,
|
2008-05-17 03:24:15 +00:00
|
|
|
#endif
|
2009-02-04 05:20:24 +00:00
|
|
|
|
|
|
|
#if BENCHMARK_MODE
|
|
|
|
OPT_BENCHMARK_MODEM, OPT_BENCHMARK_AFC, OPT_BENCHMARK_SQL, OPT_BENCHMARK_SQLEVEL,
|
|
|
|
OPT_BENCHMARK_FREQ, OPT_BENCHMARK_INPUT, OPT_BENCHMARK_OUTPUT,
|
|
|
|
OPT_BENCHMARK_SRC_RATIO, OPT_BENCHMARK_SRC_TYPE,
|
|
|
|
#endif
|
|
|
|
|
2008-10-16 10:11:28 +00:00
|
|
|
OPT_FONT, OPT_WFALL_HEIGHT, OPT_WFALL_WIDTH,
|
2008-04-16 22:17:25 +00:00
|
|
|
OPT_WINDOW_WIDTH, OPT_WINDOW_HEIGHT,
|
2008-10-29 01:14:36 +00:00
|
|
|
// OPT_TOGGLE_CHECK,
|
2007-11-28 22:32:50 +00:00
|
|
|
#if USE_PORTAUDIO
|
2008-03-01 07:03:03 +00:00
|
|
|
OPT_FRAMES_PER_BUFFER,
|
2007-11-28 22:32:50 +00:00
|
|
|
#endif
|
2008-08-26 22:33:34 +00:00
|
|
|
OPT_DEBUG_LEVEL,
|
2008-02-09 23:07:10 +00:00
|
|
|
OPT_EXIT_AFTER,
|
2008-10-12 06:35:04 +00:00
|
|
|
OPT_DEPRECATED, OPT_HELP, OPT_VERSION };
|
2007-10-12 23:15:06 +00:00
|
|
|
|
2007-10-08 06:59:57 +00:00
|
|
|
const char shortopts[] = "+";
|
|
|
|
static struct option longopts[] = {
|
2008-03-30 13:38:05 +00:00
|
|
|
#ifndef __CYGWIN__
|
2007-11-28 22:32:50 +00:00
|
|
|
{ "rx-ipc-key", 1, 0, OPT_RX_IPC_KEY },
|
|
|
|
{ "tx-ipc-key", 1, 0, OPT_TX_IPC_KEY },
|
2008-03-30 13:38:05 +00:00
|
|
|
#endif
|
2007-11-28 22:32:50 +00:00
|
|
|
{ "config-dir", 1, 0, OPT_CONFIG_DIR },
|
2008-10-12 06:35:04 +00:00
|
|
|
{ "experimental", 0, 0, OPT_DEPRECATED },
|
2008-05-17 03:24:15 +00:00
|
|
|
|
2008-08-13 15:41:18 +00:00
|
|
|
{ "arq-server-address", 1, 0, OPT_ARQ_ADDRESS },
|
|
|
|
{ "arq-server-port", 1, 0, OPT_ARQ_PORT },
|
|
|
|
|
2008-05-17 03:24:15 +00:00
|
|
|
#if USE_XMLRPC
|
2008-10-12 06:35:04 +00:00
|
|
|
{ "xmlrpc-server", 0, 0, OPT_DEPRECATED },
|
2008-05-17 03:24:15 +00:00
|
|
|
{ "xmlrpc-server-address", 1, 0, OPT_CONFIG_XMLRPC_ADDRESS },
|
|
|
|
{ "xmlrpc-server-port", 1, 0, OPT_CONFIG_XMLRPC_PORT },
|
2008-09-26 19:17:45 +00:00
|
|
|
{ "xmlrpc-allow", 1, 0, OPT_CONFIG_XMLRPC_ALLOW },
|
|
|
|
{ "xmlrpc-deny", 1, 0, OPT_CONFIG_XMLRPC_DENY },
|
|
|
|
{ "xmlrpc-list", 0, 0, OPT_CONFIG_XMLRPC_LIST },
|
2008-05-17 03:24:15 +00:00
|
|
|
#endif
|
2009-02-04 05:20:24 +00:00
|
|
|
|
|
|
|
#if BENCHMARK_MODE
|
|
|
|
{ "benchmark-modem", 1, 0, OPT_BENCHMARK_MODEM },
|
|
|
|
{ "benchmark-frequency", 1, 0, OPT_BENCHMARK_FREQ },
|
|
|
|
{ "benchmark-afc", 1, 0, OPT_BENCHMARK_AFC },
|
|
|
|
{ "benchmark-squelch", 1, 0, OPT_BENCHMARK_SQL },
|
|
|
|
{ "benchmark-squelch-level", 1, 0, OPT_BENCHMARK_SQLEVEL },
|
|
|
|
{ "benchmark-input", 1, 0, OPT_BENCHMARK_INPUT },
|
|
|
|
{ "benchmark-output", 1, 0, OPT_BENCHMARK_OUTPUT },
|
|
|
|
{ "benchmark-src-ratio", 1, 0, OPT_BENCHMARK_SRC_RATIO },
|
|
|
|
{ "benchmark-src-type", 1, 0, OPT_BENCHMARK_SRC_TYPE },
|
|
|
|
#endif
|
|
|
|
|
2007-11-28 22:32:50 +00:00
|
|
|
{ "font", 1, 0, OPT_FONT },
|
|
|
|
|
|
|
|
{ "wfall-width", 1, 0, OPT_WFALL_WIDTH },
|
|
|
|
{ "wfall-height", 1, 0, OPT_WFALL_HEIGHT },
|
|
|
|
{ "window-width", 1, 0, OPT_WINDOW_WIDTH },
|
|
|
|
{ "window-height", 1, 0, OPT_WINDOW_HEIGHT },
|
2008-10-12 06:35:04 +00:00
|
|
|
{ "twoscopes", 0, 0, OPT_DEPRECATED },
|
2008-02-20 20:10:25 +00:00
|
|
|
|
2007-11-28 22:32:50 +00:00
|
|
|
#if USE_PORTAUDIO
|
|
|
|
{ "frames-per-buf",1, 0, OPT_FRAMES_PER_BUFFER },
|
|
|
|
#endif
|
2008-02-09 23:07:10 +00:00
|
|
|
{ "exit-after", 1, 0, OPT_EXIT_AFTER },
|
|
|
|
|
2008-08-26 22:33:34 +00:00
|
|
|
{ "debug-level", 1, 0, OPT_DEBUG_LEVEL },
|
|
|
|
|
2007-11-28 22:32:50 +00:00
|
|
|
{ "help", 0, 0, OPT_HELP },
|
|
|
|
{ "version", 0, 0, OPT_VERSION },
|
2007-10-08 06:59:57 +00:00
|
|
|
{ 0 }
|
|
|
|
};
|
2007-10-18 07:49:27 +00:00
|
|
|
|
2007-10-08 06:59:57 +00:00
|
|
|
int longindex;
|
2008-02-09 23:07:10 +00:00
|
|
|
optind = idx;
|
|
|
|
int c = getopt_long(argc, argv, shortopts, longopts, &longindex);
|
2007-10-08 06:59:57 +00:00
|
|
|
|
|
|
|
switch (c) {
|
2007-10-18 07:49:27 +00:00
|
|
|
case -1:
|
|
|
|
return 0;
|
|
|
|
case 0:
|
|
|
|
// handle options with non-0 flag here
|
|
|
|
return 0;
|
|
|
|
|
2008-03-30 13:38:05 +00:00
|
|
|
#ifndef __CYGWIN__
|
2007-11-28 22:32:50 +00:00
|
|
|
case OPT_RX_IPC_KEY: case OPT_TX_IPC_KEY:
|
2007-10-18 07:49:27 +00:00
|
|
|
{
|
|
|
|
errno = 0;
|
|
|
|
int key = strtol(optarg, NULL, (strncasecmp(optarg, "0x", 2) ? 10 : 16));
|
|
|
|
if (errno || key <= 0)
|
|
|
|
cerr << "Hmm, " << key << " doesn't look like a valid IPC key\n";
|
2007-11-28 22:32:50 +00:00
|
|
|
if (c == OPT_RX_IPC_KEY)
|
2007-10-18 07:49:27 +00:00
|
|
|
progdefaults.rx_msgid = key;
|
|
|
|
else
|
|
|
|
progdefaults.tx_msgid = key;
|
2007-10-12 09:14:02 +00:00
|
|
|
}
|
2008-02-09 23:07:10 +00:00
|
|
|
break;
|
2008-03-30 13:38:05 +00:00
|
|
|
#endif
|
2007-10-18 07:49:27 +00:00
|
|
|
|
2009-01-01 17:03:36 +00:00
|
|
|
case OPT_CONFIG_DIR: {
|
|
|
|
char buf[FL_PATH_MAX + 1];
|
|
|
|
fl_filename_absolute(buf, sizeof(buf) - 1, optarg);
|
|
|
|
HomeDir = buf;
|
|
|
|
}
|
2007-10-18 07:49:27 +00:00
|
|
|
if (*HomeDir.rbegin() != '/')
|
2009-01-01 17:03:36 +00:00
|
|
|
HomeDir += '/';
|
2008-02-09 23:07:10 +00:00
|
|
|
break;
|
2007-10-18 07:49:27 +00:00
|
|
|
|
2008-08-13 15:41:18 +00:00
|
|
|
case OPT_ARQ_ADDRESS:
|
|
|
|
progdefaults.arq_address = optarg;
|
|
|
|
break;
|
|
|
|
case OPT_ARQ_PORT:
|
|
|
|
progdefaults.arq_port = optarg;
|
|
|
|
break;
|
|
|
|
|
2008-05-17 03:24:15 +00:00
|
|
|
#if USE_XMLRPC
|
|
|
|
case OPT_CONFIG_XMLRPC_ADDRESS:
|
|
|
|
progdefaults.xmlrpc_address = optarg;
|
|
|
|
break;
|
|
|
|
case OPT_CONFIG_XMLRPC_PORT:
|
|
|
|
progdefaults.xmlrpc_port = optarg;
|
|
|
|
break;
|
2008-09-26 19:17:45 +00:00
|
|
|
case OPT_CONFIG_XMLRPC_ALLOW:
|
|
|
|
progdefaults.xmlrpc_allow = optarg;
|
|
|
|
break;
|
|
|
|
case OPT_CONFIG_XMLRPC_DENY:
|
|
|
|
if (!progdefaults.xmlrpc_allow.empty())
|
|
|
|
cerr << "W: --" << longopts[longindex].name
|
|
|
|
<< " cannot be used together with --"
|
|
|
|
<< longopts[OPT_CONFIG_XMLRPC_ALLOW-1].name
|
|
|
|
<< " and will be ignored\n";
|
|
|
|
else
|
|
|
|
progdefaults.xmlrpc_deny = optarg;
|
|
|
|
break;
|
|
|
|
case OPT_CONFIG_XMLRPC_LIST:
|
|
|
|
XML_RPC_Server::list_methods(cout);
|
|
|
|
exit(EXIT_SUCCESS);
|
2008-05-17 03:24:15 +00:00
|
|
|
#endif
|
|
|
|
|
2009-02-04 05:20:24 +00:00
|
|
|
#if BENCHMARK_MODE
|
|
|
|
case OPT_BENCHMARK_MODEM:
|
|
|
|
benchmark.modem = strtol(optarg, NULL, 10);
|
|
|
|
if (!(benchmark.modem >= 0 && benchmark.modem < NUM_MODES)) {
|
|
|
|
cerr << "Bad modem id\n";
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case OPT_BENCHMARK_FREQ:
|
|
|
|
benchmark.freq = strtol(optarg, NULL, 10);
|
|
|
|
if (benchmark.freq < 0) {
|
|
|
|
cerr << "Bad frequency\n";
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case OPT_BENCHMARK_AFC:
|
|
|
|
benchmark.afc = strtol(optarg, NULL, 10);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case OPT_BENCHMARK_SQL:
|
|
|
|
benchmark.sql = strtol(optarg, NULL, 10);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case OPT_BENCHMARK_SQLEVEL:
|
|
|
|
benchmark.sqlevel = strtod(optarg, NULL);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case OPT_BENCHMARK_INPUT:
|
|
|
|
benchmark.input = optarg;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case OPT_BENCHMARK_OUTPUT:
|
|
|
|
benchmark.output = optarg;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case OPT_BENCHMARK_SRC_RATIO:
|
|
|
|
benchmark.src_ratio = strtod(optarg, NULL);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case OPT_BENCHMARK_SRC_TYPE:
|
|
|
|
benchmark.src_type = strtol(optarg, NULL, 10);
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
|
2007-11-28 22:32:50 +00:00
|
|
|
case OPT_FONT:
|
2007-10-18 07:49:27 +00:00
|
|
|
{
|
|
|
|
char *p;
|
|
|
|
if ((p = strchr(optarg, ':'))) {
|
|
|
|
*p = '\0';
|
|
|
|
FL_NORMAL_SIZE = strtol(p + 1, 0, 10);
|
|
|
|
}
|
2007-10-12 23:15:06 +00:00
|
|
|
}
|
2007-10-18 07:49:27 +00:00
|
|
|
Fl::set_font(FL_HELVETICA, optarg);
|
2008-02-09 23:07:10 +00:00
|
|
|
break;
|
2007-10-18 07:49:27 +00:00
|
|
|
|
2007-11-28 22:32:50 +00:00
|
|
|
case OPT_WFALL_WIDTH:
|
2008-10-16 10:11:28 +00:00
|
|
|
progdefaults.wfwidth = strtol(optarg, NULL, 10);
|
2008-02-09 23:07:10 +00:00
|
|
|
break;
|
2007-10-18 07:49:27 +00:00
|
|
|
|
2007-11-28 22:32:50 +00:00
|
|
|
case OPT_WFALL_HEIGHT:
|
2008-10-16 10:11:28 +00:00
|
|
|
progdefaults.wfheight = strtol(optarg, NULL, 10);
|
2008-02-09 23:07:10 +00:00
|
|
|
break;
|
2007-10-18 07:49:27 +00:00
|
|
|
|
2007-11-28 22:32:50 +00:00
|
|
|
case OPT_WINDOW_WIDTH:
|
2007-10-18 07:49:27 +00:00
|
|
|
WNOM = strtol(optarg, NULL, 10);
|
2008-02-09 23:07:10 +00:00
|
|
|
break;
|
2007-10-18 07:49:27 +00:00
|
|
|
|
2007-11-28 22:32:50 +00:00
|
|
|
case OPT_WINDOW_HEIGHT:
|
2007-10-18 07:49:27 +00:00
|
|
|
HNOM = strtol(optarg, NULL, 10);
|
2008-02-09 23:07:10 +00:00
|
|
|
break;
|
2007-10-18 07:49:27 +00:00
|
|
|
|
2007-11-28 22:32:50 +00:00
|
|
|
#if USE_PORTAUDIO
|
|
|
|
case OPT_FRAMES_PER_BUFFER:
|
2008-04-18 00:36:53 +00:00
|
|
|
progdefaults.PortFramesPerBuffer = strtol(optarg, 0, 10);
|
2008-02-09 23:07:10 +00:00
|
|
|
break;
|
2007-11-28 22:32:50 +00:00
|
|
|
#endif // USE_PORTAUDIO
|
2008-02-09 23:07:10 +00:00
|
|
|
|
|
|
|
case OPT_EXIT_AFTER:
|
|
|
|
Fl::add_timeout(strtod(optarg, 0), exit_cb);
|
|
|
|
break;
|
|
|
|
|
2008-08-26 22:33:34 +00:00
|
|
|
case OPT_DEBUG_LEVEL:
|
|
|
|
{
|
|
|
|
int v = strtol(optarg, 0, 10);
|
2008-08-30 03:02:24 +00:00
|
|
|
debug::level = (debug::level_e)CLAMP(v, 0, debug::LOG_NLEVELS-1);
|
2008-08-26 22:33:34 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2008-10-12 06:35:04 +00:00
|
|
|
case OPT_DEPRECATED:
|
|
|
|
cerr << "W: the --" << longopts[longindex].name
|
|
|
|
<< " option has been deprecated and will be removed in a future version\n";
|
|
|
|
break;
|
|
|
|
|
2007-11-28 22:32:50 +00:00
|
|
|
case OPT_HELP:
|
2008-01-29 15:58:15 +00:00
|
|
|
cout << option_help;
|
2007-10-18 07:49:27 +00:00
|
|
|
exit(EXIT_SUCCESS);
|
|
|
|
|
2007-11-28 22:32:50 +00:00
|
|
|
case OPT_VERSION:
|
2008-01-29 15:58:15 +00:00
|
|
|
cout << version_text;
|
2007-10-18 07:49:27 +00:00
|
|
|
exit(EXIT_SUCCESS);
|
|
|
|
|
2008-04-18 00:36:53 +00:00
|
|
|
case '?': default:
|
2007-11-28 22:32:50 +00:00
|
|
|
cerr << "Try `" << PACKAGE_NAME << " --help' for more information.\n";
|
2007-10-18 07:49:27 +00:00
|
|
|
exit(EXIT_FAILURE);
|
2008-02-09 23:07:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Increment idx by the number of args we used and return that number.
|
|
|
|
// We must check whether the option argument is in the same argv element
|
|
|
|
// as the option name itself, i.e., --opt=arg.
|
2008-03-02 08:22:41 +00:00
|
|
|
c = longopts[longindex].has_arg ? 2 : 1;
|
|
|
|
if (c == 2) {
|
|
|
|
string arg = argv[idx];
|
|
|
|
string::size_type p;
|
2008-06-11 17:36:06 +00:00
|
|
|
if ((p = arg.rfind(optarg)) != string::npos && arg[p-1] == '=')
|
2008-03-02 08:22:41 +00:00
|
|
|
c = 1;
|
|
|
|
}
|
2008-02-09 23:07:10 +00:00
|
|
|
idx += c;
|
|
|
|
return c;
|
2007-10-08 06:59:57 +00:00
|
|
|
}
|
2007-10-16 17:18:03 +00:00
|
|
|
|
2008-01-25 23:11:48 +00:00
|
|
|
void generate_version_text(void)
|
2007-10-16 17:18:03 +00:00
|
|
|
{
|
2008-01-25 23:11:48 +00:00
|
|
|
ostringstream s;
|
2008-10-12 06:35:04 +00:00
|
|
|
s << PACKAGE_STRING << '\n'
|
2008-11-25 00:14:59 +00:00
|
|
|
<< "Copyright (c) 2008 " PACKAGE_AUTHORS "\n" <<
|
|
|
|
_("License GPLv2+: GNU GPL version 2 or later <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>\n"
|
|
|
|
"This is free software: you are free to change and redistribute it.\n"
|
|
|
|
"There is NO WARRANTY, to the extent permitted by law.\n");
|
2008-10-12 06:35:04 +00:00
|
|
|
|
2008-11-25 00:14:59 +00:00
|
|
|
s << _("\nSystem: ");
|
2007-10-16 17:18:03 +00:00
|
|
|
struct utsname u;
|
|
|
|
if (uname(&u) != -1) {
|
2007-12-11 03:36:51 +00:00
|
|
|
s << u.sysname << ' ' << u.nodename
|
|
|
|
<< ' ' << u.release << ' ' << u.version << ' '
|
|
|
|
<< u.machine << '\n';
|
|
|
|
}
|
2007-10-16 17:18:03 +00:00
|
|
|
|
|
|
|
#include "versions.h"
|
|
|
|
#ifdef HAVE_VERSIONS_H
|
2007-12-11 03:36:51 +00:00
|
|
|
s /*<< "\nConfigured with: " << COMPILE_CFG*/ << '\n'
|
|
|
|
<< "Built on " << COMPILE_DATE << " by " << COMPILE_USER
|
|
|
|
<< '@' << COMPILE_HOST << " with:\n"
|
2008-01-25 23:11:48 +00:00
|
|
|
<< COMPILER << '\n'
|
|
|
|
<< "CFLAGS=" << CFLAGS << '\n'
|
|
|
|
<< "LDFLAGS=" << LDFLAGS << '\n';
|
2007-10-16 17:18:03 +00:00
|
|
|
#endif // HAVE_VERSIONS_H
|
|
|
|
|
2007-12-11 03:36:51 +00:00
|
|
|
s << "Libraries:\n"
|
2008-01-25 23:11:48 +00:00
|
|
|
<< "FLTK " << FL_MAJOR_VERSION << '.' << FL_MINOR_VERSION << '.'
|
2007-12-11 03:36:51 +00:00
|
|
|
<< FL_PATCH_VERSION << '\n';
|
2007-10-16 17:18:03 +00:00
|
|
|
|
2008-03-23 04:06:30 +00:00
|
|
|
s << src_get_version() << '\n';
|
|
|
|
|
2007-11-28 22:32:50 +00:00
|
|
|
#if USE_HAMLIB
|
2008-01-25 23:11:48 +00:00
|
|
|
s << hamlib_version << '\n';
|
2007-10-16 17:18:03 +00:00
|
|
|
#endif
|
|
|
|
|
2007-11-28 22:32:50 +00:00
|
|
|
#if USE_PORTAUDIO
|
2008-01-25 23:11:48 +00:00
|
|
|
s << Pa_GetVersionText() << ' ' << Pa_GetVersion() << '\n';
|
2007-10-16 17:18:03 +00:00
|
|
|
#endif
|
|
|
|
|
2007-11-28 22:32:50 +00:00
|
|
|
#if USE_SNDFILE
|
2007-12-11 03:36:51 +00:00
|
|
|
char sndfile_version[32];
|
|
|
|
sf_command(NULL, SFC_GET_LIB_VERSION, sndfile_version, sizeof(sndfile_version));
|
2008-01-25 23:11:48 +00:00
|
|
|
s << sndfile_version << '\n';
|
2007-11-28 22:32:50 +00:00
|
|
|
#endif
|
|
|
|
|
2008-01-25 23:11:48 +00:00
|
|
|
version_text = s.str();
|
2007-10-16 17:18:03 +00:00
|
|
|
}
|
2008-01-15 03:16:59 +00:00
|
|
|
|
|
|
|
// When debugging is enabled, reexec with malloc debugging hooks enabled, unless
|
2008-02-09 23:07:10 +00:00
|
|
|
// the env var FLDIGI_NO_EXEC is set, or our parent process is gdb.
|
2008-01-15 03:16:59 +00:00
|
|
|
void debug_exec(char** argv)
|
|
|
|
{
|
2008-03-30 13:38:05 +00:00
|
|
|
#if !defined(NDEBUG) && !defined(__CYGWIN__)
|
2008-01-15 03:16:59 +00:00
|
|
|
if (getenv("FLDIGI_NO_EXEC"))
|
|
|
|
return;
|
|
|
|
|
|
|
|
char ppath[32], lname[32];
|
|
|
|
ssize_t n;
|
|
|
|
snprintf(ppath, sizeof(ppath), "/proc/%u/exe", getppid());
|
|
|
|
if ((n = readlink(ppath, lname, sizeof(lname))) > 0) {
|
|
|
|
lname[n] = '\0';
|
|
|
|
if (strstr(lname, "gdb")) {
|
|
|
|
cerr << "Not using malloc debugging hooks\n";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
setenv("FLDIGI_NO_EXEC", "1", 0);
|
|
|
|
setenv("MALLOC_CHECK_", "3", 0);
|
|
|
|
setenv("MALLOC_PERTURB_", "42", 0);
|
|
|
|
if (execvp(*argv, argv) == -1)
|
|
|
|
perror("execvp");
|
|
|
|
#endif
|
|
|
|
}
|
2008-01-25 23:11:48 +00:00
|
|
|
|
2008-06-30 00:20:03 +00:00
|
|
|
void set_platform_ui(void)
|
2008-06-16 02:17:11 +00:00
|
|
|
{
|
2009-02-04 05:20:23 +00:00
|
|
|
#if defined(__APPLE__)
|
2008-08-30 03:02:24 +00:00
|
|
|
FL_NORMAL_SIZE = 12;
|
|
|
|
progdefaults.WaterfallFontsize = 12;
|
|
|
|
progdefaults.RxFontsize = 12;
|
|
|
|
progdefaults.TxFontsize = 12;
|
2008-06-16 02:17:11 +00:00
|
|
|
#elif defined(__CYGWIN__)
|
|
|
|
Fl::set_font(FL_HELVETICA, "Tahoma");
|
|
|
|
FL_NORMAL_SIZE = 11;
|
|
|
|
progdefaults.WaterfallFontnbr = FL_HELVETICA;
|
|
|
|
progdefaults.WaterfallFontsize = 12;
|
2008-06-30 00:20:03 +00:00
|
|
|
progdefaults.RxFontsize = 12;
|
|
|
|
progdefaults.TxFontsize = 12;
|
2009-02-04 05:20:23 +00:00
|
|
|
#else
|
|
|
|
FL_NORMAL_SIZE = 12;
|
2008-06-16 02:17:11 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2008-06-30 00:20:03 +00:00
|
|
|
// Convert 1 second of 1-channel silence from IN_RATE Hz to OUT_RATE Hz,
|
|
|
|
// Repeat test "repeat" times. Return (repeat / elapsed_time),
|
|
|
|
// the faster-than-realtime factor averaged over "repeat" runs.
|
|
|
|
// Some figures for SRC_SINC_FASTEST:
|
|
|
|
// Pentium 4 2.8GHz: 70
|
|
|
|
// Pentium 3 550MHz: 13
|
|
|
|
// UltraSparc II 270MHz: 3.5
|
|
|
|
#define IN_RATE 48000
|
|
|
|
#define OUT_RATE 8000
|
|
|
|
double speed_test(int converter, unsigned repeat)
|
|
|
|
{
|
|
|
|
SRC_DATA src;
|
|
|
|
src.src_ratio = (double)OUT_RATE / IN_RATE;
|
|
|
|
src.input_frames = IN_RATE;
|
|
|
|
src.output_frames = OUT_RATE;
|
|
|
|
src.data_in = new float[src.input_frames];
|
|
|
|
src.data_out = new float[src.output_frames];
|
|
|
|
|
|
|
|
memset(src.data_in, 0, src.input_frames * sizeof(float));
|
|
|
|
|
|
|
|
// warm up
|
2008-09-11 01:35:48 +00:00
|
|
|
src_simple(&src, converter, 1);
|
2008-06-30 00:20:03 +00:00
|
|
|
|
|
|
|
struct timespec t0, t1;
|
2008-07-24 12:22:53 +00:00
|
|
|
#ifdef _POSIX_MONOTONIC_CLOCK
|
|
|
|
clock_gettime(CLOCK_MONOTONIC, &t0);
|
|
|
|
#else
|
2008-06-30 00:20:03 +00:00
|
|
|
clock_gettime(CLOCK_REALTIME, &t0);
|
2008-07-24 12:22:53 +00:00
|
|
|
#endif
|
2008-06-30 00:20:03 +00:00
|
|
|
for (unsigned i = 0; i < repeat; i++)
|
2008-09-11 01:35:48 +00:00
|
|
|
src_simple(&src, converter, 1);
|
2008-07-24 12:22:53 +00:00
|
|
|
#ifdef _POSIX_MONOTONIC_CLOCK
|
|
|
|
clock_gettime(CLOCK_MONOTONIC, &t1);
|
|
|
|
#else
|
2008-06-30 00:20:03 +00:00
|
|
|
clock_gettime(CLOCK_REALTIME, &t1);
|
2008-07-24 12:22:53 +00:00
|
|
|
#endif
|
2008-06-30 00:20:03 +00:00
|
|
|
|
|
|
|
delete [] src.data_in;
|
|
|
|
delete [] src.data_out;
|
|
|
|
|
|
|
|
t0 = t1 - t0;
|
|
|
|
return repeat / (t0.tv_sec + t0.tv_nsec/1e9);
|
|
|
|
}
|
2008-09-26 19:17:45 +00:00
|
|
|
|
2008-10-12 06:35:04 +00:00
|
|
|
static void setup_signal_handlers(void)
|
2008-09-26 19:17:45 +00:00
|
|
|
{
|
2009-02-23 12:26:23 +00:00
|
|
|
#if !defined(__CYGWIN__) && !defined(__MINGW32__)
|
2008-09-26 19:17:45 +00:00
|
|
|
struct sigaction action;
|
|
|
|
memset(&action, 0, sizeof(struct sigaction));
|
|
|
|
|
|
|
|
// no child stopped notifications, no zombies
|
2008-10-12 06:35:04 +00:00
|
|
|
action.sa_handler = SIG_DFL;
|
2008-09-26 19:17:45 +00:00
|
|
|
action.sa_flags = SA_NOCLDSTOP | SA_NOCLDWAIT;
|
|
|
|
sigaction(SIGCHLD, &action, NULL);
|
|
|
|
action.sa_flags = 0;
|
|
|
|
|
|
|
|
action.sa_handler = handle_signal;
|
|
|
|
sigaction(SIGSEGV, &action, NULL);
|
|
|
|
sigaction(SIGILL, &action, NULL);
|
|
|
|
sigaction(SIGABRT, &action, NULL);
|
|
|
|
sigaction(SIGUSR2, &action, NULL);
|
|
|
|
|
|
|
|
action.sa_handler = SIG_IGN;
|
|
|
|
sigaction(SIGPIPE, &action, NULL);
|
|
|
|
|
|
|
|
sigemptyset(&action.sa_mask);
|
|
|
|
sigaddset(&action.sa_mask, SIGUSR2);
|
2008-10-12 06:35:04 +00:00
|
|
|
pthread_sigmask(SIG_BLOCK, &action.sa_mask, NULL);
|
2009-02-23 12:26:23 +00:00
|
|
|
#else
|
|
|
|
signal(SIGSEGV, handle_signal);
|
|
|
|
signal(SIGILL, handle_signal);
|
|
|
|
signal(SIGABRT, handle_signal);
|
|
|
|
#endif
|
2008-09-26 19:17:45 +00:00
|
|
|
}
|
2008-11-25 00:14:59 +00:00
|
|
|
|
|
|
|
#ifdef ENABLE_NLS
|
|
|
|
int setup_nls(void)
|
|
|
|
{
|
|
|
|
static int nls_set_up = 0;
|
|
|
|
if (nls_set_up)
|
|
|
|
return nls_set_up;
|
|
|
|
|
|
|
|
setlocale (LC_MESSAGES, "");
|
2009-02-19 01:49:30 +00:00
|
|
|
setlocale (LC_CTYPE, "C");
|
2008-11-25 00:14:59 +00:00
|
|
|
setlocale (LC_TIME, "");
|
|
|
|
// setting LC_NUMERIC might break the config read/write routines
|
|
|
|
|
|
|
|
const char* ldir;
|
|
|
|
char buf[4096];
|
|
|
|
if (!(ldir = getenv("FLDIGI_LOCALE_DIR"))) {
|
|
|
|
if (getcwd(buf, sizeof(buf) - strlen("/locale") - 1)) {
|
|
|
|
strcpy(buf + strlen(buf), "/locale");
|
|
|
|
struct stat s;
|
|
|
|
if (stat(buf, &s) != -1 && S_ISDIR(s.st_mode))
|
|
|
|
ldir = buf;
|
|
|
|
else
|
|
|
|
ldir = LOCALEDIR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bindtextdomain(PACKAGE, ldir);
|
|
|
|
/* fltk-1.1.x only knows about Latin-1 */
|
|
|
|
bind_textdomain_codeset(PACKAGE, "ISO-8859-1");
|
|
|
|
textdomain(PACKAGE);
|
|
|
|
|
|
|
|
return nls_set_up = 1;
|
|
|
|
}
|
|
|
|
#endif
|
2008-12-23 00:08:43 +00:00
|
|
|
|
|
|
|
static void checkdirectories(void)
|
|
|
|
{
|
2009-01-01 17:03:36 +00:00
|
|
|
struct {
|
|
|
|
string& dir;
|
|
|
|
const char* suffix;
|
|
|
|
void (*new_dir_func)(void);
|
|
|
|
} dirs[] = {
|
|
|
|
{ HomeDir, 0, 0 },
|
|
|
|
{ RigsDir, "rigs", 0 },
|
|
|
|
{ ScriptsDir, "scripts", 0 },
|
|
|
|
{ PalettesDir, "palettes", create_new_palettes },
|
|
|
|
{ LogsDir, "logs", 0 },
|
|
|
|
{ PicsDir, "images", 0 },
|
|
|
|
{ HelpDir, "help", 0 },
|
|
|
|
{ MacrosDir, "macros", create_new_macros },
|
2009-02-05 21:09:58 +00:00
|
|
|
{ WrapDir, "wrap", 0 },
|
|
|
|
{ TalkDir, "talk", 0 },
|
2009-01-01 17:03:36 +00:00
|
|
|
{ TempDir, "temp", 0 },
|
|
|
|
};
|
2008-12-23 00:08:43 +00:00
|
|
|
|
2009-01-01 17:03:36 +00:00
|
|
|
int r;
|
|
|
|
for (size_t i = 0; i < sizeof(dirs)/sizeof(*dirs); i++) {
|
|
|
|
if (dirs[i].suffix)
|
|
|
|
dirs[i].dir.assign(HomeDir).append(dirs[i].suffix).append("/");
|
2008-12-23 00:08:43 +00:00
|
|
|
|
2009-01-01 17:03:36 +00:00
|
|
|
if ((r = mkdir(dirs[i].dir.c_str(), 0777)) == -1 && errno != EEXIST) {
|
|
|
|
cerr << _("Could not make directory") << ' ' << dirs[i].dir
|
|
|
|
<< ": " << strerror(errno) << '\n';
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
else if (r == 0 && dirs[i].new_dir_func)
|
|
|
|
dirs[i].new_dir_func();
|
|
|
|
}
|
|
|
|
}
|