1
// ----------------------------------------------------------------------------
5
// This file is part of flrig.
7
// flrig is free software; you can redistribute it and/or modify
8
// it under the terms of the GNU General Public License as published by
9
// the Free Software Foundation; either version 3 of the License, or
10
// (at your option) any later version.
12
// flrig is distributed in the hope that it will be useful,
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
// GNU General Public License for more details.
17
// You should have received a copy of the GNU General Public License
18
// along with this program. If not, see <http://www.gnu.org/licenses/>.
19
// ----------------------------------------------------------------------------
28
#include <sys/types.h>
35
#include <FL/Enumerations.H>
36
#include <FL/Fl_Window.H>
37
#include <FL/Fl_Button.H>
38
#include <FL/Fl_Group.H>
39
#include <FL/Fl_Sys_Menu_Bar.H>
41
#include <FL/Fl_Help_Dialog.H>
42
#include <FL/Fl_Menu_Item.H>
47
# define dirent fl_dirent_no_thanks
50
#include <FL/filename.H>
53
# if FLRIG_FLTK_API_MAJOR == 1 && FLRIG_FLTK_API_MINOR < 3
62
#include <FL/Fl_Pixmap.H>
63
#include <FL/Fl_Image.H>
65
//#include "images/flrig.xpm"
75
#include "flrig_icon.cxx"
77
int parse_args(int argc, char **argv, int& idx);
79
Fl_Double_Window *mainwindow;
87
pthread_t *serial_thread = 0;
88
pthread_t *digi_thread = 0;
90
pthread_mutex_t mutex_serial = PTHREAD_MUTEX_INITIALIZER;
91
pthread_mutex_t mutex_xmlrpc = PTHREAD_MUTEX_INITIALIZER;
92
pthread_mutex_t mutex_queX = PTHREAD_MUTEX_INITIALIZER;
93
pthread_mutex_t mutex_queA = PTHREAD_MUTEX_INITIALIZER;
94
pthread_mutex_t mutex_queB = PTHREAD_MUTEX_INITIALIZER;
95
pthread_mutex_t mutex_ptt = PTHREAD_MUTEX_INITIALIZER;
97
bool RIG_DEBUG = false;
98
bool XML_DEBUG = false;
99
bool EXPAND_CONTROLS = false;
101
//----------------------------------------------------------------------
107
copyright W1HKJ <w1hkj@@w1hkj.com>\n\
108
Developer: Dave, W1HKJ";
109
fl_message(msg.c_str(), PACKAGE_TARNAME, PACKAGE_VERSION);
112
void visit_URL(void* arg)
114
const char* url = reinterpret_cast<const char *>(arg);
116
const char* browsers[] = {
118
getenv("FLDIGI_BROWSER"), // valid for any OS - set by user
121
"fl-xdg-open", // Puppy Linux
122
"xdg-open", // other Unix-Linux distros
123
getenv("FLDIGI_BROWSER"), // force use of spec'd browser
124
getenv("BROWSER"), // most Linux distributions
127
"mozilla" // must be something out there!
133
unsetenv("MALLOC_CHECK_");
134
unsetenv("MALLOC_PERTURB_");
136
for (size_t i = 0; i < sizeof(browsers)/sizeof(browsers[0]); i++)
138
execlp(browsers[i], browsers[i], url, (char*)0);
141
fl_alert(_("Could not run a web browser:\n%s\n\n"
142
"Open this URL manually:\n%s"),
143
strerror(errno), url);
146
// gurgle... gurgle... HOWL
147
// "The return value is cast as an HINSTANCE for backward
148
// compatibility with 16-bit Windows applications. It is
149
// not a true HINSTANCE, however. The only thing that can
150
// be done with the returned HINSTANCE is to cast it to an
151
// int and compare it with the value 32 or one of the error
152
// codes below." (Error codes omitted to preserve sanity).
153
if ((int)ShellExecute(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL) <= 32)
154
fl_alert(_("Could not open url:\n%s\n"), url);
158
//----------------------------------------------------------------------
160
extern void saveFreqList();
162
void * flrig_terminate(void) {
163
std::cerr << "terminating" << std::endl;
164
fl_message("Closing flrig");
169
void showEvents(void *)
174
#if defined(__WIN32__) && defined(PTW32_STATIC_LIB)
175
static void ptw32_cleanup(void)
177
(void)pthread_win32_process_detach_np();
180
void ptw32_init(void)
182
(void)pthread_win32_process_attach_np();
183
atexit(ptw32_cleanup);
187
#define KNAME "Flrig"
188
#if !defined(__WIN32__) && !defined(__APPLE__)
189
Pixmap Rig_icon_pixmap;
191
void make_pixmap(Pixmap *xpm, const char **data)
193
Fl_Window w(0,0, KNAME);
197
Fl_Pixmap icon(data);
198
int maxd = (icon.w() > icon.h()) ? icon.w() : icon.h();
199
*xpm = fl_create_offscreen(maxd, maxd);
200
fl_begin_offscreen(*xpm);
201
fl_color(FL_BACKGROUND_COLOR);
202
fl_rectf(0, 0, maxd, maxd);
203
icon.draw(maxd - icon.w(), maxd - icon.h());
209
static void checkdirectories(void)
214
void (*new_dir_func)(void);
220
for (size_t i = 0; i < sizeof(dirs)/sizeof(*dirs); i++) {
222
dirs[i].dir.assign(RigHomeDir).append(dirs[i].suffix).append("/");
224
if ((r = mkdir(dirs[i].dir.c_str(), 0777)) == -1 && errno != EEXIST) {
225
cerr << _("Could not make directory") << ' ' << dirs[i].dir
226
<< ": " << strerror(errno) << '\n';
229
else if (r == 0 && dirs[i].new_dir_func)
230
dirs[i].new_dir_func();
234
void exit_main(Fl_Widget *w)
236
if (Fl::event_key() == FL_Escape)
241
extern void open_rig_socket();
242
extern bool run_digi_loop;
244
void expand_controls(void*)
249
void close_controls(void*)
252
if (progStatus.UIsize == wide_ui) {
253
if (EXPAND_CONTROLS && selrig->has_extras) return;
254
btn_show_controls->label("@-22->");
255
btn_show_controls->redraw_label();
257
mainwindow->resizable(grpTABS);
258
mainwindow->size(progStatus.mainW, 150);
259
mainwindow->size_range(735, 150, 0, 150);
260
} else if (progStatus.UIsize == small_ui) {
261
if (EXPAND_CONTROLS && selrig->has_extras)
262
Fl::add_timeout(1.0, expand_controls);
268
initStatusConfigDialog();
270
Fl::add_timeout(0.0, close_controls);
273
int main (int argc, char *argv[])
275
std::terminate_handler(flrig_terminate);
281
Fl::args(argc, argv, arg_idx, parse_args);
284
char dirbuf[FL_PATH_MAX + 1];
285
string appdir = argv[0];
288
p = appdir.rfind("flrig.exe");
289
if (p != string::npos) appdir.erase(p);
290
p = appdir.find("FL_APPS\\");
291
if (p != string::npos) {
292
HomeDir.assign(appdir.substr(0, p + 8));
293
RigHomeDir.assign(HomeDir).append("flrig.files\\");
294
} else if (RigHomeDir.empty()) {
295
fl_filename_expand(dirbuf, sizeof(dirbuf) -1, "$USERPROFILE/");
297
RigHomeDir.assign(HomeDir).append("flrig.files\\");
300
p = appdir.rfind("flrig");
301
if (p != std::string::npos)
303
p = appdir.find("FL_APPS/");
304
if (p != string::npos)
305
RigHomeDir = appdir.substr(0, p + 8);
306
if (RigHomeDir.empty()) {
307
fl_filename_expand(dirbuf, FL_PATH_MAX, "$HOME/");
313
test_dir.assign(HomeDir).append("flrig.files/");
314
isdir = opendir(test_dir.c_str());
316
RigHomeDir = test_dir;
318
} else if (RigHomeDir.empty()) {
319
RigHomeDir.assign(HomeDir).append(".flrig/");
326
debug::start(string(RigHomeDir).append("debug_log.txt").c_str());
327
time_t t = time(NULL);
328
// for testing purposes only
329
// debug::level = debug::INFO_LEVEL;
332
LOG(debug::INFO_LEVEL, debug::LOG_OTHER, _("%s log started on %s"), PACKAGE_STRING, ctime(&t));
334
catch (const char* error) {
335
cerr << error << '\n';
340
progStatus.loadLastState();
342
if (progStatus.UIsize == small_ui)
343
mainwindow = Small_rig_window();
345
mainwindow = Wide_rig_window();
347
mainwindow->callback(exit_main);
349
progStatus.UI_laststate();
351
fntbrowser = new Font_Browser;
352
dlgMemoryDialog = Memory_Dialog();
353
dlgDisplayConfig = DisplayDialog();
357
#if defined(__WIN32__) && defined(PTW32_STATIC_LIB)
361
bypass_serial_thread_loop = true;
362
serial_thread = new pthread_t;
363
if (pthread_create(serial_thread, NULL, serial_thread_loop, NULL)) {
364
perror("pthread_create");
368
// progStatus.loadLastState();
372
digi_thread = new pthread_t;
373
if (pthread_create(digi_thread, NULL, digi_loop, NULL)) {
374
perror("pthread_create");
380
btnALC_SWR->image(image_swr);
381
sldrRcvSignal->clear();
386
if (progStatus.UIsize == small_ui)
387
mainwindow->resize( progStatus.mainX, progStatus.mainY, mainwindow->w(), btnInitializing->h() + 24 );
389
mainwindow->resize( progStatus.mainX, progStatus.mainY, progStatus.mainW, mainwindow->h());
391
btnInitializing->show();
393
mainwindow->xclass(KNAME);
395
#if defined(__WOE32__)
397
# define IDI_ICON 101
399
mainwindow->icon((char*)LoadIcon(fl_display, MAKEINTRESOURCE(IDI_ICON)));
400
mainwindow->show (argc, argv);
401
#elif !defined(__APPLE__)
402
make_pixmap(&Rig_icon_pixmap, flrig_icon);
403
mainwindow->icon((char *)Rig_icon_pixmap);
404
mainwindow->show(argc, argv);
406
mainwindow->show(argc, argv);
409
btn_show_controls->label("@-28->");
410
btn_show_controls->redraw_label();
414
Fl::add_timeout(0.50, startup);
420
int parse_args(int argc, char **argv, int& idx)
422
if (strcasecmp("--help", argv[idx]) == 0) {
424
--help this help text\n\
426
--config-dir <DIR>\n\
427
--debug-level N (0..4)\n\
430
--exp (expand menu tab controls)\n\n");
433
if (strcasecmp("--version", argv[idx]) == 0) {
434
printf("Version: "VERSION"\n");
437
if (strcasecmp("--rig_debug", argv[idx]) == 0) {
442
if (strcasecmp("--xml_debug", argv[idx]) == 0) {
447
if (strcasecmp("--debug-level", argv[idx]) == 0) {
448
string level = argv[idx + 1];
450
case '0': debug::level = debug::QUIET_LEVEL; break;
451
case '1': debug::level = debug::ERROR_LEVEL; break;
452
case '2': debug::level = debug::WARN_LEVEL; break;
453
case '3': debug::level = debug::INFO_LEVEL; break;
454
case '4': debug::level = debug::DEBUG_LEVEL; break;
455
default : debug::level = debug::WARN_LEVEL;
460
if (strcasecmp("--config-dir", argv[idx]) == 0) {
461
RigHomeDir = argv[idx + 1];
462
if (RigHomeDir[RigHomeDir.length()-1] != '/')
467
if (strcasecmp("--exp", argv[idx]) == 0) {
468
EXPAND_CONTROLS = true;