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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.