GtkTextBuffer multi-clipboard patch



One of the few places where new 2.0 API interfaces are not 
multi-head compatible is GtkTextBuffer; since the same GtkTextBuffer
could be used for multiple displays, the fact that GtkTextBuffer
always cut/pastes to "the" clipboard and updates "the" primary
selection is wrong.

The attached patch corrects this:

Wed Aug 29 20:40:58 2001  Owen Taylor  <otaylor redhat com>

	* gtk/gtktextbuffer.[ch] (gtk_text_buffer_add/remove_selection_clipboard): 
	Instead of always mirroring the selection to a single PRIMARY
	selection, allow it to be mirrored to any number of clipboards.

	* gtk/gtktextbuffer.[ch] (gtk_text_buffer_paste_primary): Remove, 
	just use gtk_text_buffer_paste_clipboard with the appropriate clipboard.

	* gtk/gtktextbuffer.[ch] (gtk_text_buffer_cut/copy/paste_clipboard): Add a
	GtkClipboard argument, and for paste_clipboard, the
	@override_location argument from @paste_primary.

	* gtk/gtktextview.c: Adapt to above change.

/**
 * gtk_text_buffer_add_selection_clipboard:
 * @buffer: a #GtkTextBuffer
 * @clipboard: a #GtkClipboard
 * 
 * Adds @clipboard to the list of clipboards in which the selection contents
 * of @buffer are available. In most cases, @clipboard will be the #GtkClipboard
 * of type %GDK_SELECTION_PRIMARY for a view of @buffer.
 **/
void
gtk_text_buffer_add_selection_clipboard (GtkTextBuffer *buffer,
					 GtkClipboard  *clipboard)
/**
 * gtk_text_buffer_remove_selection_clipboard:
 * @buffer: a #GtkTextBuffer
 * @clipboard: a #GtkClipboard added to @buffer by gtk_text_buffer_add_selection_clipboard().
 * 
 * Removes a #GtkClipboard added with gtk_text_buffer_add_selection_clipboard()
 **/
void 
gtk_text_buffer_remove_selection_clipboard (GtkTextBuffer *buffer,
					    GtkClipboard  *clipboard)


Regards,
                                        Owen

Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gtk+/ChangeLog,v
retrieving revision 1.2231
diff -u -r1.2231 ChangeLog
--- ChangeLog	2001/08/29 21:30:18	1.2231
+++ ChangeLog	2001/08/30 00:45:05
@@ -1,3 +1,18 @@
+Wed Aug 29 20:40:58 2001  Owen Taylor  <otaylor redhat com>
+
+	* gtk/gtktextbuffer.[ch] (gtk_text_buffer_add/remove_selection_clipboard): 
+	Instead of always mirroring the selection to a single PRIMARY
+	selection, allow it to be mirrored to any number of clipboards.
+
+	* gtk/gtktextbuffer.[ch] (gtk_text_buffer_paste_primary): Remove, 
+	just use gtk_text_buffer_paste_clipboard with the appropriate clipboard.
+
+	* gtk/gtktextbuffer.[ch] (gtk_text_buffer_cut/copy/paste_clipboard): Add a
+	GtkClipboard argument, and for paste_clipboard, the
+	@override_location argument from @paste_primary.
+
+	* gtk/gtktextview.c: Adapt to above change.
+	
 Wed Aug 29 17:28:04 2001  Jonathan Blandford  <jrb redhat com>
 
 	* gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_render):
Index: gtk/gtktextbuffer.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtktextbuffer.c,v
retrieving revision 1.53
diff -u -r1.53 gtktextbuffer.c
--- gtk/gtktextbuffer.c	2001/08/24 16:06:55	1.53
+++ gtk/gtktextbuffer.c	2001/08/30 00:45:06
@@ -81,7 +81,6 @@
 static void gtk_text_buffer_finalize   (GObject            *object);
 
 
