~ubuntu-branches/ubuntu/wily/flrig/wily

« back to all changes in this revision

Viewing changes to src/rig.cxx

  • Committer: Package Import Robot
  • Author(s): Kamal Mostafa
  • Date: 2014-10-25 11:17:10 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20141025111710-n32skgya3l9u1brw
Tags: 1.3.17-1
* New upstream release (Closes: #761839)
* Debian Standards-Version: 3.9.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// ----------------------------------------------------------------------------
2
 
// Copyright (C) 2014
3
 
//              David Freese, W1HKJ
4
 
//
5
 
// This file is part of flrig.
6
 
//
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.
11
 
//
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.
16
 
//
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
 
// ----------------------------------------------------------------------------
20
 
 
21
 
#include "config.h"
22
 
 
23
 
#include <stdlib.h>
24
 
#include <iostream>
25
 
#include <fstream>
26
 
#include <cstring>
27
 
#include <ctime>
28
 
#include <sys/types.h>
29
 
#include <sys/stat.h>
30
 
#include <stdio.h>
31
 
#include <fcntl.h>
32
 
#include <errno.h>
33
 
 
34
 
#include <FL/Fl.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>
40
 
#include <FL/x.H>
41
 
#include <FL/Fl_Help_Dialog.H>
42
 
#include <FL/Fl_Menu_Item.H>
43
 
 
44
 
#ifdef WIN32
45
 
#  include "flrigrc.h"
46
 
#  include "compat.h"
47
 
#  define dirent fl_dirent_no_thanks
48
 
#endif
49
 
 
50
 
#include <FL/filename.H>
51
 
 
52
 
#ifdef __MINGW32__
53
 
#       if FLRIG_FLTK_API_MAJOR == 1 && FLRIG_FLTK_API_MINOR < 3
54
 
#               undef dirent
55
 
#               include <dirent.h>
56
 
#       endif
57
 
#else
58
 
#       include <dirent.h>
59
 
#endif
60
 
 
61
 
#include <FL/x.H>
62
 
#include <FL/Fl_Pixmap.H>
63
 
#include <FL/Fl_Image.H>
64
 
 
65
 
//#include "images/flrig.xpm"
66
 
#include "support.h"
67
 
#include "dialogs.h"
68
 
#include "rig.h"
69
 
#include "status.h"
70
 
#include "debug.h"
71
 
#include "util.h"
72
 
#include "gettext.h"
73
 
#include "xml_io.h"
74
 
 
75
 
#include "flrig_icon.cxx"
76
 
 
77
 
int parse_args(int argc, char **argv, int& idx);
78
 
 
79
 
Fl_Double_Window *mainwindow;
80
 
 
81
 
string HomeDir;
82
 
string RigHomeDir;
83
 
string TempDir;
84
 
string defFileName;
85
 
string title;
86
 
 
87
 
pthread_t *serial_thread = 0;
88
 
pthread_t *digi_thread = 0;
89
 
 
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;
96
 
 
97
 
bool RIG_DEBUG = false;
98
 
bool XML_DEBUG = false;
99
 
bool EXPAND_CONTROLS = false;
100
 
 
101
 
//----------------------------------------------------------------------
102
 
void about()
103
 
{
104
 
        string msg = "\
105
 
%s\n\
106
 
Version %s\n\
107
 
copyright W1HKJ  <w1hkj@@w1hkj.com>\n\
108
 
Developer:  Dave,  W1HKJ";
109
 
        fl_message(msg.c_str(), PACKAGE_TARNAME, PACKAGE_VERSION);
110
 
}
111
 
 
112
 
void visit_URL(void* arg)
113
 
{
114
 
        const char* url = reinterpret_cast<const char *>(arg);
115
 
#ifndef __WOE32__
116
 
        const char* browsers[] = {
117
 
#  ifdef __APPLE__
118
 
                getenv("FLDIGI_BROWSER"), // valid for any OS - set by user
119
 
                "open"                    // OS X
120
 
#  else
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
125
 
                "sensible-browser",
126
 
                "firefox",
127
 
                "mozilla"                 // must be something out there!
128
 
#  endif
129
 
        };
130
 
        switch (fork()) {
131
 
        case 0:
132
 
#  ifndef NDEBUG
133
 
                unsetenv("MALLOC_CHECK_");
134
 
                unsetenv("MALLOC_PERTURB_");
135
 
#  endif
136
 
                for (size_t i = 0; i < sizeof(browsers)/sizeof(browsers[0]); i++)
137
 
                        if (browsers[i])
138
 
                                execlp(browsers[i], browsers[i], url, (char*)0);
139
 
                exit(EXIT_FAILURE);
140
 
        case -1:
141
 
                fl_alert(_("Could not run a web browser:\n%s\n\n"
142
 
                         "Open this URL manually:\n%s"),
143
 
                         strerror(errno), url);
144
 
        }
145
 
#else
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);
155
 
#endif
156
 
}
157
 
 
158
 
