X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/putty/blobdiff_plain/fc5a96b6150e10abded6504e1d5983f0d01bee8c..70637309a61321d83a4d0576b875b7dcb7085fa5:/terminal.c diff --git a/terminal.c b/terminal.c index 800a4f3f..f8d92dce 100644 --- a/terminal.c +++ b/terminal.c @@ -177,6 +177,8 @@ static void cc_check(termline *line) j += (flags[i] != 0); assert(j == line->size); + + sfree(flags); } /* @@ -433,6 +435,9 @@ static void makerle(struct buf *b, termline *ldata, hdrpos = b->len; hdrsize = 0; add(b, 0); + /* And ensure this run doesn't interfere with the next. */ + prevlen = prevpos = 0; + prev2 = FALSE; continue; } else { @@ -634,6 +639,9 @@ static unsigned char *compressline(termline *ldata) /* * Diagnostics: ensure that the compressed data really does * decompress to the right thing. + * + * XXX-REMOVE-BEFORE-RELEASE: This is a bit performance-heavy + * to be leaving in production code. */ #ifndef CHECK_SB_COMPRESSION { @@ -1134,6 +1142,22 @@ void term_reconfig(Terminal *term, Config *cfg) if (term->cfg.wordness[i] != cfg->wordness[i]) reset_charclass = 1; + /* + * If the bidi or shaping settings have changed, flush the bidi + * cache completely. + */ + if (term->cfg.arabicshaping != cfg->arabicshaping || + term->cfg.bidi != cfg->bidi) { + for (i = 0; i < term->bidi_cache_size; i++) { + sfree(term->pre_bidi_cache[i].chars); + sfree(term->post_bidi_cache[i].chars); + term->pre_bidi_cache[i].width = -1; + term->pre_bidi_cache[i].chars = NULL; + term->post_bidi_cache[i].width = -1; + term->post_bidi_cache[i].chars = NULL; + } + } + term->cfg = *cfg; /* STRUCTURE COPY */ if (reset_wrap) @@ -1294,8 +1318,8 @@ void term_free(Terminal *term) sfree(term->wcTo); for (i = 0; i < term->bidi_cache_size; i++) { - sfree(term->pre_bidi_cache[i]); - sfree(term->post_bidi_cache[i]); + sfree(term->pre_bidi_cache[i].chars); + sfree(term->post_bidi_cache[i].chars); } sfree(term->pre_bidi_cache); sfree(term->post_bidi_cache); @@ -1409,7 +1433,7 @@ void term_size(Terminal *term, int newrows, int newcols, int newsavelines) for (i = 0; i < newrows; i++) { newdisp[i] = newline(term, newcols, FALSE); for (j = 0; j < newcols; j++) - newdisp[i]->chars[i].attr = ATTR_INVALID; + newdisp[i]->chars[j].attr = ATTR_INVALID; } if (term->disptext) { for (i = 0; i < oldrows; i++) @@ -1648,7 +1672,7 @@ static void scroll(Terminal *term, int topline, int botline, int lines, int sb) addpos234(term->scrollback, compressline(line), sblen); - line = newline(term, term->cols, TRUE); + /* now `line' itself can be reused as the bottom line */ /* * If the user is currently looking at part of the @@ -2445,6 +2469,8 @@ void term_out(Terminal *term) term->wrapnext = FALSE; /* destructive backspace might be disabled */ if (!term->cfg.no_dbackspace) { + check_boundary(term, term->curs.x, term->curs.y); + check_boundary(term, term->curs.x+1, term->curs.y); copy_termchar(scrlineptr(term->curs.y), term->curs.x, &term->erase_char); } @@ -4161,11 +4187,14 @@ static int term_bidi_cache_hit(Terminal *term, int line, if (line >= term->bidi_cache_size) return FALSE; /* cache doesn't have this many lines */ - if (!term->pre_bidi_cache[line]) + if (!term->pre_bidi_cache[line].chars) return FALSE; /* cache doesn't contain _this_ line */ + if (term->pre_bidi_cache[line].width != width) + return FALSE; /* line is wrong width */ + for (i = 0; i < width; i++) - if (!termchars_equal(term->pre_bidi_cache[line] + i, lbefore + i)) + if (!termchars_equal(term->pre_bidi_cache[line].chars+i, lbefore+i)) return FALSE; /* line doesn't match cache */ return TRUE; /* it didn't match. */ @@ -4179,24 +4208,29 @@ static void term_bidi_cache_store(Terminal *term, int line, termchar *lbefore, term->bidi_cache_size = line+1; term->pre_bidi_cache = sresize(term->pre_bidi_cache, term->bidi_cache_size, - termchar *); + struct bidi_cache_entry); term->post_bidi_cache = sresize(term->post_bidi_cache, term->bidi_cache_size, - termchar *); + struct bidi_cache_entry); while (j < term->bidi_cache_size) { - term->pre_bidi_cache[j] = term->post_bidi_cache[j] = NULL; + term->pre_bidi_cache[j].chars = + term->post_bidi_cache[j].chars = NULL; + term->pre_bidi_cache[j].width = + term->post_bidi_cache[j].width = -1; j++; } } - sfree(term->pre_bidi_cache[line]); - sfree(term->post_bidi_cache[line]); + sfree(term->pre_bidi_cache[line].chars); + sfree(term->post_bidi_cache[line].chars); - term->pre_bidi_cache[line] = snewn(width, termchar); - term->post_bidi_cache[line] = snewn(width, termchar); + term->pre_bidi_cache[line].width = width; + term->pre_bidi_cache[line].chars = snewn(width, termchar); + term->post_bidi_cache[line].width = width; + term->post_bidi_cache[line].chars = snewn(width, termchar); - memcpy(term->pre_bidi_cache[line], lbefore, width * TSIZE); - memcpy(term->post_bidi_cache[line], lafter, width * TSIZE); + memcpy(term->pre_bidi_cache[line].chars, lbefore, width * TSIZE); + memcpy(term->post_bidi_cache[line].chars, lafter, width * TSIZE); } /* @@ -4399,7 +4433,7 @@ static void do_paint(Terminal *term, Context ctx, int may_optimise) lchars = term->ltemp; } else { - lchars = term->post_bidi_cache[i]; + lchars = term->post_bidi_cache[i].chars; } } else lchars = ldata->chars; @@ -4413,6 +4447,10 @@ static void do_paint(Terminal *term, Context ctx, int may_optimise) tchar = d->chr; tattr = d->attr; + if (!term->cfg.ansi_colour) + tattr = (tattr & ~(ATTR_FGMASK | ATTR_BGMASK)) | + ATTR_DEFFG | ATTR_DEFBG; + switch (tchar & CSET_MASK) { case CSET_ASCII: tchar = term->ucsdata->unitab_line[tchar & 0xFF]; @@ -4777,6 +4815,7 @@ static void clipme(Terminal *term, pos top, pos bottom, int rect, int desel) */ if (!(ldata->lattr & LATTR_WRAPPED)) { while (IS_SPACE_CHR(ldata->chars[nlpos.x - 1].chr) && + !ldata->chars[nlpos.x - 1].cc_next && poslt(top, nlpos)) decpos(nlpos); if (poslt(nlpos, bottom)) @@ -5049,7 +5088,8 @@ static pos sel_spread_half(Terminal *term, pos p, int dir) */ if (!(ldata->lattr & LATTR_WRAPPED)) { termchar *q = ldata->chars + term->cols; - while (q > ldata->chars && IS_SPACE_CHR(q[-1].chr)) + while (q > ldata->chars && + IS_SPACE_CHR(q[-1].chr) && !q[-1].cc_next) q--; if (q == ldata->chars + term->cols) q--;