-static void gtk_text_buffer_update_primary_selection   (GtkTextBuffer     *buffer);
 static void gtk_text_buffer_real_insert_text           (GtkTextBuffer     *buffer,
                                                         GtkTextIter       *iter,
                                                         const gchar       *text,
@@ -108,6 +107,10 @@
 static GtkTextBTree* get_btree (GtkTextBuffer *buffer);
 static void          free_log_attr_cache (GtkTextLogAttrCache *cache);
 
+static void remove_all_clipboard_contents_buffers (GtkTextBuffer *buffer);
+static void remove_all_selection_clipboards       (GtkTextBuffer *buffer);
+static void update_selection_clipboards           (GtkTextBuffer *buffer);
+
 static GtkObjectClass *parent_class = NULL;
 static guint signals[LAST_SIGNAL] = { 0 };
 
@@ -299,7 +302,7 @@
 void
 gtk_text_buffer_init (GtkTextBuffer *buffer)
 {
-  buffer->clipboard_contents = NULL;
+  buffer->clipboard_contents_buffers = NULL;
 }
 
 /**
@@ -334,12 +337,9 @@
 
   buffer = GTK_TEXT_BUFFER (object);
 
-  if (buffer->clipboard_contents)
-    {
-      g_object_unref (G_OBJECT (buffer->clipboard_contents));
-      buffer->clipboard_contents = NULL;
-    }
-  
+  remove_all_clipboard_contents_buffers (buffer);
+  remove_all_selection_clipboards (buffer);
+
   if (buffer->tag_table)
     {
       g_object_unref (G_OBJECT (buffer->tag_table));
@@ -1116,7 +1116,7 @@
   _gtk_text_btree_delete (start, end);
 
   /* may have deleted the selection... */
-  gtk_text_buffer_update_primary_selection (buffer);
+  update_selection_clipboards (buffer);
 
   g_signal_emit (G_OBJECT (buffer), signals[CHANGED], 0);
 }
@@ -1586,7 +1586,7 @@
   if (_gtk_text_btree_mark_is_insert (get_btree (buffer), mark) ||
       _gtk_text_btree_mark_is_selection_bound (get_btree (buffer), mark))
     {
-      gtk_text_buffer_update_primary_selection (buffer);
+      update_selection_clipboards (buffer);
     }
 
   _gtk_text_btree_get_iter_at_mark (get_btree (buffer),
@@ -2588,6 +2588,87 @@
     }
 }
 
