kopia lustrzana https://github.com/jamescoxon/dl-fldigi
Upstream version 2.11E
rodzic
ecb383b79f
commit
067cda0250
23
configure.ac
23
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, [2])
|
||||
m4_define(FLDIGI_MINOR, [11])
|
||||
m4_define(FLDIGI_PATCH, [D])
|
||||
m4_define(FLDIGI_PATCH, [E])
|
||||
|
||||
AC_INIT([fldigi], FLDIGI_MAJOR.FLDIGI_MINOR[FLDIGI_PATCH], [w1hkj AT w1hkj DOT com])
|
||||
|
||||
|
|
@ -79,7 +79,7 @@ AC_FUNC_SELECT_ARGTYPES
|
|||
AC_TYPE_SIGNAL
|
||||
AC_FUNC_STRFTIME
|
||||
AC_FUNC_STRTOD
|
||||
AC_CHECK_FUNCS([gethostbyname localtime_r memmove memset mkdir select snprintf socket strcasecmp strchr strdup strerror strncasecmp strcasestr strrchr strstr strtol uname vsnprintf])
|
||||
AC_CHECK_FUNCS([getaddrinfo gethostbyname localtime_r memmove memset mkdir select snprintf socket strcasecmp strchr strdup strerror strncasecmp strcasestr strrchr strstr strtol uname vsnprintf])
|
||||
|
||||
|
||||
AC_PRESERVE_HELP_ORDER
|
||||
|
|
@ -87,6 +87,19 @@ AC_PRESERVE_HELP_ORDER
|
|||
dnl blank line before our options in configure's help text
|
||||
AC_ARG_WITH([], [], [], [])
|
||||
|
||||
|
||||
###### OS support
|
||||
### OSX
|
||||
# Set ac_cv_mac_universal to yes/no
|
||||
# Set DARWIN Makefile conditional
|
||||
# Substitute MAC_UNIVERSAL_CFLAGS and MAC_UNIVERSAL_LDFLAGS in Makefile
|
||||
AC_FLDIGI_MACOSX
|
||||
### win32
|
||||
# Set WIN32 Makefile conditional
|
||||
# Set HAVE_WINDRES Makefile conditional
|
||||
# Substitute WINDRES in Makefile
|
||||
AC_FLDIGI_WIN32
|
||||
|
||||
### static flag
|
||||
# Set ac_cv_static to yes/no
|
||||
# Substitute RTLIB in Makefile
|
||||
|
|
@ -164,12 +177,6 @@ AC_FLDIGI_PKG_CHECK([hamlib], [hamlib >= 1.2.4], [yes], [with], [HAMLIB],
|
|||
[use hamradio control libraries @<:@autodetect@:>@],
|
||||
[ENABLE_HAMLIB])
|
||||
|
||||
### OSX
|
||||
# Set ac_cv_mac_universal to yes/no
|
||||
# Set DARWIN Makefile conditional
|
||||
# Substitute MAC_UNIVERSAL_CFLAGS and MAC_UNIVERSAL_LDFLAGS in Makefile
|
||||
AC_FLDIGI_MACOSX
|
||||
|
||||
|
||||
### output
|
||||
AH_TOP([
|
||||
|
|
|
|||
Plik binarny nie jest wyświetlany.
|
Po Szerokość: | Wysokość: | Rozmiar: 13 KiB |
|
|
@ -1,4 +1,7 @@
|
|||
AC_DEFUN([AC_FLDIGI_OSS], [
|
||||
AC_REQUIRE([AC_FLDIGI_MACOSX])
|
||||
AC_REQUIRE([AC_FLDIGI_WIN32])
|
||||
if test "x$target_darwin" = "xno" && test "x$target_win32" = "xno"; then
|
||||
AC_ARG_ENABLE([oss],
|
||||
AC_HELP_STRING([--disable-oss], [disable support for OSS @<:@autodetect@:>@]),
|
||||
[case "${enableval}" in
|
||||
|
|
@ -6,6 +9,11 @@ AC_DEFUN([AC_FLDIGI_OSS], [
|
|||
*) AC_MSG_ERROR([bad value "${enableval}" for --disable-oss]) ;;
|
||||
esac],
|
||||
[ac_cv_want_oss=check])
|
||||
else
|
||||
AC_MSG_NOTICE([disabling OSS driver on $target_os])
|
||||
ac_cv_want_oss=no
|
||||
fi
|
||||
|
||||
ac_cv_oss=no
|
||||
if test "x$ac_cv_want_oss" = "xno"; then
|
||||
AC_DEFINE(USE_OSS, 0, [Defined if we are using OSS])
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
AC_DEFUN([AC_FLDIGI_WIN32], [
|
||||
case "$target_os" in
|
||||
*cygwin*|*mingw*|*win32*|*w32*)
|
||||
target_win32="yes"
|
||||
;;
|
||||
*)
|
||||
target_win32="no"
|
||||
;;
|
||||
esac
|
||||
|
||||
if test "x$target_win32" = "xyes"; then
|
||||
AC_CHECK_PROG([WINDRES], [windres], [windres])
|
||||
if [ test "x$WINDRES" = "x" ]; then
|
||||
AC_MSG_WARN([The windres utility could not be found])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_SUBST([WINDRES])
|
||||
AM_CONDITIONAL([HAVE_WINDRES], [test "x$WINDRES" != "x"])
|
||||
AM_CONDITIONAL([WIN32], [test "x$target_win32" = "xyes"])
|
||||
])
|
||||
|
|
@ -19,9 +19,10 @@ LDADD = @PORTAUDIO_LIBS@ @BOOST_LDFLAGS@ @FLTK_LIBS@ @SNDFILE_LIBS@ \
|
|||
|
||||
|
||||
HAMLIB_SRC = include/hamlib.h rigcontrol/hamlib.cxx include/rigclass.h rigcontrol/rigclass.cxx
|
||||
WIN32_RES_SRC = fldigirc.rc
|
||||
|
||||
# We distribute these but do not always compile them
|
||||
EXTRA_fldigi_SOURCES = $(HAMLIB_SRC)
|
||||
EXTRA_fldigi_SOURCES = $(HAMLIB_SRC) $(WIN32_RES_SRC)
|
||||
|
||||
fldigi_SOURCES =
|
||||
|
||||
|
|
@ -53,6 +54,14 @@ nodist_fldigi_SOURCES = $(BUILT_SOURCES)
|
|||
CLEANFILES = $(BUILT_SOURCES)
|
||||
|
||||
|
||||
if WIN32
|
||||
if HAVE_WINDRES
|
||||
.rc.o:
|
||||
$(WINDRES) -I$(srcdir)/../data/win32 $< $@
|
||||
fldigi_SOURCES += $(WIN32_RES_SRC)
|
||||
endif
|
||||
endif
|
||||
|
||||
install-data-local:
|
||||
if test -f $(srcdir)/../data/fldigi.xpm; then \
|
||||
$(mkinstalldirs) $(DESTDIR)$(datadir)/pixmaps; \
|
||||
|
|
@ -201,6 +210,7 @@ fldigi_SOURCES += \
|
|||
include/rtty.h \
|
||||
include/serial.h \
|
||||
include/sound.h \
|
||||
include/soundconf.h \
|
||||
include/stacktrace.h \
|
||||
include/status.h \
|
||||
include/testmodem.h \
|
||||
|
|
@ -266,6 +276,7 @@ fldigi_SOURCES += \
|
|||
rigcontrol/serial.cxx \
|
||||
soundcard/mixer.cxx \
|
||||
soundcard/sound.cxx \
|
||||
soundcard/soundconf.cxx \
|
||||
throb/throb.cxx \
|
||||
trx/modem.cxx \
|
||||
trx/trx.cxx \
|
||||
|
|
@ -318,6 +329,7 @@ EXTRA_DIST = \
|
|||
$(srcdir)/../data/fldigi.xpm \
|
||||
$(srcdir)/../data/fldigi.desktop \
|
||||
$(srcdir)/../data/mac/Info.plist.in \
|
||||
$(srcdir)/../data/win32/fldigi.ico \
|
||||
fileselector/allfiles.xbm \
|
||||
fileselector/d1.xbm \
|
||||
fileselector/d1_mask.xbm \
|
||||
|
|
|
|||
|
|
@ -94,15 +94,15 @@ void rtty::restart()
|
|||
rtty_baud = _BAUD[progdefaults.rtty_baud];
|
||||
nbits = rtty_bits = _BITS[progdefaults.rtty_bits];
|
||||
if (rtty_bits == 5)
|
||||
rtty_parity = PARITY_NONE;
|
||||
rtty_parity = RTTY_PARITY_NONE;
|
||||
else
|
||||
switch (progdefaults.rtty_parity) {
|
||||
case 0 : rtty_parity = PARITY_NONE; break;
|
||||
case 1 : rtty_parity = PARITY_EVEN; break;
|
||||
case 2 : rtty_parity = PARITY_ODD; break;
|
||||
case 3 : rtty_parity = PARITY_ZERO; break;
|
||||
case 4 : rtty_parity = PARITY_ONE; break;
|
||||
default : rtty_parity = PARITY_NONE; break;
|
||||
case 0 : rtty_parity = RTTY_PARITY_NONE; break;
|
||||
case 1 : rtty_parity = RTTY_PARITY_EVEN; break;
|
||||
case 2 : rtty_parity = RTTY_PARITY_ODD; break;
|
||||
case 3 : rtty_parity = RTTY_PARITY_ZERO; break;
|
||||
case 4 : rtty_parity = RTTY_PARITY_ONE; break;
|
||||
default : rtty_parity = RTTY_PARITY_NONE; break;
|
||||
}
|
||||
rtty_stop = progdefaults.rtty_stop;
|
||||
|
||||
|
|
@ -219,19 +219,19 @@ int rtty::rttyparity(unsigned int c)
|
|||
|
||||
switch (rtty_parity) {
|
||||
default:
|
||||
case PARITY_NONE:
|
||||
case RTTY_PARITY_NONE:
|
||||
return 0;
|
||||
|
||||
case PARITY_ODD:
|
||||
case RTTY_PARITY_ODD:
|
||||
return rparity(c);
|
||||
|
||||
case PARITY_EVEN:
|
||||
case RTTY_PARITY_EVEN:
|
||||
return !rparity(c);
|
||||
|
||||
case PARITY_ZERO:
|
||||
case RTTY_PARITY_ZERO:
|
||||
return 0;
|
||||
|
||||
case PARITY_ONE:
|
||||
case RTTY_PARITY_ONE:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -243,7 +243,7 @@ int rtty::decode_char()
|
|||
parbit = (rxdata >> nbits) & 1;
|
||||
par = rttyparity(rxdata);
|
||||
|
||||
if (rtty_parity != PARITY_NONE && parbit != par)
|
||||
if (rtty_parity != RTTY_PARITY_NONE && parbit != par)
|
||||
return 0;
|
||||
|
||||
data = rxdata & ((1 << nbits) - 1);
|
||||
|
|
@ -289,7 +289,7 @@ int rtty::rx(bool bit)
|
|||
}
|
||||
|
||||
if (bitcntr == nbits) {
|
||||
if (rtty_parity == PARITY_NONE) {
|
||||
if (rtty_parity == RTTY_PARITY_NONE) {
|
||||
rxstate = RTTY_RX_STATE_STOP;
|
||||
}
|
||||
else {
|
||||
|
|
@ -588,7 +588,7 @@ void rtty::send_char(int c)
|
|||
send_symbol((c >> i) & 1);
|
||||
}
|
||||
// parity bit
|
||||
if (rtty_parity != PARITY_NONE)
|
||||
if (rtty_parity != RTTY_PARITY_NONE)
|
||||
send_symbol(rttyparity(c));
|
||||
// stop bit(s)
|
||||
send_stop();
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "confdialog.h"
|
||||
#include <config.h>
|
||||
#include "main.h"
|
||||
#include "soundconf.h"
|
||||
#include "combo.h"
|
||||
extern void initViewer();
|
||||
Fl_Double_Window *dlgConfig;
|
||||
|
|
@ -559,7 +560,7 @@ Fl_Group *tabAudio=(Fl_Group *)0;
|
|||
Fl_Group *AudioOSS=(Fl_Group *)0;
|
||||
|
||||
static void cb_btnAudioIO(Fl_Round_Button*, void*) {
|
||||
update_sound_config(SND_IDX_OSS);
|
||||
sound_update(SND_IDX_OSS);
|
||||
progdefaults.changed = true;
|
||||
resetSoundCard();
|
||||
}
|
||||
|
|
@ -575,23 +576,25 @@ progdefaults.changed = true;
|
|||
Fl_Group *AudioPort=(Fl_Group *)0;
|
||||
|
||||
static void cb_btnAudioIO1(Fl_Round_Button*, void*) {
|
||||
update_sound_config(SND_IDX_PORT);
|
||||
sound_update(SND_IDX_PORT);
|
||||
progdefaults.changed = true;
|
||||
resetSoundCard();
|
||||
}
|
||||
|
||||
Fl_Input_Choice *menuPortInDev=(Fl_Input_Choice *)0;
|
||||
Fl_Choice *menuPortInDev=(Fl_Choice *)0;
|
||||
|
||||
static void cb_menuPortInDev(Fl_Input_Choice* o, void*) {
|
||||
scDevice[0] = progdefaults.PortInDevice = o->value();
|
||||
static void cb_menuPortInDev(Fl_Choice* o, void*) {
|
||||
scDevice[0] = progdefaults.PortInDevice = o->text();
|
||||
progdefaults.PortInIndex = reinterpret_cast<intptr_t>(o->mvalue()->user_data());
|
||||
resetSoundCard();
|
||||
progdefaults.changed = true;
|
||||
}
|
||||
|
||||
Fl_Input_Choice *menuPortOutDev=(Fl_Input_Choice *)0;
|
||||
Fl_Choice *menuPortOutDev=(Fl_Choice *)0;
|
||||
|
||||
static void cb_menuPortOutDev(Fl_Input_Choice* o, void*) {
|
||||
scDevice[1] = progdefaults.PortOutDevice = o->value();
|
||||
static void cb_menuPortOutDev(Fl_Choice* o, void*) {
|
||||
scDevice[1] = progdefaults.PortOutDevice = o->text();
|
||||
progdefaults.PortOutIndex = reinterpret_cast<intptr_t>(o->mvalue()->user_data());
|
||||
resetSoundCard();
|
||||
progdefaults.changed = true;
|
||||
}
|
||||
|
|
@ -599,7 +602,7 @@ progdefaults.changed = true;
|
|||
Fl_Group *AudioPulse=(Fl_Group *)0;
|
||||
|
||||
static void cb_btnAudioIO2(Fl_Round_Button*, void*) {
|
||||
update_sound_config(SND_IDX_PULSE);
|
||||
sound_update(SND_IDX_PULSE);
|
||||
progdefaults.changed = true;
|
||||
resetSoundCard();
|
||||
}
|
||||
|
|
@ -617,7 +620,7 @@ Fl_Group *AudioNull=(Fl_Group *)0;
|
|||
Fl_Round_Button *btnAudioIO[4]={(Fl_Round_Button *)0};
|
||||
|
||||
static void cb_btnAudioIO3(Fl_Round_Button*, void*) {
|
||||
update_sound_config(SND_IDX_NULL);
|
||||
sound_update(SND_IDX_NULL);
|
||||
progdefaults.changed = true;
|
||||
resetSoundCard();
|
||||
}
|
||||
|
|
@ -1656,13 +1659,13 @@ static const char szBaudRates[] = "300|600|1200|2400|4800|9600|19200|38400|57600
|
|||
o->selection_color((Fl_Color)1);
|
||||
o->callback((Fl_Callback*)cb_btnAudioIO1);
|
||||
}
|
||||
{ Fl_Input_Choice* o = menuPortInDev = new Fl_Input_Choice(165, 99, 225, 25, "Capture");
|
||||
{ Fl_Choice* o = menuPortInDev = new Fl_Choice(165, 99, 225, 25, "Capture");
|
||||
o->down_box(FL_BORDER_BOX);
|
||||
o->callback((Fl_Callback*)cb_menuPortInDev);
|
||||
o->value(progdefaults.PortInDevice.c_str());
|
||||
}
|
||||
{ Fl_Input_Choice* o = menuPortOutDev = new Fl_Input_Choice(165, 127, 225, 25, "Playback");
|
||||
{ Fl_Choice* o = menuPortOutDev = new Fl_Choice(165, 127, 225, 25, "Playback");
|
||||
o->down_box(FL_BORDER_BOX);
|
||||
o->callback((Fl_Callback*)cb_menuPortOutDev);
|
||||
o->value(progdefaults.PortOutDevice.c_str());
|
||||
}
|
||||
o->end();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ decl {\#include <config.h>} {}
|
|||
|
||||
decl {\#include "main.h"} {}
|
||||
|
||||
decl {\#include "soundconf.h"} {}
|
||||
|
||||
decl {\#include "globals.h"} {public
|
||||
}
|
||||
|
||||
|
|
@ -666,7 +668,7 @@ o->label((inpQRZuserpassword->type() & FL_SECRET_INPUT) ? "Show" : "Hide");}
|
|||
} {
|
||||
Fl_Round_Button {btnAudioIO[0]} {
|
||||
label OSS
|
||||
callback {update_sound_config(SND_IDX_OSS);
|
||||
callback {sound_update(SND_IDX_OSS);
|
||||
progdefaults.changed = true;
|
||||
resetSoundCard();}
|
||||
xywh {5 63 100 25} down_box DIAMOND_DOWN_BOX selection_color 1
|
||||
|
|
@ -685,26 +687,26 @@ progdefaults.changed = true;} open
|
|||
} {
|
||||
Fl_Round_Button {btnAudioIO[1]} {
|
||||
label PortAudio
|
||||
callback {update_sound_config(SND_IDX_PORT);
|
||||
callback {sound_update(SND_IDX_PORT);
|
||||
progdefaults.changed = true;
|
||||
resetSoundCard();}
|
||||
xywh {5 115 95 25} down_box DIAMOND_DOWN_BOX selection_color 1
|
||||
}
|
||||
Fl_Input_Choice menuPortInDev {
|
||||
Fl_Choice menuPortInDev {
|
||||
label Capture
|
||||
callback {scDevice[0] = progdefaults.PortInDevice = o->value();
|
||||
callback {scDevice[0] = progdefaults.PortInDevice = o->text();
|
||||
progdefaults.PortInIndex = reinterpret_cast<intptr_t>(o->mvalue()->user_data());
|
||||
resetSoundCard();
|
||||
progdefaults.changed = true;} open
|
||||
xywh {165 99 225 25}
|
||||
code0 {o->value(progdefaults.PortInDevice.c_str());}
|
||||
} {}
|
||||
Fl_Input_Choice menuPortOutDev {
|
||||
Fl_Choice menuPortOutDev {
|
||||
label Playback
|
||||
callback {scDevice[1] = progdefaults.PortOutDevice = o->value();
|
||||
callback {scDevice[1] = progdefaults.PortOutDevice = o->text();
|
||||
progdefaults.PortOutIndex = reinterpret_cast<intptr_t>(o->mvalue()->user_data());
|
||||
resetSoundCard();
|
||||
progdefaults.changed = true;} open
|
||||
xywh {165 127 225 25}
|
||||
code0 {o->value(progdefaults.PortOutDevice.c_str());}
|
||||
} {}
|
||||
}
|
||||
Fl_Group AudioPulse {open
|
||||
|
|
@ -712,7 +714,7 @@ progdefaults.changed = true;} open
|
|||
} {
|
||||
Fl_Round_Button {btnAudioIO[2]} {
|
||||
label PulseAudio
|
||||
callback {update_sound_config(SND_IDX_PULSE);
|
||||
callback {sound_update(SND_IDX_PULSE);
|
||||
progdefaults.changed = true;
|
||||
resetSoundCard();}
|
||||
xywh {5 159 100 30} down_box DIAMOND_DOWN_BOX selection_color 1
|
||||
|
|
@ -732,7 +734,7 @@ http://www.pulseaudio.org/wiki/ServerStrings} xywh {165 161 225 25}
|
|||
} {
|
||||
Fl_Round_Button {btnAudioIO[3]} {
|
||||
label {File I/O only}
|
||||
callback {update_sound_config(SND_IDX_NULL);
|
||||
callback {sound_update(SND_IDX_NULL);
|
||||
progdefaults.changed = true;
|
||||
resetSoundCard();}
|
||||
xywh {5 192 100 25} down_box DIAMOND_DOWN_BOX selection_color 1
|
||||
|
|
|
|||
|
|
@ -25,8 +25,10 @@
|
|||
#include <config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifndef __CYGWIN__
|
||||
# include <sys/ipc.h>
|
||||
# include <sys/msg.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
|
|
@ -78,7 +80,7 @@
|
|||
|
||||
#include "combo.h"
|
||||
#include "font_browser.h"
|
||||
#ifndef __APPLE__
|
||||
#if !defined(__APPLE__) && !defined(__CYGWIN__)
|
||||
# include "fldigi-icon-48.xpm"
|
||||
#endif
|
||||
#include "status.h"
|
||||
|
|
@ -147,7 +149,7 @@ Fl_Progress *pgrsSquelch = (Fl_Progress *)0;
|
|||
|
||||
Fl_RGB_Image *feld_image = 0;
|
||||
|
||||
#ifndef __APPLE__
|
||||
#if !defined(__APPLE__) && !defined(__CYGWIN__)
|
||||
Pixmap fldigi_icon_pixmap;
|
||||
#endif
|
||||
|
||||
|
|
@ -1089,7 +1091,7 @@ void activate_rig_menu_item(bool b)
|
|||
mnu->redraw();
|
||||
}
|
||||
|
||||
#ifndef __APPLE__
|
||||
#if !defined(__APPLE__) && !defined(__CYGWIN__)
|
||||
void make_pixmap(Pixmap *xpm, const char **data)
|
||||
{
|
||||
// We need a displayed window to provide a GC for X_CreatePixmap
|
||||
|
|
@ -1334,9 +1336,8 @@ void create_fl_digi_main() {
|
|||
bx->color(FL_BLACK);
|
||||
xpos += 4;
|
||||
}
|
||||
btnMacro[i] = new Fl_Button(xpos, Y+2, Wbtn, Hmacros - 4);
|
||||
btnMacro[i] = new Fl_Button(xpos, Y+2, Wbtn, Hmacros - 4, macros.name[i].c_str());
|
||||
btnMacro[i]->callback(macro_cb, (void *)i);
|
||||
btnMacro[i]->label( (macros.name[i]).c_str());
|
||||
colorize_macro(i);
|
||||
xpos += Wbtn;
|
||||
}
|
||||
|
|
@ -1448,7 +1449,7 @@ void create_fl_digi_main() {
|
|||
fl_digi_main->end();
|
||||
fl_digi_main->callback(cb_wMain);
|
||||
|
||||
#ifndef __APPLE__
|
||||
#if !defined(__APPLE__) && !defined(__CYGWIN__)
|
||||
make_pixmap(&fldigi_icon_pixmap, fldigi_icon_48_xpm);
|
||||
fl_digi_main->icon((char *)fldigi_icon_pixmap);
|
||||
#endif
|
||||
|
|
@ -1517,7 +1518,13 @@ void put_rx_char(unsigned int data)
|
|||
{
|
||||
static unsigned int last = 0;
|
||||
const char **asc = ascii;
|
||||
|
||||
#ifndef __CYGWIN__
|
||||
rxmsgid = msgget( (key_t) progdefaults.rx_msgid, 0666);
|
||||
#else
|
||||
rxmsgid = -1;
|
||||
#endif
|
||||
|
||||
if (mailclient || mailserver || rxmsgid != -1)
|
||||
asc = ascii2;
|
||||
if (active_modem->get_mode() == MODE_RTTY ||
|
||||
|
|
@ -1542,11 +1549,15 @@ void put_rx_char(unsigned int data)
|
|||
}
|
||||
last = data;
|
||||
|
||||
#ifndef __CYGWIN__
|
||||
if ( rxmsgid != -1) {
|
||||
rxmsgst.msg_type = 1;
|
||||
rxmsgst.c = data;
|
||||
msgsnd (rxmsgid, (void *)&rxmsgst, 1, IPC_NOWAIT);
|
||||
}
|
||||
#else
|
||||
writeToARQfile(data);
|
||||
#endif
|
||||
|
||||
string s = iscntrl(data) ? ascii2[data & 0x7F] : string(1, data);
|
||||
if (Maillogfile)
|
||||
|
|
@ -1876,48 +1887,6 @@ void resetSoundCard()
|
|||
enableMixer(true);
|
||||
}
|
||||
|
||||
void update_sound_config(unsigned idx)
|
||||
{
|
||||
// radio button
|
||||
for (size_t i = 0; i < sizeof(btnAudioIO)/sizeof(*btnAudioIO); i++)
|
||||
btnAudioIO[i]->value(i == idx);
|
||||
|
||||
// devices
|
||||
menuOSSDev->deactivate();
|
||||
menuPortInDev->deactivate();
|
||||
menuPortOutDev->deactivate();
|
||||
inpPulseServer->deactivate();
|
||||
|
||||
// settings
|
||||
menuInSampleRate->deactivate();
|
||||
menuOutSampleRate->deactivate();
|
||||
|
||||
progdefaults.btnAudioIOis = idx;
|
||||
switch (idx) {
|
||||
case SND_IDX_OSS:
|
||||
menuOSSDev->activate();
|
||||
scDevice[0] = scDevice[1] = menuOSSDev->value();
|
||||
break;
|
||||
case SND_IDX_PORT:
|
||||
menuPortInDev->activate();
|
||||
menuPortOutDev->activate();
|
||||
menuInSampleRate->activate();
|
||||
menuOutSampleRate->activate();
|
||||
scDevice[0] = menuPortInDev->value();
|
||||
scDevice[1] = menuPortOutDev->value();
|
||||
break;
|
||||
case SND_IDX_PULSE:
|
||||
inpPulseServer->activate();
|
||||
menuInSampleRate->activate();
|
||||
menuOutSampleRate->activate();
|
||||
scDevice[0] = scDevice[1] = inpPulseServer->value();
|
||||
break;
|
||||
case SND_IDX_NULL:
|
||||
scDevice[0] = scDevice[1] = "";
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
void setReverse(int rev) {
|
||||
active_modem->set_reverse(rev);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
#include <windows.h> // include for version info constants
|
||||
|
||||
#include "fldig-config.h"
|
||||
|
||||
IDI_ICON ICON DISCARDABLE "fldigi.ico"
|
||||
|
|
@ -85,8 +85,8 @@ extern Fl_Group *AudioOSS;
|
|||
#include <FL/Fl_Input_Choice.H>
|
||||
extern Fl_Input_Choice *menuOSSDev;
|
||||
extern Fl_Group *AudioPort;
|
||||
extern Fl_Input_Choice *menuPortInDev;
|
||||
extern Fl_Input_Choice *menuPortOutDev;
|
||||
extern Fl_Choice *menuPortInDev;
|
||||
extern Fl_Choice *menuPortOutDev;
|
||||
extern Fl_Group *AudioPulse;
|
||||
extern Fl_Input *inpPulseServer;
|
||||
extern Fl_Group *AudioNull;
|
||||
|
|
|
|||
|
|
@ -131,7 +131,9 @@ struct configuration {
|
|||
string OSSdevice;
|
||||
string PAdevice;
|
||||
string PortInDevice;
|
||||
int PortInIndex;
|
||||
string PortOutDevice;
|
||||
int PortOutIndex;
|
||||
string PulseServer;
|
||||
int sample_rate;
|
||||
int in_sample_rate;
|
||||
|
|
|
|||
|
|
@ -131,7 +131,6 @@ extern void resetRTTY();
|
|||
extern void resetOLIVIA();
|
||||
extern void resetDOMEX();
|
||||
extern void resetSoundCard();
|
||||
extern void update_sound_config(unsigned idx);
|
||||
extern void restoreFocus();
|
||||
extern void setReverse(int);
|
||||
extern void clearQSO();
|
||||
|
|
|
|||
|
|
@ -25,6 +25,10 @@
|
|||
#ifndef FLDIGI_CONFIG_H
|
||||
#define FLDIGI_CONFIG_H
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
#define IDI_ICON 101
|
||||
#endif
|
||||
|
||||
// You can change the x1 width of the waterfall / spectrum display by modifying this
|
||||
// constant.
|
||||
// Suggest that you make the value a multiple of 100.
|
||||
|
|
|
|||
|
|
@ -47,8 +47,10 @@ struct MACROTEXT {
|
|||
void execute(int n);
|
||||
MACROTEXT() {
|
||||
changed = false;
|
||||
char szname[5];
|
||||
for (int i = 0; i < MAXMACROS; i++) {
|
||||
name[i] = "";
|
||||
snprintf(szname, sizeof(szname), "F-%d", i+1);
|
||||
name[i] = szname;//"";
|
||||
text[i] = "";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,10 @@ extern bool pskmail_text_available;
|
|||
extern char pskmail_get_char();
|
||||
extern void pskmail_loop(void *);
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
extern void writeToARQfile(unsigned int);
|
||||
#endif
|
||||
|
||||
struct RXMSGSTRUC {
|
||||
long int msg_type;
|
||||
char c;
|
||||
|
|
|
|||
|
|
@ -35,7 +35,11 @@ extern int parity(unsigned long w);
|
|||
extern unsigned long rbits32(unsigned long w);
|
||||
extern unsigned short int rbits16(unsigned short int w);
|
||||
extern unsigned char rbits8(unsigned char w);
|
||||
|
||||
#ifndef __CYGWIN__
|
||||
extern unsigned int log2(unsigned int x);
|
||||
#endif
|
||||
|
||||
extern unsigned char graydecode(unsigned char data);
|
||||
extern unsigned char grayencode(unsigned char data);
|
||||
extern void MilliSleep(long msecs);
|
||||
|
|
|
|||
|
|
@ -36,7 +36,29 @@
|
|||
|
||||
|
||||
extern "C" {
|
||||
|
||||
// This is needed to avoid a boolean conflict with jmorecfg.h
|
||||
#ifdef __CYGWIN__
|
||||
# include <w32api/wtypes.h>
|
||||
# define HAVE_BOOLEAN 1
|
||||
#endif
|
||||
|
||||
// This is needed to avoid a conflict between a
|
||||
// system-defined INT32 typedef, and a macro defined in
|
||||
// jmorecfg.h, included by jpeglib.h. If ADDRESS_TAG_BIT
|
||||
// is defined, basestd.h has been included and we will have
|
||||
// the typedef from cygwin, so we define XMD_H to avoid
|
||||
// defining the macro in jmorecfg.h
|
||||
#if defined(__CYGWIN__) && !defined(XMD_H)
|
||||
# define XMD_H
|
||||
# define FLDIGI_JPEG_XMD_H
|
||||
#endif
|
||||
#include <jpeglib.h>
|
||||
#ifdef FLDIGI_JPEG_XMD_H
|
||||
# undef FLDIGI_JPEG_XMD_H
|
||||
# undef XMD_H
|
||||
#endif
|
||||
|
||||
//# include "transupp.h"
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -57,11 +57,11 @@ enum RTTY_RX_STATE {
|
|||
};
|
||||
|
||||
enum RTTY_PARITY {
|
||||
PARITY_NONE = 0,
|
||||
PARITY_EVEN,
|
||||
PARITY_ODD,
|
||||
PARITY_ZERO,
|
||||
PARITY_ONE
|
||||
RTTY_PARITY_NONE = 0,
|
||||
RTTY_PARITY_EVEN,
|
||||
RTTY_PARITY_ODD,
|
||||
RTTY_PARITY_ZERO,
|
||||
RTTY_PARITY_ONE
|
||||
};
|
||||
|
||||
extern double _SHIFT[];
|
||||
|
|
|
|||
|
|
@ -28,8 +28,6 @@
|
|||
#ifndef _SOUND_H
|
||||
#define _SOUND_H
|
||||
|
||||
enum { SND_IDX_UNKNOWN = -1, SND_IDX_OSS, SND_IDX_PORT, SND_IDX_PULSE, SND_IDX_NULL, SND_IDX_END };
|
||||
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef SOUNDCONF_H
|
||||
#define SOUNDCONF_H
|
||||
|
||||
enum { SND_IDX_UNKNOWN = -1, SND_IDX_OSS, SND_IDX_PORT,
|
||||
SND_IDX_PULSE, SND_IDX_NULL, SND_IDX_END
|
||||
};
|
||||
|
||||
void sound_init(void);
|
||||
void sound_close(void);
|
||||
void sound_update(unsigned idx);
|
||||
|
||||
#endif // SOUNDCONF_H
|
||||
|
|
@ -43,9 +43,6 @@
|
|||
#ifndef Threads_H
|
||||
# define Threads_H
|
||||
|
||||
#ifndef WIN32
|
||||
// Use POSIX threading...
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
typedef pthread_t Fl_Thread;
|
||||
|
|
@ -62,15 +59,6 @@ extern int fl_lock(Fl_Mutex *m);
|
|||
extern int fl_unlock(Fl_Mutex *m);
|
||||
extern int fl_join(Fl_Thread t);
|
||||
|
||||
#else
|
||||
|
||||
# include <windows.h>
|
||||
# include <process.h>
|
||||
|
||||
typedef unsigned long Fl_Thread;
|
||||
extern int fl_create_thread(Fl_Thread * t, void *(*f) (void *), void* p);
|
||||
|
||||
# endif // !WIN32
|
||||
|
||||
// we have 4 threads, only 3 of which will use qrunner
|
||||
enum { UNKNOWN_TID = -1, TRX_TID, QRZ_TID, RIGCTL_TID, FLMAIN_TID,
|
||||
|
|
@ -82,9 +70,6 @@ enum { UNKNOWN_TID = -1, TRX_TID, QRZ_TID, RIGCTL_TID, FLMAIN_TID,
|
|||
# define SET_THREAD_ID(x) thread_id_ = (x)
|
||||
# define GET_THREAD_ID() thread_id_
|
||||
#else
|
||||
# ifdef WIN32 // assume no pthreads support
|
||||
# error need TLS support
|
||||
# endif
|
||||
extern pthread_key_t thread_id_;
|
||||
# define CREATE_THREAD_ID() pthread_key_create(&thread_id_, 0);
|
||||
# define SET_THREAD_ID(x) pthread_setspecific(thread_id_, (void *)(x))
|
||||
|
|
|
|||
|
|
@ -115,6 +115,10 @@ deprecated__ typeof(strcat) strcat;
|
|||
*/
|
||||
#endif
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
# define NOMINMAX 1
|
||||
#endif
|
||||
|
||||
#endif /* UTIL_H */
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -26,8 +26,10 @@
|
|||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#ifndef __CYGWIN__
|
||||
# include <sys/ipc.h>
|
||||
# include <sys/msg.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <string>
|
||||
|
||||
|
|
@ -133,7 +135,9 @@ void putadif(int num, const char *s)
|
|||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
#ifndef __CYGWIN__
|
||||
static msgtype msgbuf;
|
||||
#endif
|
||||
static string log_msg;
|
||||
static string errmsg;
|
||||
static char strFreqMhz[20];
|
||||
|
|
@ -144,7 +148,9 @@ char LOG_MSEPARATOR[2] = {1,0};
|
|||
int submit_log(void)
|
||||
{
|
||||
char logdate[32], logtime[32], adifdate[32];
|
||||
#ifndef __CYGWIN__
|
||||
int msqid, len;
|
||||
#endif
|
||||
struct tm *tm;
|
||||
time_t t;
|
||||
|
||||
|
|
@ -192,6 +198,7 @@ int submit_log(void)
|
|||
|
||||
writeadif();
|
||||
|
||||
#ifndef __CYGWIN__
|
||||
strncpy(msgbuf.mtext, log_msg.c_str(), sizeof(msgbuf.mtext));
|
||||
msgbuf.mtext[sizeof(msgbuf.mtext) - 1] = '\0';
|
||||
|
||||
|
|
@ -211,6 +218,9 @@ int submit_log(void)
|
|||
return -1;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
132
src/main.cxx
132
src/main.cxx
|
|
@ -29,8 +29,10 @@
|
|||
#include <cstdlib>
|
||||
#include <getopt.h>
|
||||
#include <sys/types.h>
|
||||
#ifndef __CYGWIN__
|
||||
# include <sys/ipc.h>
|
||||
# include <sys/msg.h>
|
||||
#endif
|
||||
#include <sys/utsname.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
|
|
@ -38,12 +40,16 @@
|
|||
#include <signal.h>
|
||||
#include <locale.h>
|
||||
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/Enumerations.H>
|
||||
#include <FL/Fl_Window.H>
|
||||
#include <FL/Fl_Shared_Image.H>
|
||||
#include <FL/x.H>
|
||||
|
||||
#include "main.h"
|
||||
#include "waterfall.h"
|
||||
#include "fft.h"
|
||||
#include "sound.h"
|
||||
#include "soundconf.h"
|
||||
#include "complex.h"
|
||||
#include "fl_digi.h"
|
||||
#include "rigio.h"
|
||||
|
|
@ -105,7 +111,6 @@ string option_help, version_text;
|
|||
qrunner *cbq[NUM_QRUNNER_THREADS];
|
||||
|
||||
void arqchecks(void);
|
||||
void sound_init(void);
|
||||
void generate_option_help(void);
|
||||
int parse_args(int argc, char **argv, int& idx);
|
||||
void generate_version_text(void);
|
||||
|
|
@ -166,7 +171,11 @@ int main(int argc, char ** argv)
|
|||
logfile = new cLogfile(lfname);
|
||||
logfile->log_to_file_start();
|
||||
|
||||
#ifndef __CYGWIN__
|
||||
txmsgid = msgget( (key_t) progdefaults.tx_msgid, 0666 );
|
||||
#else
|
||||
txmsgid = -1;
|
||||
#endif
|
||||
fl_filename_expand(szPskMailDir, 119, "$HOME/pskmail.files/");
|
||||
PskMailDir = szPskMailDir;
|
||||
|
||||
|
|
@ -198,10 +207,16 @@ int main(int argc, char ** argv)
|
|||
|
||||
progdefaults.setDefaults();
|
||||
|
||||
atexit(sound_close);
|
||||
sound_init();
|
||||
trx_start();
|
||||
|
||||
progdefaults.initInterface();
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
fl_digi_main->icon((char*)LoadIcon(fl_display, MAKEINTRESOURCE(IDI_ICON)));
|
||||
#endif
|
||||
|
||||
fl_digi_main->show(argc, argv);
|
||||
progStatus.initLastState();
|
||||
|
||||
|
|
@ -211,108 +226,9 @@ int main(int argc, char ** argv)
|
|||
for (int i = 0; i < NUM_QRUNNER_THREADS; i++)
|
||||
cbq[i]->detach();
|
||||
|
||||
#if USE_PORTAUDIO
|
||||
SoundPort::terminate();
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
void sound_init(void)
|
||||
{
|
||||
#if USE_OSS
|
||||
glob_t gbuf;
|
||||
glob("/dev/dsp*", 0, NULL, &gbuf);
|
||||
for (size_t i = 0; i < gbuf.gl_pathc; i++)
|
||||
menuOSSDev->add(gbuf.gl_pathv[i]);
|
||||
if (progdefaults.OSSdevice.length() == 0 && gbuf.gl_pathc)
|
||||
progdefaults.OSSdevice = gbuf.gl_pathv[0];
|
||||
menuOSSDev->value(progdefaults.OSSdevice.c_str());
|
||||
globfree(&gbuf);
|
||||
#endif
|
||||
|
||||
#if USE_PORTAUDIO
|
||||
SoundPort::initialize();
|
||||
if (SoundPort::devices().size() == 0)
|
||||
cerr << "PortAudio did not find any devices!\n";
|
||||
|
||||
for (SoundPort::device_iterator idev = SoundPort::devices().begin();
|
||||
idev != SoundPort::devices().end(); ++idev) {
|
||||
string s;
|
||||
s.append(Pa_GetHostApiInfo((*idev)->hostApi)->name).append("/").append((*idev)->name);
|
||||
|
||||
string::size_type i = s.find('/') + 1;
|
||||
// backslash-escape any slashes in the device name
|
||||
while ((i = s.find('/', i)) != string::npos) {
|
||||
s.insert(i, 1, '\\');
|
||||
i += 2;
|
||||
}
|
||||
if ((*idev)->maxInputChannels > 0)
|
||||
menuPortInDev->add(s.c_str());
|
||||
if ((*idev)->maxOutputChannels > 0)
|
||||
menuPortOutDev->add(s.c_str());
|
||||
}
|
||||
|
||||
if (progdefaults.PortInDevice.length() == 0) {
|
||||
if (progdefaults.PAdevice.length() == 0) {
|
||||
PaDeviceIndex def = Pa_GetDefaultInputDevice();
|
||||
if (def != paNoDevice)
|
||||
progdefaults.PortInDevice = (*(SoundPort::devices().begin() + def))->name;
|
||||
}
|
||||
else
|
||||
progdefaults.PortInDevice = progdefaults.PAdevice;
|
||||
}
|
||||
menuPortInDev->value(progdefaults.PortInDevice.c_str());
|
||||
if (progdefaults.PortOutDevice.length() == 0) {
|
||||
if (progdefaults.PAdevice.length() == 0) {
|
||||
PaDeviceIndex def = Pa_GetDefaultOutputDevice();
|
||||
if (def != paNoDevice)
|
||||
progdefaults.PortOutDevice = (*(SoundPort::devices().begin() + def))->name;
|
||||
}
|
||||
else
|
||||
progdefaults.PortOutDevice = progdefaults.PAdevice;
|
||||
}
|
||||
menuPortOutDev->value(progdefaults.PortOutDevice.c_str());
|
||||
#endif
|
||||
|
||||
#if USE_OSS
|
||||
glob("/dev/mixer*", 0, NULL, &gbuf);
|
||||
for (size_t i = 0; i < gbuf.gl_pathc; i++)
|
||||
menuMix->add(gbuf.gl_pathv[i]);
|
||||
if (progdefaults.MXdevice.length() == 0 && gbuf.gl_pathc)
|
||||
progdefaults.MXdevice = gbuf.gl_pathv[0];
|
||||
globfree(&gbuf);
|
||||
menuMix->value(progdefaults.MXdevice.c_str());
|
||||
#else
|
||||
progdefaults.EnableMixer = false;
|
||||
tabMixer->deactivate();
|
||||
#endif
|
||||
|
||||
// set the Sound Card configuration tab to the correct initial values
|
||||
#if !USE_OSS
|
||||
AudioOSS->deactivate();
|
||||
btnAudioIO[SND_IDX_OSS]->deactivate();
|
||||
#endif
|
||||
#if !USE_PORTAUDIO
|
||||
AudioPort->deactivate();
|
||||
btnAudioIO[SND_IDX_PORT]->deactivate();
|
||||
#endif
|
||||
#if !USE_PULSEAUDIO
|
||||
AudioPulse->deactivate();
|
||||
btnAudioIO[SND_IDX_PULSE]->deactivate();
|
||||
#endif
|
||||
if (progdefaults.btnAudioIOis == SND_IDX_UNKNOWN ||
|
||||
!btnAudioIO[progdefaults.btnAudioIOis]->active()) { // or saved sound api now disabled
|
||||
for (size_t i = 0; i < sizeof(btnAudioIO)/sizeof(*btnAudioIO); i++) {
|
||||
if (btnAudioIO[i]->active()) {
|
||||
progdefaults.btnAudioIOis = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
update_sound_config(progdefaults.btnAudioIOis);
|
||||
|
||||
resetMixerControls();
|
||||
}
|
||||
|
||||
void generate_option_help(void) {
|
||||
// is there a better way of enumerating schemes?
|
||||
|
|
@ -338,6 +254,7 @@ void generate_option_help(void) {
|
|||
<< " Look for configuration files in DIRECTORY\n"
|
||||
<< " The default is: " << HomeDir << "\n\n"
|
||||
|
||||
#ifndef __CYGWIN__
|
||||
<< " --rx-ipc-key KEY\n"
|
||||
<< " Set the receive message queue key\n"
|
||||
<< " May be given in hex if prefixed with \"0x\"\n"
|
||||
|
|
@ -349,6 +266,7 @@ void generate_option_help(void) {
|
|||
<< " May be given in hex if prefixed with \"0x\"\n"
|
||||
<< " The default is: " << progdefaults.tx_msgid
|
||||
<< " or 0x" << hex << progdefaults.tx_msgid << dec << "\n\n"
|
||||
#endif
|
||||
|
||||
<< " --resample CONVERTER\n"
|
||||
<< " Set the resampling method\n"
|
||||
|
|
@ -435,7 +353,11 @@ int parse_args(int argc, char **argv, int& idx)
|
|||
if ( !(strlen(argv[idx]) >= 2 && strncmp(argv[idx], "--", 2) == 0) )
|
||||
return 0;
|
||||
|
||||
enum { OPT_ZERO, OPT_RX_IPC_KEY, OPT_TX_IPC_KEY, OPT_CONFIG_DIR,
|
||||
enum { OPT_ZERO,
|
||||
#ifndef __CYGWIN__
|
||||
OPT_RX_IPC_KEY, OPT_TX_IPC_KEY,
|
||||
#endif
|
||||
OPT_CONFIG_DIR,
|
||||
OPT_FAST_TEXT, OPT_FONT, OPT_WFALL_WIDTH, OPT_WFALL_HEIGHT,
|
||||
OPT_WINDOW_WIDTH, OPT_WINDOW_HEIGHT, OPT_PROFILE, OPT_USE_CHECK,
|
||||
OPT_RESAMPLE,
|
||||
|
|
@ -447,8 +369,10 @@ int parse_args(int argc, char **argv, int& idx)
|
|||
|
||||
const char shortopts[] = "+";
|
||||
static struct option longopts[] = {
|
||||
#ifndef __CYGWIN__
|
||||
{ "rx-ipc-key", 1, 0, OPT_RX_IPC_KEY },
|
||||
{ "tx-ipc-key", 1, 0, OPT_TX_IPC_KEY },
|
||||
#endif
|
||||
{ "config-dir", 1, 0, OPT_CONFIG_DIR },
|
||||
{ "fast-text", 0, 0, OPT_FAST_TEXT },
|
||||
{ "font", 1, 0, OPT_FONT },
|
||||
|
|
@ -483,6 +407,7 @@ int parse_args(int argc, char **argv, int& idx)
|
|||
// handle options with non-0 flag here
|
||||
return 0;
|
||||
|
||||
#ifndef __CYGWIN__
|
||||
case OPT_RX_IPC_KEY: case OPT_TX_IPC_KEY:
|
||||
{
|
||||
errno = 0;
|
||||
|
|
@ -495,6 +420,7 @@ int parse_args(int argc, char **argv, int& idx)
|
|||
progdefaults.tx_msgid = key;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case OPT_CONFIG_DIR:
|
||||
HomeDir = optarg;
|
||||
|
|
@ -646,7 +572,7 @@ void generate_version_text(void)
|
|||
// the env var FLDIGI_NO_EXEC is set, or our parent process is gdb.
|
||||
void debug_exec(char** argv)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
#if !defined(NDEBUG) && !defined(__CYGWIN__)
|
||||
if (getenv("FLDIGI_NO_EXEC"))
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ configuration progdefaults = {
|
|||
3, // int rtty_shift; = 170
|
||||
0, // int rtty_baud; = 45
|
||||
0, // int rtty_bits; = 5
|
||||
PARITY_NONE, // RTTY_PARITY rtty_parity;
|
||||
RTTY_PARITY_NONE, // RTTY_PARITY rtty_parity;
|
||||
1, // int rtty_stop;
|
||||
false, // bool rtty_reverse;
|
||||
false, // bool rtty_msbfirst;
|
||||
|
|
@ -132,7 +132,9 @@ configuration progdefaults = {
|
|||
"", // string OSSdevice;
|
||||
"", // string PAdevice;
|
||||
"", // string PortIndevice;
|
||||
-1, // int PortInIndex;
|
||||
"", // string PortOutDevice;
|
||||
-1, // int PortOutIndex;
|
||||
"", // string PulseServer
|
||||
SAMPLE_RATE_UNSET, // int sample_rate;
|
||||
SAMPLE_RATE_UNSET, // int in_sample_rate;
|
||||
|
|
@ -241,7 +243,7 @@ enum TAG { \
|
|||
HAMRIGNAME, HAMRIGDEVICE, HAMRIGBAUDRATE,
|
||||
PTTDEV,
|
||||
SECONDARYTEXT,
|
||||
AUDIOIO, OSSDEVICE, PADEVICE, PORTINDEVICE, PORTOUTDEVICE, PULSESERVER,
|
||||
AUDIOIO, OSSDEVICE, PADEVICE, PORTINDEVICE, PORTININDEX, PORTOUTDEVICE, PORTOUTINDEX, PULSESERVER,
|
||||
SAMPLERATE, INSAMPLERATE, OUTSAMPLERATE, RXCORR, TXCORR, TXOFFSET,
|
||||
USELEADINGZEROS, CONTESTSTART, CONTESTDIGITS,
|
||||
USETIMER, MACRONUMBER, TIMEOUT,
|
||||
|
|
@ -410,7 +412,10 @@ void configuration::writeDefaultsXML()
|
|||
writeXMLstr(f, "OSSDEVICE", OSSdevice);
|
||||
writeXMLstr(f, "PADEVICE", PAdevice);
|
||||
writeXMLstr(f, "PORTINDEVICE", PortInDevice);
|
||||
writeXMLint(f, "PORTININDEX", PortInIndex);
|
||||
writeXMLstr(f, "PORTOUTDEVICE", PortOutDevice);
|
||||
writeXMLint(f, "PORTOUTINDEX", PortOutIndex);
|
||||
writeXMLstr(f, "PULSESERVER", PulseServer);
|
||||
writeXMLint(f, "SAMPLERATE", sample_rate);
|
||||
writeXMLint(f, "INSAMPLERATE", in_sample_rate);
|
||||
writeXMLint(f, "OUTSAMPLERATE", out_sample_rate);
|
||||
|
|
@ -756,9 +761,15 @@ bool configuration::readDefaultsXML()
|
|||
case PORTINDEVICE :
|
||||
PortInDevice = xml->getNodeData();
|
||||
break;
|
||||
case PORTININDEX :
|
||||
PortInIndex = atoi(xml->getNodeData());
|
||||
break;
|
||||
case PORTOUTDEVICE :
|
||||
PortOutDevice = xml->getNodeData();
|
||||
break;
|
||||
case PORTOUTINDEX :
|
||||
PortOutIndex = atoi(xml->getNodeData());
|
||||
break;
|
||||
case PULSESERVER :
|
||||
PulseServer = xml->getNodeData();
|
||||
break;
|
||||
|
|
@ -1011,7 +1022,9 @@ bool configuration::readDefaultsXML()
|
|||
else if (!strcmp("OSSDEVICE", nodeName)) tag = OSSDEVICE;
|
||||
else if (!strcmp("PADEVICE", nodeName)) tag = PADEVICE;
|
||||
else if (!strcmp("PORTINDEVICE", nodeName)) tag = PORTINDEVICE;
|
||||
else if (!strcmp("PORTININDEX", nodeName)) tag = PORTININDEX;
|
||||
else if (!strcmp("PORTOUTDEVICE", nodeName)) tag = PORTOUTDEVICE;
|
||||
else if (!strcmp("PORTOUTINDEX", nodeName)) tag = PORTOUTINDEX;
|
||||
else if (!strcmp("SAMPLERATE", nodeName)) tag = SAMPLERATE;
|
||||
else if (!strcmp("INSAMPLERATE", nodeName)) tag = INSAMPLERATE;
|
||||
else if (!strcmp("OUTSAMPLERATE", nodeName)) tag = OUTSAMPLERATE;
|
||||
|
|
@ -1080,11 +1093,11 @@ void configuration::loadDefaults() {
|
|||
selBaud->value(rtty_baud);
|
||||
selBits->value(rtty_bits);
|
||||
switch (rtty_parity) {
|
||||
case PARITY_NONE : selParity->value(0); break;
|
||||
case PARITY_EVEN : selParity->value(1); break;
|
||||
case PARITY_ODD : selParity->value(2); break;
|
||||
case PARITY_ZERO : selParity->value(3); break;
|
||||
case PARITY_ONE : selParity->value(4); break;
|
||||
case RTTY_PARITY_NONE : selParity->value(0); break;
|
||||
case RTTY_PARITY_EVEN : selParity->value(1); break;
|
||||
case RTTY_PARITY_ODD : selParity->value(2); break;
|
||||
case RTTY_PARITY_ZERO : selParity->value(3); break;
|
||||
case RTTY_PARITY_ONE : selParity->value(4); break;
|
||||
default : selParity->value(0); break;
|
||||
}
|
||||
// chkMsbFirst->value(rtty_msbfirst);
|
||||
|
|
@ -1118,15 +1131,15 @@ void configuration::storeDefaults() {
|
|||
rtty_baud = selBaud->value();
|
||||
rtty_bits = selBits->value();
|
||||
if (rtty_bits == 0)
|
||||
rtty_parity = PARITY_NONE;
|
||||
rtty_parity = RTTY_PARITY_NONE;
|
||||
else
|
||||
switch (selParity->value()) {
|
||||
case 0 : rtty_parity = PARITY_NONE; break;
|
||||
case 1 : rtty_parity = PARITY_EVEN; break;
|
||||
case 2 : rtty_parity = PARITY_ODD; break;
|
||||
case 3 : rtty_parity = PARITY_ZERO; break;
|
||||
case 4 : rtty_parity = PARITY_ONE; break;
|
||||
default : rtty_parity = PARITY_NONE; break;
|
||||
case 0 : rtty_parity = RTTY_PARITY_NONE; break;
|
||||
case 1 : rtty_parity = RTTY_PARITY_EVEN; break;
|
||||
case 2 : rtty_parity = RTTY_PARITY_ODD; break;
|
||||
case 3 : rtty_parity = RTTY_PARITY_ZERO; break;
|
||||
case 4 : rtty_parity = RTTY_PARITY_ONE; break;
|
||||
default : rtty_parity = RTTY_PARITY_NONE; break;
|
||||
}
|
||||
// rtty_msbfirst = chkMsbFirst->value();
|
||||
rtty_stop = selStopBits->value();
|
||||
|
|
@ -1311,8 +1324,6 @@ int configuration::setDefaults() {
|
|||
btnLineIn->value(LineIn);
|
||||
|
||||
menuOSSDev->value(OSSdevice.c_str());
|
||||
menuPortInDev->value(PortInDevice.c_str());
|
||||
menuPortOutDev->value(PortOutDevice.c_str());
|
||||
inpPulseServer->value(PulseServer.c_str());
|
||||
|
||||
btnMixer->value(EnableMixer);
|
||||
|
|
|
|||
|
|
@ -520,16 +520,21 @@ int MACROTEXT::loadMacros(string filename)
|
|||
|
||||
if (!mFile) {
|
||||
createDotFldigi();
|
||||
mFile.open(filename.c_str());
|
||||
if (!mFile)
|
||||
return -1;
|
||||
for (int i = 0; i < 12; i++) {
|
||||
btnMacro[i]->label( name[i].c_str());
|
||||
btnMacro[i]->redraw_label();
|
||||
}
|
||||
return 0;
|
||||
// mFile.open(filename.c_str());
|
||||
// if (!mFile)
|
||||
// return -1;
|
||||
}
|
||||
|
||||
mFile.getline(szLine, 4095);
|
||||
mLine = szLine;
|
||||
if (mLine.find("//fldigi macro definition file") != 0) {
|
||||
mFile.close();
|
||||
return -1;
|
||||
return -2;
|
||||
}
|
||||
if (mLine.find("extended") == string::npos) {
|
||||
convert = true;
|
||||
|
|
@ -555,7 +560,7 @@ int MACROTEXT::loadMacros(string filename)
|
|||
name[mNumber] = mLine.substr(idx+1);
|
||||
if (mNumber < 12) {
|
||||
FL_LOCK_D();
|
||||
btnMacro[mNumber]->label( (macros.name[mNumber]).c_str());
|
||||
btnMacro[mNumber]->label( (name[mNumber]).c_str());
|
||||
FL_UNLOCK_D();
|
||||
}
|
||||
continue;
|
||||
|
|
@ -572,9 +577,11 @@ int MACROTEXT::loadMacros(string filename)
|
|||
|
||||
void MACROTEXT::loadDefault()
|
||||
{
|
||||
int erc;
|
||||
string Filename = HomeDir;
|
||||
Filename.append("macros.mdf");
|
||||
loadMacros(Filename);
|
||||
if ((erc = loadMacros(Filename)) != 0)
|
||||
printf("Error #%d loading %s\n", erc, Filename.c_str());
|
||||
}
|
||||
|
||||
void MACROTEXT::openMacroFile()
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ unsigned char rbits8(unsigned char w)
|
|||
|
||||
// Integer base-2 logarithm
|
||||
|
||||
#ifndef __CYGWIN__
|
||||
unsigned int log2(unsigned int x)
|
||||
{
|
||||
int y = 0;
|
||||
|
|
@ -115,6 +116,7 @@ unsigned int log2(unsigned int x)
|
|||
}
|
||||
return y;
|
||||
}
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -7,18 +7,28 @@
|
|||
#include <string>
|
||||
#include <ctime>
|
||||
#include <sys/types.h>
|
||||
#ifndef __CYGWIN__
|
||||
# include <sys/ipc.h>
|
||||
# include <sys/msg.h>
|
||||
#endif
|
||||
|
||||
#include "main.h"
|
||||
#include "configuration.h"
|
||||
#include "fl_digi.h"
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
string str_infile = "c:/NBEMS/ARQXFR/txfile";
|
||||
string str_outfile = "c:/NBEMS/ARQXFR/rxfile";
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
static string mailtext;
|
||||
string::iterator pText;
|
||||
|
||||
#ifndef __CYGWIN__
|
||||
static char mailline[1000];
|
||||
#endif
|
||||
|
||||
bool pskmail_text_available = false;
|
||||
|
||||
|
|
@ -95,26 +105,11 @@ void parse_mailtext()
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
size_t mailstrftime( char *s, size_t max, const char *fmt, const struct tm *tm) {
|
||||
return strftime(s, max, fmt, tm);
|
||||
}
|
||||
|
||||
void mailZDT(string &s)
|
||||
{
|
||||
char szDt[80];
|
||||
time_t tmptr;
|
||||
tm sTime;
|
||||
time (&tmptr);
|
||||
gmtime_r(&tmptr, &sTime);
|
||||
mailstrftime(szDt, 79, "%x %H:%M %Z", &sTime);
|
||||
s = szDt;
|
||||
}
|
||||
*/
|
||||
|
||||
#define TIMEOUT 180 // 3 minutes
|
||||
|
||||
bool bSend0x06 = false;
|
||||
|
||||
#ifndef __CYGWIN__
|
||||
void process_msgque()
|
||||
{
|
||||
int nbytes = msgrcv (txmsgid, (void *)&txmsgst, BUFSIZ, 0, IPC_NOWAIT);
|
||||
|
|
@ -137,8 +132,30 @@ void process_msgque()
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
long infileptr = 0;
|
||||
bool bInitFilePtr = false;
|
||||
|
||||
void initFilePtr()
|
||||
{
|
||||
FILE *infile;
|
||||
infile = fopen(str_infile.c_str(), "rb");
|
||||
if (infile) {
|
||||
fseek(infile, 0, SEEK_END);
|
||||
infileptr = ftell(infile);
|
||||
fclose(infile);
|
||||
}
|
||||
bInitFilePtr = true;
|
||||
std::cout << "Init file pointer = " << infileptr << std::endl; std::cout.flush();
|
||||
}
|
||||
#endif
|
||||
|
||||
void check_formail() {
|
||||
|
||||
#ifndef __CYGWIN__
|
||||
time_t start_time, prog_time;
|
||||
string sAutoFile = PskMailDir;
|
||||
|
||||
|
|
@ -148,6 +165,7 @@ void check_formail() {
|
|||
arqmode = true;
|
||||
return;
|
||||
}
|
||||
|
||||
arqmode = false;
|
||||
|
||||
if (! (mailserver || mailclient) )
|
||||
|
|
@ -196,12 +214,52 @@ void check_formail() {
|
|||
wf->set_XmtRcvBtn(true);
|
||||
}
|
||||
}
|
||||
#else
|
||||
// Windows file handling for input strings
|
||||
FILE *infile;
|
||||
infile = fopen(str_infile.c_str(), "rb");
|
||||
if (infile) {
|
||||
fseek(infile, 0, SEEK_END);
|
||||
long sz = ftell(infile);
|
||||
if (sz > infileptr) {
|
||||
mailtext = "";
|
||||
fseek(infile, infileptr, SEEK_SET);
|
||||
while (infileptr < sz) {
|
||||
mailtext += fgetc(infile);
|
||||
infileptr++;
|
||||
}
|
||||
if (mailtext.length() > 0) {
|
||||
parse_mailtext();
|
||||
pText = mailtext.begin();
|
||||
pskmail_text_available = true;
|
||||
active_modem->set_stopflag(false);
|
||||
fl_lock(&trx_mutex);
|
||||
trx_state = STATE_TX;
|
||||
fl_unlock(&trx_mutex);
|
||||
wf->set_XmtRcvBtn(true);
|
||||
arqmode = true;
|
||||
}
|
||||
}
|
||||
fclose(infile);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool bSend0x06 = false;
|
||||
#ifdef __CYGWIN__
|
||||
void writeToARQfile(unsigned int data)
|
||||
{
|
||||
FILE *outfile;
|
||||
outfile = fopen(str_outfile.c_str(), "ab");
|
||||
if (outfile) {
|
||||
putc((unsigned char)data, outfile );
|
||||
fclose(outfile);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void send0x06()
|
||||
{
|
||||
#ifndef __CYGWIN__
|
||||
if (trx_state == STATE_RX) {
|
||||
bSend0x06 = false;
|
||||
rxmsgid = msgget( (key_t) progdefaults.rx_msgid, 0666 );
|
||||
|
|
@ -211,10 +269,21 @@ void send0x06()
|
|||
msgsnd (rxmsgid, (void *)&rxmsgst, 1, IPC_NOWAIT);
|
||||
}
|
||||
}
|
||||
#else
|
||||
// process output strings for Windows file i/o
|
||||
if (trx_state == STATE_RX) {
|
||||
bSend0x06 = false;
|
||||
writeToARQfile(0x06);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void pskmail_loop(void *)
|
||||
{
|
||||
#ifdef __CYGWIN__
|
||||
if (!bInitFilePtr)
|
||||
initFilePtr();
|
||||
#endif
|
||||
if (bSend0x06)
|
||||
send0x06();
|
||||
check_formail();
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ bool parse_xml();
|
|||
|
||||
int connect_to_server(const char* node, const char* service, int* fd);
|
||||
ssize_t read_from_server(int fd, const string& request, string& reply, struct timeval* timeout);
|
||||
const char* get_error_string(int err);
|
||||
|
||||
bool getSessionKey(string& sessionpage);
|
||||
bool QRZGetXML(string& xmlpage);
|
||||
|
|
@ -319,6 +320,9 @@ bool parse_xml(const string& xmlpage)
|
|||
// was some other error.
|
||||
int connect_to_server(const char* node, const char* service, int* fd)
|
||||
{
|
||||
int res = 0;
|
||||
|
||||
#if HAVE_GETADDRINFO
|
||||
struct addrinfo hints, *ai, *aip;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
|
|
@ -328,7 +332,6 @@ int connect_to_server(const char* node, const char* service, int* fd)
|
|||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
int res;
|
||||
if ((res = getaddrinfo(node, service, &hints, &ai)) < 0)
|
||||
return res;
|
||||
for (aip = ai; aip; aip = ai->ai_next) { // use the first one that works
|
||||
|
|
@ -344,6 +347,29 @@ int connect_to_server(const char* node, const char* service, int* fd)
|
|||
}
|
||||
|
||||
freeaddrinfo(ai);
|
||||
#else
|
||||
struct sockaddr_in server_addr;
|
||||
struct hostent* server_entry;
|
||||
struct servent* service_entry;
|
||||
|
||||
if ((service_entry = getservbyname(service, NULL)) == NULL)
|
||||
return errno;
|
||||
if ((server_entry = gethostbyname(node)) == NULL)
|
||||
return errno;
|
||||
|
||||
memset(&server_addr, 0, sizeof(server_addr));
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_addr = *((struct in_addr *)server_entry->h_addr_list[0]);
|
||||
server_addr.sin_port = service_entry->s_port;
|
||||
|
||||
if ((*fd = socket(server_addr.sin_family, SOCK_STREAM, 0)) == -1)
|
||||
return errno;
|
||||
if (connect(*fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)
|
||||
return errno;
|
||||
|
||||
res = 0;
|
||||
#endif // HAVE_GETADDRINFO
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -402,11 +428,21 @@ ssize_t read_from_server(int fd, const string& request, string& reply, struct ti
|
|||
return n;
|
||||
}
|
||||
|
||||
const char* get_error_string(int err)
|
||||
{
|
||||
#if HAVE_GETADDRINFO
|
||||
if (err < 0)
|
||||
return gai_strerror(err);
|
||||
else
|
||||
#endif
|
||||
return strerror(err);
|
||||
}
|
||||
|
||||
bool getSessionKey(string& sessionpage)
|
||||
{
|
||||
int r, sockfd;
|
||||
if ((r = connect_to_server(host.c_str(), "http", &sockfd)) != 0) {
|
||||
error_string = r > 0 ? strerror(r) : gai_strerror(r);
|
||||
error_string = get_error_string(r);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -440,7 +476,7 @@ bool QRZGetXML(string& xmlpage)
|
|||
{
|
||||
int r, sockfd;
|
||||
if ((r = connect_to_server(host.c_str(), "http", &sockfd)) != 0) {
|
||||
error_string = r > 0 ? strerror(r) : gai_strerror(r);
|
||||
error_string = get_error_string(r);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -764,7 +800,7 @@ bool HAMCALLget(string& htmlpage)
|
|||
{
|
||||
int r, sockfd;
|
||||
if ((r = connect_to_server(HAMCALL_HOST, "http", &sockfd)) != 0) {
|
||||
error_string = r > 0 ? strerror(r) : gai_strerror(r);
|
||||
error_string = get_error_string(r);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ FILE *imagefile = NULL;
|
|||
|
||||
#define isdirsep(c) ((c)=='/')
|
||||
|
||||
#ifndef __CYGWIN__
|
||||
size_t strlcpy(
|
||||
char *dst, /* O - Destination string */
|
||||
const char *src, /* I - Source string */
|
||||
|
|
@ -68,6 +69,7 @@ size_t strlcpy(
|
|||
dst[srclen] = '\0';
|
||||
return (srclen);
|
||||
}
|
||||
#endif
|
||||
|
||||
int filename_expand(char *to,int tolen, const char *from) {
|
||||
|
||||
|
|
|
|||
|
|
@ -29,14 +29,14 @@ extern void openViewer();
|
|||
|
||||
status progStatus = {
|
||||
(int)MODE_BPSK31, // trx_mode lastmode;
|
||||
0, // int mainX;
|
||||
0, // int mainY;
|
||||
50, // int mainX;
|
||||
50, // int mainY;
|
||||
WNOM, // int mainW;
|
||||
HNOM, // int mainH;
|
||||
Hrcvtxt, // int RxTextHeight;
|
||||
false, // bool rigShown;
|
||||
0, // int rigX;
|
||||
0, // int rigY;
|
||||
50, // int rigX;
|
||||
50, // int rigY;
|
||||
1000, // int carrier;
|
||||
1, // int mag;
|
||||
NORMAL, // WFdisp::WFspeed
|
||||
|
|
|
|||
|
|
@ -36,9 +36,6 @@
|
|||
|
||||
#include "threads.h"
|
||||
|
||||
#ifndef WIN32
|
||||
// Use POSIX threading...
|
||||
|
||||
int fl_create_thread(Fl_Thread & t, void *(*f) (void *), void* p) {
|
||||
return pthread_create((pthread_t*)&t, NULL, f, p);
|
||||
}
|
||||
|
|
@ -75,13 +72,6 @@ int fl_join (Fl_Thread t) {
|
|||
return pthread_join ((pthread_t) t, 0);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static int fl_create_thread(Fl_Thread * t, void *(*f) (void *), void* p) {
|
||||
return t = (Fl_Thread)_beginthread((void( __cdecl * )( void * ))f, 0, p);
|
||||
}
|
||||
|
||||
# endif // !WIN32
|
||||
|
||||
#if USE_TLS
|
||||
__thread int thread_id_;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,10 @@
|
|||
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#if __CYGWIN__
|
||||
# include <sys/types.h>
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#include <FL/Fl.H>
|
||||
|
||||
|
|
@ -34,7 +38,11 @@ qrunner::qrunner(size_t npri_)
|
|||
: npri(npri_), attached(false), drop_flag(false)
|
||||
{
|
||||
fifo = new fqueue(2048, npri);
|
||||
#ifndef __CYGWIN__
|
||||
if (pipe(pfd) == -1)
|
||||
#else
|
||||
if (socketpair(PF_UNIX, SOCK_DGRAM, 0, pfd) == -1)
|
||||
#endif
|
||||
throw qexception(errno);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -76,6 +76,8 @@ void PTT::reset_(int dev)//, int mode, bool inverted)
|
|||
return;
|
||||
}
|
||||
|
||||
// convert to and from Windows / Linux serial port naming
|
||||
#ifndef __CYGWIN__
|
||||
if (progdefaults.PTTdev == "COM1")
|
||||
pttdevName = "/dev/ttyS0";
|
||||
else if (progdefaults.PTTdev == "COM2")
|
||||
|
|
@ -86,6 +88,18 @@ void PTT::reset_(int dev)//, int mode, bool inverted)
|
|||
pttdevName = "/dev/ttyS3";
|
||||
else
|
||||
pttdevName = progdefaults.PTTdev;
|
||||
#else
|
||||
if (progdefaults.PTTdev == "/dev/ttyS0")
|
||||
pttdevName = "COM1";
|
||||
else if (progdefaults.PTTdev == "/dev/ttyS1")
|
||||
pttdevName = "COM2";
|
||||
else if (progdefaults.PTTdev == "/dev/ttyS2")
|
||||
pttdevName = "COM3";
|
||||
else if (progdefaults.PTTdev == "/dev/ttyS3")
|
||||
pttdevName = "COM4";
|
||||
else
|
||||
pttdevName = progdefaults.PTTdev;
|
||||
#endif
|
||||
|
||||
openptt();
|
||||
if (pttfd == -1) {
|
||||
|
|
|
|||
|
|
@ -5,9 +5,11 @@
|
|||
|
||||
#include <config.h>
|
||||
|
||||
#ifndef __CYGWIN__
|
||||
# include <sys/ipc.h>
|
||||
# include <sys/msg.h>
|
||||
# include <sys/shm.h>
|
||||
#endif
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <FL/Fl.H>
|
||||
|
|
@ -31,7 +33,9 @@ static int dummy;
|
|||
static Fl_Thread rigMEM_thread;
|
||||
static bool rigMEM_exit = false;
|
||||
static bool rigMEM_enabled;
|
||||
|
||||
static void *rigMEM_loop(void *args);
|
||||
|
||||
static bool rigMEM_PTT = PTT_OFF;
|
||||
static bool rig_qsy = false;
|
||||
static bool TogglePTT = false;
|
||||
|
|
@ -39,6 +43,9 @@ static bool rigMEMisPTT = false;
|
|||
static long long qsy_f;
|
||||
static long long qsy_fmid;
|
||||
|
||||
#ifndef __CYGWIN__
|
||||
// Linux & OS_X interface to Kachina
|
||||
|
||||
struct ST_SHMEM {
|
||||
int flag;
|
||||
long freq;
|
||||
|
|
@ -63,14 +70,11 @@ key_t hash (char *str)
|
|||
|
||||
void rigMEM_init(void)
|
||||
{
|
||||
// szFreqFormat[2] = '0' + TEN_TEC_LOG_PREC;
|
||||
|
||||
rigMEM_enabled = false;
|
||||
noshare.freq = 7070000L;
|
||||
noshare.midfreq = 1000L;
|
||||
noshare.flag = 2;
|
||||
freqflag = &noshare;
|
||||
// bool fail = false;
|
||||
|
||||
shmid = shmget ((key_t)1234, sizeof(sharedmem), 0666 | IPC_CREAT);
|
||||
|
||||
|
|
@ -94,9 +98,7 @@ void rigMEM_init(void)
|
|||
fl_message("rigMEM init: pthread_create failed");
|
||||
return;
|
||||
}
|
||||
// else {
|
||||
// std::cout << "rigMEM thread\n"; fflush(stdout);
|
||||
// }
|
||||
|
||||
rigMEM_enabled = true;
|
||||
}
|
||||
|
||||
|
|
@ -109,7 +111,6 @@ void rigMEM_close(void)
|
|||
|
||||
// and then wait for it to die
|
||||
fl_join(rigMEM_thread);
|
||||
//std::cout <<"rigMEM down\n"; fflush(stdout);
|
||||
rigMEM_enabled = false;
|
||||
rigMEM_exit = false;
|
||||
|
||||
|
|
@ -118,32 +119,6 @@ void rigMEM_close(void)
|
|||
|
||||
}
|
||||
|
||||
bool rigMEM_active(void)
|
||||
{
|
||||
return (rigMEM_enabled);
|
||||
}
|
||||
|
||||
bool rigMEM_CanPTT(void)
|
||||
{
|
||||
return rigMEMisPTT;
|
||||
}
|
||||
|
||||
void setrigMEM_PTT (bool on)
|
||||
{
|
||||
rigMEM_PTT = on;
|
||||
TogglePTT = true;
|
||||
}
|
||||
|
||||
void rigMEM_set_qsy(long long f, long long fmid)
|
||||
{
|
||||
if (!rigMEM_enabled)
|
||||
return;
|
||||
|
||||
qsy_f = f;
|
||||
qsy_fmid = fmid;
|
||||
rig_qsy = true;
|
||||
}
|
||||
|
||||
static void *rigMEM_loop(void *args)
|
||||
{
|
||||
SET_THREAD_ID(RIGCTL_TID);
|
||||
|
|
@ -219,5 +194,143 @@ static void *rigMEM_loop(void *args)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#else // __CYGWIN__
|
||||
//===================================================
|
||||
// Windows interface to Kachina / rigCAT
|
||||
//
|
||||
|
||||
FILE *IOout;
|
||||
FILE *IOin;
|
||||
int IOflag;
|
||||
long IOfreq = 7070000L;
|
||||
long IOmidfreq = 1000L;
|
||||
char szmode[80];
|
||||
|
||||
void rigMEM_init(void)
|
||||
{
|
||||
rigMEM_enabled = false;
|
||||
|
||||
rig_qsy = false;
|
||||
rigMEM_PTT = PTT_OFF;
|
||||
TogglePTT = false;
|
||||
rigMEMisPTT = false;
|
||||
|
||||
if (fl_create_thread(rigMEM_thread, rigMEM_loop, &dummy) < 0) {
|
||||
fl_message("rigMEM init: pthread_create failed");
|
||||
return;
|
||||
}
|
||||
rigMEM_enabled = true;
|
||||
}
|
||||
|
||||
void rigMEM_close(void)
|
||||
{
|
||||
if (!rigMEM_enabled) return;
|
||||
|
||||
// delete the ptt control file so Kachina can work stand alone
|
||||
remove("c:/RIGCTL/ptt");
|
||||
|
||||
// tell the rigMEM thread to kill it self
|
||||
rigMEM_exit = true;
|
||||
|
||||
// and then wait for it to die
|
||||
fl_join(rigMEM_thread);
|
||||
//std::cout <<"rigMEM down\n"; fflush(stdout);
|
||||
rigMEM_enabled = false;
|
||||
rigMEM_exit = false;
|
||||
|
||||
wf->rfcarrier(0L);
|
||||
wf->USB(true);
|
||||
|
||||
}
|
||||
static void *rigMEM_loop(void *args)
|
||||
{
|
||||
SET_THREAD_ID(RIGCTL_TID);
|
||||
|
||||
int sb = true;
|
||||
|
||||
for (;;) {
|
||||
/* see if we are being canceled */
|
||||
if (rigMEM_exit)
|
||||
break;
|
||||
|
||||
// if (rig_qsy) {
|
||||
// freqflag->freq = qsy_f;
|
||||
// freqflag->flag = -2; // set frequency
|
||||
// MilliSleep(20);
|
||||
// if (active_modem->freqlocked() == true) {
|
||||
// active_modem->set_freqlock(false);
|
||||
// active_modem->set_freq((int)qsy_fmid);
|
||||
// active_modem->set_freqlock(true);
|
||||
// } else
|
||||
// active_modem->set_freq((int)qsy_fmid);
|
||||
// wf->carrier((int)qsy_fmid);
|
||||
// wf->rfcarrier(freqflag->freq);
|
||||
// wf->movetocenter();
|
||||
// rig_qsy = false;
|
||||
// } else if (TogglePTT) {
|
||||
if (TogglePTT) {
|
||||
IOout = fopen("c:/RIGCTL/ptt", "w");
|
||||
if (IOout) {
|
||||
if (rigMEM_PTT == PTT_ON)
|
||||
putc('X', IOout);
|
||||
else
|
||||
putc('R', IOout);
|
||||
fclose(IOin);
|
||||
}
|
||||
TogglePTT = false;
|
||||
}
|
||||
|
||||
IOin = fopen("c:/RIGCTL/rig", "r");
|
||||
if (IOin) {
|
||||
fscanf(IOin, "%ld\n", &IOfreq);
|
||||
fscanf(IOin, "%s", szmode);
|
||||
fclose(IOin);
|
||||
}
|
||||
if (strcmp(szmode,"LSB") == 0)
|
||||
sb = false;
|
||||
|
||||
if (wf->rfcarrier() != IOfreq)
|
||||
wf->rfcarrier(IOfreq);
|
||||
if (wf->USB() != sb)
|
||||
wf->USB(sb);
|
||||
|
||||
// delay for 50 msec interval
|
||||
MilliSleep(50);
|
||||
|
||||
}
|
||||
|
||||
/* this will exit the rigMEM thread */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool rigMEM_active(void)
|
||||
{
|
||||
return (rigMEM_enabled);
|
||||
}
|
||||
|
||||
bool rigMEM_CanPTT(void)
|
||||
{
|
||||
return rigMEMisPTT;
|
||||
}
|
||||
|
||||
void setrigMEM_PTT (bool on)
|
||||
{
|
||||
rigMEM_PTT = on;
|
||||
TogglePTT = true;
|
||||
}
|
||||
|
||||
void rigMEM_set_qsy(long long f, long long fmid)
|
||||
{
|
||||
if (!rigMEM_enabled)
|
||||
return;
|
||||
|
||||
qsy_f = f;
|
||||
qsy_fmid = fmid;
|
||||
rig_qsy = true;
|
||||
}
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
|
|
|
|||
|
|
@ -984,22 +984,30 @@ void SoundPort::resample(int mode, float *buf, size_t count, size_t max)
|
|||
void SoundPort::init_stream(unsigned dir)
|
||||
{
|
||||
const char* dir_str[2] = { "input", "output" };
|
||||
PaDeviceIndex conf_idx[2] = { progdefaults.PortInIndex, progdefaults.PortOutIndex };
|
||||
PaDeviceIndex idx = paNoDevice;
|
||||
|
||||
#ifndef NDEBUG
|
||||
cerr << "PA_debug: looking for \"" << device[dir] << "\"\n";
|
||||
#endif
|
||||
for (idev[dir] = devs.begin(); idev[dir] != devs.end(); ++idev[dir])
|
||||
if (device[dir] == (*idev[dir])->name)
|
||||
for (idev[dir] = devs.begin(); idev[dir] != devs.end(); ++idev[dir]) {
|
||||
if (device[dir] == (*idev[dir])->name) {
|
||||
idx = idev[dir] - devs.begin(); // save this device index
|
||||
if (idx == conf_idx[dir]) // found it
|
||||
break;
|
||||
if (idev[dir] == devs.end()) {
|
||||
}
|
||||
}
|
||||
if (idx == paNoDevice) { // no match
|
||||
cerr << "PA_debug: could not find \"" << device[dir]
|
||||
<< "\", using default " << dir_str[dir] << " device\n";
|
||||
PaDeviceIndex def = (dir == STREAM_IN ? Pa_GetDefaultInputDevice() : Pa_GetDefaultOutputDevice());
|
||||
if (def == paNoDevice)
|
||||
throw SndPortException(paDeviceUnavailable);
|
||||
idev[dir] = devs.begin() + def;
|
||||
idx = def;
|
||||
}
|
||||
PaDeviceIndex idx = idev[dir] - devs.begin();
|
||||
else if (idev[dir] == devs.end()) // if we only found a near-match point the idev iterator to it
|
||||
idev[dir] = devs.begin() + idx;
|
||||
|
||||
#ifndef NDEBUG
|
||||
cerr << "PA_debug: using " << dir_str[dir] << " device:"
|
||||
|
|
@ -1094,8 +1102,10 @@ bool SoundPort::full_duplex_device(const PaDeviceInfo* dev)
|
|||
|
||||
bool SoundPort::must_close(void)
|
||||
{
|
||||
return stream_active(STREAM_OUT) &&
|
||||
Pa_GetHostApiInfo((*idev[STREAM_OUT])->hostApi)->type == paOSS;
|
||||
if (!stream_active(STREAM_OUT))
|
||||
return false;
|
||||
const PaHostApiInfo* api = Pa_GetHostApiInfo((*idev[STREAM_OUT])->hostApi);
|
||||
return api && (api->type == paOSS || api->type == paMME);
|
||||
}
|
||||
|
||||
// Determine the sample rate that we will use. We try the modem's rate
|
||||
|
|
|
|||
|
|
@ -0,0 +1,262 @@
|
|||
#include <config.h>
|
||||
|
||||
#if USE_PORTAUDIO
|
||||
# include <map>
|
||||
# include <list>
|
||||
#endif
|
||||
|
||||
#include "soundconf.h"
|
||||
#include "sound.h"
|
||||
#include "main.h"
|
||||
#include "configuration.h"
|
||||
#include "confdialog.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
static void init_oss(void)
|
||||
{
|
||||
#if USE_OSS
|
||||
glob_t gbuf;
|
||||
glob("/dev/dsp*", 0, NULL, &gbuf);
|
||||
for (size_t i = 0; i < gbuf.gl_pathc; i++)
|
||||
menuOSSDev->add(gbuf.gl_pathv[i]);
|
||||
if (progdefaults.OSSdevice.length() == 0 && gbuf.gl_pathc)
|
||||
progdefaults.OSSdevice = gbuf.gl_pathv[0];
|
||||
menuOSSDev->value(progdefaults.OSSdevice.c_str());
|
||||
globfree(&gbuf);
|
||||
|
||||
glob("/dev/mixer*", 0, NULL, &gbuf);
|
||||
for (size_t i = 0; i < gbuf.gl_pathc; i++)
|
||||
menuMix->add(gbuf.gl_pathv[i]);
|
||||
if (progdefaults.MXdevice.length() == 0 && gbuf.gl_pathc)
|
||||
progdefaults.MXdevice = gbuf.gl_pathv[0];
|
||||
globfree(&gbuf);
|
||||
menuMix->value(progdefaults.MXdevice.c_str());
|
||||
#else
|
||||
progdefaults.EnableMixer = false;
|
||||
tabMixer->deactivate();
|
||||
#endif // USE_OSS
|
||||
}
|
||||
|
||||
|
||||
#if USE_PORTAUDIO
|
||||
|
||||
map<PaHostApiTypeId, unsigned> pa_api_prio;
|
||||
|
||||
struct padev
|
||||
{
|
||||
public:
|
||||
padev(const PaDeviceInfo* dev_, PaDeviceIndex idx_, PaHostApiTypeId api_)
|
||||
: dev(dev_), idx(idx_), api(api_) { }
|
||||
|
||||
bool operator<(const padev& rhs) const
|
||||
{
|
||||
return pa_api_prio.find(api) != pa_api_prio.end() &&
|
||||
pa_api_prio.find(rhs.api) != pa_api_prio.end() &&
|
||||
pa_api_prio[api] < pa_api_prio[rhs.api];
|
||||
}
|
||||
|
||||
const PaDeviceInfo* dev;
|
||||
PaDeviceIndex idx;
|
||||
PaHostApiTypeId api;
|
||||
};
|
||||
|
||||
#endif // USE_PORTAUDIO
|
||||
|
||||
|
||||
static void init_portaudio(void)
|
||||
{
|
||||
#if USE_PORTAUDIO
|
||||
SoundPort::initialize();
|
||||
if (SoundPort::devices().size() == 0) {
|
||||
cerr << "PortAudio did not find any devices!\n";
|
||||
return;
|
||||
}
|
||||
|
||||
pa_api_prio.clear();
|
||||
#if defined(__APPLE__)
|
||||
pa_api_prio[paASIO] = 0;
|
||||
pa_api_prio[paCoreAudio] = 1;
|
||||
#elif defined(__CYGWIN__)
|
||||
pa_api_prio[paASIO] = 0;
|
||||
pa_api_prio[paWASAPI] = 1;
|
||||
pa_api_prio[paDirectSound] = 2;
|
||||
pa_api_prio[paMME] = 3;
|
||||
#else
|
||||
pa_api_prio[paALSA] = 0;
|
||||
pa_api_prio[paJACK] = 1;
|
||||
pa_api_prio[paOSS] = 2;
|
||||
#endif
|
||||
|
||||
list<padev> devlist;
|
||||
for (SoundPort::device_iterator idev = SoundPort::devices().begin();
|
||||
idev != SoundPort::devices().end(); ++idev)
|
||||
devlist.push_back( padev(*idev, idev - SoundPort::devices().begin(),
|
||||
Pa_GetHostApiInfo((*idev)->hostApi)->type) );
|
||||
devlist.sort();
|
||||
|
||||
PaHostApiTypeId first_api = devlist.begin()->api;
|
||||
for (list<padev>::const_iterator ilist = devlist.begin();
|
||||
ilist != devlist.end(); ilist++) {
|
||||
string menu_item;
|
||||
string::size_type i = 0;
|
||||
if (ilist->api != first_api) { // add a submenu
|
||||
menu_item.append(Pa_GetHostApiInfo(ilist->dev->hostApi)->name).append(" devices/");
|
||||
i = menu_item.length();
|
||||
}
|
||||
menu_item.append(ilist->dev->name);
|
||||
// backslash-escape any slashes in the device name
|
||||
while ((i = menu_item.find('/', i)) != string::npos) {
|
||||
menu_item.insert(i, 1, '\\');
|
||||
i += 2;
|
||||
}
|
||||
// add to menu
|
||||
if (ilist->dev->maxInputChannels > 0)
|
||||
menuPortInDev->add(menu_item.c_str(), 0, NULL,
|
||||
reinterpret_cast<void *>(ilist->idx), 0);
|
||||
if (ilist->dev->maxOutputChannels > 0)
|
||||
menuPortOutDev->add(menu_item.c_str(), 0, NULL,
|
||||
reinterpret_cast<void *>(ilist->idx), 0);
|
||||
}
|
||||
|
||||
if (progdefaults.PortInDevice.length() == 0) {
|
||||
if (progdefaults.PAdevice.length() == 0) {
|
||||
PaDeviceIndex def = Pa_GetDefaultInputDevice();
|
||||
if (def != paNoDevice) {
|
||||
progdefaults.PortInDevice = (*(SoundPort::devices().begin() + def))->name;
|
||||
progdefaults.PortInIndex = def;
|
||||
}
|
||||
}
|
||||
else
|
||||
progdefaults.PortInDevice = progdefaults.PAdevice;
|
||||
}
|
||||
|
||||
if (progdefaults.PortOutDevice.length() == 0) {
|
||||
if (progdefaults.PAdevice.length() == 0) {
|
||||
PaDeviceIndex def = Pa_GetDefaultOutputDevice();
|
||||
if (def != paNoDevice) {
|
||||
progdefaults.PortOutDevice = (*(SoundPort::devices().begin() + def))->name;
|
||||
progdefaults.PortOutIndex = def;
|
||||
}
|
||||
}
|
||||
else
|
||||
progdefaults.PortOutDevice = progdefaults.PAdevice;
|
||||
}
|
||||
|
||||
// select the correct menu items
|
||||
const Fl_Menu_Item* menu;
|
||||
int size;
|
||||
|
||||
menu = menuPortInDev->menu();
|
||||
size = menuPortInDev->size();
|
||||
for (int i = 0; i < size - 1; i++, menu++) {
|
||||
if (menu->label() && progdefaults.PortInDevice == menu->label()) {
|
||||
if (progdefaults.PortInIndex != -1 &&
|
||||
reinterpret_cast<intptr_t>(menu->user_data()) != progdefaults.PortInIndex)
|
||||
continue;
|
||||
menuPortInDev->value(i);
|
||||
menuPortInDev->set_changed();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
menu = menuPortOutDev->menu();
|
||||
size = menuPortOutDev->size();
|
||||
for (int i = 0; i < size - 1; i++, menu++) {
|
||||
if (menu->label() && progdefaults.PortOutDevice == menu->label()) {
|
||||
if (progdefaults.PortOutIndex != -1 &&
|
||||
reinterpret_cast<intptr_t>(menu->user_data()) != progdefaults.PortOutIndex)
|
||||
continue;
|
||||
menuPortOutDev->value(i);
|
||||
menuPortOutDev->set_changed();
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void sound_init(void)
|
||||
{
|
||||
init_oss();
|
||||
|
||||
init_portaudio();
|
||||
|
||||
// set the Sound Card configuration tab to the correct initial values
|
||||
#if !USE_OSS
|
||||
AudioOSS->deactivate();
|
||||
btnAudioIO[SND_IDX_OSS]->deactivate();
|
||||
#endif
|
||||
#if !USE_PORTAUDIO
|
||||
AudioPort->deactivate();
|
||||
btnAudioIO[SND_IDX_PORT]->deactivate();
|
||||
#endif
|
||||
#if !USE_PULSEAUDIO
|
||||
AudioPulse->deactivate();
|
||||
btnAudioIO[SND_IDX_PULSE]->deactivate();
|
||||
#endif
|
||||
if (progdefaults.btnAudioIOis == SND_IDX_UNKNOWN ||
|
||||
!btnAudioIO[progdefaults.btnAudioIOis]->active()) { // or saved sound api now disabled
|
||||
for (size_t i = 0; i < sizeof(btnAudioIO)/sizeof(*btnAudioIO); i++) {
|
||||
if (btnAudioIO[i]->active()) {
|
||||
progdefaults.btnAudioIOis = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sound_update(progdefaults.btnAudioIOis);
|
||||
|
||||
resetMixerControls();
|
||||
}
|
||||
|
||||
void sound_close(void)
|
||||
{
|
||||
#if USE_PORTAUDIO
|
||||
SoundPort::terminate();
|
||||
#endif
|
||||
}
|
||||
|
||||
void sound_update(unsigned idx)
|
||||
{
|
||||
// radio button
|
||||
for (size_t i = 0; i < sizeof(btnAudioIO)/sizeof(*btnAudioIO); i++)
|
||||
btnAudioIO[i]->value(i == idx);
|
||||
|
||||
// devices
|
||||
menuOSSDev->deactivate();
|
||||
menuPortInDev->deactivate();
|
||||
menuPortOutDev->deactivate();
|
||||
inpPulseServer->deactivate();
|
||||
|
||||
// settings
|
||||
menuInSampleRate->deactivate();
|
||||
menuOutSampleRate->deactivate();
|
||||
|
||||
progdefaults.btnAudioIOis = idx;
|
||||
switch (idx) {
|
||||
case SND_IDX_OSS:
|
||||
menuOSSDev->activate();
|
||||
scDevice[0] = scDevice[1] = menuOSSDev->value();
|
||||
break;
|
||||
case SND_IDX_PORT:
|
||||
menuPortInDev->activate();
|
||||
menuPortOutDev->activate();
|
||||
menuInSampleRate->activate();
|
||||
menuOutSampleRate->activate();
|
||||
if (menuPortInDev->text())
|
||||
scDevice[0] = menuPortInDev->text();
|
||||
if (menuPortOutDev->text())
|
||||
scDevice[1] = menuPortOutDev->text();
|
||||
break;
|
||||
case SND_IDX_PULSE:
|
||||
inpPulseServer->activate();
|
||||
menuInSampleRate->activate();
|
||||
menuOutSampleRate->activate();
|
||||
scDevice[0] = scDevice[1] = inpPulseServer->value();
|
||||
break;
|
||||
case SND_IDX_NULL:
|
||||
scDevice[0] = scDevice[1] = "";
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
|
@ -40,6 +40,7 @@
|
|||
|
||||
#include <FL/Fl.H>
|
||||
|
||||
#include "soundconf.h"
|
||||
#include "ringbuffer.h"
|
||||
#include "qrunner.h"
|
||||
|
||||
|
|
@ -99,12 +100,10 @@ void trx_trx_receive_loop()
|
|||
catch (const SndException& e) {
|
||||
put_status(e.what(), 5);
|
||||
scard->Close();
|
||||
#if USE_PORTAUDIO
|
||||
if (e.error() == EBUSY && progdefaults.btnAudioIOis == SND_IDX_PORT) {
|
||||
SoundPort::terminate();
|
||||
SoundPort::initialize();
|
||||
sound_close();
|
||||
sound_init();
|
||||
}
|
||||
#endif
|
||||
MilliSleep(1000);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
Ładowanie…
Reference in New Issue