]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkselection.c
Switch style of stamp file usage.
[~andy/gtk] / gtk / gtkselection.c
index e09da3d65e604f4958837156e5d359c2878c77c5..1974fb1c760de4663930a0470c3a1729da070a64 100644 (file)
 #include <string.h>
 #include "gdk.h"
 
-#if defined (GDK_WINDOWING_X11)
-#include "x11/gdkx.h"          /* For gdk_window_lookup() */
-#elif defined (GDK_WINDOWING_WIN32)
-#include "win32/gdkwin32.h"    /* For gdk_window_lookup() */
-#elif defined (GDK_WINDOWING_NANOX)
-#include "nanox/gdkprivate-nanox.h"    /* For gdk_window_lookup() */
-#endif
-
 #include "gtkmain.h"
 #include "gtkselection.h"
 #include "gtksignal.h"
@@ -110,7 +102,6 @@ struct _GtkIncrConversion
 
 struct _GtkIncrInfo
 {
-  GtkWidget *widget;           /* Selection owner */
   GdkWindow *requestor;                /* Requestor window - we create a GdkWindow
                                   so we can receive events */
   GdkAtom    selection;                /* Selection we're sending */
@@ -555,19 +546,6 @@ gtk_selection_remove_all (GtkWidget *widget)
   
   /* Remove pending requests/incrs for this widget */
   
-  tmp_list = current_incrs;
-  while (tmp_list)
-    {
-      next = tmp_list->next;
-      if (((GtkIncrInfo *)tmp_list->data)->widget == widget)
-       {
-         current_incrs = g_list_remove_link (current_incrs, tmp_list);
-         /* structure will be freed in timeout */
-         g_list_free (tmp_list);
-       }
-      tmp_list = next;
-    }
-  
   tmp_list = current_retrievals;
   while (tmp_list)
     {
@@ -626,7 +604,7 @@ gtk_selection_remove_all (GtkWidget *widget)
  *     this widget). 
  *************************************************************/
 
-gint
+gboolean
 gtk_selection_convert (GtkWidget *widget, 
                       GdkAtom    selection, 
                       GdkAtom    target,
@@ -777,60 +755,73 @@ init_atoms (void)
  * gtk_selection_data_set_text:
  * @selection_data: a #GtkSelectionData
  * @str: a UTF-8 string
+ * @len: the length of @str, or -1 if @str is nul-terminated.
  * 
  * Sets the contents of the selection from a UTF-8 encoded string.
  * The string is converted to the form determined by
  * @selection_data->target.
  * 
- * Return value: %TRUE if the selection was succesfully set,
+ * Return value: %TRUE if the selection was successfully set,
  *   otherwise %FALSE.
  **/
 gboolean
 gtk_selection_data_set_text (GtkSelectionData     *selection_data,
-                            const guchar         *str)
+                            const gchar          *str,
+                            gint                  len)
 {
+  gboolean result = FALSE;
+  
+  if (len < 0)
+    len = strlen (str);
+  
   init_atoms ();
 
   if (selection_data->target == utf8_atom)
     {
       gtk_selection_data_set (selection_data,
                              utf8_atom,
-                             8, (guchar *)str, strlen (str));
-      return TRUE;
+                             8, (guchar *)str, len);
+      result = TRUE;
     }
   else if (selection_data->target == GDK_TARGET_STRING)
     {
-      gchar *latin1 = gdk_utf8_to_string_target (str);
+      gchar *tmp = g_strndup (str, len);
+      gchar *latin1 = gdk_utf8_to_string_target (tmp);
+      g_free (tmp);
 
       if (latin1)
        {
          gtk_selection_data_set (selection_data,
                                  GDK_SELECTION_TYPE_STRING,
                                  8, latin1, strlen (latin1));
-         g_free(latin1);
+         g_free (latin1);
          
-         return TRUE;
+         result = TRUE;
        }
 
     }
   else if (selection_data->target == ctext_atom ||
           selection_data->target == text_atom)
     {
+      gchar *tmp;
       guchar *text;
       GdkAtom encoding;
       gint format;
       gint new_length;
-      
-      if (gdk_utf8_to_compound_text (str, &encoding, &format, &text, &new_length))
+
+      tmp = g_strndup (str, len);
+      if (gdk_utf8_to_compound_text (tmp, &encoding, &format, &text, &new_length))
        {
          gtk_selection_data_set (selection_data, encoding, format, text, new_length);
          gdk_free_compound_text (text);
-      
-         return TRUE;
+
+         result = TRUE;
        }
+
+      g_free (tmp);
     }
   
-  return FALSE;
+  return result;
 }
 
 /**
@@ -874,6 +865,84 @@ gtk_selection_data_get_text (GtkSelectionData *selection_data)
   return result;
 }
 
+/**
+ * gtk_selection_data_get_targets:
+ * @selection_data: a #GtkSelectionData object
+ * @targets: location to store an array of targets. The result
+ *           stored here must be freed with g_free().
+ * @n_atoms: location to store number of items in @targets.
+ * 
+ * Gets the contents of @selection_data as an array of targets.
+ * This can be used to interpret the results of getting
+ * the standard TARGETS target that is always supplied for
+ * any selection.
+ * 
+ * Return value: %TRUE if @selection_data contains a valid
+ *    array of targets, otherwise %FALSE.
+ **/
+gboolean
+gtk_selection_data_get_targets (GtkSelectionData  *selection_data,
+                               GdkAtom          **targets,
+                               gint              *n_atoms)
+{
+  if (selection_data->length >= 0 &&
+      selection_data->format == 32 &&
+      selection_data->type == GDK_SELECTION_TYPE_ATOM)
+    {
+      if (targets)
+       *targets = g_memdup (selection_data->data, selection_data->length);
+      if (n_atoms)
+       *n_atoms = selection_data->length / sizeof (GdkAtom);
+
+      return TRUE;
+    }
+  else
+    {
+      if (targets)
+       *targets = NULL;
+      if (n_atoms)
+       *n_atoms = -1;
+
+      return FALSE;
+    }
+}
+
+/**
+ * gtk_selection_data_targets_include_text:
+ * @selection_data: a #GtkSelectionData object
+ * 
+ * Given a #GtkSelectionData object holding a list of targets,
+ * determines if any of the targets in @targets can be used to
+ * provide text.
+ * 
+ * Return value: %TRUE if @selection_data holds a list of targets,
+ *   and a suitable target for text is included, otherwise %FALSE.
+ **/
+gboolean
+gtk_selection_data_targets_include_text (GtkSelectionData *selection_data)
+{
+  GdkAtom *targets;
+  gint n_targets;
+  gint i;
+  gboolean result = FALSE;
+
+  if (gtk_selection_data_get_targets (selection_data, &targets, &n_targets))
+    {
+      for (i=0; i < n_targets; i++)
+       {
+         if (targets[i] == gdk_atom_intern ("STRING", FALSE) ||
+             targets[i] == gdk_atom_intern ("TEXT", FALSE) ||
+             targets[i] == gdk_atom_intern ("COMPOUND_TEXT", FALSE) ||
+             targets[i] == gdk_atom_intern ("UTF8_STRING", FALSE))
+           result = TRUE;
+       }
+
+      g_free (targets);
+    }
+
+  return result;
+}
+         
 /*************************************************************
  * gtk_selection_init:
  *     Initialize local variables
@@ -900,7 +969,7 @@ gtk_selection_init (void)
  *   results:
  *************************************************************/
 
-gint
+gboolean
 gtk_selection_clear (GtkWidget         *widget,
                     GdkEventSelection *event)
 {
@@ -943,7 +1012,7 @@ gtk_selection_clear (GtkWidget         *widget,
  *   results:
  *************************************************************/
 
-gint
+gboolean
 gtk_selection_request (GtkWidget *widget,
                       GdkEventSelection *event)
 {
@@ -972,21 +1041,17 @@ gtk_selection_request (GtkWidget *widget,
   if (tmp_list == NULL)
     return FALSE;
   
-  info = g_new(GtkIncrInfo, 1);
+  info = g_new (GtkIncrInfo, 1);
+
+  g_object_ref (widget);
   
-  info->widget = widget;
   info->selection = event->selection;
   info->num_incrs = 0;
   
   /* Create GdkWindow structure for the requestor */
-  
-#if defined(GDK_WINDOWING_WIN32) || defined(GDK_WINDOWING_X11)
   info->requestor = gdk_window_lookup (event->requestor);
   if (!info->requestor)
     info->requestor = gdk_window_foreign_new (event->requestor);
-#else
-  info->requestor = NULL;
-#endif
   
   /* Determine conversions we need to perform */
   
@@ -998,7 +1063,7 @@ gtk_selection_request (GtkWidget *widget,
       
       mult_atoms = NULL;
       
-      gdk_error_trap_push();
+      gdk_error_trap_push ();
       if (!gdk_property_get (info->requestor, event->property, 0, /* AnyPropertyType */
                             0, GTK_SELECTION_MAX_SIZE, FALSE,
                             &type, &format, &length, &mult_atoms))
@@ -1009,7 +1074,7 @@ gtk_selection_request (GtkWidget *widget,
          g_free (info);
          return TRUE;
        }
-      gdk_error_trap_pop();
+      gdk_error_trap_pop ();
       
       info->num_conversions = length / (2*sizeof (GdkAtom));
       info->conversions = g_new (GtkIncrConversion, info->num_conversions);
@@ -1044,7 +1109,7 @@ gtk_selection_request (GtkWidget *widget,
 #ifdef DEBUG_SELECTION
       g_message ("Selection %ld, target %ld (%s) requested by 0x%x (property = %ld)",
                 event->selection, info->conversions[i].target,
-                gdk_atom_name(info->conversions[i].target),
+                gdk_atom_name (info->conversions[i].target),
                 event->requestor, event->property);
 #endif
       
@@ -1115,7 +1180,7 @@ gtk_selection_request (GtkWidget *widget,
   if (event->target == gtk_selection_atoms[MULTIPLE])
     {
       gdk_property_change (info->requestor, event->property,
-                          GDK_SELECTION_TYPE_ATOM, 32, 
+                          gdk_atom_intern ("ATOM_PAIR", FALSE), 32, 
                           GDK_PROP_MODE_REPLACE,
                           mult_atoms, 2*info->num_conversions);
       g_free (mult_atoms);
@@ -1133,12 +1198,14 @@ gtk_selection_request (GtkWidget *widget,
       gdk_selection_send_notify (event->requestor, event->selection, 
                                 event->target, event->property, event->time);
     }
-  
+
   if (info->num_incrs == 0)
     {
       g_free (info->conversions);
       g_free (info);
     }
+
+  g_object_unref (widget);
   
   return TRUE;
 }
@@ -1158,7 +1225,7 @@ gtk_selection_request (GtkWidget *widget,
  *   results:
  *************************************************************/
 
-gint
+gboolean
 gtk_selection_incr_event (GdkWindow       *window,
                          GdkEventProperty *event)
 {
@@ -1332,7 +1399,7 @@ gtk_selection_incr_timeout (GtkIncrInfo *info)
  *     was event handled?
  *************************************************************/
 
-gint
+gboolean
 gtk_selection_notify (GtkWidget               *widget,
                      GdkEventSelection *event)
 {
@@ -1363,7 +1430,9 @@ gtk_selection_notify (GtkWidget          *widget,
   if (event->property != GDK_NONE)
     length = gdk_selection_property_get (widget->window, &buffer, 
                                         &type, &format);
-
+  else
+    length = 0; /* silence gcc */
+  
   if (event->property == GDK_NONE || buffer == NULL)
     {
       current_retrievals = g_list_remove_link (current_retrievals, tmp_list);
@@ -1419,7 +1488,7 @@ gtk_selection_notify (GtkWidget          *widget,
  *     was event handled?
  *************************************************************/
 
-gint
+gboolean
 gtk_selection_property_notify (GtkWidget       *widget,
                               GdkEventProperty *event)
 {
@@ -1435,7 +1504,7 @@ gtk_selection_property_notify (GtkWidget  *widget,
 
 #if defined(GDK_WINDOWING_WIN32) || defined(GDK_WINDOWING_X11)
   if ((event->state != GDK_PROPERTY_NEW_VALUE) ||  /* property was deleted */
-      (event->atom != gdk_selection_property)) /* not the right property */
+      (event->atom != gdk_atom_intern ("GDK_SELECTION", FALSE))) /* not the right property */
 #endif
     return FALSE;
   
@@ -1720,7 +1789,7 @@ gtk_selection_default_handler (GtkWidget  *widget,
 }
 
 
-GtkSelectioData*
+GtkSelectionData*
 gtk_selection_data_copy (GtkSelectionData *selection_data)
 {
   GtkSelectionData *new_data;
@@ -1750,6 +1819,19 @@ gtk_selection_data_free (GtkSelectionData *data)
   g_free (data);
 }
 
+GType
+gtk_selection_data_get_type (void)
+{
+  static GType our_type = 0;
+  
+  if (our_type == 0)
+    our_type = g_boxed_type_register_static ("GtkTypeSelectionData",
+                                            (GBoxedCopyFunc) gtk_selection_data_copy,
+                                            (GBoxedFreeFunc) gtk_selection_data_free);
+
+  return our_type;
+}
+
 static int 
 gtk_selection_bytes_per_item (gint format)
 {