+typedef struct
+{
+  GtkClipboard *clipboard;
+  GtkTextBuffer *buffer;
+} ContentsBuffer;
+
+static void
+remove_all_clipboard_contents_buffers (GtkTextBuffer *buffer)
+{
+  GSList *tmp_list = buffer->clipboard_contents_buffers;
+  while (tmp_list)
+    {
+      ContentsBuffer *contents_buffer = tmp_list->data;
+
+      g_object_unref (contents_buffer->buffer);
+      g_free (contents_buffer);
+	  
+      tmp_list = tmp_list->next;
+    }
+
+  g_slist_free (buffer->clipboard_contents_buffers);
+  buffer->clipboard_contents_buffers = NULL;
+}
+
+static void
+remove_clipboard_contents_buffer (GtkTextBuffer *buffer,
+				  GtkClipboard  *clipboard)
+{
+  GSList *tmp_list = buffer->clipboard_contents_buffers;
+  while (tmp_list)
+    {
+      ContentsBuffer *contents_buffer = tmp_list->data;
+      
+      if (contents_buffer->clipboard == clipboard)
+	{
+	  buffer->clipboard_contents_buffers = g_slist_remove (buffer->clipboard_contents_buffers, contents_buffer);
+	  
+	  g_object_unref (contents_buffer->buffer);
+	  g_free (contents_buffer);
+	  
+	  return;
+	}
+
+      tmp_list = tmp_list->next;
+    }
+}
+
+static GtkTextBuffer *
+get_clipboard_contents_buffer (GtkTextBuffer *buffer,
+			       GtkClipboard  *clipboard,
+			       gboolean       create)
+{
+  ContentsBuffer *contents_buffer;
+  GSList *tmp_list;
+
+  tmp_list = buffer->clipboard_contents_buffers;
+  while (tmp_list)
+    {
+      contents_buffer = tmp_list->data;
+      if (contents_buffer->clipboard == clipboard)
+	return contents_buffer->buffer;
+    }
+  
+  if (create)
+    {
+      contents_buffer = g_new (ContentsBuffer, 1);
+      contents_buffer->clipboard = clipboard;
+      contents_buffer->buffer = gtk_text_buffer_new (gtk_text_buffer_get_tag_table (buffer));
+
+      g_object_set_data (G_OBJECT (contents_buffer->buffer), "gtk-text-buffer-clipboard",
+			 GUINT_TO_POINTER (1));
+
+      buffer->clipboard_contents_buffers = g_slist_prepend (buffer->clipboard_contents_buffers, contents_buffer);
+
+      
+      return contents_buffer->buffer;
+    }
+  else
+    return NULL;
+}
+
 /* Provide cut/copied data */
 static void
 clipboard_get_contents_cb (GtkClipboard     *clipboard,
@@ -2596,8 +2677,10 @@
                            gpointer          data)
 {
   GtkTextBuffer *buffer = GTK_TEXT_BUFFER (data);
-  GtkTextBuffer *contents = buffer->clipboard_contents;
+  GtkTextBuffer *contents = get_clipboard_contents_buffer (buffer, clipboard, FALSE);
 
+  g_assert (contents); /* This should never be called unless we own the clipboard */
+
   if (selection_data->target ==
       gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE))
     {
@@ -2612,25 +2695,16 @@
     }
   else
     {
-      /* Just provide text from the clipboard buffer */
-      if (buffer->clipboard_contents)
-        {
-          gchar *str;
-          GtkTextIter start, end;
-          
-          gtk_text_buffer_get_bounds (contents, &start, &end);
-          /* strip off the trailing newline, it isn't part of the text that was cut */
-          gtk_text_iter_backward_char (&end);
-          
-          str = gtk_text_iter_get_visible_text (&start, &end);
-          gtk_selection_data_set_text (selection_data, str);
-          g_free (str);
-        }
-      else
-        {
-          gtk_selection_data_set_text (selection_data, "");
-          return;
-        }
+      gchar *str;
+      GtkTextIter start, end;
+      
+      gtk_text_buffer_get_bounds (contents, &start, &end);
+      /* strip off the trailing newline, it isn't part of the text that was cut */
+      gtk_text_iter_backward_char (&end);
+      
+      str = gtk_text_iter_get_visible_text (&start, &end);
+      gtk_selection_data_set_text (selection_data, str);
+      g_free (str);
     }
 }
 
@@ -2640,11 +2714,7 @@
 {
   GtkTextBuffer *buffer = GTK_TEXT_BUFFER (data);
 
-  if (buffer->clipboard_contents)
-    {
-      g_object_unref (G_OBJECT (buffer->clipboard_contents));
-      buffer->clipboard_contents = NULL;
-    }  
+  remove_clipboard_contents_buffer (buffer, clipboard);
 }
 
 static void
@@ -2849,39 +2919,21 @@
     {
       GtkTextIter start, end;
 
-      gtk_text_buffer_get_bounds (src_buffer, &start, &end);
-      /* There's an extra newline on clipboard_contents */
-      gtk_text_iter_backward_char (&end);
+      if (g_object_get_data (G_OBJECT (src_buffer), "gtk-text-buffer-clipboard"))
+	{
+	  gtk_text_buffer_get_bounds (src_buffer, &start, &end);
+	  /* There's an extra newline on clipboard_contents */
+	  gtk_text_iter_backward_char (&end);
       
-      paste_from_buffer (request_data, src_buffer,
-                         &start, &end);
-    }
-  else
-    {
-      /* Request the text selection instead */
-      gtk_clipboard_request_text (clipboard,
-                                  clipboard_text_received,
-                                  data);
-    }
-}
-
-static void
-clipboard_selection_buffer_received (GtkClipboard     *clipboard,
-                                     GtkSelectionData *selection_data,
-                                     gpointer          data)
-{
-  ClipboardRequest *request_data = data;
-  GtkTextBuffer *src_buffer;
-  
-  src_buffer = selection_data_get_buffer (selection_data, request_data); 
-
-  if (src_buffer)
-    {
-      GtkTextIter start, end;
-
-      if (gtk_text_buffer_get_selection_bounds (src_buffer, &start, &end))
-        paste_from_buffer (request_data, src_buffer,
-                           &start, &end);
+	  paste_from_buffer (request_data, src_buffer,
+			     &start, &end);
+	}
+      else
+	{
+	  if (gtk_text_buffer_get_selection_bounds (src_buffer, &start, &end))
+	    paste_from_buffer (request_data, src_buffer,
+			       &start, &end);
+	}
     }
   else
     {
@@ -2900,49 +2952,179 @@
   { "GTK_TEXT_BUFFER_CONTENTS", 0, TARGET_TEXT_BUFFER_CONTENTS }
 };
 