//----------------------------------------------------------------------
159
 
 
160
 
extern void saveFreqList();
161
 
 
162
 
void * flrig_terminate(void) {
163
 
        std::cerr << "terminating" << std::endl;
164
 
        fl_message("Closing flrig");
165
 
        cbExit();
166
 
        return 0;
167
 
}
168
 
 
169
 
void showEvents(void *)
170
 
{
171
 
        debug::show();
172
 
}
173
 
 
174
 
#if defined(__WIN32__) && defined(PTW32_STATIC_LIB)
175
 
static void ptw32_cleanup(void)
176
 
{
177
 
        (void)pthread_win32_process_detach_np();
178
 
}
179
 
 
180
 
void ptw32_init(void)
181
 
{
182
 
        (void)pthread_win32_process_attach_np();
183
 
        atexit(ptw32_cleanup);
184
 
}
185
 
#endif // __WIN32__
186
 
 
187
 
#define KNAME "Flrig"
188
 
#if !defined(__WIN32__) && !defined(__APPLE__)
189
 
Pixmap  Rig_icon_pixmap;
190
 
 
191
 
void make_pixmap(Pixmap *xpm, const char **data)
192
 
{
193
 
        Fl_Window w(0,0, KNAME);
194
 
        w.xclass(KNAME);
195
 
        w.show();
196
 
        w.make_current();
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());
204
 
        fl_end_offscreen();
205
 
}
206
 
 
207
 
#endif
208
 
 
209
 
static void checkdirectories(void)
210
 
{
211
 
        struct {
212
 
                string& dir;
213
 
                const char* suffix;
214
 
                void (*new_dir_func)(void);
215
 
        } dirs[] = {
216
 
                { RigHomeDir, 0, 0 }
217
 
        };
218
 
 
219
 
        int r;
220
 
        for (size_t i = 0; i < sizeof(dirs)/sizeof(*dirs); i++) {
221
 
                if (dirs[i].suffix)
222
 
                        dirs[i].dir.assign(RigHomeDir).append(dirs[i].suffix).append("/");
223
 
 
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';
227
 
                        exit(EXIT_FAILURE);
228
 
                }
229
 
                else if (r == 0 && dirs[i].new_dir_func)
230
 
                        dirs[i].new_dir_func();
231
 
        }
232
 
}
233
 
 
234
 
void exit_main(Fl_Widget *w)
235
 
{
236
 
        if (Fl::event_key() == FL_Escape)
237
 
                return;
238
 
        cbExit();
239
 
}
240
 
 
241
 
extern void open_rig_socket();
242
 
extern bool run_digi_loop;
243
 
 
244
 
void expand_controls(void*)
245
 
{
246
 
        show_controls();
247
 
}
248
 
 
249
 
void close_controls(void*)
250
 
{
251
 
//      show_controls();
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();
256
 
                grpTABS->hide();
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);
263
 
        }
264
 
}
265
 
 
266
 
void startup(void*)
267
 
{
268
 
        initStatusConfigDialog();
269
 
 
270
 
        Fl::add_timeout(0.0, close_controls);
271
 
}
272
 
 
273
 
int main (int argc, char *argv[])
274
 
{
275
 
        std::terminate_handler(flrig_terminate);
276
 
 
277
 
        int arg_idx;
278
 
        HomeDir.clear();
279
 
        RigHomeDir.clear();
280
 
 
281
 
        Fl::args(argc, argv, arg_idx, parse_args);
282
 
        Fl::set_fonts(0);
283
 
 
284
 
        char dirbuf[FL_PATH_MAX + 1];
285
 
        string appdir = argv[0];
286
 
        size_t p;
287
 
#ifdef __WIN32__
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/");
296
 
                HomeDir = dirbuf;
297
 
                RigHomeDir.assign(HomeDir).append("flrig.files\\");
298
 
        }
299
 
#else
300
 
                p = appdir.rfind("flrig");
301
 
                if (p != std::string::npos)
302
 
                        appdir.erase(p);
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/");
308
 
                        HomeDir = dirbuf;
309
 
                }
310
 
 
311
 
                DIR *isdir = 0;
312
 
                string test_dir;
313
 
                test_dir.assign(HomeDir).append("flrig.files/");
314
 
                isdir = opendir(test_dir.c_str());
315
 
                if (isdir) {
316
 
                        RigHomeDir = test_dir;
317
 
                        closedir(isdir);
318
 
                } else if (RigHomeDir.empty()) {
319
 
                        RigHomeDir.assign(HomeDir).append(".flrig/");
320
 
                }
321
 
 
322
 
#endif
323
 
        checkdirectories();
324
 
 
325
 
        try {
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;
330
 
//              RIG_DEBUG = true;
331
 
//
332
 
                LOG(debug::INFO_LEVEL, debug::LOG_OTHER, _("%s log started on %s"), PACKAGE_STRING, ctime(&t));
333
 
        }
