From fc5a96b6150e10abded6504e1d5983f0d01bee8c Mon Sep 17 00:00:00 2001 From: simon Date: Fri, 15 Oct 2004 10:48:27 +0000 Subject: [PATCH] Fix many bugs in resizeline(). git-svn-id: svn://svn.tartarus.org/sgt/putty@4629 cda61777-01e9-0310-a592-d414129be87e --- terminal.c | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/terminal.c b/terminal.c index 08574623..800a4f3f 100644 --- a/terminal.c +++ b/terminal.c @@ -845,9 +845,12 @@ static termline *decompressline(unsigned char *data, int *bytes_used) */ static void resizeline(Terminal *term, termline *line, int cols) { - int i, oldlen; + int i, oldcols; if (line->cols != cols) { + + oldcols = line->cols; + /* * This line is the wrong length, which probably means it * hasn't been accessed since a resize. Resize it now. @@ -856,24 +859,36 @@ static void resizeline(Terminal *term, termline *line, int cols) * out in the resize (if we're shrinking the line) and * return their cc lists to the cc free list. */ - for (i = cols; i < line->cols; i++) + for (i = cols; i < oldcols; i++) clear_cc(line, i); /* + * If we're shrinking the line, we now bodily move the + * entire cc section from where it started to where it now + * needs to be. (We have to do this before the resize, so + * that the data we're copying is still there. However, if + * we're expanding, we have to wait until _after_ the + * resize so that the space we're copying into is there.) + */ + if (cols < oldcols) + memmove(line->chars + cols, line->chars + oldcols, + (line->size - line->cols) * TSIZE); + + /* * Now do the actual resize, leaving the _same_ amount of * cc space as there was to begin with. */ - oldlen = line->cols; - line->size += cols - oldlen; + line->size += cols - oldcols; line->chars = sresize(line->chars, line->size, TTYPE); line->cols = cols; /* - * Bodily move the entire cc section from where it started - * to where it now needs to be. + * If we're expanding the line, _now_ we move the cc + * section. */ - memmove(line->chars + line->cols, line->chars + oldlen, - (line->size - line->cols) * TSIZE); + if (cols > oldcols) + memmove(line->chars + cols, line->chars + oldcols, + (line->size - line->cols) * TSIZE); /* * Go through what's left of the original line, and adjust @@ -882,18 +897,18 @@ static void resizeline(Terminal *term, termline *line, int cols) * relative offsets within the cc block.) Also do the same * to the head of the cc_free list. */ - for (i = 0; i < oldlen && i < line->cols; i++) + for (i = 0; i < oldcols && i < cols; i++) if (line->chars[i].cc_next) - line->chars[i].cc_next += cols - oldlen; + line->chars[i].cc_next += cols - oldcols; if (line->cc_free) - line->cc_free += cols - oldlen; + line->cc_free += cols - oldcols; /* * And finally fill in the new space with erase chars. (We * don't have to worry about cc lists here, because we * _know_ the erase char doesn't have one.) */ - for (i = oldlen; i < cols; i++) + for (i = oldcols; i < cols; i++) line->chars[i] = term->basic_erase_char; cc_check(line); /* XXX-REMOVE-BEFORE-RELEASE */ -- 2.11.0