+typedef struct
+{
+  GtkClipboard *clipboard;
+  guint ref_count;
+} SelectionClipboard;
+
 static void
-gtk_text_buffer_update_primary_selection (GtkTextBuffer *buffer)
+update_selection_clipboards (GtkTextBuffer *buffer)
 {
-  GtkTextIter start;
-  GtkTextIter end;
+  GSList *tmp_list = buffer->selection_clipboards;
+  while (tmp_list)
+    {
+      GtkTextIter start;
+      GtkTextIter end;
+      
+      SelectionClipboard *selection_clipboard = tmp_list->data;
+      GtkClipboard *clipboard = selection_clipboard->clipboard;
 
-  GtkClipboard *clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
+      /* Determine whether we have a selection and adjust X selection
+       * accordingly.
+       */
+      if (!gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
+	{
+	  if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (buffer))
+	    gtk_clipboard_clear (clipboard);
+	}
+      else
+	{
+	  /* Even if we already have the selection, we need to update our
+	   * timestamp.
+	   */
+	  if (!gtk_clipboard_set_with_owner (clipboard, targets, G_N_ELEMENTS (targets),
+					     clipboard_get_selection_cb,
+					     clipboard_clear_selection_cb,
+					     G_OBJECT (buffer)))
+	    clipboard_clear_selection_cb (clipboard, buffer);
+	}
 
-  /* Determine whether we have a selection and adjust X selection
-   * accordingly.
-   */
+      tmp_list = tmp_list->next;
+    }
+}
 
-  if (!gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
+static SelectionClipboard *
+find_selection_clipboard (GtkTextBuffer *buffer,
+			  GtkClipboard  *clipboard)
+{
+  GSList *tmp_list = buffer->selection_clipboards;
+  while (tmp_list)
+    {
+      SelectionClipboard *selection_clipboard = tmp_list->data;
+      if (selection_clipboard->clipboard == clipboard)
+	return selection_clipboard;
+      
+      tmp_list = tmp_list->next;
+    }
+
+  return NULL;
+}
+
+/**
+ * gtk_text_buffer_add_selection_clipboard:
+ * @buffer: a #GtkTextBuffer
+ * @clipboard: a #GtkClipboard
+ * 
+ * Adds @clipboard to the list of clipboards in which the selection contents
+ * of @buffer are available. In most cases, @clipboard will be the #GtkClipboard
+ * of type %GDK_SELECTION_PRIMARY for a view of @buffer.
+ **/
+void
+gtk_text_buffer_add_selection_clipboard (GtkTextBuffer *buffer,
+					 GtkClipboard  *clipboard)
+{
+  SelectionClipboard *selection_clipboard;
+
+  g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
+  g_return_if_fail (clipboard != NULL);
+
+  selection_clipboard = find_selection_clipboard (buffer, clipboard);
+  if (selection_clipboard)
     {
-      if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (buffer))
-        gtk_clipboard_clear (clipboard);
+      selection_clipboard->ref_count++;
     }
   else
     {
-      /* Even if we already have the selection, we need to update our
-       * timestamp.
-       */
-      if (!gtk_clipboard_set_with_owner (clipboard, targets, G_N_ELEMENTS (targets),
-                                         clipboard_get_selection_cb,
-                                         clipboard_clear_selection_cb,
-                                         G_OBJECT (buffer)))
-        clipboard_clear_selection_cb (clipboard, buffer);
+      selection_clipboard = g_new (SelectionClipboard, 1);
+
+      selection_clipboard->clipboard = clipboard;
+      selection_clipboard->ref_count = 1;
+
+      buffer->selection_clipboards = g_slist_prepend (buffer->selection_clipboards, selection_clipboard);
     }
 }
 
+/**
+ * gtk_text_buffer_remove_selection_clipboard:
+ * @buffer: a #GtkTextBuffer
+ * @clipboard: a #GtkClipboard added to @buffer by gtk_text_buffer_add_selection_clipboard().
+ * 
+ * Removes a #GtkClipboard added with gtk_text_buffer_add_selection_clipboard()
+ **/
+void 
+gtk_text_buffer_remove_selection_clipboard (GtkTextBuffer *buffer,
+					    GtkClipboard  *clipboard)
+{
+  SelectionClipboard *selection_clipboard;
+
+  g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
+  g_return_if_fail (clipboard != NULL);
+
+  selection_clipboard = find_selection_clipboard (buffer, clipboard);
+  g_return_if_fail (selection_clipboard != NULL);
+
+  selection_clipboard->ref_count--;
+  if (selection_clipboard->ref_count == 0)
+    {
+      if (gtk_clipboard_get_owner (selection_clipboard->clipboard) == G_OBJECT (buffer))
+	gtk_clipboard_clear (selection_clipboard->clipboard);
+      
+      g_free (selection_clipboard);
+    }
+}
+
 static void
-paste (GtkTextBuffer *buffer,
-       gboolean       is_clipboard,
-       gboolean       interactive,
-       gboolean       default_editable)
+remove_all_selection_clipboards (GtkTextBuffer *buffer)
 {
+  GSList *tmp_list = buffer->selection_clipboards;
+  while (tmp_list)
+    {
+      SelectionClipboard *selection_clipboard = tmp_list->data;
+      
+      if (gtk_clipboard_get_owner (selection_clipboard->clipboard) == G_OBJECT (buffer))
+	gtk_clipboard_clear (selection_clipboard->clipboard);
+      
+      g_free (selection_clipboard);
+
+      tmp_list = tmp_list->next;
+    }
+
+  g_slist_free (buffer->selection_clipboards);
+  buffer->selection_clipboards = NULL;
+}
+
+/**
+ * gtk_text_buffer_paste_clipboard:
+ * @buffer: a #GtkTextBuffer
+ * @clipboard: the #GtkClipboard to paste from
+ * @override_location: location to insert pasted text, or %NULL for at the cursor
+ * @default_editable: whether the buffer is editable by default
+ *
+ * Pastes the contents of a clipboard at the insertion point, or at @override_location.
+ * (Note: pasting is asynchronous, that is, we'll ask for the paste data and
+ * return, and at some point later after the main loop runs, the paste
+ * data will be inserted.)
+ * 
+ **/
+void
+gtk_text_buffer_paste_clipboard (GtkTextBuffer *buffer,
+				 GtkClipboard  *clipboard,
+				 GtkTextIter   *override_location,
+                                 gboolean       default_editable)
+{
   ClipboardRequest *data = g_new (ClipboardRequest, 1);
   GtkTextIter paste_point;
   GtkTextIter start, end;
-  
+
+  if (override_location != NULL)
+    gtk_text_buffer_create_mark (buffer,
+                                 "gtk_paste_point_override",
+                                 override_location, FALSE);
+
   data->buffer = buffer;
   g_object_ref (G_OBJECT (buffer));
-  data->interactive = interactive;
+  data->interactive = TRUE;
   data->default_editable = default_editable;
 
   /* When pasting with the cursor inside the selection area, you
@@ -2958,62 +3140,13 @@
       (gtk_text_iter_in_range (&paste_point, &start, &end) ||
        gtk_text_iter_equal (&paste_point, &end)))
     data->replace_selection = TRUE;
-
-  if (is_clipboard)
-    gtk_clipboard_request_contents (gtk_clipboard_get (GDK_NONE),
-                                    
-                                    gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE),
-                                    clipboard_clipboard_buffer_received, data);
-  else
-    gtk_clipboard_request_contents (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
-                                    
-                                    gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE),
-                                    clipboard_selection_buffer_received, data);    
-}
-
-/**
- * gtk_text_buffer_paste_primary:
- * @buffer: a #GtkTextBuffer 
- * @override_location: location to insert pasted text, or %NULL for at the cursor
- * @default_editable: whether the buffer is editable by default 
- * 
- * Pastes the primary selection at the insertion point, or at @override_location.
- * (Note: pasting is asynchronous, that is, we'll ask for the paste data
- * and return, and at some point later after the main loop runs, the paste
- * data will be inserted.)
- **/
-void
-gtk_text_buffer_paste_primary (GtkTextBuffer       *buffer,
-                               const GtkTextIter   *override_location,
-                               gboolean             default_editable)
-{
-  if (override_location != NULL)
-    gtk_text_buffer_create_mark (buffer,
-                                 "gtk_paste_point_override",
-                                 override_location, FALSE);
 
-  paste (buffer, FALSE, TRUE, default_editable);
+  gtk_clipboard_request_contents (clipboard,
+				  gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE),
+				  clipboard_clipboard_buffer_received, data);
 }
 
 /**
- * gtk_text_buffer_paste_clipboard:
- * @buffer: a #GtkTextBuffer 
- * @default_editable: whether the buffer is editable by default
- *
- * Pastes the clipboard contents at the insertion point.  (Note:
- * pasting is asynchronous, that is, we'll ask for the paste data and
- * return, and at some point later after the main loop runs, the paste
- * data will be inserted.)
- * 
- **/
-void
-gtk_text_buffer_paste_clipboard (GtkTextBuffer *buffer,
-                                 gboolean       default_editable)
-{
-  paste (buffer, TRUE, TRUE, default_editable);
-}
-
-/**
  * gtk_text_buffer_delete_selection:
  * @buffer: a #GtkTextBuffer 
  * @interactive: whether the deletion is caused by user interaction
@@ -3055,9 +3188,10 @@
 
 static void
 cut_or_copy (GtkTextBuffer *buffer,
-             gboolean delete_region_after,
-             gboolean interactive,
-             gboolean default_editable)
+	     GtkClipboard  *clipboard,
+             gboolean       delete_region_after,
+             gboolean       interactive,
+             gboolean       default_editable)
 {
   /* We prefer to cut the selected region between selection_bound and
    * insertion point. If that region is empty, then we cut the region
@@ -3068,12 +3202,8 @@
    */
   GtkTextIter start;
   GtkTextIter end;
-  
-  if (buffer->clipboard_contents)
-    {
-      g_object_unref (G_OBJECT (buffer->clipboard_contents));
-      buffer->clipboard_contents = NULL;
-    }
+
+  remove_clipboard_contents_buffer (buffer, clipboard);
   
   if (!gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
     {
@@ -3091,19 +3221,14 @@
 
   if (!gtk_text_iter_equal (&start, &end))
     {
-      GtkClipboard *clipboard = gtk_clipboard_get (GDK_NONE);
       GtkTextIter ins;
+      GtkTextBuffer *contents;
       
-      buffer->clipboard_contents =
-        gtk_text_buffer_new (gtk_text_buffer_get_tag_table (buffer));
+      contents = get_clipboard_contents_buffer (buffer, clipboard, TRUE);
 
-      gtk_text_buffer_get_iter_at_offset (buffer->clipboard_contents,
-                                          &ins, 0);
+      gtk_text_buffer_get_iter_at_offset (contents, &ins, 0);
       
-      gtk_text_buffer_insert_range (buffer->clipboard_contents,
-                                    &ins,
-                                    &start,
-                                    &end);
+      gtk_text_buffer_insert_range (contents, &ins, &start, &end);
                                     
       if (!gtk_clipboard_set_with_owner (clipboard, targets, G_N_ELEMENTS (targets),
                                          clipboard_get_contents_cb,
@@ -3124,34 +3249,38 @@
 
 /**
  * gtk_text_buffer_cut_clipboard:
- * @buffer: a #GtkTextBuffer 
+ * @buffer: a #GtkTextBuffer
+ * @clipboard: the #GtkClipboard object to cut to.
  * @default_editable: default editability of the buffer
  *
- * Copies the currently-selected text to the clipboard, then deletes
+ * Copies the currently-selected text to a clipboard, then deletes
  * said text if it's editable.
  * 
  **/
 void
 gtk_text_buffer_cut_clipboard (GtkTextBuffer *buffer,
+			       GtkClipboard  *clipboard,
                                gboolean       default_editable)
 {
   gtk_text_buffer_begin_user_action (buffer);
-  cut_or_copy (buffer, TRUE, TRUE, default_editable);
+  cut_or_copy (buffer, clipboard, TRUE, TRUE, default_editable);
   gtk_text_buffer_end_user_action (buffer);
 }
 
 /**
  * gtk_text_buffer_copy_clipboard:
  * @buffer: a #GtkTextBuffer 
+ * @clipboard: the #GtkClipboard object to copy to.
  *
- * Copies the currently-selected text to the clipboard.
+ * Copies the currently-selected text to a clipboard.
  * 
  **/
 void
-gtk_text_buffer_copy_clipboard (GtkTextBuffer *buffer)
+gtk_text_buffer_copy_clipboard (GtkTextBuffer *buffer,
+				GtkClipboard  *clipboard)
 {
   gtk_text_buffer_begin_user_action (buffer);
-  cut_or_copy (buffer, FALSE, TRUE, TRUE);
+  cut_or_copy (buffer, clipboard, FALSE, TRUE, TRUE);
   gtk_text_buffer_end_user_action (buffer);
 }
 
Index: gtk/gtktextbuffer.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtktextbuffer.h,v
retrieving revision 1.29
diff -u -r1.29 gtktextbuffer.h
--- gtk/gtktextbuffer.h	2001/06/08 19:03:22	1.29
+++ gtk/gtktextbuffer.h	2001/08/30 00:45:06
@@ -28,6 +28,7 @@
 #define GTK_TEXT_BUFFER_H
 
 #include <gtk/gtkwidget.h>
+#include <gtk/gtkclipboard.h>
 #include <gtk/gtktexttagtable.h>
 #include <gtk/gtktextiter.h>
 #include <gtk/gtktextmark.h>
@@ -62,7 +63,8 @@
   GtkTextTagTable *tag_table;
   GtkTextBTree *btree;
 
-  GtkTextBuffer *clipboard_contents;
+  GSList *clipboard_contents_buffers;
+  GSList *selection_clipboards;
 
   GtkTextLogAttrCache *log_attr_cache;
 
@@ -324,13 +326,19 @@
 void            gtk_text_buffer_set_modified            (GtkTextBuffer *buffer,
                                                          gboolean       setting);
 
-void            gtk_text_buffer_paste_primary           (GtkTextBuffer       *buffer,
-                                                         const GtkTextIter   *override_location,
-                                                         gboolean             default_editable);
+void gtk_text_buffer_add_selection_clipboard    (GtkTextBuffer     *buffer,
+						 GtkClipboard      *clipboard);
+void gtk_text_buffer_remove_selection_clipboard (GtkTextBuffer     *buffer,
+						 GtkClipboard      *clipboard);
+
 void            gtk_text_buffer_cut_clipboard           (GtkTextBuffer *buffer,
+							 GtkClipboard  *clipboard,
                                                          gboolean       default_editable);
-void            gtk_text_buffer_copy_clipboard          (GtkTextBuffer *buffer);
+void            gtk_text_buffer_copy_clipboard          (GtkTextBuffer *buffer,
+							 GtkClipboard  *clipboard);
 void            gtk_text_buffer_paste_clipboard         (GtkTextBuffer *buffer,
+							 GtkClipboard  *clipboard,
+							 GtkTextIter   *override_location,
                                                          gboolean       default_editable);
 
 gboolean        gtk_text_buffer_get_selection_bounds    (GtkTextBuffer *buffer,
Index: gtk/gtktextview.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtktextview.c,v
retrieving revision 1.104
diff -u -r1.104 gtktextview.c
--- gtk/gtktextview.c	2001/07/19 14:57:13	1.104
+++ gtk/gtktextview.c	2001/08/30 00:45:07
@@ -1048,6 +1048,10 @@
                                             gtk_text_view_mark_set_handler, text_view);
       g_object_unref (G_OBJECT (text_view->buffer));
       text_view->dnd_mark = NULL;
+
+      if (GTK_WIDGET_REALIZED (text_view))
+	gtk_text_buffer_remove_selection_clipboard (text_view->buffer,
+						    gtk_clipboard_get (GDK_SELECTION_PRIMARY));
     }
 
   text_view->buffer = buffer;
@@ -1075,6 +1079,10 @@
 
       g_signal_connect (G_OBJECT (text_view->buffer), "mark_set",
 			G_CALLBACK (gtk_text_view_mark_set_handler), text_view);
+
+      if (GTK_WIDGET_REALIZED (text_view))
+	gtk_text_buffer_remove_selection_clipboard (text_view->buffer,
+						    gtk_clipboard_get (GDK_SELECTION_PRIMARY));
     }
 
   if (GTK_WIDGET_VISIBLE (text_view))
@@ -2929,6 +2937,10 @@
                          widget->window);
 
   gtk_text_view_ensure_layout (text_view);
+
+  if (text_view->buffer)
+    gtk_text_buffer_add_selection_clipboard (text_view->buffer,
+					     gtk_clipboard_get (GDK_SELECTION_PRIMARY));
 }
 
 static void
@@ -2938,6 +2950,10 @@
   
   text_view = GTK_TEXT_VIEW (widget);
 
+  if (text_view->buffer)
+    gtk_text_buffer_remove_selection_clipboard (text_view->buffer,
+						gtk_clipboard_get (GDK_SELECTION_PRIMARY));
+
   if (text_view->first_validate_idle)
     {
       g_source_remove (text_view->first_validate_idle);
@@ -3278,9 +3294,10 @@
                                              event->x + text_view->xoffset,
                                              event->y + text_view->yoffset);
 
-          gtk_text_buffer_paste_primary (get_buffer (text_view),
-                                         &iter,
-                                         text_view->editable);
+          gtk_text_buffer_paste_clipboard (get_buffer (text_view),
+					   gtk_clipboard_get (GDK_SELECTION_PRIMARY),
+					   &iter,
+					   text_view->editable);
           return TRUE;
         }
       else if (event->button == 3)
