-#ifndef NOT_X_WINDOWS
- unsigned char empty[] = "";
- Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
- XChangeProperty(disp, GDK_ROOT_WINDOW(),
- XA_CUT_BUFFER0, XA_STRING, 8, PropModeAppend, empty, 0);
- XChangeProperty(disp, GDK_ROOT_WINDOW(),
- XA_CUT_BUFFER1, XA_STRING, 8, PropModeAppend, empty, 0);
- XChangeProperty(disp, GDK_ROOT_WINDOW(),
- XA_CUT_BUFFER2, XA_STRING, 8, PropModeAppend, empty, 0);
- XChangeProperty(disp, GDK_ROOT_WINDOW(),
- XA_CUT_BUFFER3, XA_STRING, 8, PropModeAppend, empty, 0);
- XChangeProperty(disp, GDK_ROOT_WINDOW(),
- XA_CUT_BUFFER4, XA_STRING, 8, PropModeAppend, empty, 0);
- XChangeProperty(disp, GDK_ROOT_WINDOW(),
- XA_CUT_BUFFER5, XA_STRING, 8, PropModeAppend, empty, 0);
- XChangeProperty(disp, GDK_ROOT_WINDOW(),
- XA_CUT_BUFFER6, XA_STRING, 8, PropModeAppend, empty, 0);
- XChangeProperty(disp, GDK_ROOT_WINDOW(),
- XA_CUT_BUFFER7, XA_STRING, 8, PropModeAppend, empty, 0);
-#endif
+ inst->clipboard = gtk_clipboard_get_for_display(gdk_display_get_default(),
+ DEFAULT_CLIPBOARD);
+}
+
+/*
+ * Because calling gtk_clipboard_set_with_data triggers a call to the
+ * clipboard_clear function from the last time, we need to arrange a
+ * way to distinguish a real call to clipboard_clear for the _new_
+ * instance of the clipboard data from the leftover call for the
+ * outgoing one. We do this by setting the user data field in our
+ * gtk_clipboard_set_with_data() call, instead of the obvious pointer
+ * to 'inst', to one of these.
+ */
+struct clipboard_data_instance {
+ struct gui_data *inst;
+ char *pasteout_data_utf8;
+ int pasteout_data_utf8_len;
+};
+
+static void clipboard_provide_data(GtkClipboard *clipboard,
+ GtkSelectionData *selection_data,
+ guint info, gpointer data)
+{
+ struct clipboard_data_instance *cdi =
+ (struct clipboard_data_instance *)data;
+ struct gui_data *inst = cdi->inst;
+
+ if (inst->current_cdi == cdi) {
+ gtk_selection_data_set_text(selection_data, cdi->pasteout_data_utf8,
+ cdi->pasteout_data_utf8_len);
+ }
+}
+
+static void clipboard_clear(GtkClipboard *clipboard, gpointer data)
+{
+ struct clipboard_data_instance *cdi =
+ (struct clipboard_data_instance *)data;
+ struct gui_data *inst = cdi->inst;
+
+ if (inst->current_cdi == cdi) {
+ term_deselect(inst->term);
+ inst->current_cdi = NULL;
+ }
+ sfree(cdi->pasteout_data_utf8);
+ sfree(cdi);
+}
+
+void write_clip(void *frontend, wchar_t *data, int *attr, int len,
+ int must_deselect)
+{
+ struct gui_data *inst = (struct gui_data *)frontend;
+ struct clipboard_data_instance *cdi;
+
+ if (inst->direct_to_font) {
+ /* In this clipboard mode, we just can't paste if we're in
+ * direct-to-font mode. Fortunately, that shouldn't be
+ * important, because we'll only use this clipboard handling
+ * code on systems where that kind of font doesn't exist
+ * anyway. */
+ return;
+ }
+
+ cdi = snew(struct clipboard_data_instance);
+ cdi->inst = inst;
+ inst->current_cdi = cdi;
+ cdi->pasteout_data_utf8 = snewn(len*6, char);
+ {
+ const wchar_t *tmp = data;
+ int tmplen = len;
+ cdi->pasteout_data_utf8_len =
+ charset_from_unicode(&tmp, &tmplen, cdi->pasteout_data_utf8,
+ len*6, CS_UTF8, NULL, NULL, 0);
+ }
+
+ /*
+ * It would be nice to just call gtk_clipboard_set_text() in place
+ * of all of the faffing below. Unfortunately, that won't give me
+ * access to the clipboard-clear event, which we use to visually
+ * deselect text in the terminal.
+ */
+ {
+ GtkTargetList *targetlist;
+ GtkTargetEntry *targettable;
+ gint n_targets;
+
+ targetlist = gtk_target_list_new(NULL, 0);
+ gtk_target_list_add_text_targets(targetlist, 0);
+ targettable = gtk_target_table_new_from_list(targetlist, &n_targets);
+ gtk_clipboard_set_with_data(inst->clipboard, targettable, n_targets,
+ clipboard_provide_data, clipboard_clear,
+ cdi);
+ gtk_target_table_free(targettable, n_targets);
+ gtk_target_list_unref(targetlist);
+ }