X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/421e689af0c5510bdc8d37cef225359294cdabe4..2a6dfe0efd2e642b1e2fe89cf461b61b5bfe9fba:/terminal.c diff --git a/terminal.c b/terminal.c index cf55f8ea..b01ef80d 100644 --- a/terminal.c +++ b/terminal.c @@ -201,15 +201,40 @@ static FILE *lgfp = NULL; static void logtraffic(unsigned char c, int logmode); /* + * Resize a line to make it `cols' columns wide. + */ +unsigned long *resizeline(unsigned long *line, int cols) +{ + int i, oldlen; + unsigned long lineattrs; + + if (line[0] != (unsigned long)cols) { + /* + * This line is the wrong length, which probably means it + * hasn't been accessed since a resize. Resize it now. + */ + oldlen = line[0]; + lineattrs = line[oldlen + 1]; + line = srealloc(line, TSIZE * (2 + cols)); + line[0] = cols; + for (i = oldlen; i < cols; i++) + line[i + 1] = ERASE_CHAR; + line[cols + 1] = lineattrs & LATTR_MODE; + } + + return line; +} + +/* * Retrieve a line of the screen or of the scrollback, according to * whether the y coordinate is non-negative or negative * (respectively). */ unsigned long *lineptr(int y, int lineno) { - unsigned long *line, lineattrs; + unsigned long *line, *newline; tree234 *whichtree; - int i, treeindex, oldlen; + int treeindex; if (y >= 0) { whichtree = screen; @@ -223,20 +248,10 @@ unsigned long *lineptr(int y, int lineno) /* We assume that we don't screw up and retrieve something out of range. */ assert(line != NULL); - if (line[0] != cols) { - /* - * This line is the wrong length, which probably means it - * hasn't been accessed since a resize. Resize it now. - */ - oldlen = line[0]; - lineattrs = line[oldlen + 1]; + newline = resizeline(line, cols); + if (newline != line) { delpos234(whichtree, treeindex); - line = srealloc(line, TSIZE * (2 + cols)); - line[0] = cols; - for (i = oldlen; i < cols; i++) - line[i + 1] = ERASE_CHAR; - line[cols + 1] = lineattrs & LATTR_MODE; - addpos234(whichtree, line, treeindex); + addpos234(whichtree, newline, treeindex); } return line + 1; @@ -568,6 +583,7 @@ static void scroll(int topline, int botline, int lines, int sb) if (lines < 0) { while (lines < 0) { line = delpos234(screen, botline); + line = resizeline(line, cols); for (i = 0; i < cols; i++) line[i + 1] = erase_char; line[cols + 1] = 0; @@ -610,6 +626,7 @@ static void scroll(int topline, int botline, int lines, int sb) addpos234(scrollback, line, sblen); line = line2; } + line = resizeline(line, cols); for (i = 0; i < cols; i++) line[i + 1] = erase_char; line[cols + 1] = 0; @@ -718,6 +735,7 @@ static void erase_lots(int line_only, int from_begin, int to_end) } if (!to_end) { end = curs; + incpos(end); } check_selection(start, end); @@ -2952,6 +2970,54 @@ static void sel_spread(void) incpos(selend); } +void term_do_paste(void) +{ + wchar_t *data; + int len; + + get_clip(&data, &len); + if (data) { + wchar_t *p, *q; + + if (paste_buffer) + sfree(paste_buffer); + paste_pos = paste_hold = paste_len = 0; + paste_buffer = smalloc(len * sizeof(wchar_t)); + + p = q = data; + while (p < data + len) { + while (p < data + len && + !(p <= data + len - sel_nl_sz && + !memcmp(p, sel_nl, sizeof(sel_nl)))) + p++; + + { + int i; + for (i = 0; i < p - q; i++) { + paste_buffer[paste_len++] = q[i]; + } + } + + if (p <= data + len - sel_nl_sz && + !memcmp(p, sel_nl, sizeof(sel_nl))) { + paste_buffer[paste_len++] = '\r'; + p += sel_nl_sz; + } + q = p; + } + + /* Assume a small paste will be OK in one go. */ + if (paste_len < 256) { + luni_send(paste_buffer, paste_len); + if (paste_buffer) + sfree(paste_buffer); + paste_buffer = 0; + paste_pos = paste_hold = paste_len = 0; + } + } + get_clip(NULL, NULL); +} + void term_mouse(Mouse_Button b, Mouse_Action a, int x, int y, int shift, int ctrl) { @@ -3084,50 +3150,7 @@ void term_mouse(Mouse_Button b, Mouse_Action a, int x, int y, selstate = NO_SELECTION; } else if (b == MBT_PASTE && (a == MA_CLICK || a == MA_2CLK || a == MA_3CLK)) { - wchar_t *data; - int len; - - get_clip(&data, &len); - if (data) { - wchar_t *p, *q; - - if (paste_buffer) - sfree(paste_buffer); - paste_pos = paste_hold = paste_len = 0; - paste_buffer = smalloc(len * sizeof(wchar_t)); - - p = q = data; - while (p < data + len) { - while (p < data + len && - !(p <= data + len - sel_nl_sz && - !memcmp(p, sel_nl, sizeof(sel_nl)))) - p++; - - { - int i; - for (i = 0; i < p - q; i++) { - paste_buffer[paste_len++] = q[i]; - } - } - - if (p <= data + len - sel_nl_sz && - !memcmp(p, sel_nl, sizeof(sel_nl))) { - paste_buffer[paste_len++] = '\r'; - p += sel_nl_sz; - } - q = p; - } - - /* Assume a small paste will be OK in one go. */ - if (paste_len < 256) { - luni_send(paste_buffer, paste_len); - if (paste_buffer) - sfree(paste_buffer); - paste_buffer = 0; - paste_pos = paste_hold = paste_len = 0; - } - } - get_clip(NULL, NULL); + term_do_paste(); } term_update();