@@ -4154,7 +4171,9 @@
 static void
 gtk_text_view_cut_clipboard (GtkTextView *text_view)
 {
-  gtk_text_buffer_cut_clipboard (get_buffer (text_view), text_view->editable);
+  gtk_text_buffer_cut_clipboard (get_buffer (text_view),
+				 gtk_clipboard_get (GDK_NONE),
+				 text_view->editable);
   gtk_text_view_scroll_mark_onscreen (text_view,
                                       gtk_text_buffer_get_mark (get_buffer (text_view),
                                                                 "insert"));
@@ -4163,7 +4182,8 @@
 static void
 gtk_text_view_copy_clipboard (GtkTextView *text_view)
 {
-  gtk_text_buffer_copy_clipboard (get_buffer (text_view));
+  gtk_text_buffer_copy_clipboard (get_buffer (text_view),
+				  gtk_clipboard_get (GDK_NONE));
   gtk_text_view_scroll_mark_onscreen (text_view,
                                       gtk_text_buffer_get_mark (get_buffer (text_view),
                                                                 "insert"));
@@ -4172,7 +4192,10 @@
 static void
 gtk_text_view_paste_clipboard (GtkTextView *text_view)
 {
-  gtk_text_buffer_paste_clipboard (get_buffer (text_view), text_view->editable);
+  gtk_text_buffer_paste_clipboard (get_buffer (text_view),
+				   gtk_clipboard_get (GDK_NONE),
+				   NULL,
+				   text_view->editable);
   gtk_text_view_scroll_mark_onscreen (text_view,
                                       gtk_text_buffer_get_mark (get_buffer (text_view),
                                                                 "insert"));


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]