X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/7e394092f59f29980ec5eef77776f37dda288ea4..3ad8c6db2a0d488f0d8fa23d8e71306572df8ff2:/terminal.c diff --git a/terminal.c b/terminal.c index d62c8cd5..96472d31 100644 --- a/terminal.c +++ b/terminal.c @@ -2,6 +2,7 @@ #include #include +#include #include "putty.h" @@ -18,7 +19,6 @@ #define CL_ANSI 0x2000 /* ANSI ECMA-48 not in the VT100..VT420 */ #define CL_OTHER 0x4000 /* Others, Xterm, linux, putty, dunno, etc */ -#define TM_ANSIMIN (CL_ANSIMIN) #define TM_VT100 (CL_ANSIMIN|CL_VT100) #define TM_VT100AVO (TM_VT100|CL_VT100AVO) #define TM_VT102 (TM_VT100AVO|CL_VT102) @@ -206,11 +206,13 @@ void term_update(void) { ctx = get_ctx(); if (ctx) { if ( (seen_key_event && (cfg.scroll_on_key)) || - (seen_disp_event && (!cfg.scroll_on_key)) ) { + (seen_disp_event && (cfg.scroll_on_disp)) ) { disptop = scrtop; seen_disp_event = seen_key_event = 0; + update_sbar(); } do_paint (ctx, TRUE); + sys_cursor(curs_x, curs_y + (scrtop - disptop) / (cols+1)); free_ctx (ctx); } } @@ -702,7 +704,7 @@ static void toggle_mode (int mode, int query, int state) { repeat_off = !state; break; case 25: /* enable/disable cursor */ - compatibility(VT220); + compatibility2(OTHER,VT220); cursor_on = state; seen_disp_event = TRUE; break; @@ -726,7 +728,7 @@ static void toggle_mode (int mode, int query, int state) { * DONT send TS_RECHO/TS_LECHO; the telnet daemon tries to fix the * tty and _really_ confuses some programs. */ - compatibility(VT220); + compatibility2(OTHER,VT220); ldisc = (state? &ldisc_simple : &ldisc_term); break; case 20: /* Return sends ... */ @@ -895,6 +897,14 @@ static int beep_overload = 0; } seen_disp_event = TRUE; break; + case '\177': /* Destructive backspace + This does nothing on a real VT100 */ + compatibility(OTHER); + if (curs_x && !wrapnext) curs_x--; + wrapnext = FALSE; + fix_cpos; + *cpos = (' ' | curr_attr | ATTR_ASCII); + break; } } else switch (termstate) { @@ -920,12 +930,21 @@ static int beep_overload = 0; * we use the same font as well as the same encoding. */ case ATTR_LINEDRW: - if (c<0x60 || c>0x7F) + if (c<0x5f || c>0x7F) *cpos++ = xlat_tty2scr((unsigned char)c) | curr_attr | ATTR_ASCII; + else if (c==0x5F) + *cpos++ = ' ' | curr_attr | ATTR_ASCII; else *cpos++ = ((unsigned char)c) | curr_attr | ATTR_LINEDRW; break; + case ATTR_GBCHR: + /* If UK-ASCII, make the '#' a LineDraw Pound */ + if (c == '#') { + *cpos++ = '}' | curr_attr | ATTR_LINEDRW; + break; + } + /*FALLTHROUGH*/ default: *cpos++ = xlat_tty2scr((unsigned char)c) | curr_attr | (c <= 0x7F ? cset_attr[cset] : ATTR_ASCII); @@ -1229,7 +1248,7 @@ static int beep_overload = 0; /* VTTEST Bug 9 - if region is less than 2 lines * don't change region. */ - if (bot-top > 1) { + if (bot-top > 0) { marg_t = top; marg_b = bot; curs_x = 0; @@ -1291,16 +1310,16 @@ static int beep_overload = 0; case 7: /* enable reverse video */ curr_attr |= ATTR_REVERSE; break; case 22: /* disable bold */ - compatibility(VT220); + compatibility2(OTHER,VT220); curr_attr &= ~ATTR_BOLD; break; case 24: /* disable underline */ - compatibility(VT220); + compatibility2(OTHER,VT220); curr_attr &= ~ATTR_UNDER; break; case 25: /* disable blink */ - compatibility(VT220); + compatibility2(OTHER,VT220); curr_attr &= ~ATTR_BLINK; break; case 27: /* disable reverse video */ - compatibility(VT220); + compatibility2(OTHER,VT220); curr_attr &= ~ATTR_REVERSE; break; case 30: case 31: case 32: case 33: case 34: case 35: case 36: case 37: @@ -1416,8 +1435,8 @@ static int beep_overload = 0; * This first appeared in the VT220, but we do need to get * back to PuTTY mode so I won't check it. * - * The arg == 60 is a PuTTY extension. - * The 2nd arg, 8bit vs 7bit is not obeyed. + * The arg in 40..42 are a PuTTY extension. + * The 2nd arg, 8bit vs 7bit is not checked. * * Setting VT102 mode should also change the Fkeys to * generate PF* codes as a real VT102 has no Fkeys. @@ -1427,9 +1446,47 @@ static int beep_overload = 0; * Note ESC c will NOT change this! */ - if (esc_args[0] == 61) compatibility_level = TM_VT102; - else if (esc_args[0] == 60) compatibility_level = TM_ANSIMIN; - else compatibility_level = TM_PUTTY; + switch (esc_args[0]) { + case 61: compatibility_level &= ~TM_VTXXX; + compatibility_level |= TM_VT102; break; + case 62: compatibility_level &= ~TM_VTXXX; + compatibility_level |= TM_VT220; break; + + default: if( esc_args[0] > 60 && esc_args[0] < 70 ) + compatibility_level |= TM_VTXXX; + break; + + case 40: compatibility_level &= TM_VTXXX; break; + case 41: compatibility_level = TM_PUTTY; break; + case 42: compatibility_level = TM_SCOANSI; break; + + case ARG_DEFAULT: + compatibility_level = TM_PUTTY; break; + case 50: break; + } + + /* Change the response to CSI c */ + if (esc_args[0] == 50) { + int i; + char lbuf[64]; + strcpy(id_string, "\033[?"); + for (i=1; isend ("\033/Z", 3); break; case '=': - app_cursor_keys = TRUE; + app_keypad_keys = TRUE; break; case '>': - app_cursor_keys = FALSE; + app_keypad_keys = FALSE; break; case '<': /* XXX This should switch to VT100 mode not current or default @@ -1695,7 +1752,7 @@ static int linecmp (unsigned long *a, unsigned long *b) { * Given a context, update the window. Out of paranoia, we don't * allow WM_PAINT responses to do scrolling optimisations. */ -static void do_paint (Context ctx, int may_optimise){ +static void do_paint (Context ctx, int may_optimise){ int i, j, start, our_curs_y; unsigned long attr, rv, cursor; char ch[1024]; @@ -1860,6 +1917,85 @@ void term_scroll (int rel, int where) { term_update(); } +static void clipme(unsigned long *top, unsigned long *bottom, char *workbuf) { + char *wbptr; /* where next char goes within workbuf */ + int wblen = 0; /* workbuf len */ + int buflen; /* amount of memory allocated to workbuf */ + + if ( workbuf != NULL ) { /* user supplied buffer? */ + buflen = -1; /* assume buffer passed in is big enough */ + wbptr = workbuf; /* start filling here */ + } + else + buflen = 0; /* No data is available yet */ + + while (top < bottom) { + int nl = FALSE; + unsigned long *lineend = top - (top-text) % (cols+1) + cols; + unsigned long *nlpos = lineend; + + if (!(*nlpos & ATTR_WRAPPED)) { + while ((nlpos[-1] & CHAR_MASK) == 0x20 && nlpos > top) + nlpos--; + if (nlpos < bottom) + nl = TRUE; + } + while (top < nlpos && top < bottom) + { +#if 0 + /* VT Specials -> ISO8859-1 */ + static const char poorman2[] = +"* # HTFFCRLF\xB0 \xB1 NLVT+ + + + + - - - - - + + + + | <=>=PI!=\xA3 \xB7 "; +#endif + + int ch = (*top & CHAR_MASK); + +#if 0 + if ((*top & ATTR_LINEDRW) && ch >= 0x60 && ch < 0x7F) { + int x; + *wbptr++ = poorman2[2*(ch-0x60)]; + if ( (x = poorman2[2*(ch-0x60)+1]) != ' ') + *wbptr++ = x; + } else +#endif +#if 0 + if ((*top & ATTR_GBCHR) && ch == '#') + *wbptr++ = (unsigned char) 0xA3; + else +#endif + if ( wblen == buflen ) + { + workbuf = srealloc(workbuf, buflen += 100); + wbptr = workbuf + wblen; + } + wblen++; + *wbptr++ = (unsigned char) ch; + top++; + } + if (nl) { + int i; + for (i=0; i 0 ) /* indicates we allocated this buffer */ + sfree(workbuf); + +} +void term_copyall (void) { + clipme(sbtop, cpos, NULL /* dynamic allocation */); +} + /* * Spread the selection outwards according to the selection mode. */ @@ -1977,30 +2113,7 @@ void term_mouse (Mouse_Button b, Mouse_Action a, int x, int y) { * We've completed a selection. We now transfer the * data to the clipboard. */ - unsigned char *p = selspace; - unsigned long *q = selstart; - - while (q < selend) { - int nl = FALSE; - unsigned long *lineend = q - (q-text) % (cols+1) + cols; - unsigned long *nlpos = lineend; - - if (!(*nlpos & ATTR_WRAPPED)) { - while ((nlpos[-1] & CHAR_MASK) == 0x20 && nlpos > q) - nlpos--; - if (nlpos < selend) - nl = TRUE; - } - while (q < nlpos && q < selend) - *p++ = (unsigned char) (*q++ & CHAR_MASK); - if (nl) { - int i; - for (i=0; isend (&c, 1); + int n = 0; + while (n + paste_pos < paste_len) { + if (paste_buffer[paste_pos + n++] == '\r') + break; + } + ldisc->send (paste_buffer+paste_pos, n); + paste_pos += n; - if (c =='\r') { + if (paste_pos < paste_len) { paste_hold = 1; return; } @@ -2101,3 +2219,14 @@ void term_deselect (void) { deselect(); term_update(); } + +/* + * from_backend(), to get data from the backend for the terminal. + */ +void from_backend(int is_stderr, char *data, int len) { + while (len--) { + if (inbuf_head >= INBUF_SIZE) + term_out(); + inbuf[inbuf_head++] = *data++; + } +}