X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/760e88b21a672b2a4bb96c4c1bc041758eac1677..f2003e3230fa6f3a1cc5d60256d1a19c8b0022d5:/terminal.c diff --git a/terminal.c b/terminal.c index 090ce359..1e2d50c6 100644 --- a/terminal.c +++ b/terminal.c @@ -63,7 +63,7 @@ static unsigned long curstype; /* type of cursor on real screen */ struct beeptime { struct beeptime *next; - long ticks; + unsigned long ticks; }; static struct beeptime *beephead, *beeptail; int nbeeps; @@ -97,7 +97,7 @@ static int cset; /* 0 or 1: which char set */ static int save_cset, save_csattr; /* saved with cursor position */ static int save_utf; /* saved with cursor position */ static int rvideo; /* global reverse video flag */ -static int rvbell_timeout; /* for ESC[?5hESC[?5l vbell */ +static unsigned long rvbell_startpoint;/* for ESC[?5hESC[?5l vbell */ static int cursor_on; /* cursor enabled flag */ static int reset_132; /* Flag ESC c resets to 80 cols */ static int use_bce; /* Use Background coloured erase */ @@ -676,7 +676,7 @@ static void scroll(int topline, int botline, int lines, int sb) * selection), and also selanchor (for one being * selected as we speak). */ - seltop = sb ? -savelines : 0; + seltop = sb ? -savelines : topline; if (selstart.y >= seltop && selstart.y <= botline) { selstart.y--; @@ -848,7 +848,7 @@ static void insch(int n) */ static void toggle_mode(int mode, int query, int state) { - long ticks; + unsigned long ticks; if (query) switch (mode) { @@ -877,14 +877,20 @@ static void toggle_mode(int mode, int query, int state) * always be an actually _visible_ visual bell. */ ticks = GetTickCount(); - if (rvideo && !state && /* we're turning it off */ - ticks < rvbell_timeout) { /* and it's not long since it was turned on */ + /* turn off a previous vbell to avoid inconsistencies */ + if (ticks - vbell_startpoint >= VBELL_TIMEOUT) + in_vbell = FALSE; + if (rvideo && !state && /* we're turning it off... */ + (ticks - rvbell_startpoint) < VBELL_TIMEOUT) { /* ...soon */ + /* If there's no vbell timeout already, or this one lasts + * longer, replace vbell_timeout with ours. */ + if (!in_vbell || + (rvbell_startpoint - vbell_startpoint < VBELL_TIMEOUT)) + vbell_startpoint = rvbell_startpoint; in_vbell = TRUE; /* we may clear rvideo but we set in_vbell */ - if (vbell_timeout < rvbell_timeout) /* don't move vbell end forward */ - vbell_timeout = rvbell_timeout; /* vbell end is at least then */ } else if (!rvideo && state) { /* This is an ON, so we notice the time and save it. */ - rvbell_timeout = ticks + VBELL_TIMEOUT; + rvbell_startpoint = ticks; } rvideo = state; seen_disp_event = TRUE; @@ -1000,7 +1006,7 @@ void term_out(void) * debugging and possibly also useful for actual logging. */ if (cfg.logtype == LGTYP_DEBUG) - logtraffic((unsigned char) &c, LGTYP_DEBUG); + logtraffic((unsigned char) c, LGTYP_DEBUG); } else { c = unget; unget = -1; @@ -1194,7 +1200,7 @@ void term_out(void) case '\007': { struct beeptime *newbeep; - long ticks; + unsigned long ticks; ticks = GetTickCount(); @@ -1225,7 +1231,7 @@ void term_out(void) } if (cfg.bellovl && beep_overloaded && - ticks - lastbeep >= cfg.bellovl_s) { + ticks - lastbeep >= (unsigned)cfg.bellovl_s) { /* * If we're currently overloaded and the * last beep was more than s seconds ago, @@ -1250,7 +1256,7 @@ void term_out(void) beep(cfg.beep); if (cfg.beep == BELL_VISUAL) { in_vbell = TRUE; - vbell_timeout = ticks + VBELL_TIMEOUT; + vbell_startpoint = ticks; term_update(); } } @@ -2528,16 +2534,16 @@ static void do_paint(Context ctx, int may_optimise) pos scrpos; char ch[1024]; long cursor_background = ERASE_CHAR; - long ticks; + unsigned long ticks; /* * Check the visual bell state. */ if (in_vbell) { ticks = GetTickCount(); - if (ticks - vbell_timeout >= 0) - in_vbell = FALSE; - } + if (ticks - vbell_startpoint >= VBELL_TIMEOUT) + in_vbell = FALSE; + } rv = (!rvideo ^ !in_vbell ? ATTR_REVERSE : 0); @@ -3061,6 +3067,7 @@ static pos sel_spread_half(pos p, int dir) { unsigned long *ldata; short wvalue; + int topy = -count234(scrollback); ldata = lineptr(p.y); @@ -3087,11 +3094,47 @@ static pos sel_spread_half(pos p, int dir) */ wvalue = wordtype(ldata[p.x]); if (dir == +1) { - while (p.x < cols && wordtype(ldata[p.x + 1]) == wvalue) - p.x++; + while (1) { + if (p.x < cols-1) { + if (wordtype(ldata[p.x + 1]) == wvalue) + p.x++; + else + break; + } else { + if (ldata[cols] & LATTR_WRAPPED) { + unsigned long *ldata2; + ldata2 = lineptr(p.y+1); + if (wordtype(ldata2[0]) == wvalue) { + p.x = 0; + p.y++; + ldata = ldata2; + } else + break; + } else + break; + } + } } else { - while (p.x > 0 && wordtype(ldata[p.x - 1]) == wvalue) - p.x--; + while (1) { + if (p.x > 0) { + if (wordtype(ldata[p.x - 1]) == wvalue) + p.x--; + else + break; + } else { + unsigned long *ldata2; + if (p.y <= topy) + break; + ldata2 = lineptr(p.y-1); + if ((ldata2[cols] & LATTR_WRAPPED) && + wordtype(ldata2[cols-1]) == wvalue) { + p.x = cols-1; + p.y--; + ldata = ldata2; + } else + break; + } + } } break; case SM_LINE: