diff --git a/configure.ac b/configure.ac index f4066d0b..6e2e5d3e 100644 --- a/configure.ac +++ b/configure.ac @@ -9,7 +9,7 @@ dnl major and minor must be integers; patch may dnl contain other characters or be empty m4_define(FLDIGI_MAJOR, [3]) m4_define(FLDIGI_MINOR, [0]) -m4_define(FLDIGI_PATCH, [2]) +m4_define(FLDIGI_PATCH, [3AA]) AC_INIT([fldigi], FLDIGI_MAJOR.FLDIGI_MINOR[FLDIGI_PATCH], [w1hkj AT w1hkj DOT com]) diff --git a/m4/fltk.m4 b/m4/fltk.m4 index ce27fc70..d38af6d2 100644 --- a/m4/fltk.m4 +++ b/m4/fltk.m4 @@ -11,14 +11,17 @@ AC_DEFUN([AC_FLDIGI_FLTK], [ ]) fi HAVE_FLTK_API_VERSION=no - FLTK_API_VERSION=`$FLTK_CONFIG --api-version` - if test "x$FLTK_API_VERSION" = "x1.1" || "x$FLTK_API_VERSION" = "x1.2"; then + FLTK_API_VERSION="`$FLTK_CONFIG --api-version`" + if test $? -ne 0; then + AC_MSG_ERROR([$FLTK_CONFIG failed]) + fi + if test "x$FLTK_API_VERSION" = "x1.1" || "x$FLTK_API_VERSION" = "x1.2" || "x$FLTK_API_VERSION" = "x1.3"; then HAVE_FLTK_API_VERSION=yes fi if test "${HAVE_FLTK_API_VERSION}" = "no"; then AC_MSG_ERROR([ *** The version of FLTK found on your system provides API version $FLTK_API_VERSION. - *** To build $PACKAGE you need a FLTK version that provides API 1.1. + *** To build $PACKAGE you need a FLTK version that provides API 1.1, 1.2 or 1.3. ]) fi FLTK_CFLAGS=`$FLTK_CONFIG --cxxflags` diff --git a/src/Makefile.am b/src/Makefile.am index d216d908..3418b19c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -156,6 +156,7 @@ fldigi_SOURCES += \ include/complex.h \ include/configuration.h \ include/cw.h \ + include/debug.h \ include/digiscope.h \ include/thor.h \ include/thorvaricode.h \ @@ -256,6 +257,7 @@ fldigi_SOURCES += \ misc/ascii.cxx \ misc/configuration.cxx \ misc/colorsfonts.cxx \ + misc/debug.cxx \ misc/flstring.c \ misc/log.cxx \ misc/macroedit.cxx \ diff --git a/src/cw_rtty/cw.cxx b/src/cw_rtty/cw.cxx index fbc4a50b..aa9aa4f1 100644 --- a/src/cw_rtty/cw.cxx +++ b/src/cw_rtty/cw.cxx @@ -40,6 +40,7 @@ //#include "modeIO.h" #include "configuration.h" #include "status.h" +#include "debug.h" void cw::tx_init(SoundBase *sc) { @@ -593,7 +594,7 @@ void cw::send_symbol(int bits) if (symlen < knum) symlen = knum; } else symlen = symbollen; -// cout << (symbol & 1) << "-" << symlen << ", "; +// LOG_DEBUG("%d-%d", symbol & 1, symlen); if (delta < -(symlen - knum)) delta = -(symlen - knum); if (delta > (symlen - knum)) delta = symlen - knum; diff --git a/src/dialogs/fl_digi.cxx b/src/dialogs/fl_digi.cxx index 03071487..73bbd6d0 100644 --- a/src/dialogs/fl_digi.cxx +++ b/src/dialogs/fl_digi.cxx @@ -102,6 +102,7 @@ #include "soundconf.h" #include "htmlstrings.h" +#include "debug.h" Fl_Double_Window *fl_digi_main=(Fl_Double_Window *)0; Fl_Help_Dialog *help_dialog = (Fl_Help_Dialog *)0; @@ -479,7 +480,7 @@ bool clean_exit() { if (trx_state == STATE_RX || trx_state == STATE_TX || trx_state == STATE_TUNE) trx_state = STATE_ABORT; else { - cerr << "trx in unexpected state " << trx_state << '\n'; + LOG_ERROR("trx in unexpected state %d", trx_state); exit(1); } while (trx_state != STATE_ENDED) { @@ -643,7 +644,7 @@ void init_modem(trx_mode mode) break; default: - cerr << "Unknown mode: " << mode << '\n'; + LOG_ERROR("Unknown mode: %d", mode); return init_modem(MODE_BPSK31); } @@ -658,7 +659,7 @@ void init_modem_sync(trx_mode m) #ifndef NDEBUG if (GET_THREAD_ID() == TRX_TID) - cerr << "trx thread called init_modem_sync!\n"; + LOG_ERROR("trx thread called init_modem_sync!"); #endif wait_modem_ready_prep(); @@ -884,7 +885,7 @@ void cb_mnuVisitURL(Fl_Widget*, void* arg) for (size_t i = 0; i < sizeof(browsers)/sizeof(browsers[0]); i++) if (browsers[i]) execlp(browsers[i], browsers[i], url, (char*)0); - perror("Could not execute a web browser"); + LOG_PERROR("Could not execute a web browser"); exit(EXIT_FAILURE); case -1: fl_alert("Could not run a web browser:\n%s\n\n" @@ -986,6 +987,11 @@ void cb_mnuBuildInfo(Fl_Widget*, void*) restoreFocus(); } +void cb_mnuDebug(Fl_Widget*, void*) +{ + debug::show(); +} + #ifndef NDEBUG void cb_mnuFun(Fl_Widget*, void*) { @@ -1442,7 +1448,7 @@ Fl_Menu_Item menu_[] = { {"Digiscope", 0, (Fl_Callback*)cb_mnuDigiscope, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, {"MFSK Image", 0, (Fl_Callback*)cb_mnuPicViewer, 0, FL_MENU_INACTIVE, FL_NORMAL_LABEL, 0, 14, 0}, {"PSK Browser", 0, (Fl_Callback*)cb_mnuViewer, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, -{"Rig", 0, (Fl_Callback*)cb_mnuRig, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, +{"Rig Control", 0, (Fl_Callback*)cb_mnuRig, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, {0,0,0,0,0,0,0,0,0}, {" ", 0, 0, 0, FL_MENU_INACTIVE, FL_NORMAL_LABEL, 0, 14, 0}, @@ -1457,7 +1463,8 @@ Fl_Menu_Item menu_[] = { {"Home page", 0, cb_mnuVisitURL, (void *)PACKAGE_HOME, FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0}, {"Command line options", 0, cb_mnuCmdLineHelp, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, {"Audio device info", 0, cb_mnuAudioInfo, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, -{"Build info", 0, cb_mnuBuildInfo, 0, FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0}, +{"Build info", 0, cb_mnuBuildInfo, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, +{"Event log", 0, cb_mnuDebug, 0, FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0}, {"About", 0, cb_mnuAboutURL, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, {0,0,0,0,0,0,0,0,0}, @@ -1477,13 +1484,13 @@ Fl_Menu_Item *getMenuItem(const char *caption) } } if (!item) - cerr << "FIXME: could not find '" << caption << "' menu\n"; + LOG_ERROR("FIXME: could not find menu \"%s\"", caption); return item; } void activate_rig_menu_item(bool b) { - Fl_Menu_Item *rig = getMenuItem("Rig"); + Fl_Menu_Item *rig = getMenuItem("Rig Control"); if (!rig) return; @@ -1740,6 +1747,7 @@ void create_fl_digi_main() { progdefaults.RxColor.R, progdefaults.RxColor.G, progdefaults.RxColor.B)); + TiledGroup->add_resize_check(FTextView::wheight_mult_tsize, ReceiveText); FHdisp = new Raster(sw, Y, WNOM-sw, minRxHeight); FHdisp->hide(); diff --git a/src/dominoex/dominoex.cxx b/src/dominoex/dominoex.cxx index 986ed74f..c9661039 100644 --- a/src/dominoex/dominoex.cxx +++ b/src/dominoex/dominoex.cxx @@ -25,7 +25,6 @@ #include -#include #include #include "confdialog.h" @@ -38,6 +37,7 @@ #include "misc.h" #include "sound.h" #include "mfskvaricode.h" +#include "debug.h" using namespace std; @@ -867,28 +867,27 @@ void dominoex::sendMuPskEX(unsigned char c, int secondary) c = '_'; } code = varienc(c); -//if (secondary == 0) -//std::cout << (int)c << " ==> " << code << " ==> "; + // if (secondary == 0) + // LOG_DEBUG("char=%hhu, code=\"%s\"", c, code); while (*code) { int data = MuPskEnc->encode(*code++ - '0'); -//std::cout << (int)data << " "; + // LOG_DEBUG("data=%d", data; for (int i = 0; i < 2; i++) { bitshreg = (bitshreg << 1) | ((data >> i) & 1); Mu_bitstate++; if (Mu_bitstate == 4) { MuPskTxinlv->bits(&bitshreg); - -//std::cout << "(" << bitshreg << ") "; - + + // LOG_DEBUG("bitshreg=%d", bitshreg); + sendsymbol(bitshreg); -//decodeMuPskEX(bitshreg); + // decodeMuPskEX(bitshreg); Mu_bitstate = 0; bitshreg = 0; } } } -//std::cout << std::endl; } diff --git a/src/feld/feld.cxx b/src/feld/feld.cxx index 22fda072..37f6ccd2 100644 --- a/src/feld/feld.cxx +++ b/src/feld/feld.cxx @@ -39,6 +39,7 @@ #include "confdialog.h" #include "qrunner.h" #include "status.h" +#include "debug.h" #include #include @@ -416,7 +417,7 @@ void feld::send_symbol(int currsymb, int nextsymb) outbuf[outlen++] = Amp * nco(tone); if (outlen >= OUTBUFSIZE) { - std::cout << "feld reset" << std::endl; + LOG_DEBUG("feld reset"); break; } txcounter += upsampleinc; diff --git a/src/fileselector/fileselect.cxx b/src/fileselector/fileselect.cxx index d449695d..fcd484d2 100644 --- a/src/fileselector/fileselect.cxx +++ b/src/fileselector/fileselect.cxx @@ -5,6 +5,7 @@ #include #include "fileselect.h" +#include "debug.h" #include #include @@ -31,7 +32,7 @@ void FSEL::create(void) return; #if FSEL_THREAD if (sem_init(&fsel_sem, 0, 0) == -1) { - perror("sem_init"); + LOG_PERROR("sem_init"); return; } #endif diff --git a/src/include/FTextView.h b/src/include/FTextView.h index cb7295f7..bd6d73f8 100644 --- a/src/include/FTextView.h +++ b/src/include/FTextView.h @@ -180,6 +180,29 @@ protected: unsigned ascii_chr; }; +// A FTextView subclass to display the event log +class FTextLog : public FTextView +{ +public: + FTextLog(int x, int y, int w, int h, const char *l = 0); + ~FTextLog(); + + virtual int handle(int event); + virtual void add(unsigned char c, int attr = RECV); + virtual void add(const char *s, int attr = RECV); + +protected: + enum { LOG_MENU_CLEAR, LOG_MENU_COPY, LOG_MENU_SAVE, LOG_MENU_WRAP }; + + virtual void menu_cb(int val); +private: + FTextLog(); + FTextLog(const FTextLog &t); + +protected: + static Fl_Menu_Item log_menu[]; +}; + /// A version of Fl_Tile that runs check callbacks and moves the boundary /// between its child widgets only all resize checks return true. diff --git a/src/include/debug.h b/src/include/debug.h new file mode 100644 index 00000000..b63ede7e --- /dev/null +++ b/src/include/debug.h @@ -0,0 +1,70 @@ +// ---------------------------------------------------------------------------- +// debug.h +// +// Copyright (C) 2008 +// Stelios Bounanos, M0GLD +// +// 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 . +// ---------------------------------------------------------------------------- + +#ifndef _DEBUG_H_ +#define _DEBUG_H_ + + +class debug +{ +public: + enum level_e { _QUIET, _ERROR, _WARN, _INFO, _DEBUG, _NLEVELS }; + static void start(const char* filename); + static void stop(void); + static void log(level_e level, const char* func, const char* srcf, int line, const char* format, ...); + static void elog(const char* func, const char* srcf, int line, const char* text); + static void show(void); + static level_e level; +private: + static void sync_text(void*); + debug(const char* filename); + debug(const debug&); + debug& operator=(const debug&); + ~debug(); + static debug* inst; +}; + +#define LOG(level__, ...) \ + do { \ + if (level__ <= debug::level) \ + debug::log(level__, __func__, __FILE__, __LINE__, __VA_ARGS__); \ + } while (0) + +#define LOG_DEBUG(...) LOG(debug::_DEBUG, __VA_ARGS__) +#define LOG_INFO(...) LOG(debug::_INFO, __VA_ARGS__) +#define LOG_WARN(...) LOG(debug::_WARN, __VA_ARGS__) +#define LOG_ERROR(...) LOG(debug::_ERROR, __VA_ARGS__) + +#define LOG_PERROR(msg__) \ + do { \ + if (debug::_ERROR <= debug::level) \ + debug::elog(__func__, __FILE__, __LINE__, msg__); \ + } while (0) + + + +#endif // _DEBUG_H_ + +// Local Variables: +// mode: c++ +// c-file-style: "linux" +// End: diff --git a/src/include/fl_lock.h b/src/include/fl_lock.h index c4da9d9d..c48e5c33 100644 --- a/src/include/fl_lock.h +++ b/src/include/fl_lock.h @@ -40,19 +40,20 @@ # include # ifndef NO_LOCKS +# include "debug.h" # define FL_LOCK(x) \ do { \ switch (GET_THREAD_ID()) { \ case TRX_TID: \ - printf("E: trx lock in %s at %s:%d\n", \ + LOG_ERROR("trx lock", \ __func__, __FILE__, __LINE__); \ break; \ case FLMAIN_TID: \ - printf("W: flrun lock in %s at %s:%d\n",\ + LOG_WARN("flrun lock", \ __func__, __FILE__, __LINE__); \ break; \ default: \ - printf("I: lock in %s at %s:%d\n", \ + LOG_INFO("lock", \ __func__, __FILE__, __LINE__); \ } \ pstack_maybe(); \ diff --git a/src/include/qrunner.h b/src/include/qrunner.h index f8e62e3e..bd31099a 100644 --- a/src/include/qrunner.h +++ b/src/include/qrunner.h @@ -24,7 +24,7 @@ #define QRUNNER_H_ #ifndef NDEBUG -# include +# include "debug.h" #endif #include @@ -107,7 +107,7 @@ public: } #ifndef NDEBUG - std::cerr << "fifo full\n"; + LOG_ERROR("qrunner: thread %d fifo full!", GET_THREAD_ID()); #endif return false; } diff --git a/src/include/rigio.h b/src/include/rigio.h index 570f55bb..1753fe52 100644 --- a/src/include/rigio.h +++ b/src/include/rigio.h @@ -2,31 +2,21 @@ #define RIGIO_H #include -#include -#include -#include -#include -#include -#include -#include -#include #include "serial.h" -using namespace std; - extern Cserial rigio; -extern bool hexout( string); +extern bool hexout(const std::string&); extern long long rigCAT_getfreq(); extern void rigCAT_setfreq(long long); -extern string rigCAT_getmode(); -extern void rigCAT_setmode(string); +extern std::string rigCAT_getmode(); +extern void rigCAT_setmode(const std::string&); -extern string rigCAT_getwidth(); -extern void rigCAT_setwidth(string); +extern std::string rigCAT_getwidth(); +extern void rigCAT_setwidth(const std::string&); extern void rigCAT_close(); extern bool rigCAT_init(); diff --git a/src/logger/logger.cxx b/src/logger/logger.cxx index f0756efa..952bd1f0 100644 --- a/src/logger/logger.cxx +++ b/src/logger/logger.cxx @@ -36,6 +36,7 @@ #include "logger.h" #include "main.h" #include "modem.h" +#include "debug.h" #include @@ -123,7 +124,7 @@ void putadif(int num, const char *s) if (slen > fields[num].size) slen = fields[num].size; int n = snprintf(tempstr, sizeof(tempstr), "<%s:%zu>", fields[num].name, slen); if (n == -1) { - perror("putadif snprintf"); + LOG_PERROR("snprintf"); return; } memcpy(tempstr + n, s, slen); @@ -204,6 +205,7 @@ int submit_log(void) if ((msqid = msgget(LOG_MKEY, 0666 | IPC_CREAT)) == -1) { errmsg = "msgget: "; errmsg.append(strerror(errno)); + LOG_ERROR("%s", errmsg.c_str()); fl_message(errmsg.c_str()); return -1; } diff --git a/src/main.cxx b/src/main.cxx index 37187dd2..925d259d 100644 --- a/src/main.cxx +++ b/src/main.cxx @@ -63,6 +63,7 @@ #include "status.h" #include "fileselect.h" #include "timeops.h" +#include "debug.h" #if USE_HAMLIB #include "rigclass.h" @@ -126,10 +127,6 @@ void debug_exec(char** argv); void set_platform_ui(void); double speed_test(int converter, unsigned repeat); -#ifdef __CYGWIN__ -void redirect_streams(const std::string& dir); -void restore_streams(void); -#endif int main(int argc, char ** argv) { @@ -156,8 +153,6 @@ int main(int argc, char ** argv) #ifdef __CYGWIN__ fl_filename_expand(szHomedir, 119, "$USERPROFILE/fldigi.files/"); HomeDir = szHomedir; - redirect_streams(HomeDir); - atexit(restore_streams); #else fl_filename_expand(szHomedir, 119, "$HOME/.fldigi/"); HomeDir = szHomedir; @@ -187,6 +182,16 @@ int main(int argc, char ** argv) closedir(dir); } + try { + debug::start(string(HomeDir).append("status_log.txt").c_str()); + time_t t = time(NULL); + LOG(debug::_QUIET, "%s log started on %s", PACKAGE_STRING, ctime(&t)); + } + catch (const char* error) { + cerr << error << '\n'; + debug::stop(); + } + xmlfname = HomeDir; xmlfname.append("rig.xml"); @@ -213,9 +218,7 @@ int main(int argc, char ** argv) if (!progdefaults.readDefaultsXML()) { double speed = speed_test(SRC_SINC_FASTEST, 8); -#ifndef NDEBUG - cerr << "speed factor=" << speed << '\n'; -#endif + if (speed > 150.0) { // fast progdefaults.slowcpu = false; progdefaults.sample_converter = SRC_SINC_BEST_QUALITY; @@ -232,6 +235,9 @@ int main(int argc, char ** argv) progdefaults.slowcpu = true; progdefaults.sample_converter = SRC_LINEAR; } + + LOG_INFO("speed factor=%f, slowcpu=%d, sample_converter=\"%s\"", speed, + progdefaults.slowcpu, src_get_name(progdefaults.sample_converter)); } progdefaults.testCommPorts(); @@ -288,6 +294,7 @@ int main(int argc, char ** argv) delete cbq[i]; } FSEL::destroy(); + debug::stop(); return ret; } @@ -349,6 +356,9 @@ void generate_option_help(void) { << " The default is: " << progdefaults.xmlrpc_port << "\n\n" #endif + << " --debug-level LEVEL\n" + << " Set the event log verbosity\n\n" + << " --version\n" << " Print version information\n\n" @@ -440,14 +450,12 @@ int parse_args(int argc, char **argv, int& idx) #endif OPT_FONT, OPT_WFALL_WIDTH, OPT_WFALL_HEIGHT, OPT_WINDOW_WIDTH, OPT_WINDOW_HEIGHT, - OPT_PROFILE, OPT_TOGGLE_CHECK, - OPT_RESAMPLE, #if USE_PORTAUDIO OPT_FRAMES_PER_BUFFER, #endif OPT_TWO_SCOPES, - OPT_RIGIO_DEBUG, + OPT_DEBUG_LEVEL, OPT_EXIT_AFTER, OPT_HELP, OPT_VERSION }; @@ -474,20 +482,18 @@ int parse_args(int argc, char **argv, int& idx) { "wfall-height", 1, 0, OPT_WFALL_HEIGHT }, { "window-width", 1, 0, OPT_WINDOW_WIDTH }, { "window-height", 1, 0, OPT_WINDOW_HEIGHT }, - { "profile", 1, 0, OPT_PROFILE }, { "twoscopes", 0, 0, OPT_TWO_SCOPES }, { "toggle-check-buttons", 0, 0, OPT_TOGGLE_CHECK }, - { "resample", 1, 0, OPT_RESAMPLE }, - #if USE_PORTAUDIO { "frames-per-buf",1, 0, OPT_FRAMES_PER_BUFFER }, #endif { "exit-after", 1, 0, OPT_EXIT_AFTER }, + { "debug-level", 1, 0, OPT_DEBUG_LEVEL }, + { "help", 0, 0, OPT_HELP }, { "version", 0, 0, OPT_VERSION }, - { "rigio-debug", 0, 0, OPT_RIGIO_DEBUG }, { 0 } }; @@ -572,27 +578,14 @@ int parse_args(int argc, char **argv, int& idx) HNOM = strtol(optarg, NULL, 10); break; - case OPT_PROFILE: - cerr << "The --" << longopts[longindex].name - << " option has been deprecated and will be removed in a future release\n"; - break; - case OPT_TWO_SCOPES: twoscopes = true; break; - case OPT_RIGIO_DEBUG: - RIGIO_DEBUG = true; - break; case OPT_TOGGLE_CHECK: useCheckButtons = !useCheckButtons; break; - case OPT_RESAMPLE: - cerr << "The --" << longopts[longindex].name - << " option has been deprecated and will be removed in a future release\n"; - break; - #if USE_PORTAUDIO case OPT_FRAMES_PER_BUFFER: progdefaults.PortFramesPerBuffer = strtol(optarg, 0, 10); @@ -603,6 +596,13 @@ int parse_args(int argc, char **argv, int& idx) Fl::add_timeout(strtod(optarg, 0), exit_cb); break; + case OPT_DEBUG_LEVEL: + { + int v = strtol(optarg, 0, 10); + debug::level = (debug::level_e)CLAMP(v, 0, debug::_NLEVELS-1); + } + break; + case OPT_HELP: cout << option_help; exit(EXIT_SUCCESS); @@ -719,48 +719,6 @@ void set_platform_ui(void) #endif } -#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__ - // 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. diff --git a/src/mfsk/mfsk.cxx b/src/mfsk/mfsk.cxx index 5350c3e4..7f34fe53 100644 --- a/src/mfsk/mfsk.cxx +++ b/src/mfsk/mfsk.cxx @@ -358,13 +358,15 @@ void mfsk::recvpic(complex z) picf = 0.0; int n = picW * picH * 3; - int s = snprintf(mfskmsg, sizeof(mfskmsg), - "Recv picture: %04.1f%% done", - (100.0f * pixelnbr) / n); - print_time_left( (n - pixelnbr ) * 0.000125 * RXspp , - mfskmsg + s, - sizeof(mfskmsg) - s, ", ", " left"); - put_status(mfskmsg); + if (pixelnbr % (picW * 3) == 0) { + int s = snprintf(mfskmsg, sizeof(mfskmsg), + "Recv picture: %04.1f%% done", + (100.0f * pixelnbr) / n); + print_time_left( (n - pixelnbr ) * 0.000125 * RXspp , + mfskmsg + s, + sizeof(mfskmsg) - s, ", ", " left"); + put_status(mfskmsg); + } } } @@ -929,13 +931,15 @@ int mfsk::tx_process() sendpic( &xmtpicbuff[i], blocklen); else sendpic( &xmtpicbuff[i], xmtbytes - i); + if ( (100 * i / xmtbytes) % 2 == 0) { + int n = snprintf(mfskmsg, sizeof(mfskmsg), + "Send picture: %04.1f%% done", + (100.0f * i) / xmtbytes); + print_time_left((xmtbytes - i) * 0.000125 * TXspp, mfskmsg + n, + sizeof(mfskmsg) - n, ", ", " left"); + put_status(mfskmsg); + } i += blocklen; - int n = snprintf(mfskmsg, sizeof(mfskmsg), - "Send picture: %04.1f%% done", - (100.0f * i) / xmtbytes); - print_time_left((xmtbytes - i) * 0.000125 * TXspp, mfskmsg + n, - sizeof(mfskmsg) - n, ", ", " left"); - put_status(mfskmsg); } REQ_FLUSH(); diff --git a/src/misc/arq_io.cxx b/src/misc/arq_io.cxx index d6c9cfe6..da32a4f5 100644 --- a/src/misc/arq_io.cxx +++ b/src/misc/arq_io.cxx @@ -26,7 +26,6 @@ #include -#include #include #include #include @@ -45,6 +44,7 @@ #include "threads.h" #include "socket.h" +#include "debug.h" #include #include @@ -203,8 +203,7 @@ bool Gmfsk_arqRx() FL_AWAKE(); time(&prog_time); if (prog_time - start_time > TIMEOUT) { - std::cout << "pskmail_out failure" << std::endl; - std::cout.flush(); + LOG_ERROR("pskmail_out failure"); autofile.close(); std::remove (sAutoFile.c_str()); return false; @@ -295,7 +294,7 @@ bool ARQ_SOCKET_Server::start(const char* node, const char* service) errstring.append(e.what()).append(")"); if (e.error() == EADDRINUSE) errstring.append("\nMultiple instances of fldigi??"); - cerr << errstring << "\n"; + LOG_ERROR("%s", errstring.c_str()); fl_message(errstring.c_str()); delete arq_socket_thread; @@ -328,7 +327,7 @@ void* ARQ_SOCKET_Server::thread_func(void*) catch (const SocketException& e) { if (e.error() != ETIMEDOUT) { errstring = e.what(); - cerr << errstring << "\n"; + LOG_ERROR("%s", errstring.c_str()); Fl::add_timeout(0.0, popup_msg, (void*)errstring.c_str()); break; } diff --git a/src/misc/configuration.cxx b/src/misc/configuration.cxx index f964e66a..55e4a46d 100644 --- a/src/misc/configuration.cxx +++ b/src/misc/configuration.cxx @@ -12,6 +12,7 @@ #include "rigMEM.h" //#include "rigio.h" +#include "debug.h" #include #include @@ -354,7 +355,7 @@ void configuration::writeDefaultsXML() ofstream f(deffname.c_str(), ios::out); if (!f) { - cerr << "Could not write " << deffname << '\n'; + LOG_ERROR("Could not write %s", deffname.c_str()); return; } diff --git a/src/misc/debug.cxx b/src/misc/debug.cxx new file mode 100644 index 00000000..99fdca7a --- /dev/null +++ b/src/misc/debug.cxx @@ -0,0 +1,173 @@ +// ---------------------------------------------------------------------------- +// debug.cxx +// +// Copyright (C) 2008 +// Stelios Bounanos, M0GLD +// +// 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 . +// ---------------------------------------------------------------------------- + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include "FTextView.h" + +#include "debug.h" + +using namespace std; + +#define MAX_LINES 65536 + +static FILE* wfile; +static FILE* rfile; +static size_t nlines = 0; +static int rfd; +static bool tty; + +static Fl_Double_Window* window; +static FTextLog* text; + +debug* debug::inst = 0; +debug::level_e debug::level = debug::_WARN; + +const char* prefix[] = { "Quiet", "Error", "Warning", "Info", "Debug" }; + +static void slider_cb(Fl_Widget* w, void*); + +void debug::start(const char* filename) +{ + if (debug::inst) + return; + inst = new debug(filename); + + window = new Fl_Double_Window(512, 256, "Event log"); + window->xclass(PACKAGE_TARNAME); + + int pad = 2; + Fl_Slider* slider = new Fl_Slider(pad, pad, 128, 20, prefix[level]); + slider->tooltip("Change log level"); + slider->align(FL_ALIGN_RIGHT); + slider->type(FL_HOR_NICE_SLIDER); + slider->range(0.0, _NLEVELS - 1); + slider->step(1.0); + slider->value(level); + slider->callback(slider_cb); + + text = new FTextLog(pad, slider->h()+pad, window->w()-2*pad, window->h()-slider->h()-2*pad, 0); + text->textfont(FL_SCREEN); + text->textsize(FL_NORMAL_SIZE); + window->resizable(text); + window->end(); +} + +void debug::stop(void) +{ + delete inst; + inst = 0; + delete window; +} + +static char fmt[1024]; + +void debug::log(level_e level, const char* func, const char* srcf, int line, const char* format, ...) +{ + if (!inst) + return; + + if (unlikely(debug::level == _DEBUG)) { + time_t t = time(NULL); + struct tm stm; + (void)localtime_r(&t, &stm); + snprintf(fmt, sizeof(fmt), "%c: [%02d:%02d:%02d] %s:%d: %s\n", + *prefix[level], stm.tm_hour, stm.tm_min, stm.tm_sec, srcf, line, format); + } + else + snprintf(fmt, sizeof(fmt), "%c: %s: %s\n", *prefix[level], func, format); + va_list args; + va_start(args, format); + vfprintf(wfile, fmt, args); + if (tty && level <= _DEBUG) + vfprintf(stderr, fmt, args); + va_end(args); + + Fl::add_timeout(0.0, sync_text, 0); +} + +void debug::elog(const char* func, const char* srcf, int line, const char* text) +{ + log(_ERROR, func, srcf, line, "%s: %s", strerror(errno)); +} + +void debug::show(void) +{ + window->show(); +} + +static char buf[BUFSIZ+1]; + +void debug::sync_text(void*) +{ + ssize_t n; + while ((n = read(rfd, buf, sizeof(buf) - 1)) > 0) { + buf[n] = '\0'; + text->add(buf); + if (unlikely(++nlines > MAX_LINES)) { + text->clear(); + nlines = 0; + } + } +} + +debug::debug(const char* filename) +{ + if ((wfile = fopen(filename, "w")) == NULL) + throw strerror(errno); + setlinebuf(wfile); + if ((rfile = fopen(filename, "r")) == NULL) + throw strerror(errno); + tty = isatty(fileno(stderr)); + rfd = fileno(rfile); + int f; + if ((f = fcntl(rfd, F_GETFL)) == -1) + throw strerror(errno); + if (fcntl(rfd, F_SETFL, f | O_NONBLOCK) == -1) + throw strerror(errno); +} + +debug::~debug() +{ + fclose(wfile); + fclose(rfile); +} + +static void slider_cb(Fl_Widget* w, void*) +{ + Fl_Slider* s = static_cast(w); + debug::level = (debug::level_e)s->value(); + s->label(prefix[debug::level]); + s->parent()->redraw(); +} diff --git a/src/misc/macros.cxx b/src/misc/macros.cxx index 1855d157..864584d8 100644 --- a/src/misc/macros.cxx +++ b/src/misc/macros.cxx @@ -10,6 +10,7 @@ #include "logger.h" #include "newinstall.h" #include "globals.h" +#include "debug.h" #include #include "fileselect.h" @@ -19,7 +20,6 @@ #include #include #include -#include #include MACROTEXT macros; @@ -440,31 +440,31 @@ void pEXEC(string &s, size_t &i) int pfd[2]; if (pipe(pfd) == -1) { - perror("pipe"); + LOG_PERROR("pipe"); return; } pid_t pid; switch (pid = fork()) { case -1: - perror("fork"); + LOG_PERROR("fork"); return; case 0: // child close(pfd[0]); if (dup2(pfd[1], STDOUT_FILENO) != STDOUT_FILENO) { - perror("dup2"); + LOG_PERROR("dup2"); exit(EXIT_FAILURE); } close(pfd[1]); set_env(); execl("/bin/sh", "sh", "-c", s.substr(start, end-start).c_str(), (char *)NULL); - perror("execl"); + LOG_PERROR("execl"); exit(EXIT_FAILURE); } // parent close(pfd[1]); FILE* fp = fdopen(pfd[0], "r"); if (!fp) { - perror("fdopen"); + LOG_PERROR("fdopen"); close(pfd[0]); return; } @@ -580,7 +580,7 @@ void MACROTEXT::loadDefault() Filename.append("macros.mdf"); if ((erc = loadMacros(Filename)) != 0) #ifndef __CYGWIN__ - printf("Error #%d loading %s\n", erc, Filename.c_str()); + LOG_ERROR("Error #%d loading %s\n", erc, Filename.c_str()); #else ; #endif diff --git a/src/misc/socket.cxx b/src/misc/socket.cxx index b7778330..e665a9f4 100644 --- a/src/misc/socket.cxx +++ b/src/misc/socket.cxx @@ -39,10 +39,7 @@ #include #include -#ifndef NDEBUG -# include -#endif - +#include "debug.h" #include "socket.h" #if HAVE_GETADDRINFO && !defined(AI_NUMERICSERV) @@ -359,7 +356,7 @@ const addr_info_t* Address::get(size_t n) const for (size_t i = 0; i < n; i++) p = p->ai_next; # ifndef NDEBUG - cerr << "found " << inet_ntoa(((struct sockaddr_in*)p->ai_addr)->sin_addr) << endl; + LOG_DEBUG("Found address %s", inet_ntoa(((struct sockaddr_in*)p->ai_addr)->sin_addr)); # endif return p; #else @@ -378,7 +375,7 @@ const addr_info_t* Address::get(size_t n) const addr.ai_addrlen = sizeof(saddr); addr.ai_addr = (struct sockaddr*)&saddr; # ifndef NDEBUG - cerr << "found " << inet_ntoa(((struct sockaddr_in*)addr.ai_addr)->sin_addr) << endl; + LOG_DEBUG("Found address %s", inet_ntoa(((struct sockaddr_in*)addr.ai_addr)->sin_addr)); # endif return &addr; #endif @@ -480,7 +477,7 @@ void Socket::open(const Address& addr) for (anum = 0; anum < n; anum++) { ainfo = address.get(anum); #ifndef NDEBUG - cerr << "trying " << inet_ntoa(((struct sockaddr_in*)ainfo->ai_addr)->sin_addr) << endl; + LOG_DEBUG("trying %s", inet_ntoa(((struct sockaddr_in*)ainfo->ai_addr)->sin_addr)); #endif if ((sockfd = socket(ainfo->ai_family, ainfo->ai_socktype, ainfo->ai_protocol)) != -1) @@ -587,7 +584,7 @@ Socket Socket::accept1(void) void Socket::connect(void) { #ifndef NDEBUG - cerr << "connecting to " << inet_ntoa(((struct sockaddr_in*)ainfo->ai_addr)->sin_addr) << endl; + LOG_DEBUG("connecting to %s", inet_ntoa(((struct sockaddr_in*)ainfo->ai_addr)->sin_addr)); #endif if (::connect(sockfd, ainfo->ai_addr, ainfo->ai_addrlen) == -1) throw SocketException(errno, "connect"); diff --git a/src/misc/xmlrpc.cxx b/src/misc/xmlrpc.cxx index 2618c709..4df74c86 100644 --- a/src/misc/xmlrpc.cxx +++ b/src/misc/xmlrpc.cxx @@ -24,7 +24,6 @@ #include "xmlrpc.h" -#include #include #include #include @@ -54,6 +53,7 @@ #endif #include "rigMEM.h" #include "rigio.h" +#include "debug.h" using namespace std; @@ -99,7 +99,7 @@ void XML_RPC_Server::start(const char* node, const char* service) inst->server_socket->open(Address(node, service)); } catch (const SocketException& e) { - cerr << "Could not start XML-RPC server (" << e.what() << ")\n"; + LOG_ERROR("Could not start XML-RPC server (%s)", e.what()); return; } @@ -137,7 +137,7 @@ void* XML_RPC_Server::thread_func(void*) inst->server_socket->set_nonblocking(); } catch (const SocketException& e) { - cerr << "Could not start XML-RPC server (" << e.what() << ")\n"; + LOG_ERROR("Could not start XML-RPC server (%s)", e.what()); goto ret; } @@ -148,7 +148,7 @@ void* XML_RPC_Server::thread_func(void*) } catch (const SocketException& e) { if (e.error() != ETIMEDOUT) { - cerr << e.what() << '\n'; + LOG_ERROR("%s", e.what()); break; } } diff --git a/src/rigcontrol/hamlib.cxx b/src/rigcontrol/hamlib.cxx index ee9ab944..3d44d86c 100644 --- a/src/rigcontrol/hamlib.cxx +++ b/src/rigcontrol/hamlib.cxx @@ -27,6 +27,7 @@ #include "stacktrace.h" #include "re.h" +#include "debug.h" using namespace std; @@ -53,13 +54,13 @@ static int dummy = 0; static void *hamlib_loop(void *args); -void show_error(const char * a, const char * b) +void show_error(const char* msg1, const char* msg2 = 0) { - string msg = a; - msg.append(": "); - msg.append(b); - put_status(msg.c_str(), 10.0); - cerr << msg.c_str() << '\n'; + string error = msg1; + if (msg2) + error.append(": ").append(msg2); + put_status(error.c_str(), 10.0); + LOG_ERROR("%s", error.c_str()); } /* FIXME: remove this function @@ -71,7 +72,7 @@ bool hamlib_setRTSDTR() int hamlibfd = open(progdefaults.HamRigDevice.c_str(), O_RDWR | O_NOCTTY | O_NDELAY); if (hamlibfd < 0) { - show_error("Cannot open PTT device ", progdefaults.HamRigDevice.c_str()); + show_error("Cannot open PTT device", progdefaults.HamRigDevice.c_str()); return false; } @@ -163,7 +164,7 @@ bool hamlib_init(bool bPtt) xcvr->open(); } catch (const RigException& Ex) { - show_error("hamlib_init", Ex.what()); + show_error(__func__, Ex.what()); xcvr->close(); return false; } @@ -172,16 +173,17 @@ bool hamlib_init(bool bPtt) // return -1; MilliSleep(200); -//char temp[80]; -//xcvr->getConf("dtr_state", temp); -//cerr << "Hamlib DTR " << temp << '\n'; + + // char temp[80]; + // xcvr->getConf("dtr_state", temp); + // LOG_DEBUG("Hamlib DTR = %s", temp); try { need_freq = true; freq = xcvr->getFreq(); if (freq == 0) { xcvr->close(); - show_error("Transceiver not responding", ""); + show_error(__func__, "transceiver not responding"); return false; } } @@ -215,7 +217,7 @@ bool hamlib_init(bool bPtt) hamlib_rmode = RIG_MODE_NONE;//RIG_MODE_USB; if (fl_create_thread(hamlib_thread, hamlib_loop, &dummy) < 0) { - cerr << "Hamlib init: pthread_create failed\n"; + show_error(__func__, "pthread_create failed"); xcvr->close(); return false; } @@ -238,7 +240,7 @@ void hamlib_close(void) // cerr << "." << flush; MilliSleep(50); if (!count--) { - cerr << "Hamlib stuck, transceiver on fire\n"; + show_error(__func__, "Hamlib stuck, transceiver on fire"); xcvr->close(); diediedie(); } @@ -303,7 +305,7 @@ int hamlib_setfreq(long f) wf->rfcarrier(f);//(hamlib_freq); } catch (const RigException& Ex) { - show_error("SetFreq", Ex.what()); + show_error("SetFreq", Ex.what()); hamlib_passes = 0; } fl_unlock(&hamlib_mutex); @@ -321,7 +323,7 @@ int hamlib_setmode(rmode_t m) hamlib_rmode = m; } catch (const RigException& Ex) { - show_error("Set Mode", Ex.what()); + show_error("Set Mode", Ex.what()); hamlib_passes = 0; } fl_unlock(&hamlib_mutex); @@ -386,7 +388,7 @@ static void *hamlib_loop(void *args) } } catch (const RigException& Ex) { - show_error("No transceiver comms", ""); + show_error(__func__, "No transceiver comms"); freqok = false; hamlib_exit = true; } @@ -400,7 +402,7 @@ static void *hamlib_loop(void *args) modeok = true; } catch (const RigException& Ex) { - show_error("No transceiver comms", ""); + show_error(__func__, "No transceiver comms"); modeok = false; hamlib_exit = true; } diff --git a/src/rigcontrol/rigMEM.cxx b/src/rigcontrol/rigMEM.cxx index 79f803b5..ce0d8cf2 100644 --- a/src/rigcontrol/rigMEM.cxx +++ b/src/rigcontrol/rigMEM.cxx @@ -22,6 +22,7 @@ #include "rigMEM.h" #include "fl_digi.h" #include "main.h" +#include "debug.h" /* ---------------------------------------------------------------------- */ @@ -234,7 +235,7 @@ void rigMEM_close(void) // and then wait for it to die fl_join(rigMEM_thread); -//std::cout <<"rigMEM down\n"; fflush(stdout); + LOG_DEBUG("rigMEM down"); rigMEM_enabled = false; rigMEM_exit = false; diff --git a/src/rigcontrol/rigio.cxx b/src/rigcontrol/rigio.cxx index f7a3e83d..0e679621 100644 --- a/src/rigcontrol/rigio.cxx +++ b/src/rigcontrol/rigio.cxx @@ -7,9 +7,15 @@ #include -#include - #include +#include +#include +#include +#include +#include +#include +#include +#include #ifdef RIGCATTEST #include "rigCAT.h" @@ -24,42 +30,12 @@ #include "rigxml.h" #include "serial.h" #include "rigio.h" - +#include "debug.h" #include "threads.h" -#include -#include -#include - -#include "qrunner.h" - -Fl_Double_Window *wDebug = 0; -FTextView *txtDebug = 0; - -string sdebug; -char szDebug[200]; - -void showDebug() { - if (wDebug == 0) { - wDebug = new Fl_Double_Window(0, 0, 400, 400,"Debug Window"); - txtDebug = new FTextView( 2, 2, 396, 396 ); - } - wDebug->show(); -} - -void printDebug(string s) { - if (RIGIO_DEBUG == true) { - if (wDebug == 0) showDebug(); - if (!wDebug->visible()) wDebug->show(); - int style = FTextBase::RECV; - for (size_t i = 0; i < s.length(); i++) - REQ(&FTextView::addchr, txtDebug, s[i], style); -// std::cout << s << flush; - } -} - using namespace std; + Cserial rigio; static Fl_Mutex rigCAT_mutex = PTHREAD_MUTEX_INITIALIZER; static Fl_Thread rigCAT_thread; @@ -78,63 +54,47 @@ static int dummy = 0; static void *rigCAT_loop(void *args); -void printhex(string s) -{ - char szhex[4]; - sdebug.clear(); - for (size_t i = 0; i < s.length(); i++) { - snprintf(szhex, sizeof(szhex), "%02X ", s[i] & 0xFF); - sdebug.append(szhex); - } - sdebug.append("\n"); - printDebug(sdebug); -} +static const char hexsym[] = "0123456789ABCDEF"; -void printhex(unsigned char *s, size_t len) +const string& printhex(const unsigned char* s, size_t len) { - char szhex[4]; - sdebug.clear(); - for (size_t i = 0; i < len; i++) { - snprintf(szhex, sizeof(szhex), "%02X ", s[i] & 0xFF); - sdebug.append(szhex); + static string hex; + hex.clear(); + hex.resize(len * 3 - 1); + string::iterator i = hex.begin(); + size_t j; + for (j = 0; j < len-1; j++) { + *i++ = hexsym[s[j] >> 4]; + *i++ = hexsym[s[j] & 0xF]; + *i++ = ' '; } - sdebug.append("\n"); - printDebug(sdebug); -} + *i++ = hexsym[s[j] >> 4]; + *i = hexsym[s[j] & 0xF]; -char * printtime() + return hex; +} +const string& printhex(const string& s) { - time_t t; - time(&t); - tm *now = gmtime(&t); - static char sztime[80]; - strftime(sztime, 79, "[%H:%M:%S]\n", now); - return sztime; + return printhex((const unsigned char*)s.data(), s.length()); } bool readpending = false; int readtimeout; -bool hexout( string s, int retnbr) +bool hexout(const string& s, int retnbr) { // thread might call this function while a read from the rig is in process // wait here until that processing is finished or a timeout occurs // reset the readpending & return false if a timeout occurs -// debug code - printDebug(printtime()); - sdebug.clear(); - sdebug.append("Cmd: "); - printDebug(sdebug); - printhex(s); + LOG_DEBUG("cmd = %s", printhex(s).c_str()); readtimeout = (rig.wait +rig.timeout) * rig.retries + 2000; // 2 second min timeout while (readpending && readtimeout--) MilliSleep(1); if (readtimeout == 0) { readpending = false; - strcpy(szDebug, "rigio timeout!\n"); - printDebug(szDebug); + LOG_ERROR("rigio timeout!"); return false; } @@ -153,11 +113,7 @@ bool hexout( string s, int retnbr) MilliSleep(10); //#endif num = rigio.ReadBuffer (replybuff, s.size()); - - sdebug.clear(); - sdebug.append("echoed: "); - printDebug(sdebug); - printhex(replybuff, num); + LOG_DEBUG("echoed = %s", printhex(replybuff, num).c_str()); } memset (replybuff, 0, 200); @@ -167,25 +123,16 @@ bool hexout( string s, int retnbr) while (readtimeout--) MilliSleep(1); - sdebug.clear(); - snprintf(szDebug, sizeof(szDebug), "Reading %d\n", retnbr); - printDebug(szDebug); + LOG_DEBUG("reading %d", retnbr); if (retnbr > 0) { num = rigio.ReadBuffer (replybuff, retnbr > 200 ? 200 : retnbr); // debug code - if (num) { - sdebug.clear(); - snprintf(szDebug, sizeof(szDebug), "Resp (%d)", n); - std::cout << szDebug << flush; - printDebug(szDebug); - printhex(replybuff, num); - } else { - sdebug.clear(); - snprintf(szDebug, sizeof(szDebug), "Resp (%d) noreply\n", n); - printDebug(szDebug); - } + if (num) + LOG_DEBUG("resp (%d) = %s", n, printhex(replybuff, num).c_str()); + else + LOG_ERROR("resp (%d) no reply", n); } if (retnbr == 0 || num == retnbr) { @@ -401,7 +348,7 @@ long long rigCAT_getfreq() list::iterator itrCmd; string strCmd; -printDebug("get frequency\n"); + LOG_DEBUG("get frequency"); itrCmd = commands.begin(); while (itrCmd != commands.end()) { @@ -481,7 +428,7 @@ void rigCAT_setfreq(long long f) list::iterator itrCmd; string strCmd; -printDebug("set frequency\n"); + LOG_DEBUG("set frequency"); itrCmd = commands.begin(); while (itrCmd != commands.end()) { @@ -527,7 +474,7 @@ string rigCAT_getmode() list::iterator itrCmd; string strCmd; -printDebug("get mode\n"); + LOG_DEBUG("get mode"); itrCmd = commands.begin(); while (itrCmd != commands.end()) { @@ -617,13 +564,13 @@ printDebug("get mode\n"); return ""; } -void rigCAT_setmode(string md) +void rigCAT_setmode(const string& md) { XMLIOS modeCmd; list::iterator itrCmd; string strCmd; -printDebug("set mode\n"); + LOG_DEBUG("set mode"); itrCmd = commands.begin(); while (itrCmd != commands.end()) { @@ -685,7 +632,7 @@ string rigCAT_getwidth() list::iterator itrCmd; string strCmd; -printDebug("get width\n"); + LOG_DEBUG("get width"); itrCmd = commands.begin(); while (itrCmd != commands.end()) { @@ -775,13 +722,13 @@ printDebug("get width\n"); return ""; } -void rigCAT_setwidth(string w) +void rigCAT_setwidth(const string& w) { XMLIOS modeCmd; list::iterator itrCmd; string strCmd; -printDebug("set width\n"); + LOG_DEBUG("set width"); itrCmd = commands.begin(); while (itrCmd != commands.end()) { @@ -844,7 +791,7 @@ void rigCAT_pttON() list::iterator itrCmd; string strCmd; -printDebug("ptt ON\n"); + LOG_DEBUG("ptt ON"); rigio.SetPTT(1); // always execute the h/w ptt if enabled @@ -886,7 +833,7 @@ void rigCAT_pttOFF() list::iterator itrCmd; string strCmd; -printDebug("ptt OFF\n"); + LOG_DEBUG("ptt OFF"); rigio.SetPTT(0); // always execute the h/w ptt if enabled @@ -927,7 +874,7 @@ void rigCAT_sendINIT() list::iterator itrCmd; string strCmd; -printDebug("INIT rig\n"); + LOG_DEBUG("INIT rig"); itrCmd = commands.begin(); while (itrCmd != commands.end()) { @@ -967,30 +914,20 @@ printDebug("INIT rig\n"); // fl_unlock(&rigCAT_mutex); } -unused__ static void show_error(const char * a, const char * b) -{ - string msg = a; - msg.append(": "); - msg.append(b); - std::cout << msg << std::endl; -} - bool rigCAT_init() { if (rigCAT_open == true) { - printDebug("RigCAT already open file present\n"); + LOG_ERROR("RigCAT already open file present"); return false; } if (readRigXML() == false) { - printDebug("No rig.xml file present\n"); + LOG_ERROR("No rig.xml file present"); return false; } if (rigio.OpenPort() == false) { - printDebug("Cannot open serial port "); - printDebug(rigio.Device().c_str()); - printDebug("\n"); + LOG_ERROR("Cannot open serial port %s", rigio.Device().c_str()); return false; } llFreq = 0; @@ -998,7 +935,7 @@ bool rigCAT_init() sRigWidth = ""; if (rigCAT_getfreq() <= 0) { - printDebug("Transceiver not responding\n"); + LOG_ERROR("Transceiver not responding"); rigio.ClosePort(); return false; } @@ -1006,7 +943,7 @@ bool rigCAT_init() rigCAT_sendINIT(); if (fl_create_thread(rigCAT_thread, rigCAT_loop, &dummy) < 0) { - printDebug("rig init: pthread_create failed"); + LOG_ERROR("pthread_create failed"); rigio.ClosePort(); return false; } @@ -1031,10 +968,10 @@ void rigCAT_close(void) MilliSleep(50); count--; if (!count) { - printDebug("RigCAT stuck\n"); - fl_lock(&rigCAT_mutex); + LOG_ERROR("RigCAT stuck"); + fl_lock(&rigCAT_mutex); rigio.ClosePort(); - fl_unlock(&rigCAT_mutex); + fl_unlock(&rigCAT_mutex); exit(0); } } @@ -1079,7 +1016,7 @@ void rigCAT_set_qsy(long long f, long long fmid) } #endif -bool ModeIsLSB(string s) +bool ModeIsLSB(const string& s) { list::iterator pM = LSBmodes.begin(); while (pM != LSBmodes.end() ) { diff --git a/src/rigcontrol/rigxml.cxx b/src/rigcontrol/rigxml.cxx index 2344d8d1..feb4b18f 100644 --- a/src/rigcontrol/rigxml.cxx +++ b/src/rigcontrol/rigxml.cxx @@ -10,7 +10,6 @@ #include -#include #include #include "rigio.h" @@ -21,6 +20,7 @@ #else #include "main.h" #endif +#include "debug.h" //#define DEBUGXML @@ -170,10 +170,9 @@ TAGS datatags[] = { void print(size_t &p0, int indent) { #ifdef DEBUGXML + std::string istr(indent, '\t'); size_t tend = strXML.find(">", p0); - for (int i = 0; i < indent; i++) - std::cout << "\t"; - std::cout << strXML.substr(p0, tend - p0 + 1).c_str() << std::endl; + LOG_DEBUG("%s%s", istr.c_str(), strXML.substr(p0, tend - p0 + 1).c_str()); #endif } @@ -590,15 +589,13 @@ void parsePORT(size_t &p0) } p0 = pend; #ifdef DEBUGXML - std::cout << "port: " << rig.port.c_str() << std::endl; - std::cout << "baud: " << rig.baud << std::endl; - std::cout << "retries: " << rig.retries << std::endl; - std::cout << "timeout: " << rig.timeout << std::endl; - std::cout << "initial rts: " << (rig.rts ? "+12" : "-12") << std::endl; - std::cout << "use rts ptt: " << (rig.rtsptt ? "T" : "F") << std::endl; - std::cout << "initial dts: " << (rig.dtr ? "+12" : "-12") << std::endl; - std::cout << "use dtr ptt: " << (rig.dtrptt ? "T" : "F") << std::endl; - std::cout << "use flowcontrol: " << (rig.rtscts ? "T" : "F") << std :: endl; + LOG_DEBUG("port: %s\n" "baud: %d\n" "retries: %d\n" "timeout: %d\n", "initial rts: %+d\n" + "use rts ptt: %c\n" "initial dts: %+d\n" "use dtr ptt: %c\n" + "use flowcontrol: %c", + rig.port.c_str(), rig.baud, rig.retries, rig.timeout, (rig.rts ? +12 : -12), + (rig.rtsptt ? 'T' : 'F'), (rig.dtr ? +12 : -12), (rig.dtrptt ? 'T' : 'F'), + (rig.rtscts ? 'T' : 'F')); + #endif } diff --git a/src/soundcard/mixer.cxx b/src/soundcard/mixer.cxx index cab7f1fa..7b776ed4 100644 --- a/src/soundcard/mixer.cxx +++ b/src/soundcard/mixer.cxx @@ -42,12 +42,12 @@ #endif #include -#include #include #include #include "mixer.h" #include "configuration.h" +#include "debug.h" #if USE_OSS @@ -109,17 +109,12 @@ void MixerOSS::initValues() pcmlevel0 = PCMVolume(); vollevel0 = OutVolume(); -/* - std::cout << "Sound card initial state:" << std::endl; - std::cout << " Dev mask " << hex << devmask << std::endl; - std::cout << " Rec mask " << hex << recmask << std::endl; - std::cout << " Rec src " << hex << recsrc << std::endl; - std::cout << " Current input source # " << GetInputSourceName(inpsrc0) << std::endl; - std::cout << " Line Level = " << linelevel0 << std::endl; - std::cout << " Mic Level = " << miclevel0 << std::endl; - std::cout << " Pcm Level = " << pcmlevel0 << std::endl; - std::cout << " Vol Level = " << vollevel0 << std::endl; -*/ + + LOG_DEBUG("Sound mixer initial state:\n" "Dev mask: %02x\n" + "Rec mask: %02x\n" "Rec src: %02x\n" "Current input source #: %s\n" + "Line level: %d\n" "Mic level: %d\n" "Pcm level: %d\n" "Vol level: %d\n", + devmask, recmask, recsrc, GetInputSourceName(inpsrc0), + linelevel0, miclevel0, pcmlevel0, vollevel0); } void MixerOSS::restoreValues() diff --git a/src/soundcard/sound.cxx b/src/soundcard/sound.cxx index 9c6fa787..b57adf82 100644 --- a/src/soundcard/sound.cxx +++ b/src/soundcard/sound.cxx @@ -27,7 +27,6 @@ #include -#include #include #include #include @@ -64,6 +63,7 @@ #include "threads.h" #include "timeops.h" #include "ringbuffer.h" +#include "debug.h" // Define these constants here to avoid littering the code with magic numbers. // Audio input is mono in SoundPort and SoundPulse, stereo in SoundOSS @@ -146,7 +146,7 @@ int SoundBase::Capture(bool val) if (ofCapture) { int err; if ((err = sf_close(ofCapture)) != 0) - cerr << "sf_close error: " << sf_error_number(err) << '\n'; + LOG_ERROR("sf_close error: %s", sf_error_number(err)); ofCapture = 0; } capture = false; @@ -162,11 +162,11 @@ int SoundBase::Capture(bool val) // frames (ignored), freq, channels, format, sections (ignored), seekable (ignored) SF_INFO info = { 0, sample_frequency, SNDFILE_CHANNELS, format, 0, 0 }; if ((ofCapture = sf_open(fname, SFM_WRITE, &info)) == NULL) { - cerr << "Could not write " << fname << '\n'; + LOG_ERROR("Could not write %s", fname); return 0; } if (sf_command(ofCapture, SFC_SET_UPDATE_HEADER_AUTO, NULL, SF_TRUE) != SF_TRUE) - cerr << "ofCapture update header command failed: " << sf_strerror(ofCapture) << '\n'; + LOG_ERROR("ofCapture update header command failed: %s", sf_strerror(ofCapture)); tag_file(ofCapture, "Captured audio"); capture = true; @@ -179,7 +179,7 @@ int SoundBase::Playback(bool val) if (ifPlayback) { int err; if ((err = sf_close(ifPlayback)) != 0) - cerr << "sf_close error: " << sf_error_number(err) << '\n'; + LOG_ERROR("sf_close error: %s", sf_error_number(err)); ifPlayback = 0; } playback = false; @@ -193,7 +193,7 @@ int SoundBase::Playback(bool val) SF_INFO info = { 0, 0, 0, 0, 0, 0 }; if ((ifPlayback = sf_open(fname, SFM_READ, &info)) == NULL) { - cerr << "Could not read " << fname << '\n'; + LOG_ERROR("Could not read %s", fname); return 0; } @@ -207,7 +207,7 @@ int SoundBase::Generate(bool val) if (ofGenerate) { int err; if ((err = sf_close(ofGenerate)) != 0) - cerr << "sf_close error: " << sf_error_number(err) << '\n'; + LOG_ERROR("sf_close error: %s", sf_error_number(err)); ofGenerate = 0; } generate = false; @@ -223,11 +223,11 @@ int SoundBase::Generate(bool val) // frames (ignored), freq, channels, format, sections (ignored), seekable (ignored) SF_INFO info = { 0, sample_frequency, SNDFILE_CHANNELS, format, 0, 0 }; if ((ofGenerate = sf_open(fname, SFM_WRITE, &info)) == NULL) { - cerr << "Could not write " << fname << '\n'; + LOG_ERROR("Could not write %s", fname); return 0; } if (sf_command(ofGenerate, SFC_SET_UPDATE_HEADER_AUTO, NULL, SF_TRUE) != SF_TRUE) - cerr << "ofGenerate update header command failed: " << sf_strerror(ofGenerate) << '\n'; + LOG_ERROR("ofGenerate update header command failed: %s", sf_strerror(ofGenerate)); tag_file(ofGenerate, "Generated audio"); generate = true; @@ -264,7 +264,7 @@ void SoundBase::tag_file(SNDFILE *sndfile, const char *title) { int err; if ((err = sf_set_string(sndfile, SF_STR_TITLE, title)) != 0) { - cerr << "sf_set_string STR_TITLE: " << sf_error_number(err) << '\n'; + LOG_ERROR("sf_set_string STR_TITLE: %s", sf_error_number(err)); return; } @@ -297,10 +297,8 @@ SoundOSS::SoundOSS(const char *dev ) { getFormats(); Close(); } - catch (SndException e) { - std::cout << e.what() - << " <" << device.c_str() - << ">" << std::endl; + catch (const SndException& e) { + LOG_ERROR("device %s error: %s", device.c_str(), e.what()); } int err; @@ -310,7 +308,7 @@ SoundOSS::SoundOSS(const char *dev ) { cbuff = new unsigned char [4 * SND_BUF_LEN]; } catch (const std::bad_alloc& e) { - cerr << "Cannot allocate libsamplerate buffers\n"; + LOG_ERROR("Cannot allocate libsamplerate buffers"); throw; } for (int i = 0; i < 2*SND_BUF_LEN; i++) @@ -323,7 +321,7 @@ SoundOSS::SoundOSS(const char *dev ) { rx_src_data = new SRC_DATA; } catch (const std::bad_alloc& e) { - cerr << "Cannot create libsamplerate data structures\n"; + LOG_ERROR("Cannot create libsamplerate data structures"); throw; } @@ -782,7 +780,7 @@ SoundPort::SoundPort(const char *in_dev, const char *out_dev) tx_src_data = new SRC_DATA; } catch (const std::bad_alloc& e) { - cerr << "Cannot create libsamplerate data structures\n"; + LOG_ERROR("Cannot create libsamplerate data structures"); throw; } @@ -791,7 +789,7 @@ SoundPort::SoundPort(const char *in_dev, const char *out_dev) fbuf = new float[OUTPUT_CHANNELS * SND_BUF_LEN]; } catch (const std::bad_alloc& e) { - cerr << "Cannot allocate libsamplerate buffers\n"; + LOG_ERROR("Cannot allocate libsamplerate buffers"); throw; } @@ -807,10 +805,10 @@ SoundPort::~SoundPort() for (size_t i = 0; i < sizeof(sems)/sizeof(*sems); i++) { #if USE_NAMED_SEMAPHORES if (sem_close(sems[i]) == -1) - perror("sem_close"); + LOG_PERROR("sem_close"); #else if (sem_destroy(sems[i]) == -1) - perror("sem_destroy"); + LOG_PERROR("sem_destroy"); delete sems[i]; #endif } @@ -872,7 +870,7 @@ void SoundPort::pause_stream(unsigned dir) pthread_mutex_lock(sd[dir].cmutex); sd[dir].state = spa_pause; if (pthread_cond_timedwait_rel(sd[dir].ccond, sd[dir].cmutex, 5.0) == -1 && errno == ETIMEDOUT) - cerr << __func__ << ": stream " << dir << " wedged\n"; + LOG_ERROR("stream %u wedged", dir); pthread_mutex_unlock(sd[dir].cmutex); } @@ -897,7 +895,7 @@ void SoundPort::Close(unsigned dir) // been stopped if (pthread_cond_timedwait_rel(sd[i].ccond, sd[i].cmutex, 5.0) == -1 && errno == ETIMEDOUT) - cerr << __func__ << ": stream " << i << " wedged\n"; + LOG_ERROR("stream %u wedged", i); pthread_mutex_unlock(sd[i].cmutex); sd[i].state = spa_continue; @@ -940,7 +938,7 @@ void SoundPort::Abort(unsigned dir) } \ else if (errno == EINTR) \ continue; \ - perror("sem_timedwait"); \ + LOG_PERROR("sem_timedwait"); \ throw SndException(errno); \ } \ } \ @@ -1137,7 +1135,7 @@ void SoundPort::flush(unsigned dir) sd[i].state = spa_drain; if (pthread_cond_timedwait_rel(sd[i].ccond, sd[i].cmutex, 5.0) == -1 && errno == ETIMEDOUT) - cerr << __func__ << ": stream " << dir << " wedged\n"; + LOG_ERROR("stream %u wedged", i); pthread_mutex_unlock(sd[i].cmutex); sd[i].state = spa_continue; } @@ -1172,17 +1170,13 @@ void SoundPort::src_data_reset(unsigned dir) MIN(req_sample_rate, sd[dir].dev_sample_rate))); if (dir == 0) { rbsize = 2 * MAX(rbsize, 4096); -#ifndef NDEBUG - cerr << "input rbsize=" << rbsize << endl; -#endif + LOG_DEBUG("input rbsize=%zu", rbsize); } else if (dir == 1) { if (req_sample_rate > 8000) rbsize *= 2; rbsize = MAX(rbsize, 2048); -#ifndef NDEBUG - cerr << "output rbsize=" << rbsize << endl; -#endif + LOG_DEBUG("output rbsize=%zu", rbsize); } if (!sd[dir].rb || sd[dir].rb->length() != rbsize) { delete sd[dir].rb; @@ -1224,9 +1218,8 @@ void SoundPort::init_stream(unsigned dir) PaDeviceIndex conf_idx[2] = { progdefaults.PortInIndex, progdefaults.PortOutIndex }; PaDeviceIndex idx = paNoDevice; -#ifndef NDEBUG - cerr << "PA_debug: looking for \"" << sd[dir].device << "\"\n"; -#endif + LOG_DEBUG("looking for device \"%s\"", sd[dir].device.c_str()); + for (sd[dir].idev = devs.begin(); sd[dir].idev != devs.end(); ++sd[dir].idev) { if (sd[dir].device == (*sd[dir].idev)->name) { idx = sd[dir].idev - devs.begin(); // save this device index @@ -1235,8 +1228,8 @@ void SoundPort::init_stream(unsigned dir) } } if (idx == paNoDevice) { // no match - cerr << "PA_debug: could not find \"" << sd[dir].device - << "\", using default " << dir_str[dir] << " device\n"; + LOG_WARN("Could not find device \"%s\", using default device \"%s\"", + sd[dir].device.c_str(), dir_str[dir]); PaDeviceIndex def = (dir == 0 ? Pa_GetDefaultInputDevice() : Pa_GetDefaultOutputDevice()); if (def == paNoDevice) throw SndPortException(paDeviceUnavailable); @@ -1300,20 +1293,18 @@ void SoundPort::init_stream(unsigned dir) << "\ndefault low output latency: " << (*sd[dir].idev)->defaultLowOutputLatency << "\ndefault high output latency: " << (*sd[dir].idev)->defaultHighOutputLatency << "\n"; -#ifndef NDEBUG - cerr << "PA_debug: using " << dir_str[dir] << " device:\n" << device_text[dir].str(); -#endif + + LOG_DEBUG("using device \"%s\":\n%s", dir_str[dir], device_text[dir].str().c_str()); sd[dir].dev_sample_rate = find_srate(dir); -#ifndef NDEBUG if (sd[dir].dev_sample_rate != req_sample_rate) - cerr << "PA_debug: " << dir_str[dir] << ": resampling " - << sd[dir].dev_sample_rate << " <-> " << req_sample_rate << "\n\n"; -#endif + LOG_DEBUG("%s: resampling %f <=> %f", dir_str[dir], + sd[dir].dev_sample_rate, req_sample_rate); if (progdefaults.PortFramesPerBuffer > 0) sd[dir].frames_per_buffer = progdefaults.PortFramesPerBuffer; + LOG_DEBUG("%s: frames_per_buffer=%u", dir_str[dir], sd[dir].frames_per_buffer); } void SoundPort::start_stream(unsigned dir) @@ -1358,7 +1349,7 @@ int SoundPort::stream_process(const void* in, void* out, unsigned long nframes, }; for (size_t i = 0; i < sizeof(fa)/sizeof(*fa); i++) if (flags & fa[i].f) - cerr << "stream_process: " << fa[i].s << '\n'; + LOG_DEBUG("%s", fa[i].s); #endif if (unlikely(sd->state == spa_abort || sd->state == spa_complete)) // finished @@ -1485,23 +1476,22 @@ void SoundPort::probe_supported_rates(const device_iterator& idev) void SoundPort::pa_perror(int err, const char* str) { if (str) - cerr << str << ": " << Pa_GetErrorText(err) << '\n'; + LOG_ERROR("%s: %s", str, Pa_GetErrorText(err)); if (err == paUnanticipatedHostError) { const PaHostErrorInfo* hosterr = Pa_GetLastHostErrorInfo(); PaHostApiIndex i = Pa_HostApiTypeIdToHostApiIndex(hosterr->hostApiType); if (i < 0) { // PA failed without setting its "last host error" info. Sigh... - cerr << "Host API error info not available\n"; + LOG_ERROR("Host API error info not available"); if ( ((sd[0].stream && Pa_GetHostApiInfo((*sd[0].idev)->hostApi)->type == paOSS) || (sd[1].stream && Pa_GetHostApiInfo((*sd[1].idev)->hostApi)->type == paOSS)) && errno ) - cerr << "Possible OSS error " << errno << ": " - << strerror(errno) << '\n'; + LOG_ERROR("Possible OSS error %d: %s", errno, strerror(errno)); } else - cerr << Pa_GetHostApiInfo(i)->name << " error " - << hosterr->errorCode << ": " << hosterr->errorText << '\n'; + LOG_ERROR("%s error %d: %s", Pa_GetHostApiInfo(i)->name, + hosterr->errorCode, hosterr->errorText); } } @@ -1519,7 +1509,7 @@ void SoundPort::init_hostapi_ext(void) set_jack_client_name(PACKAGE_TARNAME); # ifndef NDEBUG else - cerr << "dlsym(PaJack_SetClientName) error: " << err << '\n'; + LOG_INFO("dlsym(PaJack_SetClientName) error: %s", err); # endif #endif } @@ -1542,7 +1532,7 @@ SoundPulse::SoundPulse(const char *dev) tx_src_data = new SRC_DATA; } catch (const std::bad_alloc& e) { - cerr << "Cannot create libsamplerate data structures\n"; + LOG_ERROR("Cannot create libsamplerate data structures"); throw; } @@ -1552,7 +1542,7 @@ SoundPulse::SoundPulse(const char *dev) fbuf = new float[MAX(INPUT_CHANNELS, OUTPUT_CHANNELS) * SND_BUF_LEN]; } catch (const std::bad_alloc& e) { - cerr << "Cannot allocate libsamplerate buffers\n"; + LOG_ERROR("Cannot allocate libsamplerate buffers"); throw; } } @@ -1642,7 +1632,7 @@ void SoundPulse::flush(unsigned dir) continue; pa_simple_drain(sd[i].stream, &err); if (err != PA_OK) - cerr << pa_strerror(err) << '\n'; + LOG_ERROR("%s", pa_strerror(err)); } } @@ -1709,7 +1699,7 @@ long SoundPulse::src_read_cb(void* arg, float** data) int err; if (pa_simple_read(p->sd[0].stream, p->snd_buffer, sizeof(float) * p->sd[0].blocksize, &err) == -1) { - cerr << "SoundPulse::pa_simple_read error: " << pa_strerror(err) << '\n'; + LOG_ERROR("%s", pa_strerror(err)); *data = 0; return 0; } diff --git a/src/soundcard/soundconf.cxx b/src/soundcard/soundconf.cxx index d29c7835..f07d82eb 100644 --- a/src/soundcard/soundconf.cxx +++ b/src/soundcard/soundconf.cxx @@ -13,6 +13,7 @@ #include "main.h" #include "configuration.h" #include "confdialog.h" +#include "debug.h" using namespace std; @@ -77,7 +78,7 @@ static void init_portaudio(void) SoundPort::initialize(); } catch (const SndPortException& e) { - cerr << e.what() << endl; + LOG_ERROR("%s", e.what()); AudioPort->deactivate(); btnAudioIO[SND_IDX_PORT]->deactivate(); progdefaults.btnAudioIOis = SND_IDX_NULL; diff --git a/src/trx/modem.cxx b/src/trx/modem.cxx index 67240530..c5e3af54 100644 --- a/src/trx/modem.cxx +++ b/src/trx/modem.cxx @@ -12,6 +12,7 @@ #include "qrunner.h" #include "status.h" +#include "debug.h" modem *cw_modem = 0; @@ -234,7 +235,7 @@ void modem::ModulateXmtr(double *buffer, int len) throw SndException("Sound write failed"); } catch (const SndException& e) { - cerr << e.what() << '\n'; + LOG_ERROR("%s", e.what()); return; } @@ -260,7 +261,7 @@ void modem::ModulateStereo(double *left, double *right, int len) throw SndException("Sound write failed"); } catch (const SndException& e) { - cerr << e.what() << '\n'; + LOG_ERROR("%s", e.what()); return; } diff --git a/src/trx/trx.cxx b/src/trx/trx.cxx index f7536a44..aa1d3763 100644 --- a/src/trx/trx.cxx +++ b/src/trx/trx.cxx @@ -43,6 +43,7 @@ #include "soundconf.h" #include "ringbuffer.h" #include "qrunner.h" +#include "debug.h" using namespace std; @@ -102,6 +103,7 @@ void trx_trx_receive_loop() REQ(sound_update, progdefaults.btnAudioIOis); } catch (const SndException& e) { + LOG_ERROR("%s", e.what()); put_status(e.what(), 5); scard->Close(); if (e.error() == EBUSY && progdefaults.btnAudioIOis == SND_IDX_PORT) { @@ -121,6 +123,7 @@ void trx_trx_receive_loop() scard->Open(O_RDONLY, current_samplerate); } catch (const SndException& e) { + LOG_ERROR("%s", e.what()); put_status(e.what(), 5); scard->Close(); if (e.error() == EBUSY && progdefaults.btnAudioIOis == SND_IDX_PORT) { @@ -139,6 +142,7 @@ void trx_trx_receive_loop() scard->Open(O_RDONLY, current_samplerate); } catch (const SndException& e) { + LOG_ERROR("%s", e.what()); put_status(e.what(), 5); scard->Close(); if (e.error() == EBUSY && progdefaults.btnAudioIOis == SND_IDX_PORT) { @@ -165,6 +169,7 @@ void trx_trx_receive_loop() } catch (const SndException& e) { scard->Close(); + LOG_ERROR("%s", e.what()); put_status(e.what(), 5); MilliSleep(10); return; @@ -217,6 +222,7 @@ void trx_trx_transmit_loop() scard->Open(O_WRONLY, current_samplerate); } catch (const SndException& e) { + LOG_ERROR("%s", e.what()); put_status(e.what(), 1); MilliSleep(10); return; @@ -235,6 +241,7 @@ void trx_trx_transmit_loop() } catch (const SndException& e) { scard->Close(); + LOG_ERROR("%s", e.what()); put_status(e.what(), 5); MilliSleep(10); return; @@ -272,6 +279,7 @@ void trx_tune_loop() scard->Open(O_WRONLY, current_samplerate); } catch (const SndException& e) { + LOG_ERROR("%s", e.what()); put_status(e.what(), 1); MilliSleep(10); return; @@ -293,6 +301,7 @@ void trx_tune_loop() } catch (const SndException& e) { scard->Close(); + LOG_ERROR("%s", e.what()); put_status(e.what(), 5); MilliSleep(10); return; @@ -336,7 +345,7 @@ void *trx_loop(void *args) trx_trx_receive_loop(); break; default: - cerr << "trx in bad state " << trx_state << '\n'; + LOG_ERROR("trx in bad state %d\n", trx_state); MilliSleep(100); } } @@ -465,7 +474,7 @@ void trx_start_macro_timer() void trx_start(void) { if (trxrunning) { - std::cout<< "trx already running!" << std::endl; + LOG_ERROR("trx already running!"); return; } @@ -502,7 +511,7 @@ void trx_start(void) _trx_tune = 0; active_modem = 0; if (fl_create_thread(trx_thread, trx_loop, &dummy) < 0) { - std::cout << "trx pthread_create:" << std::endl; + LOG_ERROR("pthread_create failed"); trxrunning = false; exit(1); } @@ -532,7 +541,7 @@ void wait_modem_ready_prep(void) { #ifndef NDEBUG if (GET_THREAD_ID() == TRX_TID) - cerr << "trx thread called wait_modem_ready_prep!\n"; + LOG_ERROR("trx thread called wait_modem_ready_prep!"); #endif fl_lock(&trx_cond_mutex); @@ -542,7 +551,7 @@ void wait_modem_ready_cmpl(void) { #ifndef NDEBUG if (GET_THREAD_ID() == TRX_TID) - cerr << "trx thread called wait_modem_ready_cmpl!\n"; + LOG_ERROR("trx thread called wait_modem_ready_cmpl!"); #endif fl_cond_wait(&trx_cond, &trx_cond_mutex); @@ -553,8 +562,7 @@ void signal_modem_ready(void) { #ifndef NDEBUG if (GET_THREAD_ID() != TRX_TID) - cerr << "thread " << GET_THREAD_ID() - << " called signal_modem_ready!\n"; + LOG_ERROR("thread %d called signal_modem_ready!", GET_THREAD_ID()); #endif fl_lock(&trx_cond_mutex); diff --git a/src/waterfall/colorbox.cxx b/src/waterfall/colorbox.cxx index 54ef065f..10231172 100644 --- a/src/waterfall/colorbox.cxx +++ b/src/waterfall/colorbox.cxx @@ -9,6 +9,7 @@ using namespace std; #include "fileselect.h" +#include "debug.h" void colorbox::draw() { int ypos = y() + 2; @@ -64,9 +65,9 @@ void loadPalette() for (int i = 0; i < 9; i++) { if (fscanf(clrfile, "%d;%d;%d\n", &r, &g, &b) == EOF) { if (ferror(clrfile)) - perror("fscanf"); + LOG_PERROR("fscanf"); else - cerr << p << ": unexpected EOF\n"; + LOG_ERROR("unexpected EOF"); fclose(clrfile); return; } diff --git a/src/widgets/FTextView.cxx b/src/widgets/FTextView.cxx index 09fc59c2..9ac863c1 100644 --- a/src/widgets/FTextView.cxx +++ b/src/widgets/FTextView.cxx @@ -397,8 +397,6 @@ FTextView::FTextView(int x, int y, int w, int h, const char *l) context_menu = view_menu; // disable some keybindings that are not allowed in FTextView buffers change_keybindings(); - - TiledGroup->add_resize_check(FTextView::wheight_mult_tsize, this); } FTextView::~FTextView() @@ -1292,3 +1290,104 @@ int FTextEdit::kf_paste(int c, Fl_Text_Editor_mod* e) { return e->insert_position() < *ptxpos ? 1 : Fl_Text_Editor_mod::kf_paste(c, e); } + +// ---------------------------------------------------------------------------- + +Fl_Menu_Item FTextLog::log_menu[] = { + { "C&lear", 0, 0 }, + { "&Copy", 0, 0 }, + { "Save to &file...", 0, 0, 0, FL_MENU_DIVIDER }, + { "Word &wrap", 0, 0, 0, FL_MENU_TOGGLE }, + { 0 } +}; + + +FTextLog::FTextLog(int x, int y, int w, int h, const char* l) + : FTextView(x, y, w, h, l) +{ + context_menu = log_menu; +// highlight_data(0, 0, 0, 0, 0, 0); +// delete sbuf; +// sbuf = 0; +} + +FTextLog::~FTextLog() { } + +int FTextLog::handle(int event) +{ + switch (event) { + case FL_PUSH: + if (!Fl::event_inside(this)) + break; + switch (Fl::event_button()) { + case FL_LEFT_MOUSE: + goto out; + case FL_MIDDLE_MOUSE: + return 1; + case FL_RIGHT_MOUSE: + break; + } + + // handle a right mouse click + if (tbuf->length()) + log_menu[LOG_MENU_CLEAR].flags &= ~FL_MENU_INACTIVE; + else + log_menu[LOG_MENU_CLEAR].flags |= FL_MENU_INACTIVE; + + if (tbuf->selected()) + log_menu[LOG_MENU_COPY].flags &= ~FL_MENU_INACTIVE; + else + log_menu[LOG_MENU_COPY].flags |= FL_MENU_INACTIVE; + if (wrap) + log_menu[LOG_MENU_WRAP].flags |= FL_MENU_VALUE; + else + log_menu[LOG_MENU_WRAP].flags &= ~FL_MENU_VALUE; + + show_context_menu(); + return 1; + case FL_KEYBOARD: + int k; + if (Fl::compose(k)) + return 1; + k = Fl::event_key(); + if (k == FL_BackSpace) + return 1; + else if (k == FL_Tab) + return Fl_Widget::handle(event); + } + +out: + return FTextBase::handle(event); +} + +void FTextLog::add(unsigned char c, int attr) +{ + const char s[] = { c, '\0' }; + tbuf->append(s); +} + +void FTextLog::add(const char* s, int attr) +{ + tbuf->append(s); +} + +void FTextLog::menu_cb(int val) +{ + switch (val) { + case LOG_MENU_CLEAR: + clear(); + break; + case LOG_MENU_COPY: + kf_copy(Fl::event_key(), this); + break; + case LOG_MENU_SAVE: + saveFile(); + break; + + case LOG_MENU_WRAP: + log_menu[RX_MENU_WRAP].flags ^= FL_MENU_VALUE; + wrap_mode((wrap = !wrap), wrap_col); + show_insert_position(); + break; + } +} diff --git a/src/widgets/Fl_Text_Display_mod.cxx b/src/widgets/Fl_Text_Display_mod.cxx index 8fc58514..ec2ae784 100644 --- a/src/widgets/Fl_Text_Display_mod.cxx +++ b/src/widgets/Fl_Text_Display_mod.cxx @@ -160,10 +160,11 @@ Fl_Text_Display_mod::~Fl_Text_Display_mod() { Fl::remove_timeout(scroll_timer_cb, this); scroll_direction = 0; } - if (mBuffer) { - mBuffer->remove_modify_callback(buffer_modified_cb, this); - mBuffer->remove_predelete_callback(buffer_predelete_cb, this); - } + // sb + // if (mBuffer) { + // mBuffer->remove_modify_callback(buffer_modified_cb, this); + // mBuffer->remove_predelete_callback(buffer_predelete_cb, this); + // } if (mLineStarts) delete[] mLineStarts; } diff --git a/src/widgets/picture.cxx b/src/widgets/picture.cxx index 26c2b28c..3ad8cad4 100644 --- a/src/widgets/picture.cxx +++ b/src/widgets/picture.cxx @@ -39,6 +39,7 @@ #endif #include "picture.h" +#include "debug.h" using namespace std; @@ -75,7 +76,8 @@ void picture::pixel(unsigned char data, int pos) if (pos < 0 || pos >= bufsize) return; FL_LOCK_D(); vidbuf[pos] = data; - redraw(); + if (pos % (width * 3) == 0) + redraw(); FL_UNLOCK_D(); } @@ -209,7 +211,7 @@ int picture::handle(int event) slant_corr(xpos, ypos); else if (evb == 3) slant_undo(); -// std::cout << "#2 " << xpos << ", " << ypos << std::endl; fflush(stdout); + LOG_DEBUG("#2 %d, %d", xpos, ypos); return 1; } return 1;