X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/putty/blobdiff_plain/8ceabe903d3305c0a14836a2b021e92bfbf4a429..9a30e26b7801d63e4ccfe8d36169299c09b89dff:/terminal.c?ds=sidebyside diff --git a/terminal.c b/terminal.c index 7a21eeed..9f79701d 100644 --- a/terminal.c +++ b/terminal.c @@ -381,6 +381,9 @@ Terminal *term_init(Config *mycfg, struct unicode_data *ucsdata, term->rows = term->cols = -1; power_on(term); term->beephead = term->beeptail = NULL; +#ifdef OPTIMISE_SCROLL + term->scrollhead = term->scrolltail = NULL; +#endif /* OPTIMISE_SCROLL */ term->nbeeps = 0; term->lastbeep = FALSE; term->beep_overloaded = FALSE; @@ -795,6 +798,35 @@ static void scroll(Terminal *term, int topline, int botline, int lines, int sb) #ifdef OPTIMISE_SCROLL /* + * Add a scroll of a region on the screen into the pending scroll list. + * `lines' is +ve for scrolling forward, -ve for backward. + * + * If the scroll is on the same area as the last scroll in the list, + * merge them. + */ +void save_scroll(Terminal *term, int topline, int botline, int lines) +{ + struct scrollregion *newscroll; + if (term->scrolltail && + term->scrolltail->topline == topline && + term->scrolltail->botline == botline) { + term->scrolltail->lines += lines; + } else { + newscroll = smalloc(sizeof(struct scrollregion)); + newscroll->topline = topline; + newscroll->botline = botline; + newscroll->lines = lines; + newscroll->next = NULL; + + if (!term->scrollhead) + term->scrollhead = newscroll; + else + term->scrolltail->next = newscroll; + term->scrolltail = newscroll; + } +} + +/* * Scroll the physical display, and our conception of it in disptext. */ static void scroll_display(Terminal *term, int topline, int botline, int lines) @@ -820,7 +852,7 @@ static void scroll_display(Terminal *term, int topline, int botline, int lines) for (i = 0; i < distance; i++) start[i] |= ATTR_INVALID; } - do_scroll(term->frontend, topline, botline, lines); + save_scroll(term, topline, botline, lines); } #endif /* OPTIMISE_SCROLL */ @@ -3087,6 +3119,9 @@ static void do_paint(Terminal *term, Context ctx, int may_optimise) char ch[1024]; long cursor_background = ERASE_CHAR; unsigned long ticks; +#ifdef OPTIMISE_SCROLL + struct scrollregion *sr; +#endif /* OPTIMISE_SCROLL */ /* * Check the visual bell state. @@ -3149,6 +3184,18 @@ static void do_paint(Terminal *term, Context ctx, int may_optimise) } term->dispcurs = NULL; +#ifdef OPTIMISE_SCROLL + /* Do scrolls */ + sr = term->scrollhead; + while (sr) { + struct scrollregion *next = sr->next; + do_scroll(ctx, sr->topline, sr->botline, sr->lines); + sfree(sr); + sr = next; + } + term->scrollhead = term->scrolltail = NULL; +#endif /* OPTIMISE_SCROLL */ + /* The normal screen data */ for (i = 0; i < term->rows; i++) { unsigned long *ldata; @@ -4052,7 +4099,7 @@ void term_key(Terminal *term, Key_Sym keysym, wchar_t *text, size_t tlen, fprintf(stderr, "keysym = %d, %d chars:", keysym, tlen); for (i = 0; i < tlen; i++) - fprintf(stderr, " %04x", text[i]); + fprintf(stderr, " %04x", (unsigned)text[i]); fprintf(stderr, "\n"); #endif @@ -4101,8 +4148,8 @@ void term_key(Terminal *term, Key_Sym keysym, wchar_t *text, size_t tlen, if (keysym == PK_NULL && (modifiers & PKM_CONTROL) && tlen == 1 && text[0] >= 0x20 && text[0] <= 0x7e) { /* ASCII chars + Control */ - if (text[0] >= 0x40 && text[0] <= 0x5f || - text[0] >= 0x61 && text[0] <= 0x7a) + if ((text[0] >= 0x40 && text[0] <= 0x5f) || + (text[0] >= 0x61 && text[0] <= 0x7a)) text[0] &= 0x1f; else { /* @@ -4141,6 +4188,7 @@ void term_key(Terminal *term, Key_Sym keysym, wchar_t *text, size_t tlen, case PK_KP7: c = 'y'; break; case PK_KP8: c = 'k'; break; case PK_KP9: c = 'u'; break; + default: break; /* else gcc warns `enum value not used' */ } if (c != 0) { if (c != '.') { @@ -4171,6 +4219,7 @@ void term_key(Terminal *term, Key_Sym keysym, wchar_t *text, size_t tlen, case PK_PF2: xkey = 'Q'; break; case PK_PF3: xkey = 'R'; break; case PK_PF4: xkey = 'S'; break; + default: break; /* else gcc warns `enum value not used' */ } } if (term->app_keypad_keys && !term->cfg.no_applic_k) { @@ -4187,6 +4236,7 @@ void term_key(Terminal *term, Key_Sym keysym, wchar_t *text, size_t tlen, case PK_KP9: xkey = 'y'; break; case PK_KPDECIMAL: xkey = 'n'; break; case PK_KPENTER: xkey = 'M'; break; + default: break; /* else gcc warns `enum value not used' */ } if (term->cfg.funky_type == FUNKY_XTERM && tlen > 0) { /* @@ -4221,6 +4271,7 @@ void term_key(Terminal *term, Key_Sym keysym, wchar_t *text, size_t tlen, break; case PK_KPMINUS: xkey = 'm'; break; case PK_KPCOMMA: xkey = 'l'; break; + default: break; /* else gcc warns `enum value not used' */ } } } @@ -4247,6 +4298,7 @@ void term_key(Terminal *term, Key_Sym keysym, wchar_t *text, size_t tlen, case PK_KP7: keysym = PK_HOME; break; case PK_KP8: keysym = PK_UP; break; case PK_KP9: keysym = PK_PAGEUP; break; + default: break; /* else gcc warns `enum value not used' */ } } } @@ -4285,6 +4337,7 @@ void term_key(Terminal *term, Key_Sym keysym, wchar_t *text, size_t tlen, *p++ = 0x0a; goto done; } + default: break; /* else gcc warns `enum value not used' */ } /* SCO function keys and editing keys */ @@ -4309,6 +4362,7 @@ void term_key(Terminal *term, Key_Sym keysym, wchar_t *text, size_t tlen, case PK_END: xkey = 'F'; break; case PK_PAGEUP: xkey = 'I'; break; case PK_PAGEDOWN: xkey = 'G'; break; + default: break; /* else gcc warns `enum value not used' */ } p += sprintf((char *) p, "\x1B[%c", xkey); } @@ -4326,6 +4380,7 @@ void term_key(Terminal *term, Key_Sym keysym, wchar_t *text, size_t tlen, case PK_END: keysym = PK_PAGEUP; break; case PK_PAGEUP: keysym = PK_DELETE; break; case PK_PAGEDOWN: keysym = PK_PAGEDOWN; break; + default: break; /* else gcc warns `enum value not used' */ } } @@ -4350,6 +4405,7 @@ void term_key(Terminal *term, Key_Sym keysym, wchar_t *text, size_t tlen, case PK_END: xkey = 'E'; break; case PK_PAGEUP: xkey = 'I'; break; case PK_PAGEDOWN: xkey = 'G'; break; + default: break; /* else gcc warns `enum value not used' */ } p += sprintf((char *) p, "\x1B%c", xkey); goto done; @@ -4362,6 +4418,7 @@ void term_key(Terminal *term, Key_Sym keysym, wchar_t *text, size_t tlen, case PK_END: code = 4; break; case PK_PAGEUP: code = 5; break; case PK_PAGEDOWN: code = 6; break; + default: break; /* else gcc warns `enum value not used' */ } p += sprintf((char *) p, "\x1B[%d~", code); goto done; @@ -4405,6 +4462,7 @@ void term_key(Terminal *term, Key_Sym keysym, wchar_t *text, size_t tlen, case PK_RIGHT: xkey = 'C'; break; case PK_LEFT: xkey = 'D'; break; case PK_REST: xkey = 'G'; break; /* centre key on number pad */ + default: break; /* else gcc warns `enum value not used' */ } if (term->vt52_mode) p += sprintf((char *) p, "\x1B%c", xkey); @@ -4462,7 +4520,7 @@ void term_key(Terminal *term, Key_Sym keysym, wchar_t *text, size_t tlen, #if 0 fprintf(stderr, "sending %d unichars:", tlen); for (i = 0; i < tlen; i++) - fprintf(stderr, " %04x", text[i]); + fprintf(stderr, " %04x", (unsigned) text[i]); fprintf(stderr, "\n"); #endif luni_send(term->ldisc, text, tlen, 1);