dl-fldigi/src/main.cxx

705 wiersze
17 KiB
C++
Czysty Zwykły widok Historia

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
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"
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"
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
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
2007-06-22 22:04:50 +00:00
char szHomedir[120] = "";
2007-06-22 22:10:49 +00:00
char szPskMailDir[120] = "";
string PskMailDir;
string PskMailFile;
2007-07-21 12:15:41 +00:00
string ArqFilename;
2007-06-22 22:04:50 +00:00
string HomeDir;
string xmlfname;
2007-06-22 22:25:46 +00:00
bool gmfskmail = false;
2007-06-22 22:04:50 +00:00
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
cLogfile *logfile = 0;;
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
extern void start_pskmail();
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-16 02:17:11 +00:00
void set_platform_fonts(void);
2007-07-21 12:15:41 +00:00
2008-04-14 22:18:15 +00:00
#ifdef __CYGWIN__
void redirect_streams(const std::string& dir);
void restore_streams(void);
#endif
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);
signal(SIGSEGV, handle_signal);
signal(SIGILL, handle_signal);
2008-04-18 00:36:53 +00:00
signal(SIGABRT, handle_signal);
2008-03-23 04:06:30 +00:00
signal(SIGCHLD, SIG_IGN);
signal(SIGPIPE, SIG_IGN);
2007-12-11 03:36:51 +00:00
2008-01-10 18:02:24 +00:00
setlocale(LC_TIME, "");
2007-12-20 08:21:04 +00:00
2008-04-01 17:47:24 +00:00
#ifndef __CYGWIN__
2007-07-21 12:15:41 +00:00
fl_filename_expand(szHomedir, 119, "$HOME/.fldigi/");
2008-04-01 17:47:24 +00:00
#else
fl_filename_expand(szHomedir, 119, "$APPDATA/fldigi/");
#endif
2007-10-27 14:57:10 +00:00
HomeDir = szHomedir;
2007-10-08 06:59:57 +00:00
2008-04-14 22:18:15 +00:00
#ifdef __CYGWIN__
redirect_streams(HomeDir);
atexit(restore_streams);
#endif
2008-06-16 02:17:11 +00:00
set_platform_fonts();
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);
}
2007-11-01 03:22:20 +00:00
{
DIR *dir = opendir(HomeDir.c_str());
if (dir == 0) {
if ( mkdir(HomeDir.c_str(), 0777) == -1) {
cerr << "Could not make directory " << HomeDir << ": "
<< strerror(errno) << endl;
exit(EXIT_FAILURE);
}
} else
closedir(dir);
2007-10-27 14:57:10 +00:00
}
2007-10-08 06:59:57 +00:00
2007-07-21 12:15:41 +00:00
xmlfname = HomeDir;
xmlfname.append("rig.xml");
string lfname = HomeDir;
lfname.append("fldigi.log");
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
2007-10-29 03:15:22 +00:00
fl_filename_expand(szPskMailDir, 119, "$HOME/pskmail.files/");
PskMailDir = szPskMailDir;
2007-09-19 00:45:42 +00:00
FL_LOCK_E(); // 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();
2007-10-07 13:20:44 +00:00
progdefaults.readDefaultsXML();
2007-09-28 15:18:32 +00:00
progdefaults.testCommPorts();
2008-03-08 23:24:42 +00:00
progStatus.loadLastState();
2007-06-22 22:04:50 +00:00
create_fl_digi_main();
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();
2007-09-28 15:18:32 +00:00
inpTTYdev->tooltip(progdefaults.strCommPorts.c_str());
inpRIGdev->tooltip(progdefaults.strCommPorts.c_str());
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-03-30 13:38:05 +00:00
2008-04-14 22:18:15 +00:00
#ifdef __CYGWIN__
fl_digi_main->icon((char*)LoadIcon(fl_display, MAKEINTRESOURCE(IDI_ICON)));
#endif
2008-02-09 23:07:10 +00:00
fl_digi_main->show(argc, argv);
progStatus.initLastState();
2007-06-22 22:04:50 +00:00
2008-02-09 23:07:10 +00:00
Fl::add_timeout(1.0, pskmail_loop);
2008-05-17 03:24:15 +00:00
#if USE_XMLRPC
if (progdefaults.xmlrpc_server)
XML_RPC_Server::start(progdefaults.xmlrpc_address.c_str(), progdefaults.xmlrpc_port.c_str());
#endif
2008-02-09 23:07:10 +00:00
int ret = Fl::run();
2008-05-17 03:24:15 +00:00
#if USE_XMLRPC
XML_RPC_Server::stop();
#endif
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-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) {
// is there a better way of enumerating schemes?
string schemes = "none";
const char *possible_schemes[] = { "plastic", "gtk+", 0 };
const char *old = Fl::scheme();
const char **s = possible_schemes;
while (*s) {
Fl::scheme(*s);
if (strcasecmp(*s, Fl::scheme()) == 0)
schemes.append(" ").append(*s);
s++;
}
Fl::scheme(old ? old : "none");
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-06-13 13:23:46 +00:00
#if USE_XMLRPC
2008-05-17 03:24:15 +00:00
<< " --xmlrpc-server\n"
<< " Start the XML-RPC server\n\n"
<< " --xmlrpc-server-address HOSTNAME\n"
<< " Set the XML-RPC server address\n"
<< " The default is: " << progdefaults.xmlrpc_address << "\n\n"
<< " --xmlrpc-server-port PORT\n"
<< " Set the XML-RPC server port\n"
<< " The default is: " << progdefaults.xmlrpc_port << "\n\n"
2008-06-13 13:23:46 +00:00
#endif
2008-05-17 03:24:15 +00:00
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"
<< " ** " << PACKAGE_NAME << " may override this settting **\n\n"
<< " -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"
<< " -s SCHEME, -scheme SCHEME\n"
<< " Set the widget scheme\n"
<< " SCHEME can be one of: " << schemes << "\n\n"
<< " -ti WINDOWTITLE, -title WINDOWTITLE\n"
<< " Set the window title\n\n"
<< " -to, -tooltips or -not, -notooltips\n"
<< " Enable or disable tooltips\n\n";
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-06-06 22:49:07 +00:00
<< " --wfall-width WIDTH\n"
<< " WIDTH may be 2000 to 4000 in Hz, recommend 50 Hz increments.\n\n"
<< " --wfall-height HEIGHT\n"
<< " HEIGHT in pixels, ie 100 - 200, recommend 10 pixel increments.\n\n"
2007-10-15 22:32:59 +00:00
2008-04-16 11:02:33 +00:00
<< " --twoscopes\n"
2008-04-18 00:36:53 +00:00
<< " Dock a second digiscope adjacent to the waterfall\n\n"
2008-04-16 11:02:33 +00:00
2008-06-28 02:15:20 +00:00
<< " --uselgtdbtns\n"
<< " Use lighted buttons for AFC / SQL.\n";
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
OPT_CONFIG_DIR,
2008-05-17 03:24:15 +00:00
#if USE_XMLRPC
OPT_CONFIG_XMLRPC, OPT_CONFIG_XMLRPC_ADDRESS, OPT_CONFIG_XMLRPC_PORT,
#endif
2008-04-01 17:47:24 +00:00
OPT_FONT, OPT_WFALL_WIDTH, OPT_WFALL_HEIGHT,
2008-04-16 22:17:25 +00:00
OPT_WINDOW_WIDTH, OPT_WINDOW_HEIGHT,
2008-04-18 00:36:53 +00:00
OPT_PROFILE,
2008-04-16 22:17:25 +00:00
OPT_USE_CHECK,
OPT_RESAMPLE,
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-04-18 00:36:53 +00:00
OPT_TWO_SCOPES,
2008-02-09 23:07:10 +00:00
OPT_EXIT_AFTER,
2007-11-28 22:32:50 +00:00
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-05-17 03:24:15 +00:00
#if USE_XMLRPC
{ "xmlrpc-server", 0, 0, OPT_CONFIG_XMLRPC },
{ "xmlrpc-server-address", 1, 0, OPT_CONFIG_XMLRPC_ADDRESS },
{ "xmlrpc-server-port", 1, 0, OPT_CONFIG_XMLRPC_PORT },
#endif
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-04-18 00:36:53 +00:00
{ "profile", 1, 0, OPT_PROFILE },
2008-04-16 11:02:33 +00:00
{ "twoscopes", 0, 0, OPT_TWO_SCOPES },
2008-06-28 02:15:20 +00:00
{ "uselgtdbtns", 0, 0, OPT_USE_CHECK },
2008-02-20 20:10:25 +00:00
{ "resample", 1, 0, OPT_RESAMPLE },
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 },
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
2007-11-28 22:32:50 +00:00
case OPT_CONFIG_DIR:
2007-10-18 07:49:27 +00:00
HomeDir = optarg;
if (*HomeDir.rbegin() != '/')
HomeDir += '/';
2008-02-09 23:07:10 +00:00
break;
2007-10-18 07:49:27 +00:00
2008-05-17 03:24:15 +00:00
#if USE_XMLRPC
case OPT_CONFIG_XMLRPC:
progdefaults.xmlrpc_server = true;
break;
case OPT_CONFIG_XMLRPC_ADDRESS:
progdefaults.xmlrpc_address = optarg;
break;
case OPT_CONFIG_XMLRPC_PORT:
progdefaults.xmlrpc_port = optarg;
break;
#endif
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:
2007-10-18 07:49:27 +00:00
IMAGE_WIDTH = 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:
2007-10-18 07:49:27 +00:00
Hwfall = 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
2008-04-18 00:36:53 +00:00
case OPT_PROFILE:
cerr << "The --" << longopts[longindex].name
<< " option has been deprecated and will be removed in a future release\n";
break;
2007-10-18 07:49:27 +00:00
2008-04-16 11:02:33 +00:00
case OPT_TWO_SCOPES:
twoscopes = true;
break;
2007-11-28 22:32:50 +00:00
case OPT_USE_CHECK:
2008-06-28 02:15:20 +00:00
useCheckButtons = false;
2008-02-09 23:07:10 +00:00
break;
2008-02-20 20:10:25 +00:00
case OPT_RESAMPLE:
2008-04-18 00:36:53 +00:00
cerr << "The --" << longopts[longindex].name
<< " option has been deprecated and will be removed in a future release\n";
2008-02-20 20:10:25 +00:00
break;
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;
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;
2007-12-11 03:36:51 +00:00
s << PACKAGE_NAME << ' ' << PACKAGE_VERSION << "\n\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-16 02:17:11 +00:00
void set_platform_fonts(void)
{
#if defined (__linux__)
FL_NORMAL_SIZE = 12;
#elif defined(__CYGWIN__)
Fl::set_font(FL_HELVETICA, "Tahoma");
FL_NORMAL_SIZE = 11;
progdefaults.WaterfallFontnbr = FL_HELVETICA;
progdefaults.WaterfallFontsize = 12;
#endif
}
2008-04-14 22:18:15 +00:00
#ifdef __CYGWIN__
static ofstream outlogfile;
static ostringstream outlogstring;
static streambuf* streambufs[3];
void redirect_streams(const std::string& dir)
{
string log = dir;
if (*log.rbegin() != '/')
log += '/';
log += "status_log.txt";
outlogfile.open(log.c_str());
if (!isatty(STDOUT_FILENO)) {
streambufs[0] = cout.rdbuf();
if (outlogfile)
cout.rdbuf(outlogfile.rdbuf());
else
cout.rdbuf(outlogstring.rdbuf());
}
if (!isatty(STDERR_FILENO)) {
streambufs[1] = cerr.rdbuf();
streambufs[2] = clog.rdbuf();
if (outlogfile) {
cerr.rdbuf(outlogfile.rdbuf());
clog.rdbuf(outlogfile.rdbuf());
}
else {
cerr.rdbuf(outlogstring.rdbuf());
clog.rdbuf(outlogstring.rdbuf());
}
}
}
void restore_streams(void)
{
cout.rdbuf(streambufs[0]);
cerr.rdbuf(streambufs[1]);
clog.rdbuf(streambufs[2]);
}
#endif // __CYGWIN__