diff --git a/fuzzterm.c b/fuzzterm.c index 707c4ae8..3ce8b584 100644 --- a/fuzzterm.c +++ b/fuzzterm.c @@ -83,7 +83,6 @@ void palette_set(void *frontend, int a, int b, int c, int d) { } void palette_reset(void *frontend) { } int palette_get(void *frontend, int n, int *r, int *g, int *b) {return FALSE;} void write_clip(void *frontend, wchar_t *a, int *b, truecolour *c, int d, int e) { } -void get_clip(void *frontend, wchar_t **w, int *i) { } void set_raw_mouse_mode(void *frontend, int m) { } void request_paste(void *frontend) { } void do_beep(void *frontend, int a) { } diff --git a/putty.h b/putty.h index 97ef7130..964b4b23 100644 --- a/putty.h +++ b/putty.h @@ -637,7 +637,6 @@ void palette_reset(void *frontend); int palette_get(void *frontend, int n, int *r, int *g, int *b); void write_aclip(void *frontend, char *, int, int); void write_clip(void *frontend, wchar_t *, int *, truecolour *, int, int); -void get_clip(void *frontend, wchar_t **, int *); void optimised_move(void *frontend, int, int, int); void set_raw_mouse_mode(void *frontend, int); void connection_fatal(void *frontend, const char *, ...); @@ -1057,7 +1056,7 @@ void term_deselect(Terminal *); void term_update(Terminal *); void term_invalidate(Terminal *); void term_blink(Terminal *, int set_cursor); -void term_do_paste(Terminal *); +void term_do_paste(Terminal *, const wchar_t *, int); void term_nopaste(Terminal *); int term_ldisc(Terminal *, int option); void term_copyall(Terminal *); diff --git a/terminal.c b/terminal.c index 96a00266..f416e109 100644 --- a/terminal.c +++ b/terminal.c @@ -6073,66 +6073,66 @@ static void term_paste_callback(void *vterm) term->paste_len = 0; } -void term_do_paste(Terminal *term) +void term_do_paste(Terminal *term, const wchar_t *data, int len) { - wchar_t *data; - int len; + const wchar_t *p, *q; - get_clip(term->frontend, &data, &len); - if (data && len > 0) { - wchar_t *p, *q; + /* + * Pasting data into the terminal counts as a keyboard event (for + * purposes of the 'Reset scrollback on keypress' config option), + * unless the paste is zero-length. + */ + if (len == 0) + return; + term_seen_key_event(term); - term_seen_key_event(term); /* pasted data counts */ + if (term->paste_buffer) + sfree(term->paste_buffer); + term->paste_pos = term->paste_len = 0; + term->paste_buffer = snewn(len + 12, wchar_t); + if (term->bracketed_paste) { + memcpy(term->paste_buffer, L"\033[200~", 6 * sizeof(wchar_t)); + term->paste_len += 6; + } + + 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++) { + term->paste_buffer[term->paste_len++] = q[i]; + } + } + + if (p <= data + len - sel_nl_sz && + !memcmp(p, sel_nl, sizeof(sel_nl))) { + term->paste_buffer[term->paste_len++] = '\015'; + p += sel_nl_sz; + } + q = p; + } + + if (term->bracketed_paste) { + memcpy(term->paste_buffer + term->paste_len, + L"\033[201~", 6 * sizeof(wchar_t)); + term->paste_len += 6; + } + + /* Assume a small paste will be OK in one go. */ + if (term->paste_len < 256) { + if (term->ldisc) + luni_send(term->ldisc, term->paste_buffer, term->paste_len, 0); if (term->paste_buffer) sfree(term->paste_buffer); + term->paste_buffer = 0; term->paste_pos = term->paste_len = 0; - term->paste_buffer = snewn(len + 12, wchar_t); - - if (term->bracketed_paste) { - memcpy(term->paste_buffer, L"\033[200~", 6 * sizeof(wchar_t)); - term->paste_len += 6; - } - - 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++) { - term->paste_buffer[term->paste_len++] = q[i]; - } - } - - if (p <= data + len - sel_nl_sz && - !memcmp(p, sel_nl, sizeof(sel_nl))) { - term->paste_buffer[term->paste_len++] = '\015'; - p += sel_nl_sz; - } - q = p; - } - - if (term->bracketed_paste) { - memcpy(term->paste_buffer + term->paste_len, - L"\033[201~", 6 * sizeof(wchar_t)); - term->paste_len += 6; - } - - /* Assume a small paste will be OK in one go. */ - if (term->paste_len < 256) { - if (term->ldisc) - luni_send(term->ldisc, term->paste_buffer, term->paste_len, 0); - if (term->paste_buffer) - sfree(term->paste_buffer); - term->paste_buffer = 0; - term->paste_pos = term->paste_len = 0; - } } - get_clip(term->frontend, NULL, NULL); queue_toplevel_callback(term_paste_callback, term); } diff --git a/unix/gtkwin.c b/unix/gtkwin.c index b8607665..96421ac5 100644 --- a/unix/gtkwin.c +++ b/unix/gtkwin.c @@ -101,8 +101,6 @@ struct gui_data { GdkColormap *colmap; #endif int direct_to_font; - wchar_t *pastein_data; - int pastein_data_len; #ifdef JUST_USE_GTK_CLIPBOARD_UTF8 GtkClipboard *clipboard; struct clipboard_data_instance *current_cdi; @@ -2594,6 +2592,8 @@ static void clipboard_text_received(GtkClipboard *clipboard, const gchar *text, gpointer data) { struct gui_data *inst = (struct gui_data *)data; + wchar_t *paste; + int paste_len; int length; if (!text) @@ -2601,14 +2601,12 @@ static void clipboard_text_received(GtkClipboard *clipboard, length = strlen(text); - if (inst->pastein_data) - sfree(inst->pastein_data); + paste = snewn(length, wchar_t); + paste_len = mb_to_wc(CS_UTF8, 0, text, length, paste, length); - inst->pastein_data = snewn(length, wchar_t); - inst->pastein_data_len = mb_to_wc(CS_UTF8, 0, text, length, - inst->pastein_data, length); + term_do_paste(inst->term, paste, paste_len); - term_do_paste(inst->term); + sfree(paste); } void request_paste(void *frontend) @@ -2855,6 +2853,8 @@ static void selection_received(GtkWidget *widget, GtkSelectionData *seldata, GdkAtom seldata_type = gtk_selection_data_get_data_type(seldata); const guchar *seldata_data = gtk_selection_data_get_data(seldata); gint seldata_length = gtk_selection_data_get_length(seldata); + wchar_t *paste; + int paste_len; if (seldata_target == utf8_string_atom && seldata_length <= 0) { /* @@ -2942,16 +2942,12 @@ static void selection_received(GtkWidget *widget, GtkSelectionData *seldata, } } - if (inst->pastein_data) - sfree(inst->pastein_data); + paste = snewn(length, wchar_t); + paste_len = mb_to_wc(charset, 0, text, length, paste, length); - inst->pastein_data = snewn(length, wchar_t); - inst->pastein_data_len = length; - inst->pastein_data_len = - mb_to_wc(charset, 0, text, length, - inst->pastein_data, inst->pastein_data_len); + term_do_paste(inst->term, paste, paste_len); - term_do_paste(inst->term); + sfree(paste); #ifndef NOT_X_WINDOWS if (free_list_required) @@ -3011,16 +3007,6 @@ void init_clipboard(struct gui_data *inst) #endif /* JUST_USE_GTK_CLIPBOARD_UTF8 */ -void get_clip(void *frontend, wchar_t ** p, int *len) -{ - struct gui_data *inst = (struct gui_data *)frontend; - - if (p) { - *p = inst->pastein_data; - *len = inst->pastein_data_len; - } -} - static void set_window_titles(struct gui_data *inst) { /* diff --git a/windows/window.c b/windows/window.c index e5bd5b7f..3a67fb87 100644 --- a/windows/window.c +++ b/windows/window.c @@ -105,7 +105,7 @@ static int is_full_screen(void); static void make_full_screen(void); static void clear_full_screen(void); static void flip_full_screen(void); -static int process_clipdata(HGLOBAL clipdata, int unicode); +static void process_clipdata(HGLOBAL clipdata, int unicode); /* Window layout information */ static void reset_window(int); @@ -135,9 +135,6 @@ static const struct telnet_special *specials = NULL; static HMENU specials_menu = NULL; static int n_specials = 0; -static wchar_t *clipboard_contents; -static size_t clipboard_length; - #define TIMING_TIMER_ID 1234 static long timing_next_time; @@ -3176,8 +3173,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, } return 0; case WM_GOT_CLIPDATA: - if (process_clipdata((HGLOBAL)lParam, wParam)) - term_do_paste(term); + process_clipdata((HGLOBAL)lParam, wParam); return 0; default: if (message == wm_mousewheel || message == WM_MOUSEWHEEL) { @@ -5340,11 +5336,10 @@ static DWORD WINAPI clipboard_read_threadfunc(void *param) return 0; } -static int process_clipdata(HGLOBAL clipdata, int unicode) +static void process_clipdata(HGLOBAL clipdata, int unicode) { - sfree(clipboard_contents); - clipboard_contents = NULL; - clipboard_length = 0; + wchar_t *clipboard_contents = NULL; + size_t clipboard_length = 0; if (unicode) { wchar_t *p = GlobalLock(clipdata); @@ -5357,7 +5352,7 @@ static int process_clipdata(HGLOBAL clipdata, int unicode) clipboard_contents = snewn(clipboard_length + 1, wchar_t); memcpy(clipboard_contents, p, clipboard_length * sizeof(wchar_t)); clipboard_contents[clipboard_length] = L'\0'; - return TRUE; + term_do_paste(term, clipboard_contents, clipboard_length); } } else { char *s = GlobalLock(clipdata); @@ -5370,11 +5365,11 @@ static int process_clipdata(HGLOBAL clipdata, int unicode) clipboard_contents, i); clipboard_length = i - 1; clipboard_contents[clipboard_length] = L'\0'; - return TRUE; + term_do_paste(term, clipboard_contents, clipboard_length); } } - return FALSE; + sfree(clipboard_contents); } void request_paste(void *frontend) @@ -5400,14 +5395,6 @@ void request_paste(void *frontend) hwnd, 0, &in_threadid); } -void get_clip(void *frontend, wchar_t **p, int *len) -{ - if (p) { - *p = clipboard_contents; - *len = clipboard_length; - } -} - #if 0 /* * Move `lines' lines from position `from' to position `to' in the