kopia lustrzana https://github.com/jamescoxon/dl-fldigi
330 wiersze
8.8 KiB
C++
330 wiersze
8.8 KiB
C++
// ----------------------------------------------------------------------------
|
|
// flarqenv.cxx
|
|
//
|
|
// Copyright (C) 2009
|
|
// Stelios Bounanos, M0GLD
|
|
// ----------------------------------------------------------------------------
|
|
// Copyright (C) 2014
|
|
// David 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
|
// ----------------------------------------------------------------------------
|
|
|
|
#include <config.h>
|
|
|
|
#include <iostream>
|
|
#include <string>
|
|
#include <sstream>
|
|
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
#include <cerrno>
|
|
|
|
#ifdef __MINGW32__
|
|
# include "compat.h"
|
|
#endif
|
|
|
|
#if HAVE_SYS_UTSNAME_H
|
|
# include <sys/utsname.h>
|
|
#endif
|
|
|
|
#include <signal.h>
|
|
#include <getopt.h>
|
|
|
|
#include <FL/Fl.H>
|
|
|
|
#include "stacktrace.h"
|
|
#include "flarq.h"
|
|
|
|
using namespace std;
|
|
|
|
string option_help, version_text, build_text;
|
|
extern string arq_address, arq_port;
|
|
extern bool ioMPSK;
|
|
extern bool SHOWDEBUG;
|
|
|
|
void generate_option_help(void)
|
|
{
|
|
ostringstream help;
|
|
help << "Usage:\n"
|
|
<< " " << PACKAGE_NAME << " [option...]\n\n";
|
|
|
|
help << PACKAGE_NAME << " options:\n\n"
|
|
<< " --arq-protocol TYPE\n"
|
|
<< " Set the ARQ protocol\n"
|
|
<< " May be either ``fldigi'' or ``multipsk''\n"
|
|
<< " The default is: " << (ioMPSK ? "multipsk" : "fldigi") << "\n\n"
|
|
|
|
<< " --arq-server-address HOSTNAME\n"
|
|
<< " Set the ARQ TCP server address\n"
|
|
<< " The default is: " << arq_address << "\n\n"
|
|
|
|
<< " --arq-server-port PORT\n"
|
|
<< " Set the ARQ TCP server port\n"
|
|
<< " The default is: " << arq_port << "\n\n"
|
|
|
|
<< " --debug\n"
|
|
<< " Enable debugging messages\n\n"
|
|
|
|
<< " --version\n"
|
|
<< " Print version information\n\n"
|
|
|
|
<< " --build-info\n"
|
|
<< " Print build information\n\n"
|
|
|
|
<< " --help\n"
|
|
<< " 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"
|
|
<< " Enable or disable drag and drop copy and paste in text fields\n\n"
|
|
|
|
<< " -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 setting **\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"
|
|
|
|
<< " -ti WINDOWTITLE, -title WINDOWTITLE\n"
|
|
<< " Set the window title\n\n";
|
|
|
|
help << "Additional UI options:\n\n"
|
|
|
|
<< " --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";
|
|
|
|
option_help = help.str();
|
|
}
|
|
|
|
int parse_args(int argc, char** argv, int& idx)
|
|
{
|
|
// Only handle long options
|
|
if ( !(strlen(argv[idx]) >= 2 && strncmp(argv[idx], "--", 2) == 0) )
|
|
return 0;
|
|
|
|
enum { OPT_ZERO,
|
|
#ifndef __WOE32__
|
|
OPT_RX_IPC_KEY, OPT_TX_IPC_KEY,
|
|
#endif
|
|
OPT_ARQ_PROTOCOL, OPT_ARQ_ADDRESS, OPT_ARQ_PORT,
|
|
|
|
OPT_FONT,
|
|
|
|
OPT_DEBUG, OPT_DEPRECATED, OPT_HELP, OPT_VERSION, OPT_BUILD_INFO
|
|
};
|
|
|
|
const char shortopts[] = "+";
|
|
struct option longopts[] = {
|
|
#ifndef __WOE32__
|
|
{ "rx-ipc-key", 1, 0, OPT_RX_IPC_KEY },
|
|
{ "tx-ipc-key", 1, 0, OPT_TX_IPC_KEY },
|
|
#endif
|
|
{ "arq-protocol", 1, 0, OPT_ARQ_PROTOCOL },
|
|
{ "arq-server-address", 1, 0, OPT_ARQ_ADDRESS },
|
|
{ "arq-server-port", 1, 0, OPT_ARQ_PORT },
|
|
|
|
{ "font", 1, 0, OPT_FONT },
|
|
|
|
{ "debug", 0, 0, OPT_DEBUG },
|
|
|
|
{ "help", 0, 0, OPT_HELP },
|
|
{ "version", 0, 0, OPT_VERSION },
|
|
{ "build-info", 0, 0, OPT_BUILD_INFO },
|
|
{ 0 }
|
|
};
|
|
|
|
int longindex;
|
|
optind = idx;
|
|
int c = getopt_long(argc, argv, shortopts, longopts, &longindex);
|
|
|
|
switch (c) {
|
|
case -1:
|
|
return 0;
|
|
case 0:
|
|
// handle options with non-0 flag here
|
|
return 0;
|
|
|
|
case OPT_ARQ_PROTOCOL:
|
|
if (!strcmp(optarg, "fldigi"))
|
|
ioMPSK = false;
|
|
else if (!strcmp(optarg, "multipsk"))
|
|
ioMPSK = true;
|
|
else {
|
|
cerr << "E: unknown protocol type\n";
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
break;
|
|
case OPT_ARQ_ADDRESS:
|
|
arq_address = optarg;
|
|
break;
|
|
case OPT_ARQ_PORT:
|
|
arq_port = optarg;
|
|
break;
|
|
|
|
case OPT_FONT: {
|
|
char *p;
|
|
if ((p = strchr(optarg, ':'))) {
|
|
*p = '\0';
|
|
FL_NORMAL_SIZE = strtol(p + 1, 0, 10);
|
|
}
|
|
|
|
Fl::set_font(FL_HELVETICA, optarg);
|
|
break;
|
|
}
|
|
|
|
case OPT_DEBUG:
|
|
SHOWDEBUG = true;
|
|
break;
|
|
|
|
case OPT_DEPRECATED:
|
|
cerr << "W: the --" << longopts[longindex].name
|
|
<< " option has been deprecated and will be removed in a future version\n";
|
|
break;
|
|
|
|
case OPT_HELP:
|
|
cout << option_help;
|
|
exit(EXIT_SUCCESS);
|
|
|
|
case OPT_VERSION:
|
|
cout << version_text;
|
|
exit(EXIT_SUCCESS);
|
|
|
|
case OPT_BUILD_INFO:
|
|
cout << build_text;
|
|
exit(EXIT_SUCCESS);
|
|
|
|
case '?': default:
|
|
cerr << "Try `" << PACKAGE_NAME << " --help' for more information.\n";
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
// 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.
|
|
c = longopts[longindex].has_arg ? 2 : 1;
|
|
if (c == 2) {
|
|
string arg = argv[idx];
|
|
string::size_type p;
|
|
if ((p = arg.rfind(optarg)) != string::npos && arg[p-1] == '=')
|
|
c = 1;
|
|
}
|
|
idx += c;
|
|
return c;
|
|
}
|
|
|
|
void set_platform_ui(void)
|
|
{
|
|
#if defined(__APPLE__)
|
|
FL_NORMAL_SIZE = 12;
|
|
#elif defined(__WOE32__)
|
|
Fl::set_font(FL_HELVETICA, "Tahoma");
|
|
FL_NORMAL_SIZE = 11;
|
|
#else
|
|
FL_NORMAL_SIZE = 12;
|
|
#endif
|
|
}
|
|
|
|
void generate_version_text(void)
|
|
{
|
|
version_text.assign(PACKAGE_STRING "\nCopyright (C) 2008, 2009 " PACKAGE_AUTHORS ".\n");
|
|
version_text.append("License GPLv3+: GNU GPL version 3 or later "
|
|
"<http://www.gnu.org/licenses/gpl.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");
|
|
|
|
ostringstream s;
|
|
s << "Build information:\n";
|
|
s << " built : " << BUILD_DATE << " by " << BUILD_USER
|
|
<< '@' << BUILD_HOST << " on " << BUILD_BUILD_PLATFORM
|
|
<< " for " << BUILD_TARGET_PLATFORM << "\n\n"
|
|
<< " configure flags: " << BUILD_CONFIGURE_ARGS << "\n\n"
|
|
<< " compiler : " << BUILD_COMPILER << "\n\n"
|
|
<< " compiler flags : " << FLARQ_BUILD_CXXFLAGS << "\n\n"
|
|
<< " linker flags : " << FLARQ_BUILD_LDFLAGS << "\n\n"
|
|
|
|
<< " libraries : " "FLTK " FLTK_BUILD_VERSION "\n";
|
|
|
|
s << "\nRuntime information:\n";
|
|
struct utsname u;
|
|
if (uname(&u) != -1) {
|
|
s << " system : " << u.sysname << ' ' << u.nodename
|
|
<< ' ' << u.release << ' ' << u.version << ' ' << u.machine << "\n\n";
|
|
}
|
|
|
|
build_text = s.str();
|
|
}
|
|
|
|
void setup_signal_handlers(void)
|
|
{
|
|
#ifndef __WOE32__
|
|
struct sigaction action;
|
|
memset(&action, 0, sizeof(struct sigaction));
|
|
|
|
// no child stopped notifications, no zombies
|
|
action.sa_handler = SIG_DFL;
|
|
action.sa_flags = SA_NOCLDSTOP;
|
|
#ifdef SA_NOCLDWAIT
|
|
action.sa_flags |= SA_NOCLDWAIT;
|
|
#endif
|
|
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);
|
|
pthread_sigmask(SIG_BLOCK, &action.sa_mask, NULL);
|
|
#else
|
|
signal(SIGSEGV, handle_signal);
|
|
signal(SIGILL, handle_signal);
|
|
signal(SIGABRT, handle_signal);
|
|
#endif
|
|
}
|