Cutting and pasting from the Unix Event Log.
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Fri, 11 Apr 2003 17:40:52 +0000 (17:40 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Fri, 11 Apr 2003 17:40:52 +0000 (17:40 +0000)
git-svn-id: svn://svn.tartarus.org/sgt/putty@3095 cda61777-01e9-0310-a592-d414129be87e

unix/gtkdlg.c
unix/pterm.c

index 4299866..68adec9 100644 (file)
@@ -2495,6 +2495,9 @@ struct eventlog_stuff {
     union control *listctrl;
     char **events;
     int nevents, negsize;
+    char *seldata;
+    int sellen;
+    int ignore_selchange;
 };
 
 static void eventlog_destroy(GtkWidget *widget, gpointer data)
@@ -2502,6 +2505,7 @@ static void eventlog_destroy(GtkWidget *widget, gpointer data)
     struct eventlog_stuff *es = (struct eventlog_stuff *)data;
 
     es->window = NULL;
+    sfree(es->seldata);
     dlg_cleanup(&es->dp);
     ctrl_free_box(es->eventbox);
 }
@@ -2525,8 +2529,82 @@ static void eventlog_list_handler(union control *ctrl, void *dlg,
            dlg_listbox_add(ctrl, dlg, es->events[i]);
        }
        dlg_update_done(ctrl, dlg);
+    } else if (event == EVENT_SELCHANGE) {
+        int i;
+        int selsize = 0;
+
+        /*
+         * If this SELCHANGE event is happening as a result of
+         * deliberate deselection because someone else has grabbed
+         * the selection, the last thing we want to do is pre-empt
+         * them.
+         */
+        if (es->ignore_selchange)
+            return;
+
+        /*
+         * Construct the data to use as the selection.
+         */
+        sfree(es->seldata);
+        es->seldata = NULL;
+        es->sellen = 0;
+        for (i = 0; i < es->nevents; i++) {
+            if (dlg_listbox_issel(ctrl, dlg, i)) {
+                int extralen = strlen(es->events[i]);
+
+                if (es->sellen + extralen + 2 > selsize) {
+                    selsize = es->sellen + extralen + 512;
+                    es->seldata = sresize(es->seldata, selsize, char);
+                }
+
+                strcpy(es->seldata + es->sellen, es->events[i]);
+                es->sellen += extralen;
+                es->seldata[es->sellen++] = '\n';
+            }
+        }
+
+        if (gtk_selection_owner_set(es->window, GDK_SELECTION_PRIMARY,
+                                    GDK_CURRENT_TIME)) {
+            extern GdkAtom compound_text_atom;
+
+            gtk_selection_add_target(es->window, GDK_SELECTION_PRIMARY,
+                                     GDK_SELECTION_TYPE_STRING, 1);
+            gtk_selection_add_target(es->window, GDK_SELECTION_PRIMARY,
+                                     compound_text_atom, 1);
+        }
+
     }
 }
+
+void eventlog_selection_get(GtkWidget *widget, GtkSelectionData *seldata,
+                            guint info, guint time_stamp, gpointer data)
+{
+    struct eventlog_stuff *es = (struct eventlog_stuff *)data;
+
+    gtk_selection_data_set(seldata, seldata->target, 8,
+                           es->seldata, es->sellen);
+}
+
+gint eventlog_selection_clear(GtkWidget *widget, GdkEventSelection *seldata,
+                              gpointer data)
+{
+    struct eventlog_stuff *es = (struct eventlog_stuff *)data;
+    struct uctrl *uc;
+
+    /*
+     * Deselect everything in the list box.
+     */
+    uc = dlg_find_byctrl(&es->dp, es->listctrl);
+    es->ignore_selchange = 1;
+    gtk_list_unselect_all(GTK_LIST(uc->list));
+    es->ignore_selchange = 0;
+
+    sfree(es->seldata);
+    es->sellen = 0;
+    es->seldata = NULL;
+    return TRUE;
+}
+
 void showeventlog(void *estuff, void *parentwin)
 {
     struct eventlog_stuff *es = (struct eventlog_stuff *)estuff;
@@ -2610,6 +2688,10 @@ void showeventlog(void *estuff, void *parentwin)
                       GTK_SIGNAL_FUNC(eventlog_destroy), es);
     gtk_signal_connect(GTK_OBJECT(window), "key_press_event",
                       GTK_SIGNAL_FUNC(win_key_press), &es->dp);
+    gtk_signal_connect(GTK_OBJECT(window), "selection_get",
+                      GTK_SIGNAL_FUNC(eventlog_selection_get), es);
+    gtk_signal_connect(GTK_OBJECT(window), "selection_clear_event",
+                      GTK_SIGNAL_FUNC(eventlog_selection_clear), es);
 }
 
 void *eventlogstuff_new(void)
