mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-26 01:32:25 +00:00
Support custom clipboard names under X.
This required me to turn the drop-lists into combo boxes and add an extra string-typed Conf setting alongside each enumerated value.
This commit is contained in:
parent
018aa57645
commit
2a76f8d4a2
98
config.c
98
config.c
@ -1342,29 +1342,100 @@ static void clipboard_selector_handler(union control *ctrl, void *dlg,
|
|||||||
{
|
{
|
||||||
Conf *conf = (Conf *)data;
|
Conf *conf = (Conf *)data;
|
||||||
int setting = ctrl->generic.context.i;
|
int setting = ctrl->generic.context.i;
|
||||||
|
#ifdef NAMED_CLIPBOARDS
|
||||||
|
int strsetting = ctrl->editbox.context2.i;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static const struct {
|
||||||
|
const char *name;
|
||||||
|
int id;
|
||||||
|
} options[] = {
|
||||||
|
{"No action", CLIPUI_NONE},
|
||||||
|
{CLIPNAME_IMPLICIT, CLIPUI_IMPLICIT},
|
||||||
|
{CLIPNAME_EXPLICIT, CLIPUI_EXPLICIT},
|
||||||
|
};
|
||||||
|
|
||||||
if (event == EVENT_REFRESH) {
|
if (event == EVENT_REFRESH) {
|
||||||
int i, val = conf_get_int(conf, setting);
|
int i, val = conf_get_int(conf, setting);
|
||||||
|
|
||||||
dlg_update_start(ctrl, dlg);
|
dlg_update_start(ctrl, dlg);
|
||||||
dlg_listbox_clear(ctrl, dlg);
|
dlg_listbox_clear(ctrl, dlg);
|
||||||
dlg_listbox_addwithid(ctrl, dlg, "No action", CLIPUI_NONE);
|
|
||||||
dlg_listbox_addwithid(ctrl, dlg, CLIPNAME_IMPLICIT, CLIPUI_IMPLICIT);
|
#ifdef NAMED_CLIPBOARDS
|
||||||
dlg_listbox_addwithid(ctrl, dlg, CLIPNAME_EXPLICIT, CLIPUI_EXPLICIT);
|
for (i = 0; i < lenof(options); i++)
|
||||||
|
dlg_listbox_add(ctrl, dlg, options[i].name);
|
||||||
|
if (val == CLIPUI_CUSTOM) {
|
||||||
|
const char *sval = conf_get_str(conf, strsetting);
|
||||||
|
for (i = 0; i < lenof(options); i++)
|
||||||
|
if (!strcmp(sval, options[i].name))
|
||||||
|
break; /* needs escaping */
|
||||||
|
if (i < lenof(options) || sval[0] == '=') {
|
||||||
|
char *escaped = dupcat("=", sval, (const char *)NULL);
|
||||||
|
dlg_editbox_set(ctrl, dlg, escaped);
|
||||||
|
sfree(escaped);
|
||||||
|
} else {
|
||||||
|
dlg_editbox_set(ctrl, dlg, sval);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dlg_editbox_set(ctrl, dlg, options[0].name); /* fallback */
|
||||||
|
for (i = 0; i < lenof(options); i++)
|
||||||
|
if (val == options[i].id)
|
||||||
|
dlg_editbox_set(ctrl, dlg, options[i].name);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
for (i = 0; i < lenof(options); i++)
|
||||||
|
dlg_listbox_addwithid(ctrl, dlg, options[i].name, options[i].id);
|
||||||
dlg_listbox_select(ctrl, dlg, 0); /* fallback */
|
dlg_listbox_select(ctrl, dlg, 0); /* fallback */
|
||||||
for (i = 0; i < 3; i++)
|
for (i = 0; i < lenof(options); i++)
|
||||||
if (val == dlg_listbox_getid(ctrl, dlg, i))
|
if (val == options[i].id)
|
||||||
dlg_listbox_select(ctrl, dlg, i);
|
dlg_listbox_select(ctrl, dlg, i);
|
||||||
|
#endif
|
||||||
dlg_update_done(ctrl, dlg);
|
dlg_update_done(ctrl, dlg);
|
||||||
} else if (event == EVENT_SELCHANGE) {
|
} else if (event == EVENT_SELCHANGE
|
||||||
|
#ifdef NAMED_CLIPBOARDS
|
||||||
|
|| event == EVENT_VALCHANGE
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
|
#ifdef NAMED_CLIPBOARDS
|
||||||
|
const char *sval = dlg_editbox_get(ctrl, dlg);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < lenof(options); i++)
|
||||||
|
if (!strcmp(sval, options[i].name)) {
|
||||||
|
conf_set_int(conf, setting, options[i].id);
|
||||||
|
conf_set_str(conf, strsetting, "");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i == lenof(options)) {
|
||||||
|
conf_set_int(conf, setting, CLIPUI_CUSTOM);
|
||||||
|
if (sval[0] == '=')
|
||||||
|
sval++;
|
||||||
|
conf_set_str(conf, strsetting, sval);
|
||||||
|
}
|
||||||
|
#else
|
||||||
int index = dlg_listbox_index(ctrl, dlg);
|
int index = dlg_listbox_index(ctrl, dlg);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
int val = dlg_listbox_getid(ctrl, dlg, index);
|
int val = dlg_listbox_getid(ctrl, dlg, index);
|
||||||
conf_set_int(conf, setting, val);
|
conf_set_int(conf, setting, val);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void clipboard_control(struct controlset *s, const char *label,
|
||||||
|
char shortcut, int percentage, intorptr helpctx,
|
||||||
|
int setting, int strsetting)
|
||||||
|
{
|
||||||
|
#ifdef NAMED_CLIPBOARDS
|
||||||
|
ctrl_combobox(s, label, shortcut, percentage, helpctx,
|
||||||
|
clipboard_selector_handler, I(setting), I(strsetting));
|
||||||
|
#else
|
||||||
|
/* strsetting isn't needed in this case */
|
||||||
|
ctrl_droplist(s, label, shortcut, percentage, helpctx,
|
||||||
|
clipboard_selector_handler, I(setting));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void setup_config_box(struct controlbox *b, int midsession,
|
void setup_config_box(struct controlbox *b, int midsession,
|
||||||
int protocol, int protcfginfo)
|
int protocol, int protcfginfo)
|
||||||
{
|
{
|
||||||
@ -1894,18 +1965,15 @@ void setup_config_box(struct controlbox *b, int midsession,
|
|||||||
CLIPNAME_EXPLICIT_OBJECT,
|
CLIPNAME_EXPLICIT_OBJECT,
|
||||||
NO_SHORTCUT, HELPCTX(selection_autocopy),
|
NO_SHORTCUT, HELPCTX(selection_autocopy),
|
||||||
conf_checkbox_handler, I(CONF_mouseautocopy));
|
conf_checkbox_handler, I(CONF_mouseautocopy));
|
||||||
ctrl_droplist(s, "Mouse paste action:", NO_SHORTCUT, 60,
|
clipboard_control(s, "Mouse paste action:", NO_SHORTCUT, 60,
|
||||||
HELPCTX(selection_clipactions),
|
HELPCTX(selection_clipactions),
|
||||||
clipboard_selector_handler,
|
CONF_mousepaste, CONF_mousepaste_custom);
|
||||||
I(CONF_mousepaste));
|
clipboard_control(s, "{Ctrl,Shift} + Ins:", NO_SHORTCUT, 60,
|
||||||
ctrl_droplist(s, "{Ctrl,Shift} + Ins:", NO_SHORTCUT, 60,
|
|
||||||
HELPCTX(selection_clipactions),
|
HELPCTX(selection_clipactions),
|
||||||
clipboard_selector_handler,
|
CONF_ctrlshiftins, CONF_ctrlshiftins_custom);
|
||||||
I(CONF_ctrlshiftins));
|
clipboard_control(s, "Ctrl + Shift + {C,V}:", NO_SHORTCUT, 60,
|
||||||
ctrl_droplist(s, "Ctrl + Shift + {C,V}:", NO_SHORTCUT, 60,
|
|
||||||
HELPCTX(selection_clipactions),
|
HELPCTX(selection_clipactions),
|
||||||
clipboard_selector_handler,
|
CONF_ctrlshiftcv, CONF_ctrlshiftcv_custom);
|
||||||
I(CONF_ctrlshiftcv));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The Window/Selection/Words panel.
|
* The Window/Selection/Words panel.
|
||||||
|
@ -1520,7 +1520,7 @@ actions pastes from (including turning the paste action off
|
|||||||
completely). On platforms with a single system clipboard, the
|
completely). On platforms with a single system clipboard, the
|
||||||
available options are to paste from that clipboard or to paste from
|
available options are to paste from that clipboard or to paste from
|
||||||
PuTTY's internal memory of the last selected text within that window.
|
PuTTY's internal memory of the last selected text within that window.
|
||||||
On X, the options are \cw{CLIPBOARD} or \cw{PRIMARY}.
|
On X, the standard options are \cw{CLIPBOARD} or \cw{PRIMARY}.
|
||||||
|
|
||||||
(\cw{PRIMARY} is conceptually similar in that it \e{also} refers to
|
(\cw{PRIMARY} is conceptually similar in that it \e{also} refers to
|
||||||
the last selected text \dash just across all applications instead of
|
the last selected text \dash just across all applications instead of
|
||||||
@ -1531,6 +1531,16 @@ The two keyboard options each come with a corresponding key to copy
|
|||||||
from, Ctrl-Ins will copy to the same location; similarly, Ctrl-Shift-C
|
from, Ctrl-Ins will copy to the same location; similarly, Ctrl-Shift-C
|
||||||
will copy to whatever Ctrl-Shift-V pastes from.
|
will copy to whatever Ctrl-Shift-V pastes from.
|
||||||
|
|
||||||
|
On X, you can also enter a selection name of your choice. For example,
|
||||||
|
there is a rarely-used standard selection called \cq{SECONDARY}, which
|
||||||
|
Emacs (for example) can work with if you hold down the Meta key while
|
||||||
|
dragging to select or clicking to paste; if you configure a PuTTY
|
||||||
|
keyboard action to access this clipboard, then you can interoperate
|
||||||
|
with other applications' use of it. Another thing you could do would
|
||||||
|
be to invent a clipboard name yourself, to create a special clipboard
|
||||||
|
shared \e{only} between instances of PuTTY, or between just instances
|
||||||
|
configured in that particular way.
|
||||||
|
|
||||||
\H{config-selection-words} The Words panel
|
\H{config-selection-words} The Words panel
|
||||||
|
|
||||||
PuTTY will \I{word-by-word selection}select a word at a time in the
|
PuTTY will \I{word-by-word selection}select a word at a time in the
|
||||||
|
3
putty.h
3
putty.h
@ -903,6 +903,9 @@ void cleanup_exit(int);
|
|||||||
X(INT, NONE, mousepaste) \
|
X(INT, NONE, mousepaste) \
|
||||||
X(INT, NONE, ctrlshiftins) \
|
X(INT, NONE, ctrlshiftins) \
|
||||||
X(INT, NONE, ctrlshiftcv) \
|
X(INT, NONE, ctrlshiftcv) \
|
||||||
|
X(STR, NONE, mousepaste_custom) \
|
||||||
|
X(STR, NONE, ctrlshiftins_custom) \
|
||||||
|
X(STR, NONE, ctrlshiftcv_custom) \
|
||||||
/* translations */ \
|
/* translations */ \
|
||||||
X(INT, NONE, vtmode) \
|
X(INT, NONE, vtmode) \
|
||||||
X(STR, NONE, line_codepage) \
|
X(STR, NONE, line_codepage) \
|
||||||
|
31
settings.c
31
settings.c
@ -448,7 +448,7 @@ static void wprefs(void *sesskey, const char *name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void write_clip_setting(void *handle, const char *savekey,
|
static void write_clip_setting(void *handle, const char *savekey,
|
||||||
Conf *conf, int confkey)
|
Conf *conf, int confkey, int strconfkey)
|
||||||
{
|
{
|
||||||
int val = conf_get_int(conf, confkey);
|
int val = conf_get_int(conf, confkey);
|
||||||
switch (val) {
|
switch (val) {
|
||||||
@ -462,21 +462,33 @@ static void write_clip_setting(void *handle, const char *savekey,
|
|||||||
case CLIPUI_EXPLICIT:
|
case CLIPUI_EXPLICIT:
|
||||||
write_setting_s(handle, savekey, "explicit");
|
write_setting_s(handle, savekey, "explicit");
|
||||||
break;
|
break;
|
||||||
|
case CLIPUI_CUSTOM:
|
||||||
|
{
|
||||||
|
char *sval = dupcat("custom:", conf_get_str(conf, strconfkey),
|
||||||
|
(const char *)NULL);
|
||||||
|
write_setting_s(handle, savekey, sval);
|
||||||
|
sfree(sval);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void read_clip_setting(void *handle, const char *savekey,
|
static void read_clip_setting(void *handle, const char *savekey,
|
||||||
int def, Conf *conf, int confkey)
|
int def, Conf *conf, int confkey, int strconfkey)
|
||||||
{
|
{
|
||||||
char *setting = read_setting_s(handle, savekey);
|
char *setting = read_setting_s(handle, savekey);
|
||||||
int val;
|
int val;
|
||||||
|
|
||||||
|
conf_set_str(conf, strconfkey, "");
|
||||||
if (!setting) {
|
if (!setting) {
|
||||||
val = def;
|
val = def;
|
||||||
} else if (!strcmp(setting, "implicit")) {
|
} else if (!strcmp(setting, "implicit")) {
|
||||||
val = CLIPUI_IMPLICIT;
|
val = CLIPUI_IMPLICIT;
|
||||||
} else if (!strcmp(setting, "explicit")) {
|
} else if (!strcmp(setting, "explicit")) {
|
||||||
val = CLIPUI_EXPLICIT;
|
val = CLIPUI_EXPLICIT;
|
||||||
|
} else if (!strncmp(setting, "custom:", 7)) {
|
||||||
|
val = CLIPUI_CUSTOM;
|
||||||
|
conf_set_str(conf, strconfkey, setting + 7);
|
||||||
} else {
|
} else {
|
||||||
val = CLIPUI_NONE;
|
val = CLIPUI_NONE;
|
||||||
}
|
}
|
||||||
@ -676,9 +688,12 @@ void save_open_settings(void *sesskey, Conf *conf)
|
|||||||
}
|
}
|
||||||
write_setting_i(sesskey, "MouseAutocopy",
|
write_setting_i(sesskey, "MouseAutocopy",
|
||||||
conf_get_int(conf, CONF_mouseautocopy));
|
conf_get_int(conf, CONF_mouseautocopy));
|
||||||
write_clip_setting(sesskey, "MousePaste", conf, CONF_mousepaste);
|
write_clip_setting(sesskey, "MousePaste", conf,
|
||||||
write_clip_setting(sesskey, "CtrlShiftIns", conf, CONF_ctrlshiftins);
|
CONF_mousepaste, CONF_mousepaste_custom);
|
||||||
write_clip_setting(sesskey, "CtrlShiftCV", conf, CONF_ctrlshiftcv);
|
write_clip_setting(sesskey, "CtrlShiftIns", conf,
|
||||||
|
CONF_ctrlshiftins, CONF_ctrlshiftins_custom);
|
||||||
|
write_clip_setting(sesskey, "CtrlShiftCV", conf,
|
||||||
|
CONF_ctrlshiftcv, CONF_ctrlshiftcv_custom);
|
||||||
write_setting_s(sesskey, "LineCodePage", conf_get_str(conf, CONF_line_codepage));
|
write_setting_s(sesskey, "LineCodePage", conf_get_str(conf, CONF_line_codepage));
|
||||||
write_setting_i(sesskey, "CJKAmbigWide", conf_get_int(conf, CONF_cjk_ambig_wide));
|
write_setting_i(sesskey, "CJKAmbigWide", conf_get_int(conf, CONF_cjk_ambig_wide));
|
||||||
write_setting_i(sesskey, "UTF8Override", conf_get_int(conf, CONF_utf8_override));
|
write_setting_i(sesskey, "UTF8Override", conf_get_int(conf, CONF_utf8_override));
|
||||||
@ -1103,11 +1118,11 @@ void load_open_settings(void *sesskey, Conf *conf)
|
|||||||
gppi(sesskey, "MouseAutocopy", CLIPUI_DEFAULT_AUTOCOPY,
|
gppi(sesskey, "MouseAutocopy", CLIPUI_DEFAULT_AUTOCOPY,
|
||||||
conf, CONF_mouseautocopy);
|
conf, CONF_mouseautocopy);
|
||||||
read_clip_setting(sesskey, "MousePaste", CLIPUI_DEFAULT_MOUSE,
|
read_clip_setting(sesskey, "MousePaste", CLIPUI_DEFAULT_MOUSE,
|
||||||
conf, CONF_mousepaste);
|
conf, CONF_mousepaste, CONF_mousepaste_custom);
|
||||||
read_clip_setting(sesskey, "CtrlShiftIns", CLIPUI_DEFAULT_INS,
|
read_clip_setting(sesskey, "CtrlShiftIns", CLIPUI_DEFAULT_INS,
|
||||||
conf, CONF_ctrlshiftins);
|
conf, CONF_ctrlshiftins, CONF_ctrlshiftins_custom);
|
||||||
read_clip_setting(sesskey, "CtrlShiftCV", CLIPUI_NONE,
|
read_clip_setting(sesskey, "CtrlShiftCV", CLIPUI_NONE,
|
||||||
conf, CONF_ctrlshiftcv);
|
conf, CONF_ctrlshiftcv, CONF_ctrlshiftcv_custom);
|
||||||
/*
|
/*
|
||||||
* The empty default for LineCodePage will be converted later
|
* The empty default for LineCodePage will be converted later
|
||||||
* into a plausible default for the locale.
|
* into a plausible default for the locale.
|
||||||
|
141
unix/gtkwin.c
141
unix/gtkwin.c
@ -115,6 +115,7 @@ struct gui_data {
|
|||||||
#endif
|
#endif
|
||||||
int direct_to_font;
|
int direct_to_font;
|
||||||
struct clipboard_state clipstates[N_CLIPBOARDS];
|
struct clipboard_state clipstates[N_CLIPBOARDS];
|
||||||
|
int clipboard_ctrlshiftins, clipboard_ctrlshiftcv;
|
||||||
int font_width, font_height;
|
int font_width, font_height;
|
||||||
int width, height;
|
int width, height;
|
||||||
int ignore_sbar;
|
int ignore_sbar;
|
||||||
@ -1041,6 +1042,12 @@ gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
|
|||||||
#endif
|
#endif
|
||||||
term_request_paste(inst->term, CLIP_CLIPBOARD);
|
term_request_paste(inst->term, CLIP_CLIPBOARD);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
case CLIPUI_CUSTOM:
|
||||||
|
#ifdef KEY_EVENT_DIAGNOSTICS
|
||||||
|
debug((" - Shift-Insert: paste from custom clipboard\n"));
|
||||||
|
#endif
|
||||||
|
term_request_paste(inst->term, inst->clipboard_ctrlshiftins);
|
||||||
|
return TRUE;
|
||||||
default:
|
default:
|
||||||
#ifdef KEY_EVENT_DIAGNOSTICS
|
#ifdef KEY_EVENT_DIAGNOSTICS
|
||||||
debug((" - Shift-Insert: no paste action\n"));
|
debug((" - Shift-Insert: no paste action\n"));
|
||||||
@ -1067,6 +1074,13 @@ gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
|
|||||||
term_request_copy(inst->term,
|
term_request_copy(inst->term,
|
||||||
clips_clipboard, lenof(clips_clipboard));
|
clips_clipboard, lenof(clips_clipboard));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
case CLIPUI_CUSTOM:
|
||||||
|
#ifdef KEY_EVENT_DIAGNOSTICS
|
||||||
|
debug((" - Ctrl-Insert: copy to custom clipboard\n"));
|
||||||
|
#endif
|
||||||
|
term_request_copy(inst->term,
|
||||||
|
&inst->clipboard_ctrlshiftins, 1);
|
||||||
|
return TRUE;
|
||||||
default:
|
default:
|
||||||
#ifdef KEY_EVENT_DIAGNOSTICS
|
#ifdef KEY_EVENT_DIAGNOSTICS
|
||||||
debug((" - Ctrl-Insert: no copy action\n"));
|
debug((" - Ctrl-Insert: no copy action\n"));
|
||||||
@ -1113,6 +1127,21 @@ gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
|
|||||||
term_request_copy(inst->term, clips, lenof(clips));
|
term_request_copy(inst->term, clips, lenof(clips));
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
case CLIPUI_CUSTOM:
|
||||||
|
if (paste) {
|
||||||
|
#ifdef KEY_EVENT_DIAGNOSTICS
|
||||||
|
debug((" - Ctrl-Shift-V: paste from custom clipboard\n"));
|
||||||
|
#endif
|
||||||
|
term_request_paste(inst->term,
|
||||||
|
inst->clipboard_ctrlshiftcv);
|
||||||
|
} else {
|
||||||
|
#ifdef KEY_EVENT_DIAGNOSTICS
|
||||||
|
debug((" - Ctrl-Shift-C: copy to custom clipboard\n"));
|
||||||
|
#endif
|
||||||
|
term_request_copy(inst->term,
|
||||||
|
&inst->clipboard_ctrlshiftcv, 1);
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2571,6 +2600,20 @@ void palette_reset(void *frontend)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct clipboard_state *clipboard_from_atom(
|
||||||
|
struct gui_data *inst, GdkAtom atom)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < N_CLIPBOARDS; i++) {
|
||||||
|
struct clipboard_state *state = &inst->clipstates[i];
|
||||||
|
if (state->inst == inst && state->atom == atom)
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef JUST_USE_GTK_CLIPBOARD_UTF8
|
#ifdef JUST_USE_GTK_CLIPBOARD_UTF8
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
@ -2580,25 +2623,27 @@ void palette_reset(void *frontend)
|
|||||||
* formats it feels like.
|
* formats it feels like.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void init_one_clipboard(struct gui_data *inst, int clipboard,
|
void set_clipboard_atom(struct gui_data *inst, int clipboard, GdkAtom atom)
|
||||||
GdkAtom atom)
|
|
||||||
{
|
{
|
||||||
struct clipboard_state *state = &inst->clipstates[clipboard];
|
struct clipboard_state *state = &inst->clipstates[clipboard];
|
||||||
|
|
||||||
state->inst = inst;
|
state->inst = inst;
|
||||||
state->atom = atom;
|
|
||||||
state->clipboard = clipboard;
|
state->clipboard = clipboard;
|
||||||
|
state->atom = atom;
|
||||||
|
|
||||||
|
if (state->atom != GDK_NONE) {
|
||||||
state->gtkclipboard = gtk_clipboard_get_for_display(
|
state->gtkclipboard = gtk_clipboard_get_for_display(
|
||||||
gdk_display_get_default(), atom);
|
gdk_display_get_default(), state->atom);
|
||||||
|
|
||||||
g_object_set_data(G_OBJECT(state->gtkclipboard), "user-data", state);
|
g_object_set_data(G_OBJECT(state->gtkclipboard), "user-data", state);
|
||||||
|
} else {
|
||||||
|
state->gtkclipboard = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int init_clipboard(struct gui_data *inst)
|
int init_clipboard(struct gui_data *inst)
|
||||||
{
|
{
|
||||||
init_one_clipboard(inst, CLIP_PRIMARY, GDK_SELECTION_PRIMARY);
|
set_clipboard_atom(inst, CLIP_PRIMARY, GDK_SELECTION_PRIMARY);
|
||||||
init_one_clipboard(inst, CLIP_CLIPBOARD, GDK_SELECTION_CLIPBOARD);
|
set_clipboard_atom(inst, CLIP_CLIPBOARD, GDK_SELECTION_CLIPBOARD);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2663,6 +2708,9 @@ void write_clip(void *frontend, int clipboard,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!state->gtkclipboard)
|
||||||
|
return;
|
||||||
|
|
||||||
cdi = snew(struct clipboard_data_instance);
|
cdi = snew(struct clipboard_data_instance);
|
||||||
state->current_cdi = cdi;
|
state->current_cdi = cdi;
|
||||||
cdi->pasteout_data_utf8 = snewn(len*6, char);
|
cdi->pasteout_data_utf8 = snewn(len*6, char);
|
||||||
@ -2721,6 +2769,10 @@ void frontend_request_paste(void *frontend, int clipboard)
|
|||||||
{
|
{
|
||||||
struct gui_data *inst = (struct gui_data *)frontend;
|
struct gui_data *inst = (struct gui_data *)frontend;
|
||||||
struct clipboard_state *state = &inst->clipstates[clipboard];
|
struct clipboard_state *state = &inst->clipstates[clipboard];
|
||||||
|
|
||||||
|
if (!state->gtkclipboard)
|
||||||
|
return;
|
||||||
|
|
||||||
gtk_clipboard_request_text(state->gtkclipboard,
|
gtk_clipboard_request_text(state->gtkclipboard,
|
||||||
clipboard_text_received, inst);
|
clipboard_text_received, inst);
|
||||||
}
|
}
|
||||||
@ -2881,20 +2933,6 @@ void write_clip(void *frontend, int clipboard,
|
|||||||
term_lost_clipboard_ownership(inst->term, clipboard);
|
term_lost_clipboard_ownership(inst->term, clipboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct clipboard_state *clipboard_from_atom(
|
|
||||||
struct gui_data *inst, GdkAtom atom)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < N_CLIPBOARDS; i++) {
|
|
||||||
struct clipboard_state *state = &inst->clipstates[i];
|
|
||||||
if (state->inst == inst && state->atom == atom)
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void selection_get(GtkWidget *widget, GtkSelectionData *seldata,
|
static void selection_get(GtkWidget *widget, GtkSelectionData *seldata,
|
||||||
guint info, guint time_stamp, gpointer data)
|
guint info, guint time_stamp, gpointer data)
|
||||||
{
|
{
|
||||||
@ -3103,16 +3141,24 @@ static void selection_received(GtkWidget *widget, GtkSelectionData *seldata,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_one_clipboard(struct gui_data *inst, int clipboard,
|
static void init_one_clipboard(struct gui_data *inst, int clipboard)
|
||||||
GdkAtom atom)
|
|
||||||
{
|
{
|
||||||
struct clipboard_state *state = &inst->clipstates[clipboard];
|
struct clipboard_state *state = &inst->clipstates[clipboard];
|
||||||
|
|
||||||
state->inst = inst;
|
state->inst = inst;
|
||||||
state->atom = atom;
|
|
||||||
state->clipboard = clipboard;
|
state->clipboard = clipboard;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_clipboard_atom(struct gui_data *inst, int clipboard, GdkAtom atom)
|
||||||
|
{
|
||||||
|
struct clipboard_state *state = &inst->clipstates[clipboard];
|
||||||
|
|
||||||
|
state->inst = inst;
|
||||||
|
state->clipboard = clipboard;
|
||||||
|
|
||||||
|
state->atom = atom;
|
||||||
|
}
|
||||||
|
|
||||||
void init_clipboard(struct gui_data *inst)
|
void init_clipboard(struct gui_data *inst)
|
||||||
{
|
{
|
||||||
#ifndef NOT_X_WINDOWS
|
#ifndef NOT_X_WINDOWS
|
||||||
@ -3148,8 +3194,10 @@ void init_clipboard(struct gui_data *inst)
|
|||||||
XA_CUT_BUFFER7, XA_STRING, 8, PropModeAppend, empty, 0);
|
XA_CUT_BUFFER7, XA_STRING, 8, PropModeAppend, empty, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
init_one_clipboard(inst, CLIP_PRIMARY, GDK_SELECTION_PRIMARY);
|
inst->clipstates[CLIP_PRIMARY].atom = GDK_SELECTION_PRIMARY;
|
||||||
init_one_clipboard(inst, CLIP_CLIPBOARD, GDK_SELECTION_CLIPBOARD);
|
inst->clipstates[CLIP_CLIPBOARD].atom = GDK_SELECTION_CLIPBOARD;
|
||||||
|
init_one_clipboard(inst, CLIP_PRIMARY);
|
||||||
|
init_one_clipboard(inst, CLIP_CLIPBOARD);
|
||||||
|
|
||||||
g_signal_connect(G_OBJECT(inst->area), "selection_received",
|
g_signal_connect(G_OBJECT(inst->area), "selection_received",
|
||||||
G_CALLBACK(selection_received), inst);
|
G_CALLBACK(selection_received), inst);
|
||||||
@ -4252,7 +4300,7 @@ void event_log_menuitem(GtkMenuItem *item, gpointer data)
|
|||||||
showeventlog(inst->eventlogstuff, inst->window);
|
showeventlog(inst->eventlogstuff, inst->window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup_clipboards(Terminal *term, Conf *conf)
|
void setup_clipboards(struct gui_data *inst, Terminal *term, Conf *conf)
|
||||||
{
|
{
|
||||||
assert(term->mouse_select_clipboards[0] == CLIP_LOCAL);
|
assert(term->mouse_select_clipboards[0] == CLIP_LOCAL);
|
||||||
|
|
||||||
@ -4265,6 +4313,10 @@ void setup_clipboards(Terminal *term, Conf *conf)
|
|||||||
term->n_mouse_select_clipboards++] = CLIP_CLIPBOARD;
|
term->n_mouse_select_clipboards++] = CLIP_CLIPBOARD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set_clipboard_atom(inst, CLIP_CUSTOM_1, GDK_NONE);
|
||||||
|
set_clipboard_atom(inst, CLIP_CUSTOM_2, GDK_NONE);
|
||||||
|
set_clipboard_atom(inst, CLIP_CUSTOM_3, GDK_NONE);
|
||||||
|
|
||||||
switch (conf_get_int(conf, CONF_mousepaste)) {
|
switch (conf_get_int(conf, CONF_mousepaste)) {
|
||||||
case CLIPUI_IMPLICIT:
|
case CLIPUI_IMPLICIT:
|
||||||
term->mouse_paste_clipboard = MOUSE_PASTE_CLIPBOARD;
|
term->mouse_paste_clipboard = MOUSE_PASTE_CLIPBOARD;
|
||||||
@ -4272,10 +4324,41 @@ void setup_clipboards(Terminal *term, Conf *conf)
|
|||||||
case CLIPUI_EXPLICIT:
|
case CLIPUI_EXPLICIT:
|
||||||
term->mouse_paste_clipboard = CLIP_CLIPBOARD;
|
term->mouse_paste_clipboard = CLIP_CLIPBOARD;
|
||||||
break;
|
break;
|
||||||
|
case CLIPUI_CUSTOM:
|
||||||
|
term->mouse_paste_clipboard = CLIP_CUSTOM_1;
|
||||||
|
set_clipboard_atom(inst, CLIP_CUSTOM_1,
|
||||||
|
gdk_atom_intern(
|
||||||
|
conf_get_str(conf, CONF_mousepaste_custom),
|
||||||
|
FALSE));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
term->mouse_paste_clipboard = CLIP_NULL;
|
term->mouse_paste_clipboard = CLIP_NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (conf_get_int(conf, CONF_ctrlshiftins) == CLIPUI_CUSTOM) {
|
||||||
|
GdkAtom atom = gdk_atom_intern(
|
||||||
|
conf_get_str(conf, CONF_ctrlshiftins_custom), FALSE);
|
||||||
|
struct clipboard_state *state = clipboard_from_atom(inst, atom);
|
||||||
|
if (state) {
|
||||||
|
inst->clipboard_ctrlshiftins = state->clipboard;
|
||||||
|
} else {
|
||||||
|
inst->clipboard_ctrlshiftins = CLIP_CUSTOM_2;
|
||||||
|
set_clipboard_atom(inst, CLIP_CUSTOM_2, atom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conf_get_int(conf, CONF_ctrlshiftcv) == CLIPUI_CUSTOM) {
|
||||||
|
GdkAtom atom = gdk_atom_intern(
|
||||||
|
conf_get_str(conf, CONF_ctrlshiftcv_custom), FALSE);
|
||||||
|
struct clipboard_state *state = clipboard_from_atom(inst, atom);
|
||||||
|
if (state) {
|
||||||
|
inst->clipboard_ctrlshiftins = state->clipboard;
|
||||||
|
} else {
|
||||||
|
inst->clipboard_ctrlshiftcv = CLIP_CUSTOM_3;
|
||||||
|
set_clipboard_atom(inst, CLIP_CUSTOM_3, atom);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct after_change_settings_dialog_ctx {
|
struct after_change_settings_dialog_ctx {
|
||||||
@ -4352,7 +4435,7 @@ static void after_change_settings_dialog(void *vctx, int retval)
|
|||||||
}
|
}
|
||||||
/* Pass new config data to the terminal */
|
/* Pass new config data to the terminal */
|
||||||
term_reconfig(inst->term, inst->conf);
|
term_reconfig(inst->term, inst->conf);
|
||||||
setup_clipboards(inst->term, inst->conf);
|
setup_clipboards(inst, inst->term, inst->conf);
|
||||||
/* Pass new config data to the back end */
|
/* Pass new config data to the back end */
|
||||||
if (inst->back)
|
if (inst->back)
|
||||||
inst->back->reconfig(inst->backhandle, inst->conf);
|
inst->back->reconfig(inst->backhandle, inst->conf);
|
||||||
@ -5131,7 +5214,7 @@ void new_session_window(Conf *conf, const char *geometry_string)
|
|||||||
inst->eventlogstuff = eventlogstuff_new();
|
inst->eventlogstuff = eventlogstuff_new();
|
||||||
|
|
||||||
inst->term = term_init(inst->conf, &inst->ucsdata, inst);
|
inst->term = term_init(inst->conf, &inst->ucsdata, inst);
|
||||||
setup_clipboards(inst->term, inst->conf);
|
setup_clipboards(inst, inst->term, inst->conf);
|
||||||
inst->logctx = log_init(inst, inst->conf);
|
inst->logctx = log_init(inst, inst->conf);
|
||||||
term_provide_logctx(inst->term, inst->logctx);
|
term_provide_logctx(inst->term, inst->logctx);
|
||||||
|
|
||||||
|
@ -121,6 +121,9 @@ unsigned long getticks(void);
|
|||||||
#define PLATFORM_CLIPBOARDS(X) \
|
#define PLATFORM_CLIPBOARDS(X) \
|
||||||
X(CLIP_PRIMARY, "X11 primary selection") \
|
X(CLIP_PRIMARY, "X11 primary selection") \
|
||||||
X(CLIP_CLIPBOARD, "XDG clipboard") \
|
X(CLIP_CLIPBOARD, "XDG clipboard") \
|
||||||
|
X(CLIP_CUSTOM_1, "<custom#1>") \
|
||||||
|
X(CLIP_CUSTOM_2, "<custom#2>") \
|
||||||
|
X(CLIP_CUSTOM_3, "<custom#3>") \
|
||||||
/* end of list */
|
/* end of list */
|
||||||
|
|
||||||
#ifdef OSX_GTK
|
#ifdef OSX_GTK
|
||||||
@ -149,6 +152,8 @@ unsigned long getticks(void);
|
|||||||
#define CLIPUI_DEFAULT_AUTOCOPY FALSE
|
#define CLIPUI_DEFAULT_AUTOCOPY FALSE
|
||||||
#define CLIPUI_DEFAULT_MOUSE CLIPUI_IMPLICIT
|
#define CLIPUI_DEFAULT_MOUSE CLIPUI_IMPLICIT
|
||||||
#define CLIPUI_DEFAULT_INS CLIPUI_IMPLICIT
|
#define CLIPUI_DEFAULT_INS CLIPUI_IMPLICIT
|
||||||
|
/* X11 supports arbitrary named clipboards */
|
||||||
|
#define NAMED_CLIPBOARDS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The per-session frontend structure managed by gtkwin.c */
|
/* The per-session frontend structure managed by gtkwin.c */
|
||||||
|
Loading…
Reference in New Issue
Block a user