From: Cathryn Mataga <cathryn@junglevision.com>
To: Thomas Osterried <thomas@osterried.de>
Cc: n1uro@n1uro.ampr.org, Ralf Baechle <ralf@linux-mips.org>,
linux-hams <linux-hams@vger.kernel.org>
Subject: utf8-patch
Date: Tue, 16 Jul 2013 23:54:31 -0700 [thread overview]
Message-ID: <51E63FA7.7070601@junglevision.com> (raw)
In-Reply-To: <AE263F20-4B10-465A-BBAE-DB62498DB3CF@osterried.de>
[-- Attachment #1: Type: text/plain, Size: 422 bytes --]
>Cathryn, there's also work left for your utf8-patch in the userspace
call program. It has been some years ago, and it >came right after
serveral bugfixes that crashed the call program. I
I had a free evening, so I rebased this patch with the most recent
code. I got as far as determining that the code still works for me,
but it's not extensively tested. This needs to link to ncursesw rather
than ncurses.
[-- Attachment #2: patch.ax25-apps-0.0.8-rc4.callintl --]
[-- Type: text/plain, Size: 47147 bytes --]
diff -pruN '--exclude=*.dep*' '--exclude=Makefile' '--exclude=config.status' '--exclude=*.log' '--exclude=*.swp' ax25-apps-0.0.8-rc4/call/call.c ax25-apps-0.0.8-rc4.callintl/call/call.c
--- ax25-apps-0.0.8-rc4/call/call.c 2013-06-17 03:10:27.000000000 -0400
+++ ax25-apps-0.0.8-rc4.callintl/call/call.c 2013-07-17 02:26:34.096307443 -0400
@@ -35,7 +35,15 @@
#include <sys/wait.h>
#include <termios.h>
#include <unistd.h>
+#define __USE_XOPEN
+#include <wchar.h>
+#include <wctype.h>
+#define _XOPEN_SOURCE_EXTENDED 1
#include <curses.h>
+#include <ncurses.h>
+#include <locale.h>
+#include <iconv.h>
+#include <sys/ioctl.h>
#include <netax25/ax25.h>
#include <netrom/netrom.h>
@@ -78,10 +86,13 @@ static char *port = NULL;
static char *mycall = NULL;
static int stdin_is_tty = 1;
+static iconv_t ibm850toutf8 = 0,wcharttoibm850 = 0, wcharttoutf8 = 0, utf8towchart = 0;
int interrupted = FALSE;
+static int sigwinchsignal = FALSE;
int paclen = 0;
int fd;
+int curson = 1;
int wait_for_remote_disconnect = FALSE;
static struct timeval inactivity_timeout;
@@ -103,7 +114,7 @@ typedef struct {
WINDOW *ptr;
int max_y;
int max_x;
- char string[MAX_BUFLEN];
+ wchar_t string[MAX_BUFLEN];
unsigned long bytes;
int curs_pos;
} t_win;
@@ -112,11 +123,234 @@ typedef struct {
#define SLAVEMODE 002 /* Menu mode */
#define RAWMODE 004 /* mode used by earlier versions */
+#define ORIGINALENCODING 0
+#define UTF8ENCODING 1
+
+#define SCROLLBACKSIZE 5000
+
+typedef struct {
+ char *str;int len;
+}scrollbackstruct;
+
+
+static scrollbackstruct scrollback[SCROLLBACKSIZE];
+static int topscroll=0, lastscroll = 0, scrolledup=0, eatchar = 0;
+static char inbuf[MAX_BUFLEN];static int inbuflen = 0, inbufwid = 0;
+static char incharbuf[6];static int incharbuflen = 0;
+void statline(int mode, char *s);
+
+void addscrollline(char *s, int len)
+{
+ scrollback[lastscroll].str = malloc(len);
+ memcpy(scrollback[lastscroll].str, s, len);
+ scrollback[lastscroll].len = len;
+ if (++lastscroll >= SCROLLBACKSIZE)lastscroll = 0;
+ if (lastscroll == topscroll){
+ free(scrollback[topscroll].str);
+ if (++topscroll >= SCROLLBACKSIZE)topscroll = 0;
+ }
+}
+
+// Notes: Japanese, Chinese and Korean characters mostly take up two
+// characters in width. These characters return 2 via
+// wcwidth to let the code know that they require two
+// spaces. Mono-space fonts/ncurses seems to work correctly with
+// East Asian characters.
+//
+// There are also some characters that return a wcwidth of 0. I'm
+// not sure about all of them, but some of the 0 width characters
+// add a mark above or below a character. In order for these marks
+// to appear correctly, the previous character and the overstrike
+// must be drawn together. using wmove and drawing the accent doesn't
+// work.
+//
+// There are some other characters that have functions, and these
+// are not supported using a print to the screen. South Asian
+// fonts are complicated. I don't believe south asian fonts work
+// correctly from the Linux command line (as of late 2009). They
+// print but don't combine. The result is distorted.
+//
+// Many characters, as of 12/09, are too wide for a single space
+// in the font, although they return a wcwidth of 1. I suspect
+// this is due to these characters not being part of the mono-spaced
+// font and are instead pulled from an alternate font. These
+// characters also glitch in xterm, vim and other ncurses
+// software. I suspect this is actually a font bug, and any character
+// that returns wcwidth=1 in a monospaced font should be
+// monospaced.
+//
+
+
+int widthchar(char *s, size_t bytes, int xpos)
+{
+ wchar_t c;int width;
+ char *outbuf=(char *) &c;
+ size_t outsize = sizeof(wchar_t);
+ // Note: Actually need to check if bad UTF8 characters show as ?
+ if (iconv(utf8towchart, &s, &bytes, &outbuf, &outsize)< 0)return 0;
+ if (c == 9){
+ return 8 - (xpos & 7);
+ }
+ width = wcwidth(c);
+ if (width < 0)return 0;
+ return width;
+}
+
+
+int completecharlen(char *s)
+{
+ unsigned ut = (unsigned char)s[0];int clen;
+ if (ut <= 0x80)clen = 1;
+ else if ((ut >= 192) && (ut < 192+32))clen = 2;
+ else if ((ut >= 224) && (ut < 224+16))clen = 3;
+ else if ((ut >= 240) && (ut < 240+8))clen = 4;
+ else if ((ut >= 248) && (ut < 248+4))clen = 5;
+ else if ((ut >= 252) && (ut < 252+2))clen = 6;
+ else clen = 1; // bad
+ return clen;
+}
+
+
+// Must check for COLS while redrawing from history. Or otherwise the text
+// wraps around and does strange things.
+int waddnstrcolcheck(WINDOW *win, char *s, int len, int twidth)
+{
+ int n;
+ for (twidth = 0,n=0;n<len;){
+ int cwidth = completecharlen(&s[n]), width;
+ if (n + cwidth > len)return twidth; // Error condition
+ width = widthchar(&s[n], cwidth, twidth);
+ if (twidth+width > COLS)return twidth; //
+ waddnstr(win, &s[n], cwidth);
+ n += cwidth;
+ twidth += width;
+ }
+ return twidth;
+}
+
+// Update a line on the screen from the backscroll buffer.
+void updateline(int screeny, int yfrom, t_win *win_in, int mode, t_win *win_out)
+{
+ wmove(win_in->ptr, screeny, 0);
+ if (yfrom == lastscroll){
+ int twidth = 0;
+ if (inbuflen > 0)
+ twidth = waddnstrcolcheck(win_in->ptr, inbuf, inbuflen, 0);
+ if (mode == SLAVEMODE){
+ char obuf[MAX_BUFLEN];
+ char *inbuf = (char *)win_out->string, *outbuf = obuf;
+ size_t insize = win_out->bytes * sizeof(wchar_t), outsize = MAX_BUFLEN;
+ iconv(wcharttoutf8, &inbuf, &insize, &outbuf, &outsize);
+ waddnstrcolcheck(win_in->ptr, obuf, MAX_BUFLEN - outsize, twidth);
+ win_out->curs_pos = win_out->bytes;
+ }
+ }
+ else {
+ waddnstrcolcheck(win_in->ptr, scrollback[yfrom].str, scrollback[yfrom].len, 0);
+ }
+}
+
+// Cursor in SLAVE mode while scrolling looks broken.
+// Cursor in TALK mode is always good, because it's on the bottom window
+void checkcursor(int mode)
+{
+ int newcursor;
+ if ((mode == SLAVEMODE) && scrolledup)newcursor = 0;
+ else newcursor = 1;
+ if (curson != newcursor){
+ curs_set(newcursor);
+ curson = newcursor;
+ }
+}
+
+/* For CJK, it's important to keep the cursor always on the input
+ * window. Otherwise the display is confused */
+static void restorecursor(int mode, t_win *win_out)
+{
+ checkcursor(mode);
+ if (mode != RAWMODE){
+ int x,y;
+ getyx(win_out->ptr, y, x);// Must restore input cursor location.
+ wmove(win_out->ptr,y, x);
+ wrefresh(win_out->ptr);
+ }
+}
+
+void redrawscreen(t_win *win_in, int mode, t_win *win_out)
+{
+ int y, storedlines;
+ if (lastscroll >= topscroll) storedlines = lastscroll - topscroll;
+ else storedlines = lastscroll + SCROLLBACKSIZE - topscroll;
+ // Note it's stored lines + 1 extra line for text input.
+ for (y=0;(y<=win_in->max_y) && (y <= storedlines);y++){
+ int linefrom;
+ if (storedlines <= win_in->max_y){// This is a little confusing.
+ linefrom = topscroll + y;// The screen scrolls top down at start
+ }
+ else linefrom = lastscroll -scrolledup - (win_in->max_y) + y;
+ while (linefrom < 0)linefrom += SCROLLBACKSIZE;
+ while (linefrom >= SCROLLBACKSIZE)linefrom -= SCROLLBACKSIZE;
+ updateline(y,linefrom , win_in, mode, win_out);
+ }
+ checkcursor(mode);
+}
+
+void scrolltext(t_win *win_in, int lines, int mode, t_win *win_out)
+{
+ int topline, storedlines;
+ int y;
+ int wasscrolledup;
+ if (scrolledup + lines < 0){
+ lines = -scrolledup;
+ }
+ // storedlines = Lines stored in buffer.
+ if (lastscroll >= topscroll) storedlines = lastscroll - topscroll;
+ else storedlines = lastscroll + SCROLLBACKSIZE - topscroll;
+ // The max scrolling we can do is the # of lines stored - the
+ // screen size.
+ topline = storedlines - win_in->max_y;
+ if (topline < 0)topline = 0;
+ if (scrolledup + lines > topline){
+ lines = topline - scrolledup;
+ }
+ if (!lines)return;
+ wasscrolledup = scrolledup;
+ scrolledup += lines;
+ wscrl(win_in->ptr, -lines);
+ scrollok(win_in->ptr, FALSE);
+ if (lines > 0){
+ for (y=0;y<lines;y++){
+ int linefrom = lastscroll -scrolledup - (win_in->max_y) + y;
+ while (linefrom < 0)linefrom += SCROLLBACKSIZE;
+ while (linefrom >= SCROLLBACKSIZE)linefrom -= SCROLLBACKSIZE;
+ updateline(y,linefrom , win_in, mode, win_out);
+ }
+ }
+ else {
+ for (y=-lines-1;y>=0;y--){
+ int linefrom = lastscroll -scrolledup - y;
+ while (linefrom < 0)linefrom += SCROLLBACKSIZE;
+ while (linefrom >= SCROLLBACKSIZE)linefrom -= SCROLLBACKSIZE;
+ updateline(win_in->max_y - y,linefrom , win_in, mode, win_out);
+ }
+
+ }
+ scrollok(win_in->ptr, TRUE);
+ checkcursor(mode);
+ wrefresh(win_in->ptr);
+ if (wasscrolledup && !scrolledup){
+ statline(mode, "");
+ }
+ else if (!wasscrolledup && scrolledup){
+ statline(mode, "Viewing Scrollback");
+ }
+}
+
void usage(void)
{
- fprintf(stderr, "usage: call [-b l|e] [-d] [-h] [-m s|e] [-p paclen] [-r] [-R]\n");
- fprintf(stderr, " [-s mycall] [-t] [-T timeout] [-v] [-w window] [-W]\n");
- fprintf(stderr, " port callsign [[via] digipeaters...]\n");
+ fprintf(stderr, "usage: call [-b l|e] [-d] [-h] [-m s|e] [-p paclen] [-r] [-R]\n");
+ fprintf(stderr, " [-s mycall] [-t] [-T timeout] [-v] [-w window] [-W]\n");
+ fprintf(stderr, " port callsign [[via] digipeaters...]\n");
exit(1);
}
@@ -128,8 +362,8 @@ const char *key_words[] = { "//",
"\0"
};
const char *rkey_words[] = {
- // actually restricted keywords are very restrictive
- "\0"
+ // actually restricted keywords are very restrictive
+ "\0"
};
#define MAXCMDLEN 10
@@ -160,6 +394,73 @@ void convert_upper_lower(char *buf, int
}
+
+/* Return the with of this character in character blocks. (Normal = 1, CJK=2)
+ * Also for control chracters, return the width of the replacement string.
+ * */
+static int wcwidthcontrol(wchar_t c)
+{
+ int width;
+ cchar_t cc = {0};
+ wchar_t *str;
+ cc.chars[0] = c;
+ str = wunctrl(&cc);
+ if (!str)return 0;
+ width = wcswidth(str, wcslen(str));
+ return width;
+}
+
+/* Return a string to print for a wchar_t. Expand control characters.
+ * Strings returned by wunctrl don't like to be freed. It seems. */
+static wchar_t *wunctrlwchar(wchar_t c)
+{
+ cchar_t cc = {0};
+ wchar_t *str;
+ cc.chars[0] = c;
+ str = wunctrl(&cc);
+ return str;
+}
+
+// For some reason wins_nwstr fails on fedora 12 on some characters
+// but waddnstr works.
+// Draw the entire input buffer when adding text.
+// The fonts that do overstrike fail when written one char at a time.
+void drawinbuf(WINDOW *w, wchar_t *string, int bytes, int cur_pos)
+{
+ int n, x, cursorx, xpos, ypos, width;
+ getyx(w, ypos, xpos);// Assume cursor to be at position of current char to draw.
+ x = xpos;cursorx = xpos;
+ // cur_pos-1 = the chracter that was just added.
+ for (n=cur_pos-2;n>=0;n--){// Move x position to start of string or 0
+ width = wcwidthcontrol(string[n]);
+ if (x >= width)x -= width;
+ else x = 0;
+ }
+ wmove(w, ypos, x);
+ for (n=0;n<bytes;n++){
+ char obuf[MAX_BUFLEN];
+ char *inbuf, *outbuf = obuf;
+ size_t insize, outsize = MAX_BUFLEN;
+ wchar_t *str;int len, width;
+ if (n == cur_pos){
+ cursorx = x;
+ }
+ str = wunctrlwchar(string[n]);
+ if (!str)continue;
+ inbuf = (char *) str;
+ len = wcslen(str);
+ insize = len * sizeof(wchar_t);
+ width = wcswidth(str, len);
+ iconv(wcharttoutf8, &inbuf, &insize, &outbuf, &outsize);
+ waddnstr(w, obuf, MAX_BUFLEN-outsize);
+ x += width;
+ }
+ if (cur_pos < bytes){
+ wmove(w,ypos, cursorx);
+ }
+}
+
+
/* Convert linear UNIX date to a MS-DOS time/date pair. */
static char * unix_to_sfbin_date_string(time_t gmt)
@@ -411,6 +712,13 @@ static int connect_to(char *address[])
return (fd);
}
+
+static void cmd_sigwinch(int sig)
+{
+ signal(SIGWINCH, cmd_sigwinch);
+ sigwinchsignal = TRUE;
+}
+
void cmd_intr(int sig)
{
signal(SIGQUIT, cmd_intr);
@@ -428,7 +736,7 @@ void statline(int mode, char *s)
if (oldlen > 0) {
move(0, STATW_STAT);
attron(A_REVERSE);
- for (cnt = 0; cnt < oldlen; cnt++)
+ for (cnt = STATW_STAT; cnt < COLS; cnt++)
addch(' ');
oldlen = 0;
attroff(A_REVERSE);
@@ -441,21 +749,18 @@ void statline(int mode, char *s)
fflush(stdout);
return;
}
- if (strlen(s) > 80 - STATW_STAT)
- s[80 - STATW_STAT] = '\0';
+ if (COLS <= STATW_STAT)return;
+ l = strlen(s);
+ if (l > COLS - STATW_STAT)
+ l = COLS-STATW_STAT;
move(0, STATW_STAT);
attron(A_REVERSE);
- addstr(s);
-
- if (oldlen > strlen(s)) {
- l = oldlen - strlen(s);
- for (cnt = 0; cnt < l; cnt++)
- addch(' ');
- }
+ addnstr(s, l);
+ for (cnt = STATW_STAT+l;cnt < COLS;cnt++)addch(' ');
attroff(A_REVERSE);
- oldlen = strlen(s);
+ oldlen = l;
refresh();
}
@@ -487,7 +792,7 @@ void wrdstatw(WINDOW * win, char s[])
return;
}
waddstr(win, s);
- y = getcury(win);
+ y = getcury(win);
wmove(win, y + 1, 2);
wrefresh(win);
}
@@ -671,11 +976,11 @@ int start_ab_download(int mode, WINDOW *
}
if (bytes == 1) {
if (write(fd, "#OK#\r", 5) == -1) {
- perror("write");
- close(gp->dwn_file);
- gp->dwn_file = -1;
- gp->dwn_cnt = 0;
- gp->file_name[0] = '\0';
+ perror("write");
+ close(gp->dwn_file);
+ gp->dwn_file = -1;
+ gp->dwn_cnt = 0;
+ gp->file_name[0] = '\0';
return -1;
}
gp->calc_crc = 0;
@@ -683,26 +988,26 @@ int start_ab_download(int mode, WINDOW *
unsigned long offset = 0L;
while (offset != bytes) {
int ret = write(gp->dwn_file, buf+offset, bytes-offset);
- if (ret == -1) {
- perror("write");
- if (errno == EWOULDBLOCK || errno == EAGAIN) {
- usleep(100000);
- continue;
- }
- close(gp->dwn_file);
- gp->dwn_file = -1;
- gp->dwn_cnt = 0;
- gp->file_name[0] = '\0';
- return -1;
- }
- if (ret == 0) {
- close(gp->dwn_file);
- gp->dwn_file = -1;
- gp->dwn_cnt = 0;
- gp->file_name[0] = '\0';
- return -1;
- break;
- }
+ if (ret == -1) {
+ perror("write");
+ if (errno == EWOULDBLOCK || errno == EAGAIN) {
+ usleep(100000);
+ continue;
+ }
+ close(gp->dwn_file);
+ gp->dwn_file = -1;
+ gp->dwn_cnt = 0;
+ gp->file_name[0] = '\0';
+ return -1;
+ }
+ if (ret == 0) {
+ close(gp->dwn_file);
+ gp->dwn_file = -1;
+ gp->dwn_cnt = 0;
+ gp->file_name[0] = '\0';
+ return -1;
+ break;
+ }
gp->calc_crc = calc_crc((unsigned char *) buf, ret, 0);
gp->dwn_cnt -= ret;
offset += ret;
@@ -721,7 +1026,6 @@ int ab_down(int mode, WINDOW * swin, win
if (*bytes == 8 && strncmp(buf, "#ABORT#\r", 8) == 0) {
gp->dwn_cnt = 0;
close(gp->dwn_file);
- gp->dwn_file = -1;
statline(mode, "Remote aborts AutoBin transfer!");
gp->file_name[0] = '\0';
*bytes = 0;
@@ -779,9 +1083,8 @@ int ab_down(int mode, WINDOW * swin, win
}
statline(mode, s);
close(gp->dwn_file);
- gp->dwn_file = -1;
utime(gp->file_name, &gp->ut);
- gp->file_name[0] = '\0';
+ gp->file_name[0] = '\0';
if (extrach != 0) {
memmove(buf, buf + *bytes, extrach);
*bytes = extrach;
@@ -800,8 +1103,11 @@ int start_screen(char *call[])
{
int cnt;
char idString[12];
- sprintf(idString, " %9.9s ", call[0]);
+ struct winsize winsz = {0};
+ if ((ioctl(0, TIOCGWINSZ, &winsz) >= 0) && winsz.ws_row && winsz.ws_col)
+ resizeterm(winsz.ws_row, winsz.ws_col);
+ sprintf(idString, " %9.9s ", call[0]);
if ((win = initscr()) == NULL)
return -1;
@@ -811,7 +1117,8 @@ int start_screen(char *call[])
addch(ACS_VLINE);
addstr("--------");
addch(ACS_VLINE);
- for (cnt = STATW_STAT; cnt <= 80; cnt++)
+ move(0, STATW_STAT);
+ for (cnt = STATW_STAT; cnt < COLS; cnt++)
addch(' ');
attroff(A_REVERSE);
@@ -819,8 +1126,8 @@ int start_screen(char *call[])
raw();
nodelay(win, TRUE);
keypad(win, TRUE);
+ curson = 1;
refresh();
-
return 0;
}
@@ -841,7 +1148,8 @@ int start_slave_mode(wint * wintab, t_wi
win_out->curs_pos = 0;
win_in->bytes = 0;
win_in->curs_pos = 0;
-
+ redrawscreen(win_in, SLAVEMODE, win_out);
+ wrefresh(win_in->ptr);
return 0;
}
@@ -872,15 +1180,16 @@ int start_talk_mode(wint * wintab, t_win
scrollok(win_out->ptr, TRUE);
wclear(win_out->ptr);
- wrefresh(win_out->ptr);
wclear(win_in->ptr);
- wrefresh(win_in->ptr);
win_out->bytes = 0;
win_out->curs_pos = 0;
win_in->bytes = 0;
win_out->curs_pos = 0;
-
+ redrawscreen(win_in, TALKMODE, win_out);
+ restorecursor(TALKMODE, win_out);
+ wrefresh(win_in->ptr);
+ wrefresh(win_out->ptr);
return 0;
}
@@ -930,171 +1239,210 @@ int change_mode(int oldmode, int newmode
}
break;
}
-
+ scrolledup = 0;
return newmode;
}
-void writeincom(int mode, t_win * win_in, unsigned char buf[], int bytes)
+static void reinit_mode(int mode, wint * wintab, t_win * win_in,
+ t_win * win_out, char *call[])
{
- int cnt;
+ switch (mode) {
+ case RAWMODE:
+ break;
- if (mode & RAWMODE) {
- while (write(STDOUT_FILENO, buf, bytes) == -1) {
- if (errno == EWOULDBLOCK || errno == EAGAIN) {
- usleep(100000);
- continue;
- }
- exit(1);
- }
- return;
- }
- for (cnt = 0; cnt < bytes; cnt++) {
- switch (buf[cnt]) {
- case 201:
- case 218:
- waddch(win_in->ptr, ACS_ULCORNER);
- break;
- case 187:
- case 191:
- waddch(win_in->ptr, ACS_URCORNER);
- break;
- case 200:
- case 192:
- waddch(win_in->ptr, ACS_LLCORNER);
- break;
- case 188:
- case 217:
- waddch(win_in->ptr, ACS_LRCORNER);
- break;
- case 204:
- case 195:
- waddch(win_in->ptr, ACS_LTEE);
- break;
- case 185:
- case 180:
- waddch(win_in->ptr, ACS_RTEE);
- break;
- case 203:
- case 194:
- waddch(win_in->ptr, ACS_TTEE);
- break;
- case 202:
- case 193:
- waddch(win_in->ptr, ACS_BTEE);
- break;
- case 205:
- case 196:
- waddch(win_in->ptr, ACS_HLINE);
- break;
- case 186:
- case 179:
- waddch(win_in->ptr, ACS_VLINE);
- break;
- case 129:
- waddch(win_in->ptr, 252); /*u umlaut */
- break;
- case 132:
- waddch(win_in->ptr, 228); /*a umlaut */
- break;
- case 142:
- waddch(win_in->ptr, 196); /*A umlaut */
- break;
- case 148:
- waddch(win_in->ptr, 246); /*o umlaut */
- break;
- case 153:
- waddch(win_in->ptr, 214); /*O umlaut */
- break;
- case 154:
- waddch(win_in->ptr, 220); /*U umlaut */
+ case TALKMODE:// Clear the screen and re-init. Which looks awful.
+ wclear(win_out->ptr);
+ wrefresh(win_out->ptr);
+ wclear(win_in->ptr);
+ // wrefresh(win_in->ptr);
+ wintab->next = 0;
+ endwin();
+ start_screen(call);
+ start_talk_mode(wintab, win_in, win_out);
+ restorecursor(mode, win_out);
break;
- case 225:
- waddch(win_in->ptr, 223); /*sz */
+
+ case SLAVEMODE:// Also fix me.
+ wclear(win_out->ptr);
+ //wrefresh(win_out->ptr);
+ wintab->next = 0;
+ endwin();
+ start_screen(call);
+ start_slave_mode(wintab, win_in, win_out);
+ restorecursor(mode, win_out);
break;
- default:
- {
- if (buf[cnt] > 127)
- waddch(win_in->ptr, '.');
- else
- waddch(win_in->ptr, buf[cnt]);
+ }
+}
+
+
+void waddnstrcrcheck(t_win *win_in, char *buf, int bytes, int draw, int mode, t_win *win_out)
+{
+ int n;
+ for (n=0;n<bytes;n++){
+ int width;
+ incharbuf[incharbuflen++] = buf[n];
+ if (completecharlen(incharbuf) > incharbuflen)continue;
+ if (eatchar && (incharbuf[0] == '\n')){
+ eatchar = 0;
+ incharbuflen = 0;
+ continue;
+ }
+ width = widthchar(incharbuf, incharbuflen, inbufwid);
+ eatchar = 0;
+ if (draw) {
+ if (win_in) waddnstr(win_in->ptr, incharbuf, incharbuflen);
+ else write(STDOUT_FILENO, incharbuf, incharbuflen);
+ }
+ if (incharbuf[0] == '\n')incharbuflen = 0;
+ else if (width + inbufwid <= COLS){
+ if (inbuflen + incharbuflen <= MAX_BUFLEN){
+ memcpy(&inbuf[inbuflen], incharbuf, incharbuflen);
+ inbuflen += incharbuflen;
}
+ incharbuflen = 0;
+ inbufwid += width;
+ if (inbufwid >= COLS)eatchar = 1;
+ continue;// Skip to next line when width goes over.
+ }
+ addscrollline(inbuf, inbuflen);
+ if (incharbuflen){
+ memcpy(&inbuf[0], incharbuf, incharbuflen);
+ inbuflen = incharbuflen;
+ incharbuflen = 0;
+ inbufwid = width;
+ }
+ else {
+ inbuflen = 0;
+ inbufwid = 0;
+ }
+ if (scrolledup && win_in && win_out){
+ scrolledup++; // scrolledup is relative to bottom line
+ scrolltext(win_in, 0, mode, win_out);
}
}
+ if (draw && win_in) wrefresh(win_in->ptr);
+
+}
-/* waddnstr(win_in->ptr, buf, bytes); */
- wrefresh(win_in->ptr);
+void writeincom(int mode, int encoding, t_win * win_in, unsigned char buf[], int bytes, t_win *win_out)
+{
+ if (mode & RAWMODE) {
+ while (write(STDOUT_FILENO, buf, bytes) == -1) {
+ if (errno == EWOULDBLOCK || errno == EAGAIN) {
+ usleep(100000);
+ continue;
+ }
+ exit(1);
+ }
+ return;
+ }
+ // waddnstrcrcheck(0, (char *)buf, bytes,1, mode, 0); // Had this, but this is wrong.
+ else if (encoding == UTF8ENCODING)
+ waddnstrcrcheck(win_in, (char *)buf, bytes,scrolledup == 0, mode, win_out);
+ else {
+ char *inbuf = (char *) buf, out[MAX_BUFLEN], *outbuf=out;
+ size_t insize = bytes, outsize = MAX_BUFLEN;
+ iconv(ibm850toutf8, &inbuf, &insize, &outbuf, &outsize);
+ waddnstrcrcheck(win_in, out, MAX_BUFLEN-outsize,scrolledup == 0, mode, win_out);
+ }
return;
}
-
+static void writeincomstr(int mode, int encoding, t_win * win_in, char buf[], t_win *win_out)
+{
+ int len;
+ len = strlen(buf);
+ writeincom(mode, encoding, win_in, (unsigned char *)buf, len, win_out);
+}
+
+int outstring(char *buf, wchar_t *string, int bytes, int encoding)
+{
+ char *inbuf = (char *) string, *outbuf = buf;
+ size_t insize = bytes * sizeof(wchar_t), outsize = MAX_BUFLEN-1;
+ if (encoding == UTF8ENCODING){
+ iconv(wcharttoutf8, &inbuf, &insize, &outbuf, &outsize);
+ }
+ else {
+ iconv(wcharttoibm850, &inbuf, &insize, &outbuf, &outsize);
+
+ }
+ buf[(MAX_BUFLEN-1)-outsize] = '\0';
+ return (MAX_BUFLEN-1)-outsize;
+}
+
int getstring(wint * wintab, char text[], char buf[])
{
- int c;
+ wchar_t c;
int ypos = 0, xpos = 0;
int bytes = 0;
-
+ wchar_t wbuf[MAX_BUFLEN];
WINDOW *win = winopen(wintab, 3, COLS, 10, 0, TRUE);
+ int done = 0;
wmove(win, 1, 2);
waddstr(win, text);
wrefresh(win);
do {
- c = getch();
- if (c != ERR) {
- switch (c) {
- case KEY_BACKSPACE:
- case 127:
- {
- getyx(win, ypos, xpos);
- if (xpos > 0 && bytes > 0) {
- wmove(win, ypos, --xpos);
- waddch(win, ' ');
- wmove(win, ypos, xpos);
- bytes--;
- }
- }
- break;
- case (int) '\n':
- case (int) '\r':
- case KEY_ENTER:
- {
- waddch(win, '\n');
- buf[bytes++] = (char) '\n';
- wrefresh(win);
- buf[bytes] = 0;
- }
- break;
- default:
- {
- waddch(win, (char) c);
- buf[bytes++] = (char) c;
+ int r;
+ wint_t ci;
+ r = get_wch(&ci);
+ if (r != ERR) {
+ c = (wchar_t) ci;
+ if (((r == KEY_CODE_YES) && (c == KEY_BACKSPACE))||
+ ((r == OK) && ((c==127)|| (c==8)))){
+ getyx(win, ypos, xpos);
+ if (bytes > 0) {
+ int width, j;
+ width = wcwidthcontrol(wbuf[bytes-1]);
+ for (j=0;j<width;j++) mvwdelch(win, ypos, xpos-width);
+ xpos -= width;
+ wmove(win, ypos, xpos);
+ bytes--;
}
}
+ else if (( (r==KEY_CODE_YES) && (c == KEY_ENTER))||
+ ( (r == OK) && ((c=='\n') || (c=='\r')))){
+ wbuf[bytes++] = (wchar_t) '\n';
+ outstring(buf, wbuf, bytes, UTF8ENCODING);
+ done = 1;
+ }
+ else if (r == KEY_CODE_YES); // Put in code for other KEYCODES here
+ else if (bytes+2 < MAX_BUFLEN){
+ //int width;
+ //width = wins_nwchrmy(win, c);
+ //getyx(win, ypos, xpos);
+ //wmove(win, ypos, xpos+width);
+ wbuf[bytes++] = c;
+ drawinbuf(win, wbuf, bytes, bytes);
+ }
wrefresh(win);
}
}
- while (c != '\n' && c != '\r' && c != KEY_ENTER);
+ while (!done);
delwin(win);
winclose(wintab);
return 0;
}
int readoutg(t_win * win_out, wint * wintab, menuitem * top, char buf[],
- int keyesc)
+ int keyesc, int mode, int encoding, t_win *win_in)
{
- int out_cnt;
- int c;
+ int out_cnt, r;
+ wint_t ci;wchar_t c;
int ypos = 0, xpos = 0;
int value;
- c = getch();
- if (c == ERR)
+ r = get_wch(&ci);
+ if (r == ERR)
return 0;
-
+ c = (wchar_t) ci;
if (c == keyesc) {
- if ((value = top_menu(wintab, top, 1)) == 0)
+ if ((value = top_menu(wintab, top, 1)) == 0){
+ restorecursor(mode, win_out);
return 0;
+ }
+ restorecursor(mode, win_out);
buf[0] = '~';
switch (value) {
case 0x01:
@@ -1113,6 +1461,7 @@ int readoutg(t_win * win_out, wint * win
getstring(wintab,
"Please enter filename: ",
&buf[2]);
+ restorecursor(mode, win_out);
return strlen(buf);
}
case 0x12:
@@ -1137,6 +1486,7 @@ int readoutg(t_win * win_out, wint * win
getstring(wintab,
"Please enter filename: ",
buf + 2);
+ restorecursor(mode, win_out);
return strlen(buf);
}
case 0x21:
@@ -1160,97 +1510,164 @@ int readoutg(t_win * win_out, wint * win
wrefresh(win_out->ptr);
return 2;
}
- switch (c) {
- case KEY_BACKSPACE:
- case 127:
- {
+ if (((r == KEY_CODE_YES) && (c == KEY_BACKSPACE))||
+ ((r == OK) && ((c==127)|| (c==8)))){
+ if ((mode == SLAVEMODE) && scrolledup) return 0;
+ while(win_out->curs_pos > 0){
+ int width;int j;
getyx(win_out->ptr, ypos, xpos);
- if (win_out->bytes > 0) {
- if (win_out->curs_pos < win_out->bytes) {
- mvwaddnstr(win_out->ptr, ypos,
- --xpos,
- &win_out->
- string[win_out->
- curs_pos],
- win_out->bytes -
- win_out->curs_pos);
- waddch(win_out->ptr, ' ');
- memmove(&win_out->
- string[win_out->curs_pos -
- 1],
- &win_out->string[win_out->
- curs_pos],
- win_out->bytes -
- win_out->curs_pos);
- } else
- mvwaddch(win_out->ptr, ypos,
- --xpos, ' ');
-
- wmove(win_out->ptr, ypos, xpos);
- win_out->bytes--;
- win_out->curs_pos--;
- }
- }
- break;
- case KEY_LEFT:
- if (win_out->curs_pos > 0) {
+ width = wcwidthcontrol(win_out->string[win_out->curs_pos-1]);
+ for (j=0;j<width;j++) mvwdelch(win_out->ptr, ypos, xpos-width);
+ xpos -= width;
+ wmove(win_out->ptr, ypos, xpos);
+ if (win_out->curs_pos < win_out->bytes) {
+ memmove(&win_out->
+ string[win_out->curs_pos - 1],
+ &win_out->string[win_out-> curs_pos],
+ (win_out->bytes -
+ win_out->curs_pos) * sizeof(wchar_t));
+ }
+ win_out->bytes--;
win_out->curs_pos--;
- getyx(win_out->ptr, ypos, xpos);
- wmove(win_out->ptr, ypos, xpos - 1);
+ if (width)break;
}
- break;
- case KEY_RIGHT:
- if (win_out->curs_pos < win_out->bytes) {
+ }
+ else if (( (r==KEY_CODE_YES) && (c == KEY_ENTER))||
+ ( (r == OK) && ((c=='\n') || (c=='\r')))){
+ if ((mode == SLAVEMODE) && scrolledup) return 0;
+ while (win_out->curs_pos < win_out->bytes) { // Move to end of the line
+ int width;
+ width = wcwidthcontrol(win_out->string[win_out->curs_pos]);
win_out->curs_pos++;
getyx(win_out->ptr, ypos, xpos);
- wmove(win_out->ptr, ypos, xpos + 1);
- }
- break;
- case KEY_ENTER:
- case (int) '\n':
- case (int) '\r':
- {
- if (win_out->curs_pos < win_out->bytes) {
- getyx(win_out->ptr, ypos, xpos);
- wmove(win_out->ptr, ypos,
- xpos + win_out->bytes -
- win_out->curs_pos);
+ wmove(win_out->ptr, ypos, xpos + width);
}
- waddch(win_out->ptr, '\n');
- win_out->string[win_out->bytes++] = (char) '\n';
- wrefresh(win_out->ptr);
- strncpy(buf, win_out->string, win_out->bytes);
- wrefresh(win_out->ptr);
- out_cnt = win_out->bytes;
- win_out->bytes = 0;
- win_out->curs_pos = 0;
- return out_cnt;
+ waddch(win_out->ptr, '\n');
+ win_out->string[win_out->bytes++] = (wchar_t) '\n';
+ wrefresh(win_out->ptr);
+ out_cnt = outstring(buf, win_out->string, win_out->bytes, encoding);
+ if (mode == SLAVEMODE){
+ char obuf[MAX_BUFLEN];
+ char *inbuf = (char *)win_out->string, *outbuf = obuf;
+ size_t insize = win_out->bytes * sizeof(wchar_t), outsize = MAX_BUFLEN;
+ iconv(wcharttoutf8, &inbuf, &insize, &outbuf, &outsize);
+ waddnstrcrcheck(win_in, obuf, MAX_BUFLEN-outsize, 0, mode, win_out);
+ }
+ win_out->bytes = 0;
+ win_out->curs_pos = 0;
+ return out_cnt;
+ }
+ else if (r == KEY_CODE_YES){
+ switch(c){
+ case KEY_LEFT:// Character of 0 width
+ while (win_out->curs_pos > 0) {
+ int width;
+ win_out->curs_pos--;
+ width = wcwidthcontrol(win_out->string[win_out->curs_pos]);
+ getyx(win_out->ptr, ypos, xpos);
+ wmove(win_out->ptr, ypos, xpos - width);
+ if (width)break; // Skip to non-width
+ }
+ break;
+ case KEY_RIGHT:
+ {
+ int skipped = 0;// Skip over 0 length characters
+ while (win_out->curs_pos < win_out->bytes) {
+ int width;
+ width = wcwidthcontrol(win_out->string[win_out->curs_pos]);
+ if (width){
+ if (skipped)break;
+ skipped = 1;
+ }
+ win_out->curs_pos++;
+ getyx(win_out->ptr, ypos, xpos);
+ wmove(win_out->ptr, ypos, xpos + width);
+ }
+ break;
+ }
+ case KEY_UP:
+ scrolltext(win_in, 1, mode, win_out);
+ break;
+ case KEY_DOWN:
+ scrolltext(win_in, -1, mode, win_out);
+ break;
+ case KEY_NPAGE:
+ scrolltext(win_in, -win_in->max_y, mode, win_out);
+ break;
+ case KEY_PPAGE:
+ scrolltext(win_in, win_in->max_y, mode, win_out);
+ break;
+ case KEY_HOME:
+ while (win_out->curs_pos > 0) {
+ int width;
+ win_out->curs_pos--;
+ width = wcwidthcontrol(win_out->string[win_out->curs_pos]);
+ getyx(win_out->ptr, ypos, xpos);
+ wmove(win_out->ptr, ypos, xpos - width);
+ }
+ break;
+ case KEY_END:
+ while (win_out->curs_pos < win_out->bytes) { // Move to end of the line
+ int width;
+ width = wcwidthcontrol(win_out->string[win_out->curs_pos]);
+ win_out->curs_pos++;
+ getyx(win_out->ptr, ypos, xpos);
+ wmove(win_out->ptr, ypos, xpos + width);
+ }
+ break;
+ case KEY_DC:{
+ int skipped = 0;
+ if ((mode == SLAVEMODE) && scrolledup) return 0;
+ while (win_out->curs_pos < win_out->bytes){
+ int width;int j;
+ getyx(win_out->ptr, ypos, xpos);
+ width = wcwidthcontrol(win_out->string[win_out->curs_pos]);
+ if (width){
+ if (skipped)break;
+ skipped = 1;
+ }
+ for (j=0;j<width;j++) mvwdelch(win_out->ptr, ypos, xpos);
+ if (win_out->curs_pos + 1 < win_out->bytes) {
+ memmove(&win_out-> string[win_out->curs_pos],
+ &win_out->string[win_out-> curs_pos+1],
+ (win_out->bytes - (win_out->curs_pos+1)) * sizeof(wchar_t));
+ }
+ win_out->bytes--;
+ }
+ break;
+ }
+ case KEY_RESIZE:
+ break;
+ case KEY_BACKSPACE:
+ break;
+ case KEY_ENTER:
+ break;
+ default:
+ break;
}
+ }
+ else switch (c) {
+ case 8:
+ case 127:
+ case '\r':
+ case '\n':
break;
default:
- {
- waddch(win_out->ptr, (char) c);
+ if ((mode == SLAVEMODE) && scrolledup) return 0; // Don't try to edit while scrolled up in SLAVEmode.
+ // It's just not possible because the cursor is off screen
+ if (win_out->bytes < MAX_BUFLEN ) {
if (win_out->curs_pos < win_out->bytes) {
- getyx(win_out->ptr, ypos, xpos);
- waddnstr(win_out->ptr,
- &win_out->string[win_out->
- curs_pos],
- win_out->bytes -
- win_out->curs_pos);
memmove(&win_out->
string[win_out->curs_pos + 1],
- &win_out->string[win_out->
- curs_pos],
- win_out->bytes -
- win_out->curs_pos);
- win_out->string[win_out->curs_pos] =
- (char) c;
- wmove(win_out->ptr, ypos, xpos);
- } else
- win_out->string[win_out->bytes] = (char) c;
-
+ &win_out->string[win_out-> curs_pos],
+ (win_out->bytes -
+ win_out->curs_pos) * sizeof(wchar_t));
+ }
+ win_out->string[win_out->curs_pos] = c;
win_out->bytes++;
win_out->curs_pos++;
+ drawinbuf(win_out->ptr, win_out->string, win_out->bytes, win_out->curs_pos);
+ break;
}
}
wrefresh(win_out->ptr);
@@ -1349,7 +1766,6 @@ int searche_key_words(char buf[], int *b
int cnt = 0;
int t = 0;
-
if (cmpstrbyte != 0) {
memmove(buf + cmpstrbyte, buf, *bytes);
*bytes += cmpstrbyte;
@@ -1371,22 +1787,22 @@ int searche_key_words(char buf[], int *b
command = 0;
cmdstpos = cnt;
- t = -1;
- while (*pkey_words[command] != '\0') {
- if ((t =
- compstr(pkey_words[command], &buf[cnt],
- *bytes - cnt)) != -1)
- break;
- command++;
- }
-
- for (; !eol(buf[cnt]) && cnt < *bytes - 1; cnt++);
-
- if (cnt < *bytes - 1)
- cnt++;
- else
- break;
- } while (t == -1);
+ t = -1;
+ while (*pkey_words[command] != '\0') {
+ if ((t =
+ compstr(pkey_words[command], &buf[cnt],
+ *bytes - cnt)) != -1)
+ break;
+ command++;
+ }
+
+ for (; !eol(buf[cnt]) && cnt < *bytes - 1; cnt++);
+
+ if (cnt < *bytes - 1)
+ cnt++;
+ else
+ break;
+ } while (t == -1);
if (t < 0)
command = -1;
@@ -1525,7 +1941,7 @@ void statbits(int mode, char stat, int m
}
-int cmd_call(char *call[], int mode)
+int cmd_call(char *call[], int mode, int encoding)
{
menuitem con[] = {
{"~Reconnect", 'R', M_ITEM, (void *) 0x01},
@@ -1588,8 +2004,8 @@ int cmd_call(char *call[], int mode)
int upllen = 0;
char *c, *t;
t_gp gp;
- t_win win_in;
- t_win win_out;
+ t_win win_in = {0};
+ t_win win_out = {0};
WINDOW *swin = 0;
int cnt;
int crc = 0;
@@ -1609,9 +2025,11 @@ int cmd_call(char *call[], int mode)
return FALSE;
interrupted = FALSE;
+ sigwinchsignal = FALSE;
signal(SIGQUIT, cmd_intr);
signal(SIGINT, SIG_IGN);
signal(SIGTSTP, SIG_IGN);
+ signal(SIGWINCH, cmd_sigwinch);
fcntl(fd, F_SETFL, O_NONBLOCK);
fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);
@@ -1633,13 +2051,14 @@ int cmd_call(char *call[], int mode)
}
while (TRUE) {
- struct timeval tv;
+ struct timespec tv;
+ sigset_t sigmask;
if (inactivity_timeout_is_set == TRUE && uploadfile == -1 && downloadfile == -1) {
tv.tv_sec = inactivity_timeout.tv_sec;
- tv.tv_usec = inactivity_timeout.tv_usec;
+ tv.tv_nsec = inactivity_timeout.tv_usec * 1000;
} else {
tv.tv_sec = 0;
- tv.tv_usec = 10;
+ tv.tv_nsec = 10000;
}
FD_ZERO(&sock_read);
if (EOF_on_STDIN == FALSE)
@@ -1647,17 +2066,28 @@ int cmd_call(char *call[], int mode)
FD_SET(fd, &sock_read);
FD_ZERO(&sock_write);
+ sigemptyset(&sigmask);
if (uploadfile != -1)
FD_SET(fd, &sock_write);
- if (select(fd + 1, &sock_read, &sock_write, NULL, (uploadfile == -1 && downloadfile == -1 && inactivity_timeout_is_set == FALSE) ? NULL : &tv) == -1) {
+ if (pselect(fd + 1, &sock_read, &sock_write, NULL, (uploadfile == -1 && downloadfile == -1 && inactivity_timeout_is_set == FALSE) ? NULL : &tv, &sigmask) == -1) {
if (!interrupted && errno == EAGAIN) {
usleep(100000);
continue;
}
- if (!interrupted)
- perror("select");
- break;
+ if ((errno == EINTR) && sigwinchsignal){
+ // Just process screen resize here.
+ reinit_mode(mode, &wintab, &win_in,
+ &win_out, call);
+ sigwinchsignal = 0;
+ continue;
+ }
+ else {
+ if (!interrupted){
+ perror("select");
+ }
+ break;
+ }
}
if (inactivity_timeout_is_set == TRUE && !FD_ISSET(fd, &sock_read) && !FD_ISSET(STDIN_FILENO, &sock_read)) {
if (!be_silent) {
@@ -1702,8 +2132,9 @@ int cmd_call(char *call[], int mode)
convert_cr_lf(buf, bytes);
if (!sevenplus) {
- writeincom(mode, &win_in,
- (unsigned char * ) buf, bytes);
+ writeincom(mode, encoding, &win_in,
+ (unsigned char * ) buf, bytes, &win_out);
+ restorecursor(mode, &win_out);
} else {
for (cnt = 0; cnt < bytes;
cnt++)
@@ -1830,7 +2261,7 @@ int cmd_call(char *call[], int mode)
} else {
bytes =
readoutg(&win_out, &wintab, top, buf,
- 0x1d);
+ 0x1d, mode, encoding, &win_in);
if (bytes == -1) {
wclear(win_in.ptr);
wrefresh(win_in.ptr);
@@ -1895,23 +2326,23 @@ int cmd_call(char *call[], int mode)
case '?':
case 'h':
case 'H':
- printf("\nTilde escapes:\n");
- printf(". close\n");
- printf("~ send ~\n");
- printf("r reconnect\n");
- printf("! shell\n");
- printf("Z suspend program. Resume with \"fg\"\n");
- printf("s Stop upload\n");
- printf("o Open log\n");
- printf("c Close log\n");
- printf("0 Switch GUI to \"RAW\" (line) mode - already here ;)\n");
- printf("1 Switch GUI to \"Slave\" mode\n");
- printf("2 Switch GUI to \"Talk\" (split) mode\n");
- printf("u Upload\n");
- printf("a Upload (autobin protocol)\n");
- printf("b Upload binary data (crlf conversion)\n");
- printf("yd YAPP Download\n");
- printf("yu YAPP Upload\n");
+ writeincomstr(mode, encoding, &win_in,"\nTilde escapes:\n", &win_out);
+ writeincomstr(mode, encoding, &win_in,". close\n", &win_out);
+ writeincomstr(mode, encoding, &win_in,"~ send ~\n", &win_out);
+ writeincomstr(mode, encoding, &win_in,"r reconnect\n", &win_out);
+ writeincomstr(mode, encoding, &win_in,"! shell\n", &win_out);
+ writeincomstr(mode, encoding, &win_in,"Z suspend program. Resume with \"fg\"\n", &win_out);
+ writeincomstr(mode, encoding, &win_in,"s Stop upload\n", &win_out);
+ writeincomstr(mode, encoding, &win_in,"o Open log\n", &win_out);
+ writeincomstr(mode, encoding, &win_in,"c Close log\n", &win_out);
+ writeincomstr(mode, encoding, &win_in,"0 Switch GUI to \"RAW\" (line) mode - already here ;)\n", &win_out);
+ writeincomstr(mode, encoding, &win_in,"1 Switch GUI to \"Slave\" mode\n", &win_out);
+ writeincomstr(mode, encoding, &win_in,"2 Switch GUI to \"Talk\" (split) mode\n", &win_out);
+ writeincomstr(mode, encoding, &win_in,"u Upload\n", &win_out);
+ writeincomstr(mode, encoding, &win_in,"a Upload (autobin protocol)\n", &win_out);
+ writeincomstr(mode, encoding, &win_in,"b Upload binary data (crlf conversion)\n", &win_out);
+ writeincomstr(mode, encoding, &win_in,"yd YAPP Download\n", &win_out);
+ writeincomstr(mode, encoding, &win_in,"yu YAPP Upload\n", &win_out);
fflush(stdout);
continue;
case 'S':
@@ -1925,6 +2356,7 @@ int cmd_call(char *call[], int mode)
statline(mode,
"No upload in progress");
}
+ restorecursor(mode, &win_out);
continue;
case 'A':
case 'a':
@@ -1935,6 +2367,7 @@ int cmd_call(char *call[], int mode)
if (uploadfile != -1) {
statline(mode,
"Already uploading");
+ restorecursor(mode, &win_out);
continue;
}
if ((t =
@@ -1946,12 +2379,14 @@ int cmd_call(char *call[], int mode)
if (*t == '\0') {
statline(mode,
"Upload requires a filename");
+ restorecursor(mode, &win_out);
continue;
}
uploadfile = open(t, O_RDONLY);
if (uploadfile == -1) {
statline(mode,
"Unable to open upload file");
+ restorecursor(mode, &win_out);
continue;
}
if (lseek(uploadfile, 0L, SEEK_END)
@@ -2051,6 +2486,7 @@ int cmd_call(char *call[], int mode)
upldp = -1;
upllen = 0;
}
+ restorecursor(mode, &win_out);
break;
case 'b':
case 'B':
@@ -2100,10 +2536,12 @@ int cmd_call(char *call[], int mode)
statline(mode,
"Log file not open");
}
+ restorecursor(mode, &win_out);
continue;
case 'Y':
case 'y':
cmd_yapp(buf + 2, bytes - 2);
+ restorecursor(mode, &win_out);
continue;
case '~':
bytes--;
@@ -2133,6 +2571,17 @@ int cmd_call(char *call[], int mode)
&wintab, &win_in,
&win_out, call);
continue;
+ case '8':
+ encoding = UTF8ENCODING;
+ statline(mode, "UTF-8 encoding");
+ restorecursor(mode, &win_out);
+ continue;
+ case 'i':
+ case 'I':
+ encoding = ORIGINALENCODING;
+ statline(mode, "IBM850 encoding");
+ restorecursor(mode, &win_out);
+ continue;
default:
statline(mode,
"Unknown '~' escape. Type ~h for a list");
@@ -2151,6 +2600,7 @@ int cmd_call(char *call[], int mode)
if (uploadfile != -1) {
statline(mode,
"Ignored. Type ~s to stop upload");
+ restorecursor(mode, &win_out);
continue;
}
convert_lf_cr(buf, bytes);
@@ -2186,6 +2636,7 @@ int cmd_call(char *call[], int mode)
winclose(&wintab);
statline(mode,
"Upload complete: 0 bytes");
+ restorecursor(mode, &win_out);
continue;
}
if (upldp == -1) {
@@ -2200,6 +2651,7 @@ int cmd_call(char *call[], int mode)
sprintf(s,
"Upload complete: %ld bytes",
uplpos);
+ restorecursor(mode, &win_out);
statline(mode, s);
continue;
}
@@ -2212,6 +2664,7 @@ int cmd_call(char *call[], int mode)
"Error reading upload file: upload aborted at %ld bytes",
uplpos);
statline(mode, s);
+ restorecursor(mode, &win_out);
continue;
}
if (!binup)
@@ -2231,6 +2684,7 @@ int cmd_call(char *call[], int mode)
if (errno != EWOULDBLOCK && errno != EAGAIN) {
sprintf(s, "Write error during upload. Connection lost");
statline(mode, s);
+ restorecursor(mode, &win_out);
perror("write");
break;
}
@@ -2289,17 +2743,27 @@ int cmd_call(char *call[], int mode)
}
+void iconvclose(void)
+{
+ iconv_close(ibm850toutf8);
+ iconv_close(wcharttoibm850);
+ iconv_close(wcharttoutf8);
+ iconv_close(utf8towchart);
+}
+
int main(int argc, char **argv)
{
int p;
int mode = TALKMODE;
+ int encoding = UTF8ENCODING;// Maybe controversial?
+ setlocale(LC_ALL, "");
if (!isatty(STDIN_FILENO))
stdin_is_tty = 0;
setlinebuf(stdin);
- while ((p = getopt(argc, argv, "b:dhm:p:rs:RStT:vw:W")) != -1) {
+ while ((p = getopt(argc, argv, "b:dhm:p:rs:RStT:vw:Wi8")) != -1) {
switch (p) {
case 'b':
if (*optarg != 'e' && *optarg != 'l') {
@@ -2336,6 +2800,7 @@ int main(int argc, char **argv)
}
break;
case 'r':
+ COLS = 80; // This is used to format the scrollback buffer, which is stored in raw
mode = RAWMODE;
break;
case 's':
@@ -2346,17 +2811,17 @@ int main(int argc, char **argv)
case 'S':
be_silent = 1;
break;
- case 'T':
- { double f = atof(optarg);
- inactivity_timeout.tv_sec = ((time_t) f) & 0x7fffffff;
- inactivity_timeout.tv_usec = (time_t ) (f - (double ) (time_t ) f);
- if (f < 0.001 || f > (double) (0x7fffffff) || (inactivity_timeout.tv_sec == 0 && inactivity_timeout.tv_usec == 0)) {
- fprintf(stderr, "call: option '-T' must be > 0.001 (1ms) and < 69 years\n");
- return 1;
- }
- inactivity_timeout_is_set = TRUE;
- }
- break;
+ case 'T':
+ { double f = atof(optarg);
+ inactivity_timeout.tv_sec = ((time_t) f) & 0x7fffffff;
+ inactivity_timeout.tv_usec = (time_t ) (f - (double ) (time_t ) f);
+ if (f < 0.001 || f > (double) (0x7fffffff) || (inactivity_timeout.tv_sec == 0 && inactivity_timeout.tv_usec == 0)) {
+ fprintf(stderr, "call: option '-T' must be > 0.001 (1ms) and < 69 years\n");
+ return 1;
+ }
+ inactivity_timeout_is_set = TRUE;
+ }
+ break;
case 't':
mode = TALKMODE;
break;
@@ -2386,6 +2851,12 @@ int main(int argc, char **argv)
case 'W':
wait_for_remote_disconnect = TRUE;
break;
+ case 'i':
+ encoding = ORIGINALENCODING;
+ break;
+ case '8':
+ encoding = UTF8ENCODING;
+ break;
case '?':
case ':':
usage();
@@ -2395,6 +2866,13 @@ int main(int argc, char **argv)
if (optind == argc || optind == argc - 1) {
usage();
}
+
+ ibm850toutf8 = iconv_open("UTF8", "IBM850");
+ wcharttoibm850 = iconv_open("IBM850", "WCHAR_T");
+ wcharttoutf8 = iconv_open("UTF8", "WCHAR_T");
+ utf8towchart = iconv_open("WCHAR_T", "UTF8");
+ atexit(iconvclose);
+
port = argv[optind];
if (ax25_config_load_ports() == 0) {
@@ -2443,7 +2921,7 @@ int main(int argc, char **argv)
printf("GW4PTS AX.25 Connect v1.11\n");
fflush(stdout);
}
- while (cmd_call(argv + optind + 1, mode)) {
+ while (cmd_call(argv + optind + 1, mode, encoding)) {
if (!be_silent) {
printf("Wait 60 sec before reconnect\n");
fflush(stdout);
diff -pruN '--exclude=*.dep*' '--exclude=Makefile' '--exclude=config.status' '--exclude=*.log' '--exclude=*.swp' ax25-apps-0.0.8-rc4/configure ax25-apps-0.0.8-rc4.callintl/configure
--- ax25-apps-0.0.8-rc4/configure 2013-06-18 14:57:12.000000000 -0400
+++ ax25-apps-0.0.8-rc4.callintl/configure 2013-07-17 00:00:13.931803675 -0400
@@ -11497,13 +11497,13 @@ else
as_fn_error $? "Could not find the libax25 libraries; aborting" "$LINENO" 5
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for initscr in -lncurses" >&5
-$as_echo_n "checking for initscr in -lncurses... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for initscr in -lncursesw" >&5
+$as_echo_n "checking for initscr in -lncursesw... " >&6; }
if ${ac_cv_lib_ncurses_initscr+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
-LIBS="-lncurses $LIBS"
+LIBS="-lncursesw $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -11534,7 +11534,7 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncurses_initscr" >&5
$as_echo "$ac_cv_lib_ncurses_initscr" >&6; }
if test "x$ac_cv_lib_ncurses_initscr" = xyes; then :
- NCURSES_LIB="-lncurses"
+ NCURSES_LIB="-lncursesw"
else
as_fn_error $? "Could not find the ncurses library; aborting" "$LINENO" 5
fi
prev parent reply other threads:[~2013-07-17 6:54 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20130708115635.A4B233700A5@n1uro.ampr.org>
[not found] ` <51DABEDA.8020905@junglevision.com>
[not found] ` <1373314487.13641.19.camel@n1uro.ampr.org>
2013-07-09 4:37 ` Netrom on kernel version 3.9.6-200 Cathryn Mataga
2013-07-09 12:05 ` Netrom Brian Rogers
2013-07-09 22:34 ` Netrom Thomas Osterried
2013-07-10 2:08 ` Netrom Cathryn Mataga
2013-07-10 2:13 ` Netrom Cathryn Mataga
2013-07-10 3:17 ` Netrom Nate Bargmann
2013-07-10 4:51 ` Netrom Brian Rogers
[not found] ` <1373415104.26592.32.camel@n1uro.ampr.org>
[not found] ` <EB9D8B55-6554-46D8-B0D4-D83F0A1499CC@osterried.de>
[not found] ` <1373460041.4524.33.camel@n1uro.ampr.org>
[not found] ` <6389184E-68DE-4B2D-B955-75E69726E08A@osterried.de>
[not found] ` <1373489422.1842.24.camel@n1uro.ampr.org>
[not found] ` <AE263F20-4B10-465A-BBAE-DB62498DB3CF@osterried.de>
2013-07-17 6:54 ` Cathryn Mataga [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=51E63FA7.7070601@junglevision.com \
--to=cathryn@junglevision.com \
--cc=linux-hams@vger.kernel.org \
--cc=n1uro@n1uro.ampr.org \
--cc=ralf@linux-mips.org \
--cc=thomas@osterried.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox