Index: call/call.c =================================================================== RCS file: /home/ax25-cvs/ax25-apps/call/call.c,v retrieving revision 1.26 diff -c -r1.26 call.c *** call/call.c 28 Oct 2012 13:39:44 -0000 1.26 --- call/call.c 9 Dec 2012 00:36:14 -0000 *************** *** 35,41 **** #include #include #include ! #include #include #include --- 35,48 ---- #include #include #include ! #define __USE_XOPEN ! #include ! #include ! #define _XOPEN_SOURCE_EXTENDED 1 ! #include ! #include ! #include ! #include #include #include *************** *** 78,90 **** static char *mycall = NULL; static int stdin_is_tty = 1; int interrupted = FALSE; int paclen = 0; int fd; int wait_for_remote_disconnect = FALSE; ! static struct timeval inactivity_timeout; int inactivity_timeout_is_set = FALSE; int remote_commands_enabled = TRUE; --- 85,100 ---- 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 timespec inactivity_timeout; int inactivity_timeout_is_set = FALSE; int remote_commands_enabled = TRUE; *************** *** 103,109 **** WINDOW *ptr; int max_y; int max_x; ! char string[MAX_BUFLEN]; unsigned long bytes; int curs_pos; } t_win; --- 113,119 ---- WINDOW *ptr; int max_y; int max_x; ! wchar_t string[MAX_BUFLEN]; unsigned long bytes; int curs_pos; } t_win; *************** *** 112,117 **** --- 122,350 ---- #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)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, err; + 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; + err= wscrl(win_in->ptr, -lines); + scrollok(win_in->ptr, FALSE); + if (lines > 0){ + for (y=0;ymax_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"); *************** *** 120,125 **** --- 353,426 ---- exit(1); } + + /* 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 0) { move(0, STATW_STAT); attron(A_REVERSE); ! for (cnt = 0; cnt < oldlen; cnt++) addch(' '); oldlen = 0; attroff(A_REVERSE); --- 735,741 ---- if (oldlen > 0) { move(0, STATW_STAT); attron(A_REVERSE); ! for (cnt = STATW_STAT; cnt < COLS; cnt++) addch(' '); oldlen = 0; attroff(A_REVERSE); *************** *** 441,461 **** fflush(stdout); return; } ! if (strlen(s) > 80 - STATW_STAT) ! s[80 - STATW_STAT] = '\0'; move(0, STATW_STAT); attron(A_REVERSE); ! addstr(s); ! ! if (oldlen > strlen(s)) { ! l = oldlen - strlen(s); ! for (cnt = 0; cnt < l; cnt++) ! addch(' '); ! } attroff(A_REVERSE); ! oldlen = strlen(s); refresh(); } --- 748,767 ---- fflush(stdout); return; } ! if (COLS <= STATW_STAT) ! return; ! l = strlen(s); ! if (l > COLS - STATW_STAT) ! l = COLS-STATW_STAT; move(0, STATW_STAT); attron(A_REVERSE); ! addnstr(s, l); ! for (cnt = STATW_STAT+l;cnt < COLS;cnt++) ! addch(' '); attroff(A_REVERSE); ! oldlen = l; refresh(); } *************** *** 800,805 **** --- 1106,1115 ---- { int cnt; char idString[12]; + 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) *************** *** 811,817 **** addch(ACS_VLINE); addstr("--------"); addch(ACS_VLINE); ! for (cnt = STATW_STAT; cnt <= 80; cnt++) addch(' '); attroff(A_REVERSE); --- 1121,1128 ---- addch(ACS_VLINE); addstr("--------"); addch(ACS_VLINE); ! move(0, STATW_STAT); ! for (cnt = STATW_STAT; cnt < COLS; cnt++) addch(' '); attroff(A_REVERSE); *************** *** 819,824 **** --- 1130,1136 ---- raw(); nodelay(win, TRUE); keypad(win, TRUE); + curson = 1; refresh(); return 0; *************** *** 841,846 **** --- 1153,1160 ---- 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,885 **** 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; return 0; } --- 1186,1201 ---- scrollok(win_out->ptr, TRUE); wclear(win_out->ptr); wclear(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; } *************** *** 931,1100 **** break; } return newmode; } ! void writeincom(int mode, t_win * win_in, unsigned char buf[], int bytes) ! { ! int cnt; ! 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 */ break; ! case 225: ! waddch(win_in->ptr, 223); /*sz */ break; - default: - { - if (buf[cnt] > 127) - waddch(win_in->ptr, '.'); - else - waddch(win_in->ptr, buf[cnt]); - } - } } ! /* waddnstr(win_in->ptr, buf, bytes); */ ! wrefresh(win_in->ptr); ! ! return; } int getstring(wint * wintab, char text[], char buf[]) { ! int c; int ypos = 0, xpos = 0; int bytes = 0; WINDOW *win = winopen(wintab, 3, COLS, 10, 0, TRUE); 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; ! } ! } ! wrefresh(win); ! } ! } ! while (c != '\n' && c != '\r' && c != KEY_ENTER); delwin(win); winclose(wintab); return 0; } int readoutg(t_win * win_out, wint * wintab, menuitem * top, char buf[], ! int keyesc) { ! int out_cnt; ! int c; int ypos = 0, xpos = 0; int value; ! c = getch(); ! if (c == ERR) return 0; if (c == keyesc) { ! if ((value = top_menu(wintab, top, 1)) == 0) return 0; buf[0] = '~'; switch (value) { case 0x01: --- 1247,1579 ---- break; } + scrolledup = 0; return newmode; } ! // **void writeincom(int mode, t_win * win_in, unsigned char buf[], int bytes) ! // **{ ! // ** int cnt; ! // ** ! // ** 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 */ ! // ** break; ! // ** case 225: ! // ** waddch(win_in->ptr, 223); /*sz */ ! // ** break; ! // ** default: ! // ** { ! // ** if (buf[cnt] > 127) ! // ** waddch(win_in->ptr, '.'); ! // ** else ! // ** waddch(win_in->ptr, buf[cnt]); ! // ** } ! // ** } ! // ** } ! // ** ! // ** /* waddnstr(win_in->ptr, buf, bytes); */ ! // ** wrefresh(win_in->ptr); ! // ** ! // ** return; ! // **} ! static void reinit_mode(int mode, wint * wintab, t_win * win_in, ! t_win * win_out, char *call[]) ! { ! switch (mode) { ! case RAWMODE: break; ! ! 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 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; } + } ! void waddnstrcrcheck(t_win *win_in, char *buf, int bytes, int draw, int mode, t_win *win_out) ! { ! int n; ! for (n=0;n 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); ! } ! ! void writeincom(int mode, int encoding, t_win * win_in, unsigned char buf[], int bytes, t_win *win_out) ! { ! if (mode & RAWMODE) waddnstrcrcheck(0, (char *)buf, bytes,1, mode, 0); ! 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[]) { ! 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; + // ** } + // ** } + // ** wrefresh(win); + // ** } + // ** } + do { ! 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;jptr); return 2; } ! switch (c) { ! case KEY_BACKSPACE: case 127: ! { ! 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) { ! win_out->curs_pos--; ! getyx(win_out->ptr, ypos, xpos); ! wmove(win_out->ptr, ypos, xpos - 1); ! } ! break; ! case KEY_RIGHT: ! if (win_out->curs_pos < win_out->bytes) { ! 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); ! } ! 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; ! } ! break; default: ! { ! waddch(win_out->ptr, (char) c); ! 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->bytes++; ! win_out->curs_pos++; ! } ! } wrefresh(win_out->ptr); return 0; } void writemsg(char fname[], char caller[]) { char text_row[255]; --- 1641,1903 ---- wrefresh(win_out->ptr); return 2; } ! // ** switch (c) { ! // ** case KEY_BACKSPACE: ! // ** case 127: ! // ** { ! // ** 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) { ! // ** win_out->curs_pos--; ! // ** getyx(win_out->ptr, ypos, xpos); ! // ** wmove(win_out->ptr, ypos, xpos - 1); ! // ** } ! // ** break; ! // ** case KEY_RIGHT: ! // ** if (win_out->curs_pos < win_out->bytes) { ! // ** 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); ! // ** } ! // ** 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; ! // ** } ! // ** break; ! // ** default: ! // ** { ! // ** waddch(win_out->ptr, (char) c); ! // ** 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->bytes++; ! // ** win_out->curs_pos++; ! // ** } ! // ** } ! 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); ! width = wcwidthcontrol(win_out->string[win_out->curs_pos-1]); ! for (j=0;jptr, 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--; ! if (width)break; ! } ! } ! 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 + width); ! } ! 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;jptr, 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: ! 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) { ! 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->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); return 0; } + void writemsg(char fname[], char caller[]) { char text_row[255]; *************** *** 1525,1531 **** } ! int cmd_call(char *call[], int mode) { menuitem con[] = { {"~Reconnect", 'R', M_ITEM, (void *) 0x01}, --- 2167,2173 ---- } ! int cmd_call(char *call[], int mode, int encoding) { menuitem con[] = { {"~Reconnect", 'R', M_ITEM, (void *) 0x01}, *************** *** 1589,1596 **** char *c, *t; int extrach = 0; t_gp gp; ! t_win win_in; ! t_win win_out; WINDOW *swin = 0; int cnt; int crc = 0; --- 2231,2238 ---- char *c, *t; int extrach = 0; t_gp gp; ! t_win win_in = {0}; ! t_win win_out = {0}; WINDOW *swin = 0; int cnt; int crc = 0; *************** *** 1610,1618 **** --- 2252,2262 ---- 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); *************** *** 1634,1646 **** } while (TRUE) { ! struct timeval tv; if (inactivity_timeout_is_set == TRUE && uploadfile == -1 && downloadfile == -1) { tv.tv_sec = inactivity_timeout.tv_sec; ! tv.tv_usec = inactivity_timeout.tv_usec; } else { tv.tv_sec = 0; ! tv.tv_usec = 10; } FD_ZERO(&sock_read); if (EOF_on_STDIN == FALSE) --- 2278,2291 ---- } while (TRUE) { ! 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_nsec = inactivity_timeout.tv_nsec; } else { tv.tv_sec = 0; ! tv.tv_nsec = 10000; } FD_ZERO(&sock_read); if (EOF_on_STDIN == FALSE) *************** *** 1651,1664 **** 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 (!interrupted && errno == EAGAIN) { usleep(100000); continue; } ! 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) { --- 2296,2319 ---- if (uploadfile != -1) FD_SET(fd, &sock_write); ! 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 ((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) { *************** *** 1703,1710 **** convert_cr_lf(buf, bytes); if (!sevenplus) { ! writeincom(mode, &win_in, ! (unsigned char * ) buf, bytes); } else { for (cnt = 0; cnt < bytes; cnt++) --- 2358,2366 ---- convert_cr_lf(buf, bytes); if (!sevenplus) { ! writeincom(mode, encoding, &win_in, ! (unsigned char * ) buf, bytes, &win_out); ! restorecursor(mode, &win_out); } else { for (cnt = 0; cnt < bytes; cnt++) *************** *** 1832,1838 **** } else { bytes = readoutg(&win_out, &wintab, top, buf, ! 0x1d); if (bytes == -1) { wclear(win_in.ptr); wrefresh(win_in.ptr); --- 2488,2494 ---- } else { bytes = readoutg(&win_out, &wintab, top, buf, ! 0x1d, mode, encoding, &win_in); if (bytes == -1) { wclear(win_in.ptr); wrefresh(win_in.ptr); *************** *** 1897,1920 **** 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"); ! fflush(stdout); continue; case 'S': case 's': --- 2553,2596 ---- 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"); ! // ** fflush(stdout); ! 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); ! writeincomstr(mode, encoding, &win_in,"i IBM850 encoding\n", &win_out); ! writeincomstr(mode, encoding, &win_in,"8 UTF-8 encoding\n", &win_out); ! restorecursor(mode, &win_out); continue; case 'S': case 's': *************** *** 1927,1932 **** --- 2603,2609 ---- statline(mode, "No upload in progress"); } + restorecursor(mode, &win_out); continue; case 'A': case 'a': *************** *** 1937,1942 **** --- 2614,2620 ---- if (uploadfile != -1) { statline(mode, "Already uploading"); + restorecursor(mode, &win_out); continue; } if ((t = *************** *** 1948,1959 **** --- 2626,2639 ---- 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) *************** *** 2053,2058 **** --- 2733,2739 ---- upldp = -1; upllen = 0; } + restorecursor(mode, &win_out); break; case 'b': case 'B': *************** *** 2091,2096 **** --- 2772,2778 ---- statline(mode, s); } else statbits(mode, 'L', 1); + restorecursor(mode, &win_out); continue; case 'C': case 'c': *************** *** 2102,2111 **** --- 2784,2795 ---- 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--; *************** *** 2135,2143 **** --- 2819,2839 ---- &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"); + restorecursor(mode, &win_out); continue; } } *************** *** 2153,2158 **** --- 2849,2855 ---- if (uploadfile != -1) { statline(mode, "Ignored. Type ~s to stop upload"); + restorecursor(mode, &win_out); continue; } convert_lf_cr(buf, bytes); *************** *** 2202,2207 **** --- 2899,2905 ---- sprintf(s, "Upload complete: %ld bytes", uplpos); + restorecursor(mode, &win_out); statline(mode, s); continue; } *************** *** 2214,2219 **** --- 2912,2918 ---- "Error reading upload file: upload aborted at %ld bytes", uplpos); statline(mode, s); + restorecursor(mode, &win_out); continue; } if (!binup) *************** *** 2233,2238 **** --- 2932,2938 ---- if (errno != EWOULDBLOCK && errno != EAGAIN) { sprintf(s, "Write error during upload. Connection lost"); statline(mode, s); + restorecursor(mode, &win_out); perror("write"); break; } *************** *** 2290,2307 **** } } int main(int argc, char **argv) { int p; int mode = TALKMODE; if (!isatty(STDIN_FILENO)) stdin_is_tty = 0; setlinebuf(stdin); ! while ((p = getopt(argc, argv, "b:dhm:p:rs:RStT:vw:W")) != -1) { switch (p) { case 'b': if (*optarg != 'e' && *optarg != 'l') { --- 2990,3016 ---- } } + 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:Wi8")) != -1) { switch (p) { case 'b': if (*optarg != 'e' && *optarg != 'l') { *************** *** 2338,2343 **** --- 3047,3053 ---- } break; case 'r': + COLS = 80; // This is used to format the scrollback buffer, which is stored in raw mode = RAWMODE; break; case 's': *************** *** 2351,2358 **** 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; } --- 3061,3068 ---- case 'T': { double f = atof(optarg); inactivity_timeout.tv_sec = ((time_t) f) & 0x7fffffff; ! inactivity_timeout.tv_nsec = (time_t ) (f - (double ) (time_t ) f); ! if (f < 0.001 || f > (double) (0x7fffffff) || (inactivity_timeout.tv_sec == 0 && inactivity_timeout.tv_nsec == 0)) { fprintf(stderr, "call: option '-T' must be > 0.001 (1ms) and < 69 years\n"); return 1; } *************** *** 2388,2393 **** --- 3098,3109 ---- case 'W': wait_for_remote_disconnect = TRUE; break; + case 'i': + encoding = ORIGINALENCODING; + break; + case '8': + encoding = UTF8ENCODING; + break; case '?': case ':': usage(); *************** *** 2397,2402 **** --- 3113,3125 ---- 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) { *************** *** 2445,2451 **** printf("GW4PTS AX.25 Connect v1.11\n"); fflush(stdout); } ! while (cmd_call(argv + optind + 1, mode)) { if (!be_silent) { printf("Wait 60 sec before reconnect\n"); fflush(stdout); --- 3168,3174 ---- printf("GW4PTS AX.25 Connect v1.11\n"); fflush(stdout); } ! while (cmd_call(argv + optind + 1, mode, encoding)) { if (!be_silent) { printf("Wait 60 sec before reconnect\n"); fflush(stdout);