#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/time.h>
#include <curses.h>
#include <keycodes.h>
#include "mfjterm.h"
#include "init.h"
#include "fkeys.h"
#include "scrollback.h"
#include "yapp.h"
#include "inout.h"
#include "rs232.h"
#include "misc.h"
#include "opmode.h"
#include "cq.h"
#include "qso.h"
#include "file.h"
#include "timefuncs.h"
#define TAB 9
#define ESC 27
extern char nofifo;
unsigned char pc2latin[128] =
{
199, 252, 233, 226, 228, 224, 229, 231, 234, 235, 232, 239, 238, 236, 196, 197,
201, 230, 198, 244, 246, 242, 251, 249, 255, 214, 220, 162, 163, 165, 0, 0,
225, 237, 243, 250, 241, 209, 170, 186, 191, 0, 172, 189, 188, 161, 171, 187,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 223, 0, 0, 0, 0, 181, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 177, 0, 0, 0, 0, 247, 0, 176, 0, 183, 0, 0, 178, 0, 160
};
unsigned char latin2pc[128] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
255, 173, 155, 156, 254, 157, 124, 21, 254, 254, 166, 174, 170, 45, 254, 254,
248, 241, 253, 254, 254, 230, 20, 249, 254, 254, 167, 175, 172, 171, 254, 168,
254, 254, 254, 254, 142, 143, 146, 128, 254, 144, 254, 254, 254, 254, 254, 254,
254, 165, 254, 254, 254, 254, 153, 254, 232, 254, 254, 254, 154, 254, 254, 225,
133, 160, 131, 254, 132, 134, 145, 135, 138, 130, 136, 137, 141, 161, 140, 139,
254, 164, 149, 162, 147, 254, 148, 246, 237, 151, 163, 150, 129, 254, 254, 152
};
char tab_move[80] = {
8,7,6,5,4,3,2,1,
8,7,6,5,4,3,2,1,
8,7,6,5,4,3,2,1,
8,7,6,5,4,3,2,1,
8,7,6,5,4,3,2,1,
8,7,6,5,4,3,2,1,
8,7,6,5,4,3,2,1,
8,7,6,5,4,3,2,1,
8,7,6,5,4,3,2,1,
7,6,5,4,3,2,1,0
};
void toggle_translate(void)
{
static char *translate_state[2] = {"Off", "On"};
char tmp[80];
pc_translate ^= 1;
curs_set(0);
attrset(A_REVERSE);
move(19, 1);
sprintf(tmp, "PC <-> Latin1 character translation now %s", translate_state[pc_translate]);
addstr(tmp);
refresh();
sleep(1);
move(19, 1);
addstr(" ");
move(tnc_y, tnc_x);
curs_set(1);
refresh();
}
void toggle_bell(void)
{
static char *translate_state[2] = {"Off", "On"};
char tmp[80];
bell ^= 1;
curs_set(0);
attrset(A_REVERSE);
move(19, 1);
sprintf(tmp, "Bell now %s", translate_state[bell]);
addstr(tmp);
refresh();
sleep(1);
move(19, 1);
addstr(" ");
move(tnc_y, tnc_x);
curs_set(1);
refresh();
}
void read_key(void)
{
int key;
key = getch();
if (key < KEY_MIN) {
if (key == ESC) {
key = getch();
switch (key) {
case 'a':
set_bps();
break;
case 'b':
scrollback();
break;
case 'c':
conn();
break;
case 'd':
send_daytime();
break;
case 'e':
invoke_editor();
break;
case 'f':
if ((opmode == AMTOR) != (opmode == PACTOR))
switch_fec(fec ^= 1);
break;
case 'g':
grab_callsign();
break;
case 'h':
show_help();
break;
case 'k':
set_my_callsign();
break;
case 'o':
change_opmode();
break;
case 'p':
toggle_translate();
break;
case 'q':
send_cq();
break;
case 'r':
send_ry();
break;
case 's':
save_settings();
break;
case 't':
turn_it_over();
break;
case 'u':
if (opmode == RTTY)
set_usos(usos ^= 1);
break;
case 'w':
save_sb_buf();
break;
case 'x':
quit(0);
break;
case 'y':
set_scancrit();
break;
case 'z':
get_call();
break;
default:
curs_set(0);
move(19, 1);
attrset(A_REVERSE);
addstr("Illegal command");
refresh();
sleep(2);
move(19, 1);
addstr(" ");
attrset(A_NORMAL);
move(tnc_y, tnc_x);
curs_set(1);
refresh();
}
} else {
switch(key) {
case K_CTL_B:
toggle_bell();
break;
case K_CTL_X:
quit(1);
break;
case K_CTL_Y:
nodelay(stdscr, FALSE);
key = getch();
nodelay(stdscr, TRUE);
switch(key) {
case KEY_PPAGE:
yapp(YAPP_UL);
break;
case KEY_NPAGE:
yapp(YAPP_DL);
break;
}
break;
case K_CTL_F:
fkeys();
break;
case K_CTL_G:
bbs_capture();
break;
default:
write_tnc((unsigned char)key);
}
}
} else {
if ((key >= KEY_F(1)) && key <= KEY_F(10))
out_fk(key - KEY_F(1));
else {
switch(key) {
case KEY_BACKSPACE:
write_tnc(K_BACKSPACE);
break;
case KEY_PPAGE:
send_file();
break;
case KEY_NPAGE:
capture();
break;
case KEY_IC:
insert_call_sequence(1);
break;
case KEY_LEFT:
case KEY_RIGHT:
set_spd(key);
break;
case KEY_DOWN:
set_inv();
break;
case KEY_UP:
set_shift();
break;
case KEY_END:
end_qso();
break;
}
}
}
}
int chk_incoming(void)
{
struct timeval timeout;
FD_ZERO(&io_set);
FD_SET(tnc, &io_set);
timeout.tv_sec = 0;
timeout.tv_usec = 0;
return select(tnc + 1, &io_set, NULL, NULL, &timeout);
}
void send_string(unsigned char *s, int lfeed)
{
int i;
for (i = 0; i < strlen(s); i++) {
if (chk_incoming())
read_tnc();
write_tnc(s[i]);
zleep(1);
}
if (lfeed) {
if (chk_incoming())
read_tnc();
write_tnc(10);
}
}
void waitfor_string(unsigned char *s)
{
fd_set io_set;
struct timeval timeout;
w_cmpstr = (s[0] << 24) + (s[1] << 16) + (s[2] << 8) + (s[3]);
w_instr = 0;
w_found = FALSE;
wait_string = TRUE;
while (! w_found) {
FD_ZERO(&io_set);
FD_SET(0, &io_set);
FD_SET(tnc, &io_set);
timeout.tv_sec = 0;
timeout.tv_usec = 400000;
if (select(tnc+1, &io_set, NULL, NULL, &timeout) > 0) {
if (FD_ISSET(tnc, &io_set))
read_tnc();
if (FD_ISSET(0, &io_set))
break;
}
}
}
void write_tnc(unsigned char c)
{
setscrreg(20, 24);
attrset(A_NORMAL);
move(console_y, console_x);
if (c < 0x20) {
switch(c) {
case K_CTL_C:
case K_CTL_T:
case K_CTL_R:
case K_CTL_Y:
goto tnc_only;
}
}
if (c == 13) c = K_LINEFEED;
addch(c);
switch(c) {
case K_LINEFEED:
console_x = 0;
console_y++;
c = 13;
break;
case K_BACKSPACE:
if (console_x > 0) {
console_x--;
move(console_y, console_x);
addch(' ');
}
break;
case K_TAB:
console_x += tab_move[console_x];
break;
default:
if ((++console_x) == 80) {
addch(K_LINEFEED);
console_x = 0;
console_y++;
}
}
if (console_y > 24)
console_y = 24;
move(console_y, console_x);
tnc_only:
if ((c >= 128) && (pc_translate)) {
c = latin2pc[c - 128];
if (c == 0)
c = ' ';
}
write(tnc, &c, 1);
refresh();
}
void new_bufline(void)
{
sb_bufstr[strno][strptr] = 0;
if (++strno > 808)
strno = 0;
strptr = 0;
memset(sb_bufstr[strno], 0, 81);
if (lines_in_buffer < 808)
lines_in_buffer++;
}
void newline(void)
{
addch(K_LINEFEED);
new_bufline();
tnc_x = 0;
tnc_y++;
}
void read_tnc(void)
{
static unsigned char cbuf[128];
unsigned char c;
static char old_c = 0xff, cmdflag = FALSE;
int i, n;
n = read(tnc, cbuf, 128);
setscrreg(1, 18);
attrset(A_NORMAL);
move(tnc_y, tnc_x);
for (i = 0; i < n; i++) {
if (cmdflag) {
cmdflag = FALSE;
newline();
if (tnc_y > 18) tnc_y = 18;
}
c = cbuf[i];
if ((c >= 128) && (pc_translate)) {
c = pc2latin[c - 128];
if (c == 0)
c = ' ';
}
if (cap)
fputc((char)c, capf);
if (bbs_cap && bbs_capf_open) {
fputc((char)c, bbs_capf);
if ((c == 10) && (old_c == 10)) {
close_bbs_capf();
old_c = 0xff;
} else
old_c = c;
}
if (c >= 0x20) {
if ((c != 127) && (c != 128+27)) {
addch(c);
sb_bufstr[strno][strptr++] = c;
if ((++tnc_x) == 80)
newline();
}
} else {
switch(c) {
case K_CTL_G: /* Ctrl-G, Bell */
if(bell) beep();
break;
case K_LINEFEED:
newline();
break;
case K_TAB:
/* addch(c); */ /* buggy */
tnc_x += tab_move[tnc_x];
memset(&sb_bufstr[strno][strptr], 0x20,
tab_move[strptr]);
strptr += tab_move[strptr];
break;
case K_BACKSPACE:
if (tnc_x > 0) {
tnc_x--;
move(tnc_y, tnc_x);
addch(' ');
}
if (--strptr == -1)
strptr = 0;
break;
}
}
if (tnc_y > 18)
tnc_y = 18;
move(tnc_y, tnc_x);
cmdstr <<= 8;
cmdstr += (int)c;
if (cmdstr == 0x636D643A) /* Check for 'cmd:' string */
cmdflag = TRUE;
if (scan || cs_grab || bbs_cap) {
strcpy(scanstr,&scanstr[1]);
scanstr[29] = c;
if (! cs_grab) {
if (scan) {
if (strstr(scanstr,scancrit))
sound_alarm();
} else if (! bbs_capf_open) {
char *p;
if ((p = strstr(scanstr, HOME_BBS">FBB")) &&
(strrchr(scanstr, '\012') ==
scanstr + strlen(scanstr) - 1))
open_bbs_capf(FBB);
else if ((p = strstr(scanstr, HOME_BBS">MAIL")) &&
(strrchr(scanstr, '\012') ==
scanstr + strlen(scanstr) - 1))
open_bbs_capf(MAIL);
}
}
}
if (wait_string) {
w_instr <<= 8;
w_instr += c;
if (w_instr == w_cmpstr) {
w_found = TRUE;
wait_string = FALSE;
}
}
refresh();
}
}