334
 
        catch (const char* error) {
335
 
                cerr << error << '\n';
336
 
                debug::stop();
337
 
                exit(1);
338
 
        }
339
 
 
340
 
        progStatus.loadLastState();
341
 
 
342
 
        if (progStatus.UIsize == small_ui)
343
 
                mainwindow = Small_rig_window();
344
 
        else
345
 
                mainwindow = Wide_rig_window();
346
 
 
347
 
        mainwindow->callback(exit_main);
348
 
 
349
 
        progStatus.UI_laststate();
350
 
 
351
 
        fntbrowser = new Font_Browser;
352
 
        dlgMemoryDialog = Memory_Dialog();
353
 
        dlgDisplayConfig = DisplayDialog();
354
 
 
355
 
        Fl::lock();
356
 
 
357
 
#if defined(__WIN32__) && defined(PTW32_STATIC_LIB)
358
 
        ptw32_init();
359
 
#endif
360
 
 
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");
365
 
                exit(EXIT_FAILURE);
366
 
        }
367
 
 
368
 
//      progStatus.loadLastState();
369
 
 
370
 
        open_rig_xmlrpc();
371
 
 
372
 
        digi_thread = new pthread_t;      
373
 
        if (pthread_create(digi_thread, NULL, digi_loop, NULL)) {
374
 
                perror("pthread_create");
375
 
                exit(EXIT_FAILURE);
376
 
        }
377
 
 
378
 
        createXcvrDialog();
379
 
 
380
 
        btnALC_SWR->image(image_swr);
381
 
        sldrRcvSignal->clear();
382
 
        sldrFwdPwr->clear();
383
 
        sldrALC->clear();
384
 
        sldrSWR->clear();
385
 
 
386
 
        if (progStatus.UIsize == small_ui)
387
 
                mainwindow->resize( progStatus.mainX, progStatus.mainY, mainwindow->w(), btnInitializing->h() + 24 );
388
 
        else
389
 
                mainwindow->resize( progStatus.mainX, progStatus.mainY, progStatus.mainW, mainwindow->h());
390
 
 
391
 
        btnInitializing->show();
392
 
 
393
 
        mainwindow->xclass(KNAME);
394
 
 
395
 
#if defined(__WOE32__)
396
 
#  ifndef IDI_ICON
397
 
#    define IDI_ICON 101
398
 
#  endif
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);
405
 
#else
406
 
        mainwindow->show(argc, argv);
407
 
#endif
408
 
 
409
 
        btn_show_controls->label("@-28->");
410
 
        btn_show_controls->redraw_label();
411
 
 
412
 
//      show_controls();
413
 
 
414
 
        Fl::add_timeout(0.50, startup);
415
 
 
416
 
        return Fl::run();
417
 
 
418
 
}
419
 
 
420
 
int parse_args(int argc, char **argv, int& idx)
421
 
{
422
 
        if (strcasecmp("--help", argv[idx]) == 0) {
423
 
                printf("Usage: \n\
424
 
  --help this help text\n\
425
 
  --version\n\
426
 
  --config-dir <DIR>\n\
427
 
  --debug-level N (0..4)\n\
428
 
  --rig_debug\n\
429
 
  --xml_debug\n\
430
 
  --exp (expand menu tab controls)\n\n");
431
 
                exit(0);
432
 
        } 
433
 
        if (strcasecmp("--version", argv[idx]) == 0) {
434
 
                printf("Version: "VERSION"\n");
435
 
                exit (0);
436
 
        }
437
 
        if (strcasecmp("--rig_debug", argv[idx]) == 0) {
438
 
                RIG_DEBUG = true;
439
 
                idx++;
440
 
                return 1;
441
 
        }
442
 
        if (strcasecmp("--xml_debug", argv[idx]) == 0) {
443
 
                XML_DEBUG = true;
444
 
                idx++;
445
 
                return 1;
446
 
        }
447
 
        if (strcasecmp("--debug-level", argv[idx]) == 0) {
448
 
                string level = argv[idx + 1];
449
 
                switch (level[0]) {
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;
456
 
                }
457
 
                idx += 2;
458
 
                return 1;
459
 
        }
460
 
        if (strcasecmp("--config-dir", argv[idx]) == 0) {
461
 
                RigHomeDir = argv[idx + 1];
462
 
                if (RigHomeDir[RigHomeDir.length()-1] != '/')
463
 
                        RigHomeDir += '/';
464
 
                idx += 2;
465
 
                return 1;
466
 
        }
467
 
        if (strcasecmp("--exp", argv[idx]) == 0) {
468
 
                EXPAND_CONTROLS = true;
469
 
                idx++;
470
 
                return 1;
471
 
        }
472
 
        return 0;
473
 
}