1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 17:38:00 +00:00

Add a cross-platform clipboard called CLIP_LOCAL.

This stores the last text selected in _this_ terminal, regardless of
whether any other application has since taken back whatever system
clipboard we also copied it to. It's written unconditionally whenever
text is selected in terminal.c.

The main purpose of this will be that it's also the place that you can
go and find the data you need to write to a system clipboard in
response to an explicit Copy operation. But it can also act as a data
source for pastes in its own right, so you can use it to implement an
intra-window private extra clipboard if that's useful. (OS X Terminal
has one of those, so _someone_ at least seems to like the idea.)
This commit is contained in:
Simon Tatham 2017-12-10 14:53:55 +00:00
parent 41aa675a5b
commit cd7348281b
3 changed files with 62 additions and 12 deletions

23
putty.h
View File

@ -616,13 +616,23 @@ typedef struct truecolour {
optionalrgb_equal((c1).bg, (c2).bg))
/*
* Enumeration of clipboards. CLIP_NULL is the only one provided
* systemwide: it's a non=clipboard, writes to which are ignored and
* reads from which return no data. Each platform front end extends
* this enumeration in its own way.
* Enumeration of clipboards. We provide some standard ones cross-
* platform, and then permit each platform to extend this enumeration
* further by defining PLATFORM_CLIPBOARDS in its own header file.
*
* CLIP_NULL is a non-clipboard, writes to which are ignored and reads
* from which return no data.
*
* CLIP_LOCAL refers to a buffer within terminal.c, which
* unconditionally saves the last data selected in the terminal. In
* configurations where a system clipboard is not written
* automatically on selection but instead by an explicit UI action,
* this is where the code responding to that action can find the data
* to write to the clipboard in question.
*/
#define CROSS_PLATFORM_CLIPBOARDS(X) \
X(CLIP_NULL, "null clipboard") \
#define CROSS_PLATFORM_CLIPBOARDS(X) \
X(CLIP_NULL, "null clipboard") \
X(CLIP_LOCAL, "last text selected in terminal") \
/* end of list */
#define ALL_CLIPBOARDS(X) \
@ -1080,6 +1090,7 @@ void term_nopaste(Terminal *);
int term_ldisc(Terminal *, int option);
void term_copyall(Terminal *, int clipboard);
void term_reconfig(Terminal *, Conf *);
void term_request_copy(Terminal *, int clipboard);
void term_request_paste(Terminal *, int clipboard);
void term_seen_key_event(Terminal *);
int term_data(Terminal *, int is_stderr, const char *data, int len);

View File

@ -1703,6 +1703,10 @@ Terminal *term_init(Conf *myconf, struct unicode_data *ucsdata,
term->basic_erase_char.truecolour.bg = optionalrgb_none;
term->erase_char = term->basic_erase_char;
term->last_selected_text = NULL;
term->last_selected_attr = NULL;
term->last_selected_tc = NULL;
term->last_selected_len = 0;
/* frontends will typically overwrite these with clipboard ids they
* know about */
term->mouse_select_clipboard = CLIP_NULL;
@ -5805,11 +5809,15 @@ static void clipme(Terminal *term, pos top, pos bottom, int rect, int desel,
clip_addchar(&buf, 0, 0, term->basic_erase_char.truecolour);
#endif
/* Finally, transfer all that to the clipboard. */
sfree(term->last_selected_text);
sfree(term->last_selected_attr);
sfree(term->last_selected_tc);
term->last_selected_text = buf.textbuf;
term->last_selected_attr = buf.attrbuf;
term->last_selected_tc = buf.tcbuf;
term->last_selected_len = buf.bufpos;
write_clip(term->frontend, clipboard,
buf.textbuf, buf.attrbuf, buf.tcbuf, buf.bufpos, desel);
sfree(buf.textbuf);
sfree(buf.attrbuf);
sfree(buf.tcbuf);
}
void term_copyall(Terminal *term, int clipboard)
@ -5824,11 +5832,38 @@ void term_copyall(Terminal *term, int clipboard)
clipme(term, top, bottom, 0, TRUE, clipboard);
}
static void paste_from_clip_local(void *vterm)
{
Terminal *term = (Terminal *)vterm;
term_do_paste(term, term->last_selected_text, term->last_selected_len);
}
void term_request_copy(Terminal *term, int clipboard)
{
assert(clipboard != CLIP_LOCAL);
if (clipboard != CLIP_NULL) {
write_clip(term->frontend, clipboard,
term->last_selected_text,
term->last_selected_attr,
term->last_selected_tc,
term->last_selected_len,
FALSE);
}
}
void term_request_paste(Terminal *term, int clipboard)
{
if (clipboard == CLIP_NULL)
return;
frontend_request_paste(term->frontend, clipboard);
switch (clipboard) {
case CLIP_NULL:
/* Do nothing: CLIP_NULL never has data in it. */
break;
case CLIP_LOCAL:
queue_toplevel_callback(paste_from_clip_local, term);
break;
default:
frontend_request_paste(term->frontend, clipboard);
break;
}
}
/*

View File

@ -328,6 +328,10 @@ struct terminal_tag {
int xterm_256_colour;
int true_colour;
wchar_t *last_selected_text;
int *last_selected_attr;
truecolour *last_selected_tc;
size_t last_selected_len;
int mouse_select_clipboard;
int mouse_paste_clipboard;
};