index 9f57018..15c6439 100644 (file)
@@ -34,6 +34,8 @@
 
 #define NCOLOURS (lenof(((Config *)0)->colours))
 
+GdkAtom compound_text_atom, utf8_string_atom;
+
 struct gui_data {
     GtkWidget *window, *area, *sbar;
     GtkBox *hbox;
@@ -59,7 +61,6 @@ struct gui_data {
     int ignore_sbar;
     int mouseptr_visible;
     guint term_paste_idle_id;
-    GdkAtom compound_text_atom, utf8_string_atom;
     int alt_keycode;
     int alt_digits;
     char wintitle[sizeof(((Config *)0)->wintitle)];
@@ -1306,10 +1307,10 @@ void write_clip(void *frontend, wchar_t * data, int len, int must_deselect)
        gtk_selection_add_target(inst->area, GDK_SELECTION_PRIMARY,
                                 GDK_SELECTION_TYPE_STRING, 1);
        gtk_selection_add_target(inst->area, GDK_SELECTION_PRIMARY,
-                                inst->compound_text_atom, 1);
+                                compound_text_atom, 1);
        if (inst->pasteout_data_utf8)
            gtk_selection_add_target(inst->area, GDK_SELECTION_PRIMARY,
-                                    inst->utf8_string_atom, 1);
+                                    utf8_string_atom, 1);
     }
 }
 
@@ -1317,7 +1318,7 @@ void selection_get(GtkWidget *widget, GtkSelectionData *seldata,
                   guint info, guint time_stamp, gpointer data)
 {
     struct gui_data *inst = (struct gui_data *)data;
-    if (seldata->target == inst->utf8_string_atom)
+    if (seldata->target == utf8_string_atom)
        gtk_selection_data_set(seldata, seldata->target, 8,
                               inst->pasteout_data_utf8,
                               inst->pasteout_data_utf8_len);
@@ -1360,7 +1361,7 @@ void request_paste(void *frontend)
         * fall back to an ordinary string.
         */
        gtk_selection_convert(inst->area, GDK_SELECTION_PRIMARY,
-                             inst->utf8_string_atom, GDK_CURRENT_TIME);
+                             utf8_string_atom, GDK_CURRENT_TIME);
     } else {
        /*
         * If we're in direct-to-font mode, we disable UTF-8
@@ -1378,7 +1379,7 @@ void selection_received(GtkWidget *widget, GtkSelectionData *seldata,
 {
     struct gui_data *inst = (struct gui_data *)data;
 
-    if (seldata->target == inst->utf8_string_atom && seldata->length <= 0) {
+    if (seldata->target == utf8_string_atom && seldata->length <= 0) {
        /*
         * Failed to get a UTF-8 selection string. Try an ordinary
         * string.
@@ -1393,7 +1394,7 @@ void selection_received(GtkWidget *widget, GtkSelectionData *seldata,
      */
     if (seldata->length <= 0 ||
        (seldata->type != GDK_SELECTION_TYPE_STRING &&
-        seldata->type != inst->utf8_string_atom))
+        seldata->type != utf8_string_atom))
        return;                        /* Nothing happens. */
 
     if (inst->pastein_data)
@@ -1402,7 +1403,7 @@ void selection_received(GtkWidget *widget, GtkSelectionData *seldata,
     inst->pastein_data = snewn(seldata->length, wchar_t);
     inst->pastein_data_len = seldata->length;
     inst->pastein_data_len =
-       mb_to_wc((seldata->type == inst->utf8_string_atom ?
+       mb_to_wc((seldata->type == utf8_string_atom ?
                  CS_UTF8 : inst->ucsdata.line_codepage),
                 0, seldata->data, seldata->length,
                 inst->pastein_data, inst->pastein_data_len);
@@ -2569,8 +2570,10 @@ int pt_main(int argc, char **argv)
     if (!*inst->cfg.host && !cfgbox(&inst->cfg))
        exit(0);                       /* config box hit Cancel */
 
-    inst->compound_text_atom = gdk_atom_intern("COMPOUND_TEXT", FALSE);
-    inst->utf8_string_atom = gdk_atom_intern("UTF8_STRING", FALSE);
+    if (!compound_text_atom)
+        compound_text_atom = gdk_atom_intern("COMPOUND_TEXT", FALSE);
+    if (!utf8_string_atom)
+        utf8_string_atom = gdk_atom_intern("UTF8_STRING", FALSE);
 
     setup_fonts_ucs(inst);