Blame gtk/gtkselection.c

Packit Service fb6fa5
/* GTK - The GIMP Toolkit
Packit Service fb6fa5
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * This library is free software; you can redistribute it and/or
Packit Service fb6fa5
 * modify it under the terms of the GNU Lesser General Public
Packit Service fb6fa5
 * License as published by the Free Software Foundation; either
Packit Service fb6fa5
 * version 2 of the License, or (at your option) any later version.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * This library is distributed in the hope that it will be useful,
Packit Service fb6fa5
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service fb6fa5
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
Packit Service fb6fa5
 * Lesser General Public License for more details.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * You should have received a copy of the GNU Lesser General Public
Packit Service fb6fa5
 * License along with this library; if not, write to the
Packit Service fb6fa5
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Packit Service fb6fa5
 * Boston, MA 02111-1307, USA.
Packit Service fb6fa5
 */
Packit Service fb6fa5
Packit Service fb6fa5
/* This file implements most of the work of the ICCCM selection protocol.
Packit Service fb6fa5
 * The code was written after an intensive study of the equivalent part
Packit Service fb6fa5
 * of John Ousterhout's Tk toolkit, and does many things in much the 
Packit Service fb6fa5
 * same way.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * The one thing in the ICCCM that isn't fully supported here (or in Tk)
Packit Service fb6fa5
 * is side effects targets. For these to be handled properly, MULTIPLE
Packit Service fb6fa5
 * targets need to be done in the order specified. This cannot be
Packit Service fb6fa5
 * guaranteed with the way we do things, since if we are doing INCR
Packit Service fb6fa5
 * transfers, the order will depend on the timing of the requestor.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * By Owen Taylor <owt1@cornell.edu>	      8/16/97
Packit Service fb6fa5
 */
Packit Service fb6fa5
Packit Service fb6fa5
/* Terminology note: when not otherwise specified, the term "incr" below
Packit Service fb6fa5
 * refers to the _sending_ part of the INCR protocol. The receiving
Packit Service fb6fa5
 * portion is referred to just as "retrieval". (Terminology borrowed
Packit Service fb6fa5
 * from Tk, because there is no good opposite to "retrieval" in English.
Packit Service fb6fa5
 * "send" can't be made into a noun gracefully and we're already using
Packit Service fb6fa5
 * "emission" for something else ....)
Packit Service fb6fa5
 */
Packit Service fb6fa5
Packit Service fb6fa5
/* The MOTIF entry widget seems to ask for the TARGETS target, then
Packit Service fb6fa5
   (regardless of the reply) ask for the TEXT target. It's slightly
Packit Service fb6fa5
   possible though that it somehow thinks we are responding negatively
Packit Service fb6fa5
   to the TARGETS request, though I don't really think so ... */
Packit Service fb6fa5
Packit Service fb6fa5
/*
Packit Service fb6fa5
 * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
Packit Service fb6fa5
 * file for a list of people on the GTK+ Team.  See the ChangeLog
Packit Service fb6fa5
 * files for a list of changes.  These files are distributed with
Packit Service fb6fa5
 * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
Packit Service fb6fa5
 */
Packit Service fb6fa5
Packit Service fb6fa5
#include "config.h"
Packit Service fb6fa5
#include <stdarg.h>
Packit Service fb6fa5
#include <string.h>
Packit Service fb6fa5
#include "gdk.h"
Packit Service fb6fa5
Packit Service fb6fa5
#include "gtkmain.h"
Packit Service fb6fa5
#include "gtkselection.h"
Packit Service fb6fa5
#include "gtktextbufferrichtext.h"
Packit Service fb6fa5
#include "gtkintl.h"
Packit Service fb6fa5
#include "gdk-pixbuf/gdk-pixbuf.h"
Packit Service fb6fa5
Packit Service fb6fa5
#ifdef GDK_WINDOWING_X11
Packit Service fb6fa5
#include "x11/gdkx.h"
Packit Service fb6fa5
#endif
Packit Service fb6fa5
Packit Service fb6fa5
#ifdef GDK_WINDOWING_WIN32
Packit Service fb6fa5
#include "win32/gdkwin32.h"
Packit Service fb6fa5
#endif
Packit Service fb6fa5
Packit Service fb6fa5
#include "gtkalias.h"
Packit Service fb6fa5
Packit Service fb6fa5
#undef DEBUG_SELECTION
Packit Service fb6fa5
Packit Service fb6fa5
/* Maximum size of a sent chunk, in bytes. Also the default size of
Packit Service fb6fa5
   our buffers */
Packit Service fb6fa5
#ifdef GDK_WINDOWING_X11
Packit Service fb6fa5
#define GTK_SELECTION_MAX_SIZE(display)                                 \
Packit Service fb6fa5
  MIN(262144,                                                           \
Packit Service fb6fa5
      XExtendedMaxRequestSize (GDK_DISPLAY_XDISPLAY (display)) == 0     \
Packit Service fb6fa5
       ? XMaxRequestSize (GDK_DISPLAY_XDISPLAY (display)) - 100         \
Packit Service fb6fa5
       : XExtendedMaxRequestSize (GDK_DISPLAY_XDISPLAY (display)) - 100)
Packit Service fb6fa5
#else
Packit Service fb6fa5
/* No chunks on Win32 */
Packit Service fb6fa5
#define GTK_SELECTION_MAX_SIZE(display) G_MAXINT
Packit Service fb6fa5
#endif
Packit Service fb6fa5
Packit Service fb6fa5
#define IDLE_ABORT_TIME 30
Packit Service fb6fa5
Packit Service fb6fa5
enum {
Packit Service fb6fa5
  INCR,
Packit Service fb6fa5
  MULTIPLE,
Packit Service fb6fa5
  TARGETS,
Packit Service fb6fa5
  TIMESTAMP,
Packit Service fb6fa5
  SAVE_TARGETS,
Packit Service fb6fa5
  LAST_ATOM
Packit Service fb6fa5
};
Packit Service fb6fa5
Packit Service fb6fa5
typedef struct _GtkSelectionInfo GtkSelectionInfo;
Packit Service fb6fa5
typedef struct _GtkIncrConversion GtkIncrConversion;
Packit Service fb6fa5
typedef struct _GtkIncrInfo GtkIncrInfo;
Packit Service fb6fa5
typedef struct _GtkRetrievalInfo GtkRetrievalInfo;
Packit Service fb6fa5
Packit Service fb6fa5
struct _GtkSelectionInfo
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkAtom	 selection;
Packit Service fb6fa5
  GtkWidget	*widget;	/* widget that owns selection */
Packit Service fb6fa5
  guint32	 time;		/* time used to acquire selection */
Packit Service fb6fa5
  GdkDisplay	*display;	/* needed in gtk_selection_remove_all */    
Packit Service fb6fa5
};
Packit Service fb6fa5
Packit Service fb6fa5
struct _GtkIncrConversion 
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkAtom	    target;	/* Requested target */
Packit Service fb6fa5
  GdkAtom	    property;	/* Property to store in */
Packit Service fb6fa5
  GtkSelectionData  data;	/* The data being supplied */
Packit Service fb6fa5
  gint		    offset;	/* Current offset in sent selection.
Packit Service fb6fa5
				 *  -1 => All done
Packit Service fb6fa5
				 *  -2 => Only the final (empty) portion
Packit Service fb6fa5
				 *	  left to send */
Packit Service fb6fa5
};
Packit Service fb6fa5
Packit Service fb6fa5
struct _GtkIncrInfo
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkWindow *requestor;		/* Requestor window - we create a GdkWindow
Packit Service fb6fa5
				   so we can receive events */
Packit Service fb6fa5
  GdkAtom    selection;		/* Selection we're sending */
Packit Service fb6fa5
  
Packit Service fb6fa5
  GtkIncrConversion *conversions; /* Information about requested conversions -
Packit Service fb6fa5
				   * With MULTIPLE requests (benighted 1980's
Packit Service fb6fa5
				   * hardware idea), there can be more than
Packit Service fb6fa5
				   * one */
Packit Service fb6fa5
  gint num_conversions;
Packit Service fb6fa5
  gint num_incrs;		/* number of remaining INCR style transactions */
Packit Service fb6fa5
  guint32 idle_time;
Packit Service fb6fa5
};
Packit Service fb6fa5
Packit Service fb6fa5
Packit Service fb6fa5
struct _GtkRetrievalInfo
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkWidget *widget;
Packit Service fb6fa5
  GdkAtom selection;		/* Selection being retrieved. */
Packit Service fb6fa5
  GdkAtom target;		/* Form of selection that we requested */
Packit Service fb6fa5
  guint32 idle_time;		/* Number of seconds since we last heard
Packit Service fb6fa5
				   from selection owner */
Packit Service fb6fa5
  guchar   *buffer;		/* Buffer in which to accumulate results */
Packit Service fb6fa5
  gint	   offset;		/* Current offset in buffer, -1 indicates
Packit Service fb6fa5
				   not yet started */
Packit Service fb6fa5
  guint32 notify_time;		/* Timestamp from SelectionNotify */
Packit Service fb6fa5
};
Packit Service fb6fa5
Packit Service fb6fa5
/* Local Functions */
Packit Service fb6fa5
static void gtk_selection_init              (void);
Packit Service fb6fa5
static gboolean gtk_selection_incr_timeout      (GtkIncrInfo      *info);
Packit Service fb6fa5
static gboolean gtk_selection_retrieval_timeout (GtkRetrievalInfo *info);
Packit Service fb6fa5
static void gtk_selection_retrieval_report  (GtkRetrievalInfo *info,
Packit Service fb6fa5
					     GdkAtom           type,
Packit Service fb6fa5
					     gint              format,
Packit Service fb6fa5
					     guchar           *buffer,
Packit Service fb6fa5
					     gint              length,
Packit Service fb6fa5
					     guint32           time);
Packit Service fb6fa5
static void gtk_selection_invoke_handler    (GtkWidget        *widget,
Packit Service fb6fa5
					     GtkSelectionData *data,
Packit Service fb6fa5
					     guint             time);
Packit Service fb6fa5
static void gtk_selection_default_handler   (GtkWidget        *widget,
Packit Service fb6fa5
					     GtkSelectionData *data);
Packit Service fb6fa5
static int  gtk_selection_bytes_per_item    (gint              format);
Packit Service fb6fa5
Packit Service fb6fa5
/* Local Data */
Packit Service fb6fa5
static gint initialize = TRUE;
Packit Service fb6fa5
static GList *current_retrievals = NULL;
Packit Service fb6fa5
static GList *current_incrs = NULL;
Packit Service fb6fa5
static GList *current_selections = NULL;
Packit Service fb6fa5
Packit Service fb6fa5
static GdkAtom gtk_selection_atoms[LAST_ATOM];
Packit Service fb6fa5
static const char gtk_selection_handler_key[] = "gtk-selection-handlers";
Packit Service fb6fa5
Packit Service fb6fa5
/****************
Packit Service fb6fa5
 * Target Lists *
Packit Service fb6fa5
 ****************/
Packit Service fb6fa5
Packit Service fb6fa5
/*
Packit Service fb6fa5
 * Target lists
Packit Service fb6fa5
 */
Packit Service fb6fa5
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_target_list_new:
Packit Service fb6fa5
 * @targets: (array length=ntargets): Pointer to an array of #GtkTargetEntry
Packit Service fb6fa5
 * @ntargets: number of entries in @targets.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Creates a new #GtkTargetList from an array of #GtkTargetEntry.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Return value: (transfer full): the new #GtkTargetList.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
GtkTargetList *
Packit Service fb6fa5
gtk_target_list_new (const GtkTargetEntry *targets,
Packit Service fb6fa5
		     guint                 ntargets)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkTargetList *result = g_slice_new (GtkTargetList);
Packit Service fb6fa5
  result->list = NULL;
Packit Service fb6fa5
  result->ref_count = 1;
Packit Service fb6fa5
Packit Service fb6fa5
  if (targets)
Packit Service fb6fa5
    gtk_target_list_add_table (result, targets, ntargets);
Packit Service fb6fa5
  
Packit Service fb6fa5
  return result;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_target_list_ref:
Packit Service fb6fa5
 * @list:  a #GtkTargetList
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Increases the reference count of a #GtkTargetList by one.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Return value: the passed in #GtkTargetList.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
GtkTargetList *
Packit Service fb6fa5
gtk_target_list_ref (GtkTargetList *list)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_val_if_fail (list != NULL, NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  list->ref_count++;
Packit Service fb6fa5
Packit Service fb6fa5
  return list;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_target_list_unref:
Packit Service fb6fa5
 * @list: a #GtkTargetList
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Decreases the reference count of a #GtkTargetList by one.
Packit Service fb6fa5
 * If the resulting reference count is zero, frees the list.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
void               
Packit Service fb6fa5
gtk_target_list_unref (GtkTargetList *list)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_if_fail (list != NULL);
Packit Service fb6fa5
  g_return_if_fail (list->ref_count > 0);
Packit Service fb6fa5
Packit Service fb6fa5
  list->ref_count--;
Packit Service fb6fa5
  if (list->ref_count == 0)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      GList *tmp_list = list->list;
Packit Service fb6fa5
      while (tmp_list)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  GtkTargetPair *pair = tmp_list->data;
Packit Service fb6fa5
	  g_slice_free (GtkTargetPair, pair);
Packit Service fb6fa5
Packit Service fb6fa5
	  tmp_list = tmp_list->next;
Packit Service fb6fa5
	}
Packit Service fb6fa5
      
Packit Service fb6fa5
      g_list_free (list->list);
Packit Service fb6fa5
      g_slice_free (GtkTargetList, list);
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_target_list_add:
Packit Service fb6fa5
 * @list:  a #GtkTargetList
Packit Service fb6fa5
 * @target: the interned atom representing the target
Packit Service fb6fa5
 * @flags: the flags for this target
Packit Service fb6fa5
 * @info: an ID that will be passed back to the application
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Appends another target to a #GtkTargetList.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
void 
Packit Service fb6fa5
gtk_target_list_add (GtkTargetList *list,
Packit Service fb6fa5
		     GdkAtom        target,
Packit Service fb6fa5
		     guint          flags,
Packit Service fb6fa5
		     guint          info)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkTargetPair *pair;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_if_fail (list != NULL);
Packit Service fb6fa5
  
Packit Service fb6fa5
  pair = g_slice_new (GtkTargetPair);
Packit Service fb6fa5
  pair->target = target;
Packit Service fb6fa5
  pair->flags = flags;
Packit Service fb6fa5
  pair->info = info;
Packit Service fb6fa5
Packit Service fb6fa5
  list->list = g_list_append (list->list, pair);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static GdkAtom utf8_atom;
Packit Service fb6fa5
static GdkAtom text_atom;
Packit Service fb6fa5
static GdkAtom ctext_atom;
Packit Service fb6fa5
static GdkAtom text_plain_atom;
Packit Service fb6fa5
static GdkAtom text_plain_utf8_atom;
Packit Service fb6fa5
static GdkAtom text_plain_locale_atom;
Packit Service fb6fa5
static GdkAtom text_uri_list_atom;
Packit Service fb6fa5
Packit Service fb6fa5
static void 
Packit Service fb6fa5
init_atoms (void)
Packit Service fb6fa5
{
Packit Service fb6fa5
  gchar *tmp;
Packit Service fb6fa5
  const gchar *charset;
Packit Service fb6fa5
Packit Service fb6fa5
  if (!utf8_atom)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      utf8_atom = gdk_atom_intern_static_string ("UTF8_STRING");
Packit Service fb6fa5
      text_atom = gdk_atom_intern_static_string ("TEXT");
Packit Service fb6fa5
      ctext_atom = gdk_atom_intern_static_string ("COMPOUND_TEXT");
Packit Service fb6fa5
      text_plain_atom = gdk_atom_intern_static_string ("text/plain");
Packit Service fb6fa5
      text_plain_utf8_atom = gdk_atom_intern_static_string ("text/plain;charset=utf-8");
Packit Service fb6fa5
      g_get_charset (&charset);
Packit Service fb6fa5
      tmp = g_strdup_printf ("text/plain;charset=%s", charset);
Packit Service fb6fa5
      text_plain_locale_atom = gdk_atom_intern (tmp, FALSE);
Packit Service fb6fa5
      g_free (tmp);
Packit Service fb6fa5
Packit Service fb6fa5
      text_uri_list_atom = gdk_atom_intern_static_string ("text/uri-list");
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_target_list_add_text_targets:
Packit Service fb6fa5
 * @list: a #GtkTargetList
Packit Service fb6fa5
 * @info: an ID that will be passed back to the application
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Appends the text targets supported by #GtkSelection to
Packit Service fb6fa5
 * the target list. All targets are added with the same @info.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Since: 2.6
Packit Service fb6fa5
 **/
Packit Service fb6fa5
void 
Packit Service fb6fa5
gtk_target_list_add_text_targets (GtkTargetList *list,
Packit Service fb6fa5
				  guint          info)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_if_fail (list != NULL);
Packit Service fb6fa5
  
Packit Service fb6fa5
  init_atoms ();
Packit Service fb6fa5
Packit Service fb6fa5
  /* Keep in sync with gtk_selection_data_targets_include_text()
Packit Service fb6fa5
   */
Packit Service fb6fa5
  gtk_target_list_add (list, utf8_atom, 0, info);  
Packit Service fb6fa5
  gtk_target_list_add (list, ctext_atom, 0, info);  
Packit Service fb6fa5
  gtk_target_list_add (list, text_atom, 0, info);  
Packit Service fb6fa5
  gtk_target_list_add (list, GDK_TARGET_STRING, 0, info);  
Packit Service fb6fa5
  gtk_target_list_add (list, text_plain_utf8_atom, 0, info);  
Packit Service fb6fa5
  if (!g_get_charset (NULL))
Packit Service fb6fa5
    gtk_target_list_add (list, text_plain_locale_atom, 0, info);  
Packit Service fb6fa5
  gtk_target_list_add (list, text_plain_atom, 0, info);  
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_target_list_add_rich_text_targets:
Packit Service fb6fa5
 * @list: a #GtkTargetList
Packit Service fb6fa5
 * @info: an ID that will be passed back to the application
Packit Service fb6fa5
 * @deserializable: if %TRUE, then deserializable rich text formats
Packit Service fb6fa5
 *                  will be added, serializable formats otherwise.
Packit Service fb6fa5
 * @buffer: a #GtkTextBuffer.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Appends the rich text targets registered with
Packit Service fb6fa5
 * gtk_text_buffer_register_serialize_format() or
Packit Service fb6fa5
 * gtk_text_buffer_register_deserialize_format() to the target list. All
Packit Service fb6fa5
 * targets are added with the same @info.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Since: 2.10
Packit Service fb6fa5
 **/
Packit Service fb6fa5
void
Packit Service fb6fa5
gtk_target_list_add_rich_text_targets (GtkTargetList  *list,
Packit Service fb6fa5
                                       guint           info,
Packit Service fb6fa5
                                       gboolean        deserializable,
Packit Service fb6fa5
                                       GtkTextBuffer  *buffer)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkAtom *atoms;
Packit Service fb6fa5
  gint     n_atoms;
Packit Service fb6fa5
  gint     i;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_if_fail (list != NULL);
Packit Service fb6fa5
  g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
Packit Service fb6fa5
Packit Service fb6fa5
  if (deserializable)
Packit Service fb6fa5
    atoms = gtk_text_buffer_get_deserialize_formats (buffer, &n_atoms);
Packit Service fb6fa5
  else
Packit Service fb6fa5
    atoms = gtk_text_buffer_get_serialize_formats (buffer, &n_atoms);
Packit Service fb6fa5
Packit Service fb6fa5
  for (i = 0; i < n_atoms; i++)
Packit Service fb6fa5
    gtk_target_list_add (list, atoms[i], 0, info);
Packit Service fb6fa5
Packit Service fb6fa5
  g_free (atoms);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_target_list_add_image_targets:
Packit Service fb6fa5
 * @list: a #GtkTargetList
Packit Service fb6fa5
 * @info: an ID that will be passed back to the application
Packit Service fb6fa5
 * @writable: whether to add only targets for which GTK+ knows
Packit Service fb6fa5
 *   how to convert a pixbuf into the format
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Appends the image targets supported by #GtkSelection to
Packit Service fb6fa5
 * the target list. All targets are added with the same @info.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Since: 2.6
Packit Service fb6fa5
 **/
Packit Service fb6fa5
void 
Packit Service fb6fa5
gtk_target_list_add_image_targets (GtkTargetList *list,
Packit Service fb6fa5
				   guint          info,
Packit Service fb6fa5
				   gboolean       writable)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GSList *formats, *f;
Packit Service fb6fa5
  gchar **mimes, **m;
Packit Service fb6fa5
  GdkAtom atom;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_if_fail (list != NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  formats = gdk_pixbuf_get_formats ();
Packit Service fb6fa5
Packit Service fb6fa5
  /* Make sure png comes first */
Packit Service fb6fa5
  for (f = formats; f; f = f->next)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      GdkPixbufFormat *fmt = f->data;
Packit Service fb6fa5
      gchar *name; 
Packit Service fb6fa5
 
Packit Service fb6fa5
      name = gdk_pixbuf_format_get_name (fmt);
Packit Service fb6fa5
      if (strcmp (name, "png") == 0)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  formats = g_slist_delete_link (formats, f);
Packit Service fb6fa5
	  formats = g_slist_prepend (formats, fmt);
Packit Service fb6fa5
Packit Service fb6fa5
	  g_free (name);
Packit Service fb6fa5
Packit Service fb6fa5
	  break;
Packit Service fb6fa5
	}
Packit Service fb6fa5
Packit Service fb6fa5
      g_free (name);
Packit Service fb6fa5
    }  
Packit Service fb6fa5
Packit Service fb6fa5
  for (f = formats; f; f = f->next)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      GdkPixbufFormat *fmt = f->data;
Packit Service fb6fa5
Packit Service fb6fa5
      if (writable && !gdk_pixbuf_format_is_writable (fmt))
Packit Service fb6fa5
	continue;
Packit Service fb6fa5
      
Packit Service fb6fa5
      mimes = gdk_pixbuf_format_get_mime_types (fmt);
Packit Service fb6fa5
      for (m = mimes; *m; m++)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  atom = gdk_atom_intern (*m, FALSE);
Packit Service fb6fa5
	  gtk_target_list_add (list, atom, 0, info);  
Packit Service fb6fa5
	}
Packit Service fb6fa5
      g_strfreev (mimes);
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  g_slist_free (formats);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_target_list_add_uri_targets:
Packit Service fb6fa5
 * @list: a #GtkTargetList
Packit Service fb6fa5
 * @info: an ID that will be passed back to the application
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Appends the URI targets supported by #GtkSelection to
Packit Service fb6fa5
 * the target list. All targets are added with the same @info.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Since: 2.6
Packit Service fb6fa5
 **/
Packit Service fb6fa5
void 
Packit Service fb6fa5
gtk_target_list_add_uri_targets (GtkTargetList *list,
Packit Service fb6fa5
				 guint          info)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_if_fail (list != NULL);
Packit Service fb6fa5
  
Packit Service fb6fa5
  init_atoms ();
Packit Service fb6fa5
Packit Service fb6fa5
  gtk_target_list_add (list, text_uri_list_atom, 0, info);  
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_target_list_add_table:
Packit Service fb6fa5
 * @list: a #GtkTargetList
Packit Service fb6fa5
 * @targets: (array length=ntargets): the table of #GtkTargetEntry
Packit Service fb6fa5
 * @ntargets: number of targets in the table
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Prepends a table of #GtkTargetEntry to a target list.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
void               
Packit Service fb6fa5
gtk_target_list_add_table (GtkTargetList        *list,
Packit Service fb6fa5
			   const GtkTargetEntry *targets,
Packit Service fb6fa5
			   guint                 ntargets)
Packit Service fb6fa5
{
Packit Service fb6fa5
  gint i;
Packit Service fb6fa5
Packit Service fb6fa5
  for (i=ntargets-1; i >= 0; i--)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      GtkTargetPair *pair = g_slice_new (GtkTargetPair);
Packit Service fb6fa5
      pair->target = gdk_atom_intern (targets[i].target, FALSE);
Packit Service fb6fa5
      pair->flags = targets[i].flags;
Packit Service fb6fa5
      pair->info = targets[i].info;
Packit Service fb6fa5
      
Packit Service fb6fa5
      list->list = g_list_prepend (list->list, pair);
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_target_list_remove:
Packit Service fb6fa5
 * @list: a #GtkTargetList
Packit Service fb6fa5
 * @target: the interned atom representing the target
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Removes a target from a target list.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
void 
Packit Service fb6fa5
gtk_target_list_remove (GtkTargetList *list,
Packit Service fb6fa5
			GdkAtom            target)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GList *tmp_list;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_if_fail (list != NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  tmp_list = list->list;
Packit Service fb6fa5
  while (tmp_list)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      GtkTargetPair *pair = tmp_list->data;
Packit Service fb6fa5
      
Packit Service fb6fa5
      if (pair->target == target)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  g_slice_free (GtkTargetPair, pair);
Packit Service fb6fa5
Packit Service fb6fa5
	  list->list = g_list_remove_link (list->list, tmp_list);
Packit Service fb6fa5
	  g_list_free_1 (tmp_list);
Packit Service fb6fa5
Packit Service fb6fa5
	  return;
Packit Service fb6fa5
	}
Packit Service fb6fa5
      
Packit Service fb6fa5
      tmp_list = tmp_list->next;
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_target_list_find:
Packit Service fb6fa5
 * @list: a #GtkTargetList
Packit Service fb6fa5
 * @target: an interned atom representing the target to search for
Packit Service fb6fa5
 * @info: a pointer to the location to store application info for target,
Packit Service fb6fa5
 *        or %NULL
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Looks up a given target in a #GtkTargetList.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Return value: %TRUE if the target was found, otherwise %FALSE
Packit Service fb6fa5
 **/
Packit Service fb6fa5
gboolean
Packit Service fb6fa5
gtk_target_list_find (GtkTargetList *list,
Packit Service fb6fa5
		      GdkAtom        target,
Packit Service fb6fa5
		      guint         *info)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GList *tmp_list;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (list != NULL, FALSE);
Packit Service fb6fa5
Packit Service fb6fa5
  tmp_list = list->list;
Packit Service fb6fa5
  while (tmp_list)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      GtkTargetPair *pair = tmp_list->data;
Packit Service fb6fa5
Packit Service fb6fa5
      if (pair->target == target)
Packit Service fb6fa5
	{
Packit Service fb6fa5
          if (info)
Packit Service fb6fa5
            *info = pair->info;
Packit Service fb6fa5
Packit Service fb6fa5
	  return TRUE;
Packit Service fb6fa5
	}
Packit Service fb6fa5
Packit Service fb6fa5
      tmp_list = tmp_list->next;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  return FALSE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_target_table_new_from_list:
Packit Service fb6fa5
 * @list: a #GtkTargetList
Packit Service fb6fa5
 * @n_targets: return location for the number ot targets in the table
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * This function creates an #GtkTargetEntry array that contains the
Packit Service fb6fa5
 * same targets as the passed %list. The returned table is newly
Packit Service fb6fa5
 * allocated and should be freed using gtk_target_table_free() when no
Packit Service fb6fa5
 * longer needed.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Return value: (array length=n_targets) (transfer full): the new table.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Since: 2.10
Packit Service fb6fa5
 **/
Packit Service fb6fa5
GtkTargetEntry *
Packit Service fb6fa5
gtk_target_table_new_from_list (GtkTargetList *list,
Packit Service fb6fa5
                                gint          *n_targets)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkTargetEntry *targets;
Packit Service fb6fa5
  GList          *tmp_list;
Packit Service fb6fa5
  gint            i;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (list != NULL, NULL);
Packit Service fb6fa5
  g_return_val_if_fail (n_targets != NULL, NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  *n_targets = g_list_length (list->list);
Packit Service fb6fa5
  targets = g_new0 (GtkTargetEntry, *n_targets);
Packit Service fb6fa5
Packit Service fb6fa5
  for (i = 0, tmp_list = list->list;
Packit Service fb6fa5
       i < *n_targets;
Packit Service fb6fa5
       i++, tmp_list = g_list_next (tmp_list))
Packit Service fb6fa5
    {
Packit Service fb6fa5
      GtkTargetPair *pair = tmp_list->data;
Packit Service fb6fa5
Packit Service fb6fa5
      targets[i].target = gdk_atom_name (pair->target);
Packit Service fb6fa5
      targets[i].flags  = pair->flags;
Packit Service fb6fa5
      targets[i].info   = pair->info;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  return targets;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_target_table_free:
Packit Service fb6fa5
 * @targets: (array length=n_targets): a #GtkTargetEntry array
Packit Service fb6fa5
 * @n_targets: the number of entries in the array
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * This function frees a target table as returned by
Packit Service fb6fa5
 * gtk_target_table_new_from_list()
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Since: 2.10
Packit Service fb6fa5
 **/
Packit Service fb6fa5
void
Packit Service fb6fa5
gtk_target_table_free (GtkTargetEntry *targets,
Packit Service fb6fa5
                       gint            n_targets)
Packit Service fb6fa5
{
Packit Service fb6fa5
  gint i;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_if_fail (targets == NULL || n_targets > 0);
Packit Service fb6fa5
Packit Service fb6fa5
  for (i = 0; i < n_targets; i++)
Packit Service fb6fa5
    g_free (targets[i].target);
Packit Service fb6fa5
Packit Service fb6fa5
  g_free (targets);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_selection_owner_set_for_display:
Packit Service fb6fa5
 * @display: the #Gdkdisplay where the selection is set
Packit Service fb6fa5
 * @widget: (allow-none): new selection owner (a #GdkWidget), or %NULL.
Packit Service fb6fa5
 * @selection: an interned atom representing the selection to claim.
Packit Service fb6fa5
 * @time_: timestamp with which to claim the selection
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Claim ownership of a given selection for a particular widget, or,
Packit Service fb6fa5
 * if @widget is %NULL, release ownership of the selection.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Return value: TRUE if the operation succeeded 
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Since: 2.2
Packit Service fb6fa5
 */
Packit Service fb6fa5
gboolean
Packit Service fb6fa5
gtk_selection_owner_set_for_display (GdkDisplay   *display,
Packit Service fb6fa5
				     GtkWidget    *widget,
Packit Service fb6fa5
				     GdkAtom       selection,
Packit Service fb6fa5
				     guint32       time)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GList *tmp_list;
Packit Service fb6fa5
  GtkWidget *old_owner;
Packit Service fb6fa5
  GtkSelectionInfo *selection_info = NULL;
Packit Service fb6fa5
  GdkWindow *window;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
Packit Service fb6fa5
  g_return_val_if_fail (selection != GDK_NONE, FALSE);
Packit Service fb6fa5
  g_return_val_if_fail (widget == NULL || gtk_widget_get_realized (widget), FALSE);
Packit Service fb6fa5
  g_return_val_if_fail (widget == NULL || gtk_widget_get_display (widget) == display, FALSE);
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (widget == NULL)
Packit Service fb6fa5
    window = NULL;
Packit Service fb6fa5
  else
Packit Service fb6fa5
    window = widget->window;
Packit Service fb6fa5
Packit Service fb6fa5
  tmp_list = current_selections;
Packit Service fb6fa5
  while (tmp_list)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (((GtkSelectionInfo *)tmp_list->data)->selection == selection)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  selection_info = tmp_list->data;
Packit Service fb6fa5
	  break;
Packit Service fb6fa5
	}
Packit Service fb6fa5
      
Packit Service fb6fa5
      tmp_list = tmp_list->next;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (gdk_selection_owner_set_for_display (display, window, selection, time, TRUE))
Packit Service fb6fa5
    {
Packit Service fb6fa5
      old_owner = NULL;
Packit Service fb6fa5
      
Packit Service fb6fa5
      if (widget == NULL)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  if (selection_info)
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      old_owner = selection_info->widget;
Packit Service fb6fa5
	      current_selections = g_list_remove_link (current_selections,
Packit Service fb6fa5
						       tmp_list);
Packit Service fb6fa5
	      g_list_free (tmp_list);
Packit Service fb6fa5
	      g_slice_free (GtkSelectionInfo, selection_info);
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	}
Packit Service fb6fa5
      else
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  if (selection_info == NULL)
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      selection_info = g_slice_new (GtkSelectionInfo);
Packit Service fb6fa5
	      selection_info->selection = selection;
Packit Service fb6fa5
	      selection_info->widget = widget;
Packit Service fb6fa5
	      selection_info->time = time;
Packit Service fb6fa5
	      selection_info->display = display;
Packit Service fb6fa5
	      current_selections = g_list_prepend (current_selections,
Packit Service fb6fa5
						   selection_info);
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	  else
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      old_owner = selection_info->widget;
Packit Service fb6fa5
	      selection_info->widget = widget;
Packit Service fb6fa5
	      selection_info->time = time;
Packit Service fb6fa5
	      selection_info->display = display;
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	}
Packit Service fb6fa5
      /* If another widget in the application lost the selection,
Packit Service fb6fa5
       *  send it a GDK_SELECTION_CLEAR event.
Packit Service fb6fa5
       */
Packit Service fb6fa5
      if (old_owner && old_owner != widget)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  GdkEvent *event = gdk_event_new (GDK_SELECTION_CLEAR);
Packit Service fb6fa5
	  
Packit Service fb6fa5
	  event->selection.window = g_object_ref (old_owner->window);
Packit Service fb6fa5
	  event->selection.selection = selection;
Packit Service fb6fa5
	  event->selection.time = time;
Packit Service fb6fa5
	  
Packit Service fb6fa5
	  gtk_widget_event (old_owner, event);
Packit Service fb6fa5
Packit Service fb6fa5
	  gdk_event_free (event);
Packit Service fb6fa5
	}
Packit Service fb6fa5
      return TRUE;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    return FALSE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_selection_owner_set:
Packit Service fb6fa5
 * @widget: (allow-none):  a #GtkWidget, or %NULL.
Packit Service fb6fa5
 * @selection:  an interned atom representing the selection to claim
Packit Service fb6fa5
 * @time_: timestamp with which to claim the selection
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Claims ownership of a given selection for a particular widget,
Packit Service fb6fa5
 * or, if @widget is %NULL, release ownership of the selection.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Return value: %TRUE if the operation succeeded
Packit Service fb6fa5
 **/
Packit Service fb6fa5
gboolean
Packit Service fb6fa5
gtk_selection_owner_set (GtkWidget *widget,
Packit Service fb6fa5
			 GdkAtom    selection,
Packit Service fb6fa5
			 guint32    time)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkDisplay *display;
Packit Service fb6fa5
  
Packit Service fb6fa5
  g_return_val_if_fail (widget == NULL || gtk_widget_get_realized (widget), FALSE);
Packit Service fb6fa5
  g_return_val_if_fail (selection != GDK_NONE, FALSE);
Packit Service fb6fa5
Packit Service fb6fa5
  if (widget)
Packit Service fb6fa5
    display = gtk_widget_get_display (widget);
Packit Service fb6fa5
  else
Packit Service fb6fa5
    {
Packit Service fb6fa5
      GTK_NOTE (MULTIHEAD,
Packit Service fb6fa5
		g_warning ("gtk_selection_owner_set (NULL,...) is not multihead safe"));
Packit Service fb6fa5
		 
Packit Service fb6fa5
      display = gdk_display_get_default ();
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  return gtk_selection_owner_set_for_display (display, widget,
Packit Service fb6fa5
					      selection, time);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
typedef struct _GtkSelectionTargetList GtkSelectionTargetList;
Packit Service fb6fa5
Packit Service fb6fa5
struct _GtkSelectionTargetList {
Packit Service fb6fa5
  GdkAtom selection;
Packit Service fb6fa5
  GtkTargetList *list;
Packit Service fb6fa5
};
Packit Service fb6fa5
Packit Service fb6fa5
static GtkTargetList *
Packit Service fb6fa5
gtk_selection_target_list_get (GtkWidget    *widget,
Packit Service fb6fa5
			       GdkAtom       selection)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkSelectionTargetList *sellist;
Packit Service fb6fa5
  GList *tmp_list;
Packit Service fb6fa5
  GList *lists;
Packit Service fb6fa5
Packit Service fb6fa5
  lists = g_object_get_data (G_OBJECT (widget), gtk_selection_handler_key);
Packit Service fb6fa5
  
Packit Service fb6fa5
  tmp_list = lists;
Packit Service fb6fa5
  while (tmp_list)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      sellist = tmp_list->data;
Packit Service fb6fa5
      if (sellist->selection == selection)
Packit Service fb6fa5
	return sellist->list;
Packit Service fb6fa5
      tmp_list = tmp_list->next;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  sellist = g_slice_new (GtkSelectionTargetList);
Packit Service fb6fa5
  sellist->selection = selection;
Packit Service fb6fa5
  sellist->list = gtk_target_list_new (NULL, 0);
Packit Service fb6fa5
Packit Service fb6fa5
  lists = g_list_prepend (lists, sellist);
Packit Service fb6fa5
  g_object_set_data (G_OBJECT (widget), I_(gtk_selection_handler_key), lists);
Packit Service fb6fa5
Packit Service fb6fa5
  return sellist->list;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gtk_selection_target_list_remove (GtkWidget    *widget)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkSelectionTargetList *sellist;
Packit Service fb6fa5
  GList *tmp_list;
Packit Service fb6fa5
  GList *lists;
Packit Service fb6fa5
Packit Service fb6fa5
  lists = g_object_get_data (G_OBJECT (widget), gtk_selection_handler_key);
Packit Service fb6fa5
  
Packit Service fb6fa5
  tmp_list = lists;
Packit Service fb6fa5
  while (tmp_list)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      sellist = tmp_list->data;
Packit Service fb6fa5
Packit Service fb6fa5
      gtk_target_list_unref (sellist->list);
Packit Service fb6fa5
Packit Service fb6fa5
      g_slice_free (GtkSelectionTargetList, sellist);
Packit Service fb6fa5
      tmp_list = tmp_list->next;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  g_list_free (lists);
Packit Service fb6fa5
  g_object_set_data (G_OBJECT (widget), I_(gtk_selection_handler_key), NULL);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_selection_clear_targets:
Packit Service fb6fa5
 * @widget:    a #GtkWidget
Packit Service fb6fa5
 * @selection: an atom representing a selection
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Remove all targets registered for the given selection for the
Packit Service fb6fa5
 * widget.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
void 
Packit Service fb6fa5
gtk_selection_clear_targets (GtkWidget *widget,
Packit Service fb6fa5
			     GdkAtom    selection)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkSelectionTargetList *sellist;
Packit Service fb6fa5
  GList *tmp_list;
Packit Service fb6fa5
  GList *lists;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_if_fail (GTK_IS_WIDGET (widget));
Packit Service fb6fa5
  g_return_if_fail (selection != GDK_NONE);
Packit Service fb6fa5
Packit Service fb6fa5
  lists = g_object_get_data (G_OBJECT (widget), gtk_selection_handler_key);
Packit Service fb6fa5
  
Packit Service fb6fa5
  tmp_list = lists;
Packit Service fb6fa5
  while (tmp_list)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      sellist = tmp_list->data;
Packit Service fb6fa5
      if (sellist->selection == selection)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  lists = g_list_delete_link (lists, tmp_list);
Packit Service fb6fa5
	  gtk_target_list_unref (sellist->list);
Packit Service fb6fa5
	  g_slice_free (GtkSelectionTargetList, sellist);
Packit Service fb6fa5
Packit Service fb6fa5
	  break;
Packit Service fb6fa5
	}
Packit Service fb6fa5
      
Packit Service fb6fa5
      tmp_list = tmp_list->next;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  g_object_set_data (G_OBJECT (widget), I_(gtk_selection_handler_key), lists);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_selection_add_target:
Packit Service fb6fa5
 * @widget:  a #GtkTarget
Packit Service fb6fa5
 * @selection: the selection
Packit Service fb6fa5
 * @target: target to add.
Packit Service fb6fa5
 * @info: A unsigned integer which will be passed back to the application.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Appends a specified target to the list of supported targets for a 
Packit Service fb6fa5
 * given widget and selection.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
void 
Packit Service fb6fa5
gtk_selection_add_target (GtkWidget	    *widget, 
Packit Service fb6fa5
			  GdkAtom	     selection,
Packit Service fb6fa5
			  GdkAtom	     target,
Packit Service fb6fa5
			  guint              info)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkTargetList *list;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_if_fail (GTK_IS_WIDGET (widget));
Packit Service fb6fa5
  g_return_if_fail (selection != GDK_NONE);
Packit Service fb6fa5
Packit Service fb6fa5
  list = gtk_selection_target_list_get (widget, selection);
Packit Service fb6fa5
  gtk_target_list_add (list, target, 0, info);
Packit Service fb6fa5
#ifdef GDK_WINDOWING_WIN32
Packit Service fb6fa5
  gdk_win32_selection_add_targets (widget->window, selection, 1, &target);
Packit Service fb6fa5
#endif
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_selection_add_targets:
Packit Service fb6fa5
 * @widget: a #GtkWidget
Packit Service fb6fa5
 * @selection: the selection
Packit Service fb6fa5
 * @targets: (array length=ntargets): a table of targets to add
Packit Service fb6fa5
 * @ntargets:  number of entries in @targets
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Prepends a table of targets to the list of supported targets
Packit Service fb6fa5
 * for a given widget and selection.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
void 
Packit Service fb6fa5
gtk_selection_add_targets (GtkWidget            *widget, 
Packit Service fb6fa5
			   GdkAtom               selection,
Packit Service fb6fa5
			   const GtkTargetEntry *targets,
Packit Service fb6fa5
			   guint                 ntargets)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkTargetList *list;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_if_fail (GTK_IS_WIDGET (widget));
Packit Service fb6fa5
  g_return_if_fail (selection != GDK_NONE);
Packit Service fb6fa5
  g_return_if_fail (targets != NULL);
Packit Service fb6fa5
  
Packit Service fb6fa5
  list = gtk_selection_target_list_get (widget, selection);
Packit Service fb6fa5
  gtk_target_list_add_table (list, targets, ntargets);
Packit Service fb6fa5
Packit Service fb6fa5
#ifdef GDK_WINDOWING_WIN32
Packit Service fb6fa5
  {
Packit Service fb6fa5
    int i;
Packit Service fb6fa5
    GdkAtom *atoms = g_new (GdkAtom, ntargets);
Packit Service fb6fa5
Packit Service fb6fa5
    for (i = 0; i < ntargets; ++i)
Packit Service fb6fa5
      atoms[i] = gdk_atom_intern (targets[i].target, FALSE);
Packit Service fb6fa5
    gdk_win32_selection_add_targets (widget->window, selection, ntargets, atoms);
Packit Service fb6fa5
    g_free (atoms);
Packit Service fb6fa5
  }
Packit Service fb6fa5
#endif
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_selection_remove_all:
Packit Service fb6fa5
 * @widget: a #GtkWidget 
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Removes all handlers and unsets ownership of all 
Packit Service fb6fa5
 * selections for a widget. Called when widget is being
Packit Service fb6fa5
 * destroyed. This function will not generally be
Packit Service fb6fa5
 * called by applications.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
void
Packit Service fb6fa5
gtk_selection_remove_all (GtkWidget *widget)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GList *tmp_list;
Packit Service fb6fa5
  GList *next;
Packit Service fb6fa5
  GtkSelectionInfo *selection_info;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_if_fail (GTK_IS_WIDGET (widget));
Packit Service fb6fa5
Packit Service fb6fa5
  /* Remove pending requests/incrs for this widget */
Packit Service fb6fa5
  
Packit Service fb6fa5
  tmp_list = current_retrievals;
Packit Service fb6fa5
  while (tmp_list)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      next = tmp_list->next;
Packit Service fb6fa5
      if (((GtkRetrievalInfo *)tmp_list->data)->widget == widget)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  current_retrievals = g_list_remove_link (current_retrievals, 
Packit Service fb6fa5
						   tmp_list);
Packit Service fb6fa5
	  /* structure will be freed in timeout */
Packit Service fb6fa5
	  g_list_free (tmp_list);
Packit Service fb6fa5
	}
Packit Service fb6fa5
      tmp_list = next;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  /* Disclaim ownership of any selections */
Packit Service fb6fa5
  
Packit Service fb6fa5
  tmp_list = current_selections;
Packit Service fb6fa5
  while (tmp_list)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      next = tmp_list->next;
Packit Service fb6fa5
      selection_info = (GtkSelectionInfo *)tmp_list->data;
Packit Service fb6fa5
      
Packit Service fb6fa5
      if (selection_info->widget == widget)
Packit Service fb6fa5
	{	
Packit Service fb6fa5
	  gdk_selection_owner_set_for_display (selection_info->display,
Packit Service fb6fa5
					       NULL, 
Packit Service fb6fa5
					       selection_info->selection,
Packit Service fb6fa5
				               GDK_CURRENT_TIME, FALSE);
Packit Service fb6fa5
	  current_selections = g_list_remove_link (current_selections,
Packit Service fb6fa5
						   tmp_list);
Packit Service fb6fa5
	  g_list_free (tmp_list);
Packit Service fb6fa5
	  g_slice_free (GtkSelectionInfo, selection_info);
Packit Service fb6fa5
	}
Packit Service fb6fa5
      
Packit Service fb6fa5
      tmp_list = next;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  /* Remove all selection lists */
Packit Service fb6fa5
  gtk_selection_target_list_remove (widget);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_selection_convert:
Packit Service fb6fa5
 * @widget: The widget which acts as requestor
Packit Service fb6fa5
 * @selection: Which selection to get
Packit Service fb6fa5
 * @target: Form of information desired (e.g., STRING)
Packit Service fb6fa5
 * @time_: Time of request (usually of triggering event)
Packit Service fb6fa5
       In emergency, you could use #GDK_CURRENT_TIME
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Requests the contents of a selection. When received, 
Packit Service fb6fa5
 * a "selection-received" signal will be generated.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Return value: %TRUE if requested succeeded. %FALSE if we could not process
Packit Service fb6fa5
 *          request. (e.g., there was already a request in process for
Packit Service fb6fa5
 *          this widget).
Packit Service fb6fa5
 **/
Packit Service fb6fa5
gboolean
Packit Service fb6fa5
gtk_selection_convert (GtkWidget *widget, 
Packit Service fb6fa5
		       GdkAtom	  selection, 
Packit Service fb6fa5
		       GdkAtom	  target,
Packit Service fb6fa5
		       guint32	  time_)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkRetrievalInfo *info;
Packit Service fb6fa5
  GList *tmp_list;
Packit Service fb6fa5
  GdkWindow *owner_window;
Packit Service fb6fa5
  GdkDisplay *display;
Packit Service fb6fa5
  
Packit Service fb6fa5
  g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
Packit Service fb6fa5
  g_return_val_if_fail (selection != GDK_NONE, FALSE);
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (initialize)
Packit Service fb6fa5
    gtk_selection_init ();
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (!gtk_widget_get_realized (widget))
Packit Service fb6fa5
    gtk_widget_realize (widget);
Packit Service fb6fa5
  
Packit Service fb6fa5
  /* Check to see if there are already any retrievals in progress for
Packit Service fb6fa5
     this widget. If we changed GDK to use the selection for the 
Packit Service fb6fa5
     window property in which to store the retrieved information, then
Packit Service fb6fa5
     we could support multiple retrievals for different selections.
Packit Service fb6fa5
     This might be useful for DND. */
Packit Service fb6fa5
  
Packit Service fb6fa5
  tmp_list = current_retrievals;
Packit Service fb6fa5
  while (tmp_list)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      info = (GtkRetrievalInfo *)tmp_list->data;
Packit Service fb6fa5
      if (info->widget == widget)
Packit Service fb6fa5
	return FALSE;
Packit Service fb6fa5
      tmp_list = tmp_list->next;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  info = g_slice_new (GtkRetrievalInfo);
Packit Service fb6fa5
  
Packit Service fb6fa5
  info->widget = widget;
Packit Service fb6fa5
  info->selection = selection;
Packit Service fb6fa5
  info->target = target;
Packit Service fb6fa5
  info->idle_time = 0;
Packit Service fb6fa5
  info->buffer = NULL;
Packit Service fb6fa5
  info->offset = -1;
Packit Service fb6fa5
  
Packit Service fb6fa5
  /* Check if this process has current owner. If so, call handler
Packit Service fb6fa5
     procedure directly to avoid deadlocks with INCR. */
Packit Service fb6fa5
Packit Service fb6fa5
  display = gtk_widget_get_display (widget);
Packit Service fb6fa5
  owner_window = gdk_selection_owner_get_for_display (display, selection);
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (owner_window != NULL)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      GtkWidget *owner_widget;
Packit Service fb6fa5
      gpointer owner_widget_ptr;
Packit Service fb6fa5
      GtkSelectionData selection_data;
Packit Service fb6fa5
      
Packit Service fb6fa5
      selection_data.selection = selection;
Packit Service fb6fa5
      selection_data.target = target;
Packit Service fb6fa5
      selection_data.data = NULL;
Packit Service fb6fa5
      selection_data.length = -1;
Packit Service fb6fa5
      selection_data.display = display;
Packit Service fb6fa5
      
Packit Service fb6fa5
      gdk_window_get_user_data (owner_window, &owner_widget_ptr);
Packit Service fb6fa5
      owner_widget = owner_widget_ptr;
Packit Service fb6fa5
      
Packit Service fb6fa5
      if (owner_widget != NULL)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  gtk_selection_invoke_handler (owner_widget, 
Packit Service fb6fa5
					&selection_data,
Packit Service fb6fa5
					time_);
Packit Service fb6fa5
	  
Packit Service fb6fa5
	  gtk_selection_retrieval_report (info,
Packit Service fb6fa5
					  selection_data.type, 
Packit Service fb6fa5
					  selection_data.format,
Packit Service fb6fa5
					  selection_data.data,
Packit Service fb6fa5
					  selection_data.length,
Packit Service fb6fa5
					  time_);
Packit Service fb6fa5
	  
Packit Service fb6fa5
	  g_free (selection_data.data);
Packit Service fb6fa5
          selection_data.data = NULL;
Packit Service fb6fa5
          selection_data.length = -1;
Packit Service fb6fa5
	  
Packit Service fb6fa5
	  g_slice_free (GtkRetrievalInfo, info);
Packit Service fb6fa5
	  return TRUE;
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  /* Otherwise, we need to go through X */
Packit Service fb6fa5
  
Packit Service fb6fa5
  current_retrievals = g_list_append (current_retrievals, info);
Packit Service fb6fa5
  gdk_selection_convert (widget->window, selection, target, time_);
Packit Service fb6fa5
  gdk_threads_add_timeout (1000,
Packit Service fb6fa5
      (GSourceFunc) gtk_selection_retrieval_timeout, info);
Packit Service fb6fa5
  
Packit Service fb6fa5
  return TRUE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_selection_data_get_selection:
Packit Service fb6fa5
 * @selection_data: a pointer to a #GtkSelectionData structure.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Retrieves the selection #GdkAtom of the selection data.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Returns: (transfer none): the selection #GdkAtom of the selection data.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Since: 2.16
Packit Service fb6fa5
 **/
Packit Service fb6fa5
GdkAtom
Packit Service fb6fa5
gtk_selection_data_get_selection (GtkSelectionData *selection_data)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_val_if_fail (selection_data != NULL, 0);
Packit Service fb6fa5
Packit Service fb6fa5
  return selection_data->selection;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_selection_data_get_target:
Packit Service fb6fa5
 * @selection_data: a pointer to a #GtkSelectionData structure.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Retrieves the target of the selection.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Returns: (transfer none): the target of the selection.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Since: 2.14
Packit Service fb6fa5
 **/
Packit Service fb6fa5
GdkAtom
Packit Service fb6fa5
gtk_selection_data_get_target (GtkSelectionData *selection_data)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_val_if_fail (selection_data != NULL, 0);
Packit Service fb6fa5
Packit Service fb6fa5
  return selection_data->target;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_selection_data_get_data_type:
Packit Service fb6fa5
 * @selection_data: a pointer to a #GtkSelectionData structure.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Retrieves the data type of the selection.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Returns: (transfer none): the data type of the selection.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Since: 2.14
Packit Service fb6fa5
 **/
Packit Service fb6fa5
GdkAtom
Packit Service fb6fa5
gtk_selection_data_get_data_type (GtkSelectionData *selection_data)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_val_if_fail (selection_data != NULL, 0);
Packit Service fb6fa5
Packit Service fb6fa5
  return selection_data->type;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_selection_data_get_format:
Packit Service fb6fa5
 * @selection_data: a pointer to a #GtkSelectionData structure.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Retrieves the format of the selection.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Returns: the format of the selection.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Since: 2.14
Packit Service fb6fa5
 **/
Packit Service fb6fa5
gint
Packit Service fb6fa5
gtk_selection_data_get_format (GtkSelectionData *selection_data)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_val_if_fail (selection_data != NULL, 0);
Packit Service fb6fa5
Packit Service fb6fa5
  return selection_data->format;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_selection_data_get_data:
Packit Service fb6fa5
 * @selection_data: a pointer to a #GtkSelectionData structure.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Retrieves the raw data of the selection.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Returns: the raw data of the selection.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Since: 2.14
Packit Service fb6fa5
 **/
Packit Service fb6fa5
const guchar*
Packit Service fb6fa5
gtk_selection_data_get_data (GtkSelectionData *selection_data)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_val_if_fail (selection_data != NULL, NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  return selection_data->data;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_selection_data_get_length:
Packit Service fb6fa5
 * @selection_data: a pointer to a #GtkSelectionData structure.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Retrieves the length of the raw data of the selection.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Returns: the length of the data of the selection.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Since: 2.14
Packit Service fb6fa5
 */
Packit Service fb6fa5
gint
Packit Service fb6fa5
gtk_selection_data_get_length (GtkSelectionData *selection_data)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_val_if_fail (selection_data != NULL, -1);
Packit Service fb6fa5
Packit Service fb6fa5
  return selection_data->length;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_selection_data_get_display:
Packit Service fb6fa5
 * @selection_data: a pointer to a #GtkSelectionData structure.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Retrieves the display of the selection.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Returns: (transfer none): the display of the selection.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Since: 2.14
Packit Service fb6fa5
 **/
Packit Service fb6fa5
GdkDisplay *
Packit Service fb6fa5
gtk_selection_data_get_display (GtkSelectionData *selection_data)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_val_if_fail (selection_data != NULL, NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  return selection_data->display;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_selection_data_set:
Packit Service fb6fa5
 * @selection_data: a pointer to a #GtkSelectionData structure.
Packit Service fb6fa5
 * @type: the type of selection data
Packit Service fb6fa5
 * @format: format (number of bits in a unit)
Packit Service fb6fa5
 * @data: (array length=length): pointer to the data (will be copied)
Packit Service fb6fa5
 * @length: length of the data
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Stores new data into a #GtkSelectionData object. Should
Packit Service fb6fa5
 * <emphasis>only</emphasis> be called from a selection handler callback.
Packit Service fb6fa5
 * Zero-terminates the stored data.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
void 
Packit Service fb6fa5
gtk_selection_data_set (GtkSelectionData *selection_data,
Packit Service fb6fa5
			GdkAtom		  type,
Packit Service fb6fa5
			gint		  format,
Packit Service fb6fa5
			const guchar	 *data,
Packit Service fb6fa5
			gint		  length)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_if_fail (selection_data != NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  g_free (selection_data->data);
Packit Service fb6fa5
  
Packit Service fb6fa5
  selection_data->type = type;
Packit Service fb6fa5
  selection_data->format = format;
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (data)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      selection_data->data = g_new (guchar, length+1);
Packit Service fb6fa5
      memcpy (selection_data->data, data, length);
Packit Service fb6fa5
      selection_data->data[length] = 0;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    {
Packit Service fb6fa5
      g_return_if_fail (length <= 0);
Packit Service fb6fa5
      
Packit Service fb6fa5
      if (length < 0)
Packit Service fb6fa5
	selection_data->data = NULL;
Packit Service fb6fa5
      else
Packit Service fb6fa5
	selection_data->data = (guchar *) g_strdup ("");
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  selection_data->length = length;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static gboolean
Packit Service fb6fa5
selection_set_string (GtkSelectionData *selection_data,
Packit Service fb6fa5
		      const gchar      *str,
Packit Service fb6fa5
		      gint              len)
Packit Service fb6fa5
{
Packit Service fb6fa5
  gchar *tmp = g_strndup (str, len);
Packit Service fb6fa5
  gchar *latin1 = gdk_utf8_to_string_target (tmp);
Packit Service fb6fa5
  g_free (tmp);
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (latin1)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      gtk_selection_data_set (selection_data,
Packit Service fb6fa5
			      GDK_SELECTION_TYPE_STRING,
Packit Service fb6fa5
			      8, (guchar *) latin1, strlen (latin1));
Packit Service fb6fa5
      g_free (latin1);
Packit Service fb6fa5
      
Packit Service fb6fa5
      return TRUE;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    return FALSE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static gboolean
Packit Service fb6fa5
selection_set_compound_text (GtkSelectionData *selection_data,
Packit Service fb6fa5
			     const gchar      *str,
Packit Service fb6fa5
			     gint              len)
Packit Service fb6fa5
{
Packit Service fb6fa5
  gchar *tmp;
Packit Service fb6fa5
  guchar *text;
Packit Service fb6fa5
  GdkAtom encoding;
Packit Service fb6fa5
  gint format;
Packit Service fb6fa5
  gint new_length;
Packit Service fb6fa5
  gboolean result = FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
#ifdef GDK_WINDOWING_X11
Packit Service fb6fa5
  tmp = g_strndup (str, len);
Packit Service fb6fa5
  if (gdk_x11_display_utf8_to_compound_text (selection_data->display, tmp,
Packit Service fb6fa5
                                             &encoding, &format, &text, &new_length))
Packit Service fb6fa5
    {
Packit Service fb6fa5
      gtk_selection_data_set (selection_data, encoding, format, text, new_length);
Packit Service fb6fa5
      gdk_x11_free_compound_text (text);
Packit Service fb6fa5
Packit Service fb6fa5
      result = TRUE;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  g_free (tmp);
Packit Service fb6fa5
#elif defined(GDK_WINDOWING_WIN32) || defined(GDK_WINDOWING_QUARTZ)
Packit Service fb6fa5
  result = FALSE; /* not needed on Win32 or Quartz */
Packit Service fb6fa5
#else
Packit Service fb6fa5
  g_warning ("%s is not implemented", G_STRFUNC);
Packit Service fb6fa5
  result = FALSE;
Packit Service fb6fa5
#endif
Packit Service fb6fa5
Packit Service fb6fa5
  return result;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/* Normalize \r and \n into \r\n
Packit Service fb6fa5
 */
Packit Service fb6fa5
static gchar *
Packit Service fb6fa5
normalize_to_crlf (const gchar *str, 
Packit Service fb6fa5
		   gint         len)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GString *result = g_string_sized_new (len);
Packit Service fb6fa5
  const gchar *p = str;
Packit Service fb6fa5
  const gchar *end = str + len;
Packit Service fb6fa5
Packit Service fb6fa5
  while (p < end)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (*p == '\n')
Packit Service fb6fa5
	g_string_append_c (result, '\r');
Packit Service fb6fa5
Packit Service fb6fa5
      if (*p == '\r')
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  g_string_append_c (result, *p);
Packit Service fb6fa5
	  p++;
Packit Service fb6fa5
	  if (p == end || *p != '\n')
Packit Service fb6fa5
	    g_string_append_c (result, '\n');
Packit Service fb6fa5
	  if (p == end)
Packit Service fb6fa5
	    break;
Packit Service fb6fa5
	}
Packit Service fb6fa5
Packit Service fb6fa5
      g_string_append_c (result, *p);
Packit Service fb6fa5
      p++;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  return g_string_free (result, FALSE);  
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/* Normalize \r and \r\n into \n
Packit Service fb6fa5
 */
Packit Service fb6fa5
static gchar *
Packit Service fb6fa5
normalize_to_lf (gchar *str, 
Packit Service fb6fa5
		 gint   len)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GString *result = g_string_sized_new (len);
Packit Service fb6fa5
  const gchar *p = str;
Packit Service fb6fa5
Packit Service fb6fa5
  while (1)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (*p == '\r')
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  p++;
Packit Service fb6fa5
	  if (*p != '\n')
Packit Service fb6fa5
	    g_string_append_c (result, '\n');
Packit Service fb6fa5
	}
Packit Service fb6fa5
Packit Service fb6fa5
      if (*p == '\0')
Packit Service fb6fa5
	break;
Packit Service fb6fa5
Packit Service fb6fa5
      g_string_append_c (result, *p);
Packit Service fb6fa5
      p++;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  return g_string_free (result, FALSE);  
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static gboolean
Packit Service fb6fa5
selection_set_text_plain (GtkSelectionData *selection_data,
Packit Service fb6fa5
			  const gchar      *str,
Packit Service fb6fa5
			  gint              len)
Packit Service fb6fa5
{
Packit Service fb6fa5
  const gchar *charset = NULL;
Packit Service fb6fa5
  gchar *result;
Packit Service fb6fa5
  GError *error = NULL;
Packit Service fb6fa5
Packit Service fb6fa5
  result = normalize_to_crlf (str, len);
Packit Service fb6fa5
  if (selection_data->target == text_plain_atom)
Packit Service fb6fa5
    charset = "ASCII";
Packit Service fb6fa5
  else if (selection_data->target == text_plain_locale_atom)
Packit Service fb6fa5
    g_get_charset (&charset);
Packit Service fb6fa5
Packit Service fb6fa5
  if (charset)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      gchar *tmp = result;
Packit Service fb6fa5
      result = g_convert_with_fallback (tmp, -1, 
Packit Service fb6fa5
					charset, "UTF-8", 
Packit Service fb6fa5
					NULL, NULL, NULL, &error);
Packit Service fb6fa5
      g_free (tmp);
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  if (!result)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      g_warning ("Error converting from %s to %s: %s",
Packit Service fb6fa5
		 "UTF-8", charset, error->message);
Packit Service fb6fa5
      g_error_free (error);
Packit Service fb6fa5
      
Packit Service fb6fa5
      return FALSE;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  gtk_selection_data_set (selection_data,
Packit Service fb6fa5
			  selection_data->target, 
Packit Service fb6fa5
			  8, (guchar *) result, strlen (result));
Packit Service fb6fa5
  g_free (result);
Packit Service fb6fa5
  
Packit Service fb6fa5
  return TRUE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static guchar *
Packit Service fb6fa5
selection_get_text_plain (GtkSelectionData *selection_data)
Packit Service fb6fa5
{
Packit Service fb6fa5
  const gchar *charset = NULL;
Packit Service fb6fa5
  gchar *str, *result;
Packit Service fb6fa5
  gsize len;
Packit Service fb6fa5
  GError *error = NULL;
Packit Service fb6fa5
Packit Service fb6fa5
  str = g_strdup ((const gchar *) selection_data->data);
Packit Service fb6fa5
  len = selection_data->length;
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (selection_data->type == text_plain_atom)
Packit Service fb6fa5
    charset = "ISO-8859-1";
Packit Service fb6fa5
  else if (selection_data->type == text_plain_locale_atom)
Packit Service fb6fa5
    g_get_charset (&charset);
Packit Service fb6fa5
Packit Service fb6fa5
  if (charset)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      gchar *tmp = str;
Packit Service fb6fa5
      str = g_convert_with_fallback (tmp, len, 
Packit Service fb6fa5
				     "UTF-8", charset,
Packit Service fb6fa5
				     NULL, NULL, &len, &error);
Packit Service fb6fa5
      g_free (tmp);
Packit Service fb6fa5
Packit Service fb6fa5
      if (!str)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  g_warning ("Error converting from %s to %s: %s",
Packit Service fb6fa5
		     charset, "UTF-8", error->message);
Packit Service fb6fa5
	  g_error_free (error);
Packit Service fb6fa5
Packit Service fb6fa5
	  return NULL;
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else if (!g_utf8_validate (str, -1, NULL))
Packit Service fb6fa5
    {
Packit Service fb6fa5
      g_warning ("Error converting from %s to %s: %s",
Packit Service fb6fa5
		 "text/plain;charset=utf-8", "UTF-8", "invalid UTF-8");
Packit Service fb6fa5
      g_free (str);
Packit Service fb6fa5
Packit Service fb6fa5
      return NULL;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  result = normalize_to_lf (str, len);
Packit Service fb6fa5
  g_free (str);
Packit Service fb6fa5
Packit Service fb6fa5
  return (guchar *) result;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_selection_data_set_text:
Packit Service fb6fa5
 * @selection_data: a #GtkSelectionData
Packit Service fb6fa5
 * @str: a UTF-8 string
Packit Service fb6fa5
 * @len: the length of @str, or -1 if @str is nul-terminated.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Sets the contents of the selection from a UTF-8 encoded string.
Packit Service fb6fa5
 * The string is converted to the form determined by
Packit Service fb6fa5
 * @selection_data->target.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Return value: %TRUE if the selection was successfully set,
Packit Service fb6fa5
 *   otherwise %FALSE.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
gboolean
Packit Service fb6fa5
gtk_selection_data_set_text (GtkSelectionData     *selection_data,
Packit Service fb6fa5
			     const gchar          *str,
Packit Service fb6fa5
			     gint                  len)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_val_if_fail (selection_data != NULL, FALSE);
Packit Service fb6fa5
Packit Service fb6fa5
  if (len < 0)
Packit Service fb6fa5
    len = strlen (str);
Packit Service fb6fa5
  
Packit Service fb6fa5
  init_atoms ();
Packit Service fb6fa5
Packit Service fb6fa5
  if (selection_data->target == utf8_atom)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      gtk_selection_data_set (selection_data,
Packit Service fb6fa5
			      utf8_atom,
Packit Service fb6fa5
			      8, (guchar *)str, len);
Packit Service fb6fa5
      return TRUE;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else if (selection_data->target == GDK_TARGET_STRING)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      return selection_set_string (selection_data, str, len);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else if (selection_data->target == ctext_atom ||
Packit Service fb6fa5
	   selection_data->target == text_atom)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (selection_set_compound_text (selection_data, str, len))
Packit Service fb6fa5
	return TRUE;
Packit Service fb6fa5
      else if (selection_data->target == text_atom)
Packit Service fb6fa5
	return selection_set_string (selection_data, str, len);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else if (selection_data->target == text_plain_atom ||
Packit Service fb6fa5
	   selection_data->target == text_plain_utf8_atom ||
Packit Service fb6fa5
	   selection_data->target == text_plain_locale_atom)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      return selection_set_text_plain (selection_data, str, len);
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  return FALSE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_selection_data_get_text:
Packit Service fb6fa5
 * @selection_data: a #GtkSelectionData
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Gets the contents of the selection data as a UTF-8 string.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Return value: if the selection data contained a recognized
Packit Service fb6fa5
 *   text type and it could be converted to UTF-8, a newly allocated
Packit Service fb6fa5
 *   string containing the converted text, otherwise %NULL.
Packit Service fb6fa5
 *   If the result is non-%NULL it must be freed with g_free().
Packit Service fb6fa5
 **/
Packit Service fb6fa5
guchar *
Packit Service fb6fa5
gtk_selection_data_get_text (GtkSelectionData *selection_data)
Packit Service fb6fa5
{
Packit Service fb6fa5
  guchar *result = NULL;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (selection_data != NULL, NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  init_atoms ();
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (selection_data->length >= 0 &&
Packit Service fb6fa5
      (selection_data->type == GDK_TARGET_STRING ||
Packit Service fb6fa5
       selection_data->type == ctext_atom ||
Packit Service fb6fa5
       selection_data->type == utf8_atom))
Packit Service fb6fa5
    {
Packit Service fb6fa5
      gchar **list;
Packit Service fb6fa5
      gint i;
Packit Service fb6fa5
      gint count = gdk_text_property_to_utf8_list_for_display (selection_data->display,
Packit Service fb6fa5
      							       selection_data->type,
Packit Service fb6fa5
						   	       selection_data->format, 
Packit Service fb6fa5
						               selection_data->data,
Packit Service fb6fa5
						               selection_data->length,
Packit Service fb6fa5
						               &list);
Packit Service fb6fa5
      if (count > 0)
Packit Service fb6fa5
	result = (guchar *) list[0];
Packit Service fb6fa5
Packit Service fb6fa5
      for (i = 1; i < count; i++)
Packit Service fb6fa5
	g_free (list[i]);
Packit Service fb6fa5
      g_free (list);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else if (selection_data->length >= 0 &&
Packit Service fb6fa5
	   (selection_data->type == text_plain_atom ||
Packit Service fb6fa5
	    selection_data->type == text_plain_utf8_atom ||
Packit Service fb6fa5
	    selection_data->type == text_plain_locale_atom))
Packit Service fb6fa5
    {
Packit Service fb6fa5
      result = selection_get_text_plain (selection_data);
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  return result;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_selection_data_set_pixbuf:
Packit Service fb6fa5
 * @selection_data: a #GtkSelectionData
Packit Service fb6fa5
 * @pixbuf: a #GdkPixbuf
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Sets the contents of the selection from a #GdkPixbuf
Packit Service fb6fa5
 * The pixbuf is converted to the form determined by
Packit Service fb6fa5
 * @selection_data->target.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Return value: %TRUE if the selection was successfully set,
Packit Service fb6fa5
 *   otherwise %FALSE.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Since: 2.6
Packit Service fb6fa5
 **/
Packit Service fb6fa5
gboolean
Packit Service fb6fa5
gtk_selection_data_set_pixbuf (GtkSelectionData *selection_data,
Packit Service fb6fa5
			       GdkPixbuf        *pixbuf)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GSList *formats, *f;
Packit Service fb6fa5
  gchar **mimes, **m;
Packit Service fb6fa5
  GdkAtom atom;
Packit Service fb6fa5
  gboolean result;
Packit Service fb6fa5
  gchar *str, *type;
Packit Service fb6fa5
  gsize len;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (selection_data != NULL, FALSE);
Packit Service fb6fa5
  g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), FALSE);
Packit Service fb6fa5
Packit Service fb6fa5
  formats = gdk_pixbuf_get_formats ();
Packit Service fb6fa5
Packit Service fb6fa5
  for (f = formats; f; f = f->next)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      GdkPixbufFormat *fmt = f->data;
Packit Service fb6fa5
Packit Service fb6fa5
      mimes = gdk_pixbuf_format_get_mime_types (fmt);
Packit Service fb6fa5
      for (m = mimes; *m; m++)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  atom = gdk_atom_intern (*m, FALSE);
Packit Service fb6fa5
	  if (selection_data->target == atom)
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      str = NULL;
Packit Service fb6fa5
	      type = gdk_pixbuf_format_get_name (fmt);
Packit Service fb6fa5
	      result = gdk_pixbuf_save_to_buffer (pixbuf, &str, &len,
Packit Service fb6fa5
						  type, NULL,
Packit Service fb6fa5
                                                  ((strcmp (type, "png") == 0) ?
Packit Service fb6fa5
                                                   "compression" : NULL), "2",
Packit Service fb6fa5
                                                  NULL);
Packit Service fb6fa5
	      if (result)
Packit Service fb6fa5
		gtk_selection_data_set (selection_data,
Packit Service fb6fa5
					atom, 8, (guchar *)str, len);
Packit Service fb6fa5
	      g_free (type);
Packit Service fb6fa5
	      g_free (str);
Packit Service fb6fa5
	      g_strfreev (mimes);
Packit Service fb6fa5
	      g_slist_free (formats);
Packit Service fb6fa5
Packit Service fb6fa5
	      return result;
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	}
Packit Service fb6fa5
Packit Service fb6fa5
      g_strfreev (mimes);
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  g_slist_free (formats);
Packit Service fb6fa5
 
Packit Service fb6fa5
  return FALSE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_selection_data_get_pixbuf:
Packit Service fb6fa5
 * @selection_data: a #GtkSelectionData
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Gets the contents of the selection data as a #GdkPixbuf.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Return value: (transfer full): if the selection data contained a recognized
Packit Service fb6fa5
 *   image type and it could be converted to a #GdkPixbuf, a 
Packit Service fb6fa5
 *   newly allocated pixbuf is returned, otherwise %NULL.
Packit Service fb6fa5
 *   If the result is non-%NULL it must be freed with g_object_unref().
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Since: 2.6
Packit Service fb6fa5
 **/
Packit Service fb6fa5
GdkPixbuf *
Packit Service fb6fa5
gtk_selection_data_get_pixbuf (GtkSelectionData *selection_data)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkPixbufLoader *loader;
Packit Service fb6fa5
  GdkPixbuf *result = NULL;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (selection_data != NULL, NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  if (selection_data->length > 0)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      loader = gdk_pixbuf_loader_new ();
Packit Service fb6fa5
      
Packit Service fb6fa5
      gdk_pixbuf_loader_write (loader, 
Packit Service fb6fa5
			       selection_data->data,
Packit Service fb6fa5
			       selection_data->length,
Packit Service fb6fa5
			       NULL);
Packit Service fb6fa5
      gdk_pixbuf_loader_close (loader, NULL);
Packit Service fb6fa5
      result = gdk_pixbuf_loader_get_pixbuf (loader);
Packit Service fb6fa5
      
Packit Service fb6fa5
      if (result)
Packit Service fb6fa5
	g_object_ref (result);
Packit Service fb6fa5
      
Packit Service fb6fa5
      g_object_unref (loader);
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  return result;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_selection_data_set_uris:
Packit Service fb6fa5
 * @selection_data: a #GtkSelectionData
Packit Service fb6fa5
 * @uris: (array zero-terminated=1): a %NULL-terminated array of
Packit Service fb6fa5
 *     strings holding URIs
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Sets the contents of the selection from a list of URIs.
Packit Service fb6fa5
 * The string is converted to the form determined by
Packit Service fb6fa5
 * @selection_data->target.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Return value: %TRUE if the selection was successfully set,
Packit Service fb6fa5
 *   otherwise %FALSE.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Since: 2.6
Packit Service fb6fa5
 **/
Packit Service fb6fa5
gboolean
Packit Service fb6fa5
gtk_selection_data_set_uris (GtkSelectionData  *selection_data,
Packit Service fb6fa5
			     gchar            **uris)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_val_if_fail (selection_data != NULL, FALSE);
Packit Service fb6fa5
  g_return_val_if_fail (uris != NULL, FALSE);
Packit Service fb6fa5
Packit Service fb6fa5
  init_atoms ();
Packit Service fb6fa5
Packit Service fb6fa5
  if (selection_data->target == text_uri_list_atom)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      GString *list;
Packit Service fb6fa5
      gint i;
Packit Service fb6fa5
      gchar *result;
Packit Service fb6fa5
      gsize length;
Packit Service fb6fa5
      
Packit Service fb6fa5
      list = g_string_new (NULL);
Packit Service fb6fa5
      for (i = 0; uris[i]; i++)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  g_string_append (list, uris[i]);
Packit Service fb6fa5
	  g_string_append (list, "\r\n");
Packit Service fb6fa5
	}
Packit Service fb6fa5
Packit Service fb6fa5
      result = g_convert (list->str, list->len,
Packit Service fb6fa5
			  "ASCII", "UTF-8", 
Packit Service fb6fa5
			  NULL, &length, NULL);
Packit Service fb6fa5
      g_string_free (list, TRUE);
Packit Service fb6fa5
      
Packit Service fb6fa5
      if (result)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  gtk_selection_data_set (selection_data,
Packit Service fb6fa5
				  text_uri_list_atom,
Packit Service fb6fa5
				  8, (guchar *)result, length);
Packit Service fb6fa5
	  
Packit Service fb6fa5
	  g_free (result);
Packit Service fb6fa5
Packit Service fb6fa5
	  return TRUE;
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  return FALSE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_selection_data_get_uris:
Packit Service fb6fa5
 * @selection_data: a #GtkSelectionData
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Gets the contents of the selection data as array of URIs.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Return value:  (array zero-terminated=1) (element-type utf8) (transfer full): if
Packit Service fb6fa5
 *   the selection data contains a list of
Packit Service fb6fa5
 *   URIs, a newly allocated %NULL-terminated string array
Packit Service fb6fa5
 *   containing the URIs, otherwise %NULL. If the result is
Packit Service fb6fa5
 *   non-%NULL it must be freed with g_strfreev().
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Since: 2.6
Packit Service fb6fa5
 **/
Packit Service fb6fa5
gchar **
Packit Service fb6fa5
gtk_selection_data_get_uris (GtkSelectionData *selection_data)
Packit Service fb6fa5
{
Packit Service fb6fa5
  gchar **result = NULL;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (selection_data != NULL, NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  init_atoms ();
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (selection_data->length >= 0 &&
Packit Service fb6fa5
      selection_data->type == text_uri_list_atom)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      gchar **list;
Packit Service fb6fa5
      gint count = gdk_text_property_to_utf8_list_for_display (selection_data->display,
Packit Service fb6fa5
      							       utf8_atom,
Packit Service fb6fa5
						   	       selection_data->format, 
Packit Service fb6fa5
						               selection_data->data,
Packit Service fb6fa5
						               selection_data->length,
Packit Service fb6fa5
						               &list);
Packit Service fb6fa5
      if (count > 0)
Packit Service fb6fa5
	result = g_uri_list_extract_uris (list[0]);
Packit Service fb6fa5
      
Packit Service fb6fa5
      g_strfreev (list);
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  return result;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_selection_data_get_targets:
Packit Service fb6fa5
 * @selection_data: a #GtkSelectionData object
Packit Service fb6fa5
 * @targets: (out) (array length=n_atoms) (transfer container):
Packit Service fb6fa5
 *           location to store an array of targets. The result
Packit Service fb6fa5
 *           stored here must be freed with g_free().
Packit Service fb6fa5
 * @n_atoms: location to store number of items in @targets.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Gets the contents of @selection_data as an array of targets.
Packit Service fb6fa5
 * This can be used to interpret the results of getting
Packit Service fb6fa5
 * the standard TARGETS target that is always supplied for
Packit Service fb6fa5
 * any selection.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Return value: %TRUE if @selection_data contains a valid
Packit Service fb6fa5
 *    array of targets, otherwise %FALSE.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
gboolean
Packit Service fb6fa5
gtk_selection_data_get_targets (GtkSelectionData  *selection_data,
Packit Service fb6fa5
				GdkAtom          **targets,
Packit Service fb6fa5
				gint              *n_atoms)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_val_if_fail (selection_data != NULL, FALSE);
Packit Service fb6fa5
Packit Service fb6fa5
  if (selection_data->length >= 0 &&
Packit Service fb6fa5
      selection_data->format == 32 &&
Packit Service fb6fa5
      selection_data->type == GDK_SELECTION_TYPE_ATOM)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (targets)
Packit Service fb6fa5
	*targets = g_memdup (selection_data->data, selection_data->length);
Packit Service fb6fa5
      if (n_atoms)
Packit Service fb6fa5
	*n_atoms = selection_data->length / sizeof (GdkAtom);
Packit Service fb6fa5
Packit Service fb6fa5
      return TRUE;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (targets)
Packit Service fb6fa5
	*targets = NULL;
Packit Service fb6fa5
      if (n_atoms)
Packit Service fb6fa5
	*n_atoms = -1;
Packit Service fb6fa5
Packit Service fb6fa5
      return FALSE;
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_targets_include_text:
Packit Service fb6fa5
 * @targets: (array length=n_targets): an array of #GdkAtoms
Packit Service fb6fa5
 * @n_targets: the length of @targets
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Determines if any of the targets in @targets can be used to
Packit Service fb6fa5
 * provide text.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Return value: %TRUE if @targets include a suitable target for text,
Packit Service fb6fa5
 *   otherwise %FALSE.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Since: 2.10
Packit Service fb6fa5
 **/
Packit Service fb6fa5
gboolean 
Packit Service fb6fa5
gtk_targets_include_text (GdkAtom *targets,
Packit Service fb6fa5
                          gint     n_targets)
Packit Service fb6fa5
{
Packit Service fb6fa5
  gint i;
Packit Service fb6fa5
  gboolean result = FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (targets != NULL || n_targets == 0, FALSE);
Packit Service fb6fa5
Packit Service fb6fa5
  /* Keep in sync with gtk_target_list_add_text_targets()
Packit Service fb6fa5
   */
Packit Service fb6fa5
 
Packit Service fb6fa5
  init_atoms ();
Packit Service fb6fa5
 
Packit Service fb6fa5
  for (i = 0; i < n_targets; i++)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (targets[i] == utf8_atom ||
Packit Service fb6fa5
	  targets[i] == text_atom ||
Packit Service fb6fa5
	  targets[i] == GDK_TARGET_STRING ||
Packit Service fb6fa5
	  targets[i] == ctext_atom ||
Packit Service fb6fa5
	  targets[i] == text_plain_atom ||
Packit Service fb6fa5
	  targets[i] == text_plain_utf8_atom ||
Packit Service fb6fa5
	  targets[i] == text_plain_locale_atom)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  result = TRUE;
Packit Service fb6fa5
	  break;
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  return result;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_targets_include_rich_text:
Packit Service fb6fa5
 * @targets: (array length=n_targets): an array of #GdkAtoms
Packit Service fb6fa5
 * @n_targets: the length of @targets
Packit Service fb6fa5
 * @buffer: a #GtkTextBuffer
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Determines if any of the targets in @targets can be used to
Packit Service fb6fa5
 * provide rich text.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Return value: %TRUE if @targets include a suitable target for rich text,
Packit Service fb6fa5
 *               otherwise %FALSE.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Since: 2.10
Packit Service fb6fa5
 **/
Packit Service fb6fa5
gboolean
Packit Service fb6fa5
gtk_targets_include_rich_text (GdkAtom       *targets,
Packit Service fb6fa5
                               gint           n_targets,
Packit Service fb6fa5
                               GtkTextBuffer *buffer)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkAtom *rich_targets;
Packit Service fb6fa5
  gint n_rich_targets;
Packit Service fb6fa5
  gint i, j;
Packit Service fb6fa5
  gboolean result = FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (targets != NULL || n_targets == 0, FALSE);
Packit Service fb6fa5
  g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
Packit Service fb6fa5
Packit Service fb6fa5
  init_atoms ();
Packit Service fb6fa5
Packit Service fb6fa5
  rich_targets = gtk_text_buffer_get_deserialize_formats (buffer,
Packit Service fb6fa5
                                                          &n_rich_targets);
Packit Service fb6fa5
Packit Service fb6fa5
  for (i = 0; i < n_targets; i++)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      for (j = 0; j < n_rich_targets; j++)
Packit Service fb6fa5
        {
Packit Service fb6fa5
          if (targets[i] == rich_targets[j])
Packit Service fb6fa5
            {
Packit Service fb6fa5
              result = TRUE;
Packit Service fb6fa5
              goto done;
Packit Service fb6fa5
            }
Packit Service fb6fa5
        }
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
 done:
Packit Service fb6fa5
  g_free (rich_targets);
Packit Service fb6fa5
Packit Service fb6fa5
  return result;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_selection_data_targets_include_text:
Packit Service fb6fa5
 * @selection_data: a #GtkSelectionData object
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Given a #GtkSelectionData object holding a list of targets,
Packit Service fb6fa5
 * determines if any of the targets in @targets can be used to
Packit Service fb6fa5
 * provide text.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Return value: %TRUE if @selection_data holds a list of targets,
Packit Service fb6fa5
 *   and a suitable target for text is included, otherwise %FALSE.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
gboolean
Packit Service fb6fa5
gtk_selection_data_targets_include_text (GtkSelectionData *selection_data)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkAtom *targets;
Packit Service fb6fa5
  gint n_targets;
Packit Service fb6fa5
  gboolean result = FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (selection_data != NULL, FALSE);
Packit Service fb6fa5
Packit Service fb6fa5
  init_atoms ();
Packit Service fb6fa5
Packit Service fb6fa5
  if (gtk_selection_data_get_targets (selection_data, &targets, &n_targets))
Packit Service fb6fa5
    {
Packit Service fb6fa5
      result = gtk_targets_include_text (targets, n_targets);
Packit Service fb6fa5
      g_free (targets);
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  return result;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_selection_data_targets_include_rich_text:
Packit Service fb6fa5
 * @selection_data: a #GtkSelectionData object
Packit Service fb6fa5
 * @buffer: a #GtkTextBuffer
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Given a #GtkSelectionData object holding a list of targets,
Packit Service fb6fa5
 * determines if any of the targets in @targets can be used to
Packit Service fb6fa5
 * provide rich text.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Return value: %TRUE if @selection_data holds a list of targets,
Packit Service fb6fa5
 *               and a suitable target for rich text is included,
Packit Service fb6fa5
 *               otherwise %FALSE.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Since: 2.10
Packit Service fb6fa5
 **/
Packit Service fb6fa5
gboolean
Packit Service fb6fa5
gtk_selection_data_targets_include_rich_text (GtkSelectionData *selection_data,
Packit Service fb6fa5
                                              GtkTextBuffer    *buffer)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkAtom *targets;
Packit Service fb6fa5
  gint n_targets;
Packit Service fb6fa5
  gboolean result = FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (selection_data != NULL, FALSE);
Packit Service fb6fa5
  g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
Packit Service fb6fa5
Packit Service fb6fa5
  init_atoms ();
Packit Service fb6fa5
Packit Service fb6fa5
  if (gtk_selection_data_get_targets (selection_data, &targets, &n_targets))
Packit Service fb6fa5
    {
Packit Service fb6fa5
      result = gtk_targets_include_rich_text (targets, n_targets, buffer);
Packit Service fb6fa5
      g_free (targets);
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  return result;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_targets_include_image:
Packit Service fb6fa5
 * @targets: (array length=n_targets): an array of #GdkAtoms
Packit Service fb6fa5
 * @n_targets: the length of @targets
Packit Service fb6fa5
 * @writable: whether to accept only targets for which GTK+ knows
Packit Service fb6fa5
 *   how to convert a pixbuf into the format
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Determines if any of the targets in @targets can be used to
Packit Service fb6fa5
 * provide a #GdkPixbuf.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Return value: %TRUE if @targets include a suitable target for images,
Packit Service fb6fa5
 *   otherwise %FALSE.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Since: 2.10
Packit Service fb6fa5
 **/
Packit Service fb6fa5
gboolean 
Packit Service fb6fa5
gtk_targets_include_image (GdkAtom *targets,
Packit Service fb6fa5
			   gint     n_targets,
Packit Service fb6fa5
			   gboolean writable)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkTargetList *list;
Packit Service fb6fa5
  GList *l;
Packit Service fb6fa5
  gint i;
Packit Service fb6fa5
  gboolean result = FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (targets != NULL || n_targets == 0, FALSE);
Packit Service fb6fa5
Packit Service fb6fa5
  list = gtk_target_list_new (NULL, 0);
Packit Service fb6fa5
  gtk_target_list_add_image_targets (list, 0, writable);
Packit Service fb6fa5
  for (i = 0; i < n_targets && !result; i++)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      for (l = list->list; l; l = l->next)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  GtkTargetPair *pair = (GtkTargetPair *)l->data;
Packit Service fb6fa5
	  if (pair->target == targets[i])
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      result = TRUE;
Packit Service fb6fa5
	      break;
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
  gtk_target_list_unref (list);
Packit Service fb6fa5
Packit Service fb6fa5
  return result;
Packit Service fb6fa5
}
Packit Service fb6fa5
				    
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_selection_data_targets_include_image:
Packit Service fb6fa5
 * @selection_data: a #GtkSelectionData object
Packit Service fb6fa5
 * @writable: whether to accept only targets for which GTK+ knows
Packit Service fb6fa5
 *   how to convert a pixbuf into the format
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Given a #GtkSelectionData object holding a list of targets,
Packit Service fb6fa5
 * determines if any of the targets in @targets can be used to
Packit Service fb6fa5
 * provide a #GdkPixbuf.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Return value: %TRUE if @selection_data holds a list of targets,
Packit Service fb6fa5
 *   and a suitable target for images is included, otherwise %FALSE.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Since: 2.6
Packit Service fb6fa5
 **/
Packit Service fb6fa5
gboolean 
Packit Service fb6fa5
gtk_selection_data_targets_include_image (GtkSelectionData *selection_data,
Packit Service fb6fa5
					  gboolean          writable)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkAtom *targets;
Packit Service fb6fa5
  gint n_targets;
Packit Service fb6fa5
  gboolean result = FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (selection_data != NULL, FALSE);
Packit Service fb6fa5
Packit Service fb6fa5
  init_atoms ();
Packit Service fb6fa5
Packit Service fb6fa5
  if (gtk_selection_data_get_targets (selection_data, &targets, &n_targets))
Packit Service fb6fa5
    {
Packit Service fb6fa5
      result = gtk_targets_include_image (targets, n_targets, writable);
Packit Service fb6fa5
      g_free (targets);
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  return result;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_targets_include_uri:
Packit Service fb6fa5
 * @targets: (array length=n_targets): an array of #GdkAtoms
Packit Service fb6fa5
 * @n_targets: the length of @targets
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Determines if any of the targets in @targets can be used to
Packit Service fb6fa5
 * provide an uri list.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Return value: %TRUE if @targets include a suitable target for uri lists,
Packit Service fb6fa5
 *   otherwise %FALSE.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Since: 2.10
Packit Service fb6fa5
 **/
Packit Service fb6fa5
gboolean 
Packit Service fb6fa5
gtk_targets_include_uri (GdkAtom *targets,
Packit Service fb6fa5
			 gint     n_targets)
Packit Service fb6fa5
{
Packit Service fb6fa5
  gint i;
Packit Service fb6fa5
  gboolean result = FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (targets != NULL || n_targets == 0, FALSE);
Packit Service fb6fa5
Packit Service fb6fa5
  /* Keep in sync with gtk_target_list_add_uri_targets()
Packit Service fb6fa5
   */
Packit Service fb6fa5
Packit Service fb6fa5
  init_atoms ();
Packit Service fb6fa5
Packit Service fb6fa5
  for (i = 0; i < n_targets; i++)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (targets[i] == text_uri_list_atom)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  result = TRUE;
Packit Service fb6fa5
	  break;
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  return result;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_selection_data_targets_include_uri:
Packit Service fb6fa5
 * @selection_data: a #GtkSelectionData object
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Given a #GtkSelectionData object holding a list of targets,
Packit Service fb6fa5
 * determines if any of the targets in @targets can be used to
Packit Service fb6fa5
 * provide a list or URIs.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Return value: %TRUE if @selection_data holds a list of targets,
Packit Service fb6fa5
 *   and a suitable target for URI lists is included, otherwise %FALSE.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Since: 2.10
Packit Service fb6fa5
 **/
Packit Service fb6fa5
gboolean
Packit Service fb6fa5
gtk_selection_data_targets_include_uri (GtkSelectionData *selection_data)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkAtom *targets;
Packit Service fb6fa5
  gint n_targets;
Packit Service fb6fa5
  gboolean result = FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (selection_data != NULL, FALSE);
Packit Service fb6fa5
Packit Service fb6fa5
  init_atoms ();
Packit Service fb6fa5
Packit Service fb6fa5
  if (gtk_selection_data_get_targets (selection_data, &targets, &n_targets))
Packit Service fb6fa5
    {
Packit Service fb6fa5
      result = gtk_targets_include_uri (targets, n_targets);
Packit Service fb6fa5
      g_free (targets);
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  return result;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
	  
Packit Service fb6fa5
/*************************************************************
Packit Service fb6fa5
 * gtk_selection_init:
Packit Service fb6fa5
 *     Initialize local variables
Packit Service fb6fa5
 *   arguments:
Packit Service fb6fa5
 *     
Packit Service fb6fa5
 *   results:
Packit Service fb6fa5
 *************************************************************/
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gtk_selection_init (void)
Packit Service fb6fa5
{
Packit Service fb6fa5
  gtk_selection_atoms[INCR] = gdk_atom_intern_static_string ("INCR");
Packit Service fb6fa5
  gtk_selection_atoms[MULTIPLE] = gdk_atom_intern_static_string ("MULTIPLE");
Packit Service fb6fa5
  gtk_selection_atoms[TIMESTAMP] = gdk_atom_intern_static_string ("TIMESTAMP");
Packit Service fb6fa5
  gtk_selection_atoms[TARGETS] = gdk_atom_intern_static_string ("TARGETS");
Packit Service fb6fa5
  gtk_selection_atoms[SAVE_TARGETS] = gdk_atom_intern_static_string ("SAVE_TARGETS");
Packit Service fb6fa5
Packit Service fb6fa5
  initialize = FALSE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_selection_clear:
Packit Service fb6fa5
 * @widget: a #GtkWidget
Packit Service fb6fa5
 * @event: the event
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * The default handler for the #GtkWidget::selection-clear-event
Packit Service fb6fa5
 * signal. 
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Return value: %TRUE if the event was handled, otherwise false
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Since: 2.2
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Deprecated: 2.4: Instead of calling this function, chain up from
Packit Service fb6fa5
 * your selection-clear-event handler. Calling this function
Packit Service fb6fa5
 * from any other context is illegal. 
Packit Service fb6fa5
 **/
Packit Service fb6fa5
gboolean
Packit Service fb6fa5
gtk_selection_clear (GtkWidget         *widget,
Packit Service fb6fa5
		     GdkEventSelection *event)
Packit Service fb6fa5
{
Packit Service fb6fa5
  /* Note that we filter clear events in gdkselection-x11.c, so
Packit Service fb6fa5
   * that we only will get here if the clear event actually
Packit Service fb6fa5
   * represents a change that we didn't do ourself.
Packit Service fb6fa5
   */
Packit Service fb6fa5
  GList *tmp_list;
Packit Service fb6fa5
  GtkSelectionInfo *selection_info = NULL;
Packit Service fb6fa5
  
Packit Service fb6fa5
  tmp_list = current_selections;
Packit Service fb6fa5
  while (tmp_list)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      selection_info = (GtkSelectionInfo *)tmp_list->data;
Packit Service fb6fa5
      
Packit Service fb6fa5
      if ((selection_info->selection == event->selection) &&
Packit Service fb6fa5
	  (selection_info->widget == widget))
Packit Service fb6fa5
	break;
Packit Service fb6fa5
      
Packit Service fb6fa5
      tmp_list = tmp_list->next;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (tmp_list)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      current_selections = g_list_remove_link (current_selections, tmp_list);
Packit Service fb6fa5
      g_list_free (tmp_list);
Packit Service fb6fa5
      g_slice_free (GtkSelectionInfo, selection_info);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  return TRUE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
Packit Service fb6fa5
/*************************************************************
Packit Service fb6fa5
 * _gtk_selection_request:
Packit Service fb6fa5
 *     Handler for "selection_request_event" 
Packit Service fb6fa5
 *   arguments:
Packit Service fb6fa5
 *     widget:
Packit Service fb6fa5
 *     event:
Packit Service fb6fa5
 *   results:
Packit Service fb6fa5
 *************************************************************/
Packit Service fb6fa5
Packit Service fb6fa5
gboolean
Packit Service fb6fa5
_gtk_selection_request (GtkWidget *widget,
Packit Service fb6fa5
			GdkEventSelection *event)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkDisplay *display = gtk_widget_get_display (widget);
Packit Service fb6fa5
  GtkIncrInfo *info;
Packit Service fb6fa5
  GList *tmp_list;
Packit Service fb6fa5
  int i;
Packit Service fb6fa5
  gulong selection_max_size;
Packit Service fb6fa5
Packit Service fb6fa5
  if (initialize)
Packit Service fb6fa5
    gtk_selection_init ();
Packit Service fb6fa5
  
Packit Service fb6fa5
  selection_max_size = GTK_SELECTION_MAX_SIZE (display);
Packit Service fb6fa5
Packit Service fb6fa5
  /* Check if we own selection */
Packit Service fb6fa5
  
Packit Service fb6fa5
  tmp_list = current_selections;
Packit Service fb6fa5
  while (tmp_list)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      GtkSelectionInfo *selection_info = (GtkSelectionInfo *)tmp_list->data;
Packit Service fb6fa5
      
Packit Service fb6fa5
      if ((selection_info->selection == event->selection) &&
Packit Service fb6fa5
	  (selection_info->widget == widget))
Packit Service fb6fa5
	break;
Packit Service fb6fa5
      
Packit Service fb6fa5
      tmp_list = tmp_list->next;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (tmp_list == NULL)
Packit Service fb6fa5
    return FALSE;
Packit Service fb6fa5
  
Packit Service fb6fa5
  info = g_slice_new (GtkIncrInfo);
Packit Service fb6fa5
Packit Service fb6fa5
  g_object_ref (widget);
Packit Service fb6fa5
  
Packit Service fb6fa5
  info->selection = event->selection;
Packit Service fb6fa5
  info->num_incrs = 0;
Packit Service fb6fa5
Packit Service fb6fa5
  /* Create GdkWindow structure for the requestor */
Packit Service fb6fa5
#ifdef GDK_WINDOWING_X11
Packit Service fb6fa5
  info->requestor = gdk_x11_window_foreign_new_for_display (display, event->requestor);
Packit Service fb6fa5
#elif defined GDK_WINDOWING_WIN32
Packit Service fb6fa5
  info->requestor = gdk_win32_window_lookup_for_display (display, event->requestor);
Packit Service fb6fa5
  if (!info->requestor)
Packit Service fb6fa5
    info->requestor = gdk_win32_window_foreign_new_for_display (display, event->requestor);
Packit Service fb6fa5
#else
Packit Service fb6fa5
  g_warning ("%s is not implemented", G_STRFUNC);
Packit Service fb6fa5
  info->requestor = NULL;
Packit Service fb6fa5
#endif
Packit Service fb6fa5
Packit Service fb6fa5
  /* Determine conversions we need to perform */
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (event->target == gtk_selection_atoms[MULTIPLE])
Packit Service fb6fa5
    {
Packit Service fb6fa5
      GdkAtom  type;
Packit Service fb6fa5
      guchar  *mult_atoms;
Packit Service fb6fa5
      gint     format;
Packit Service fb6fa5
      gint     length;
Packit Service fb6fa5
      
Packit Service fb6fa5
      mult_atoms = NULL;
Packit Service fb6fa5
      
Packit Service fb6fa5
      gdk_error_trap_push ();
Packit Service fb6fa5
      if (!gdk_property_get (info->requestor, event->property, GDK_NONE, /* AnyPropertyType */
Packit Service fb6fa5
			     0, selection_max_size, FALSE,
Packit Service fb6fa5
			     &type, &format, &length, &mult_atoms))
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  gdk_selection_send_notify_for_display (display,
Packit Service fb6fa5
						 event->requestor, 
Packit Service fb6fa5
						 event->selection,
Packit Service fb6fa5
						 event->target, 
Packit Service fb6fa5
						 GDK_NONE, 
Packit Service fb6fa5
						 event->time);
Packit Service fb6fa5
	  g_free (mult_atoms);
Packit Service fb6fa5
	  g_slice_free (GtkIncrInfo, info);
Packit Service fb6fa5
          gdk_error_trap_pop ();
Packit Service fb6fa5
	  return TRUE;
Packit Service fb6fa5
	}
Packit Service fb6fa5
      gdk_error_trap_pop ();
Packit Service fb6fa5
Packit Service fb6fa5
      /* This is annoying; the ICCCM doesn't specify the property type
Packit Service fb6fa5
       * used for the property contents, so the autoconversion for
Packit Service fb6fa5
       * ATOM / ATOM_PAIR in GDK doesn't work properly.
Packit Service fb6fa5
       */
Packit Service fb6fa5
#ifdef GDK_WINDOWING_X11
Packit Service fb6fa5
      if (type != GDK_SELECTION_TYPE_ATOM &&
Packit Service fb6fa5
	  type != gdk_atom_intern_static_string ("ATOM_PAIR"))
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  info->num_conversions = length / (2*sizeof (glong));
Packit Service fb6fa5
	  info->conversions = g_new (GtkIncrConversion, info->num_conversions);
Packit Service fb6fa5
	  
Packit Service fb6fa5
	  for (i=0; i<info->num_conversions; i++)
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      info->conversions[i].target = gdk_x11_xatom_to_atom_for_display (display,
Packit Service fb6fa5
									       ((glong *)mult_atoms)[2*i]);
Packit Service fb6fa5
	      info->conversions[i].property = gdk_x11_xatom_to_atom_for_display (display,
Packit Service fb6fa5
										 ((glong *)mult_atoms)[2*i + 1]);
Packit Service fb6fa5
	    }
Packit Service fb6fa5
Packit Service fb6fa5
	  g_free (mult_atoms);
Packit Service fb6fa5
	}
Packit Service fb6fa5
      else
Packit Service fb6fa5
#endif
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  info->num_conversions = length / (2*sizeof (GdkAtom));
Packit Service fb6fa5
	  info->conversions = g_new (GtkIncrConversion, info->num_conversions);
Packit Service fb6fa5
	  
Packit Service fb6fa5
	  for (i=0; i<info->num_conversions; i++)
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      info->conversions[i].target = ((GdkAtom *)mult_atoms)[2*i];
Packit Service fb6fa5
	      info->conversions[i].property = ((GdkAtom *)mult_atoms)[2*i+1];
Packit Service fb6fa5
	    }
Packit Service fb6fa5
Packit Service fb6fa5
	  g_free (mult_atoms);
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else				/* only a single conversion */
Packit Service fb6fa5
    {
Packit Service fb6fa5
      info->conversions = g_new (GtkIncrConversion, 1);
Packit Service fb6fa5
      info->num_conversions = 1;
Packit Service fb6fa5
      info->conversions[0].target = event->target;
Packit Service fb6fa5
      info->conversions[0].property = event->property;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  /* Loop through conversions and determine which of these are big
Packit Service fb6fa5
     enough to require doing them via INCR */
Packit Service fb6fa5
  for (i=0; i<info->num_conversions; i++)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      GtkSelectionData data;
Packit Service fb6fa5
      glong items;
Packit Service fb6fa5
      
Packit Service fb6fa5
      data.selection = event->selection;
Packit Service fb6fa5
      data.target = info->conversions[i].target;
Packit Service fb6fa5
      data.data = NULL;
Packit Service fb6fa5
      data.length = -1;
Packit Service fb6fa5
      data.display = gtk_widget_get_display (widget);
Packit Service fb6fa5
      
Packit Service fb6fa5
#ifdef DEBUG_SELECTION
Packit Service fb6fa5
      g_message ("Selection %ld, target %ld (%s) requested by 0x%x (property = %ld)",
Packit Service fb6fa5
		 event->selection, 
Packit Service fb6fa5
		 info->conversions[i].target,
Packit Service fb6fa5
		 gdk_atom_name (info->conversions[i].target),
Packit Service fb6fa5
		 event->requestor, info->conversions[i].property);
Packit Service fb6fa5
#endif
Packit Service fb6fa5
      
Packit Service fb6fa5
      gtk_selection_invoke_handler (widget, &data, event->time);
Packit Service fb6fa5
      if (data.length < 0)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  info->conversions[i].property = GDK_NONE;
Packit Service fb6fa5
	  continue;
Packit Service fb6fa5
	}
Packit Service fb6fa5
      
Packit Service fb6fa5
      g_return_val_if_fail ((data.format >= 8) && (data.format % 8 == 0), FALSE);
Packit Service fb6fa5
      
Packit Service fb6fa5
      items = data.length / gtk_selection_bytes_per_item (data.format);
Packit Service fb6fa5
      
Packit Service fb6fa5
      if (data.length > selection_max_size)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  /* Sending via INCR */
Packit Service fb6fa5
#ifdef DEBUG_SELECTION
Packit Service fb6fa5
	  g_message ("Target larger (%d) than max. request size (%ld), sending incrementally\n",
Packit Service fb6fa5
		     data.length, selection_max_size);
Packit Service fb6fa5
#endif
Packit Service fb6fa5
	  
Packit Service fb6fa5
	  info->conversions[i].offset = 0;
Packit Service fb6fa5
	  info->conversions[i].data = data;
Packit Service fb6fa5
	  info->num_incrs++;
Packit Service fb6fa5
	  
Packit Service fb6fa5
	  gdk_property_change (info->requestor, 
Packit Service fb6fa5
			       info->conversions[i].property,
Packit Service fb6fa5
			       gtk_selection_atoms[INCR],
Packit Service fb6fa5
			       32,
Packit Service fb6fa5
			       GDK_PROP_MODE_REPLACE,
Packit Service fb6fa5
			       (guchar *)&items, 1);
Packit Service fb6fa5
	}
Packit Service fb6fa5
      else
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  info->conversions[i].offset = -1;
Packit Service fb6fa5
	  
Packit Service fb6fa5
	  gdk_property_change (info->requestor, 
Packit Service fb6fa5
			       info->conversions[i].property,
Packit Service fb6fa5
			       data.type,
Packit Service fb6fa5
			       data.format,
Packit Service fb6fa5
			       GDK_PROP_MODE_REPLACE,
Packit Service fb6fa5
			       data.data, items);
Packit Service fb6fa5
	  
Packit Service fb6fa5
	  g_free (data.data);
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  /* If we have some INCR's, we need to send the rest of the data in
Packit Service fb6fa5
     a callback */
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (info->num_incrs > 0)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      /* FIXME: this could be dangerous if window doesn't still
Packit Service fb6fa5
	 exist */
Packit Service fb6fa5
      
Packit Service fb6fa5
#ifdef DEBUG_SELECTION
Packit Service fb6fa5
      g_message ("Starting INCR...");
Packit Service fb6fa5
#endif
Packit Service fb6fa5
      
Packit Service fb6fa5
      gdk_window_set_events (info->requestor,
Packit Service fb6fa5
			     gdk_window_get_events (info->requestor) |
Packit Service fb6fa5
			     GDK_PROPERTY_CHANGE_MASK);
Packit Service fb6fa5
      current_incrs = g_list_append (current_incrs, info);
Packit Service fb6fa5
      gdk_threads_add_timeout (1000, (GSourceFunc) gtk_selection_incr_timeout, info);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  /* If it was a MULTIPLE request, set the property to indicate which
Packit Service fb6fa5
     conversions succeeded */
Packit Service fb6fa5
  if (event->target == gtk_selection_atoms[MULTIPLE])
Packit Service fb6fa5
    {
Packit Service fb6fa5
      GdkAtom *mult_atoms = g_new (GdkAtom, 2 * info->num_conversions);
Packit Service fb6fa5
      for (i = 0; i < info->num_conversions; i++)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  mult_atoms[2*i] = info->conversions[i].target;
Packit Service fb6fa5
	  mult_atoms[2*i+1] = info->conversions[i].property;
Packit Service fb6fa5
	}
Packit Service fb6fa5
      
Packit Service fb6fa5
      gdk_property_change (info->requestor, event->property,
Packit Service fb6fa5
			   gdk_atom_intern_static_string ("ATOM_PAIR"), 32, 
Packit Service fb6fa5
			   GDK_PROP_MODE_REPLACE,
Packit Service fb6fa5
			   (guchar *)mult_atoms, 2*info->num_conversions);
Packit Service fb6fa5
      g_free (mult_atoms);
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  if (info->num_conversions == 1 &&
Packit Service fb6fa5
      info->conversions[0].property == GDK_NONE)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      /* Reject the entire conversion */
Packit Service fb6fa5
      gdk_selection_send_notify_for_display (gtk_widget_get_display (widget),
Packit Service fb6fa5
					     event->requestor, 
Packit Service fb6fa5
					     event->selection, 
Packit Service fb6fa5
					     event->target, 
Packit Service fb6fa5
					     GDK_NONE, 
Packit Service fb6fa5
					     event->time);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    {
Packit Service fb6fa5
      gdk_selection_send_notify_for_display (gtk_widget_get_display (widget),
Packit Service fb6fa5
					     event->requestor, 
Packit Service fb6fa5
					     event->selection,
Packit Service fb6fa5
					     event->target,
Packit Service fb6fa5
					     event->property, 
Packit Service fb6fa5
					     event->time);
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  if (info->num_incrs == 0)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      g_free (info->conversions);
Packit Service fb6fa5
      g_slice_free (GtkIncrInfo, info);
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  g_object_unref (widget);
Packit Service fb6fa5
  
Packit Service fb6fa5
  return TRUE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/*************************************************************
Packit Service fb6fa5
 * _gtk_selection_incr_event:
Packit Service fb6fa5
 *     Called whenever an PropertyNotify event occurs for an 
Packit Service fb6fa5
 *     GdkWindow with user_data == NULL. These will be notifications
Packit Service fb6fa5
 *     that a window we are sending the selection to via the
Packit Service fb6fa5
 *     INCR protocol has deleted a property and is ready for
Packit Service fb6fa5
 *     more data.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 *   arguments:
Packit Service fb6fa5
 *     window:	the requestor window
Packit Service fb6fa5
 *     event:	the property event structure
Packit Service fb6fa5
 *
Packit Service fb6fa5
 *   results:
Packit Service fb6fa5
 *************************************************************/
Packit Service fb6fa5
Packit Service fb6fa5
gboolean
Packit Service fb6fa5
_gtk_selection_incr_event (GdkWindow	   *window,
Packit Service fb6fa5
			   GdkEventProperty *event)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GList *tmp_list;
Packit Service fb6fa5
  GtkIncrInfo *info = NULL;
Packit Service fb6fa5
  gint num_bytes;
Packit Service fb6fa5
  guchar *buffer;
Packit Service fb6fa5
  gulong selection_max_size;
Packit Service fb6fa5
  
Packit Service fb6fa5
  int i;
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (event->state != GDK_PROPERTY_DELETE)
Packit Service fb6fa5
    return FALSE;
Packit Service fb6fa5
  
Packit Service fb6fa5
#ifdef DEBUG_SELECTION
Packit Service fb6fa5
  g_message ("PropertyDelete, property %ld", event->atom);
Packit Service fb6fa5
#endif
Packit Service fb6fa5
Packit Service fb6fa5
  selection_max_size = GTK_SELECTION_MAX_SIZE (gdk_window_get_display (window));
Packit Service fb6fa5
Packit Service fb6fa5
  /* Now find the appropriate ongoing INCR */
Packit Service fb6fa5
  tmp_list = current_incrs;
Packit Service fb6fa5
  while (tmp_list)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      info = (GtkIncrInfo *)tmp_list->data;
Packit Service fb6fa5
      if (info->requestor == event->window)
Packit Service fb6fa5
	break;
Packit Service fb6fa5
      
Packit Service fb6fa5
      tmp_list = tmp_list->next;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (tmp_list == NULL)
Packit Service fb6fa5
    return FALSE;
Packit Service fb6fa5
  
Packit Service fb6fa5
  /* Find out which target this is for */
Packit Service fb6fa5
  for (i=0; i<info->num_conversions; i++)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (info->conversions[i].property == event->atom &&
Packit Service fb6fa5
	  info->conversions[i].offset != -1)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  int bytes_per_item;
Packit Service fb6fa5
	  
Packit Service fb6fa5
	  info->idle_time = 0;
Packit Service fb6fa5
	  
Packit Service fb6fa5
	  if (info->conversions[i].offset == -2) /* only the last 0-length
Packit Service fb6fa5
						    piece*/
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      num_bytes = 0;
Packit Service fb6fa5
	      buffer = NULL;
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	  else
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      num_bytes = info->conversions[i].data.length -
Packit Service fb6fa5
		info->conversions[i].offset;
Packit Service fb6fa5
	      buffer = info->conversions[i].data.data + 
Packit Service fb6fa5
		info->conversions[i].offset;
Packit Service fb6fa5
	      
Packit Service fb6fa5
	      if (num_bytes > selection_max_size)
Packit Service fb6fa5
		{
Packit Service fb6fa5
		  num_bytes = selection_max_size;
Packit Service fb6fa5
		  info->conversions[i].offset += selection_max_size;
Packit Service fb6fa5
		}
Packit Service fb6fa5
	      else
Packit Service fb6fa5
		info->conversions[i].offset = -2;
Packit Service fb6fa5
	    }
Packit Service fb6fa5
#ifdef DEBUG_SELECTION
Packit Service fb6fa5
	  g_message ("INCR: put %d bytes (offset = %d) into window 0x%lx , property %ld",
Packit Service fb6fa5
		     num_bytes, info->conversions[i].offset, 
Packit Service fb6fa5
		     GDK_WINDOW_XWINDOW(info->requestor), event->atom);
Packit Service fb6fa5
#endif
Packit Service fb6fa5
Packit Service fb6fa5
	  bytes_per_item = gtk_selection_bytes_per_item (info->conversions[i].data.format);
Packit Service fb6fa5
	  gdk_property_change (info->requestor, event->atom,
Packit Service fb6fa5
			       info->conversions[i].data.type,
Packit Service fb6fa5
			       info->conversions[i].data.format,
Packit Service fb6fa5
			       GDK_PROP_MODE_REPLACE,
Packit Service fb6fa5
			       buffer,
Packit Service fb6fa5
			       num_bytes / bytes_per_item);
Packit Service fb6fa5
	  
Packit Service fb6fa5
	  if (info->conversions[i].offset == -2)
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      g_free (info->conversions[i].data.data);
Packit Service fb6fa5
	      info->conversions[i].data.data = NULL;
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	  
Packit Service fb6fa5
	  if (num_bytes == 0)
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      info->num_incrs--;
Packit Service fb6fa5
	      info->conversions[i].offset = -1;
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  /* Check if we're finished with all the targets */
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (info->num_incrs == 0)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      current_incrs = g_list_remove_link (current_incrs, tmp_list);
Packit Service fb6fa5
      g_list_free (tmp_list);
Packit Service fb6fa5
      /* Let the timeout free it */
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  return TRUE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/*************************************************************
Packit Service fb6fa5
 * gtk_selection_incr_timeout:
Packit Service fb6fa5
 *     Timeout callback for the sending portion of the INCR
Packit Service fb6fa5
 *     protocol
Packit Service fb6fa5
 *   arguments:
Packit Service fb6fa5
 *     info:	Information about this incr
Packit Service fb6fa5
 *   results:
Packit Service fb6fa5
 *************************************************************/
Packit Service fb6fa5
Packit Service fb6fa5
static gint
Packit Service fb6fa5
gtk_selection_incr_timeout (GtkIncrInfo *info)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GList *tmp_list;
Packit Service fb6fa5
  gboolean retval;
Packit Service fb6fa5
Packit Service fb6fa5
  /* Determine if retrieval has finished by checking if it still in
Packit Service fb6fa5
     list of pending retrievals */
Packit Service fb6fa5
  
Packit Service fb6fa5
  tmp_list = current_incrs;
Packit Service fb6fa5
  while (tmp_list)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (info == (GtkIncrInfo *)tmp_list->data)
Packit Service fb6fa5
	break;
Packit Service fb6fa5
      tmp_list = tmp_list->next;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  /* If retrieval is finished */
Packit Service fb6fa5
  if (!tmp_list || info->idle_time >= IDLE_ABORT_TIME)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (tmp_list && info->idle_time >= IDLE_ABORT_TIME)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  current_incrs = g_list_remove_link (current_incrs, tmp_list);
Packit Service fb6fa5
	  g_list_free (tmp_list);
Packit Service fb6fa5
	}
Packit Service fb6fa5
      
Packit Service fb6fa5
      g_free (info->conversions);
Packit Service fb6fa5
      /* FIXME: we should check if requestor window is still in use,
Packit Service fb6fa5
	 and if not, remove it? */
Packit Service fb6fa5
      
Packit Service fb6fa5
      g_slice_free (GtkIncrInfo, info);
Packit Service fb6fa5
      
Packit Service fb6fa5
      retval =  FALSE;		/* remove timeout */
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    {
Packit Service fb6fa5
      info->idle_time++;
Packit Service fb6fa5
      
Packit Service fb6fa5
      retval = TRUE;		/* timeout will happen again */
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  return retval;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/*************************************************************
Packit Service fb6fa5
 * _gtk_selection_notify:
Packit Service fb6fa5
 *     Handler for "selection-notify-event" signals on windows
Packit Service fb6fa5
 *     where a retrieval is currently in process. The selection
Packit Service fb6fa5
 *     owner has responded to our conversion request.
Packit Service fb6fa5
 *   arguments:
Packit Service fb6fa5
 *     widget:		Widget getting signal
Packit Service fb6fa5
 *     event:		Selection event structure
Packit Service fb6fa5
 *     info:		Information about this retrieval
Packit Service fb6fa5
 *   results:
Packit Service fb6fa5
 *     was event handled?
Packit Service fb6fa5
 *************************************************************/
Packit Service fb6fa5
Packit Service fb6fa5
gboolean
Packit Service fb6fa5
_gtk_selection_notify (GtkWidget	       *widget,
Packit Service fb6fa5
		       GdkEventSelection *event)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GList *tmp_list;
Packit Service fb6fa5
  GtkRetrievalInfo *info = NULL;
Packit Service fb6fa5
  guchar  *buffer = NULL;
Packit Service fb6fa5
  gint length;
Packit Service fb6fa5
  GdkAtom type;
Packit Service fb6fa5
  gint	  format;
Packit Service fb6fa5
  
Packit Service fb6fa5
#ifdef DEBUG_SELECTION
Packit Service fb6fa5
  g_message ("Initial receipt of selection %ld, target %ld (property = %ld)",
Packit Service fb6fa5
	     event->selection, event->target, event->property);
Packit Service fb6fa5
#endif
Packit Service fb6fa5
  
Packit Service fb6fa5
  tmp_list = current_retrievals;
Packit Service fb6fa5
  while (tmp_list)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      info = (GtkRetrievalInfo *)tmp_list->data;
Packit Service fb6fa5
      if (info->widget == widget && info->selection == event->selection)
Packit Service fb6fa5
	break;
Packit Service fb6fa5
      tmp_list = tmp_list->next;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (!tmp_list)		/* no retrieval in progress */
Packit Service fb6fa5
    return FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
  if (event->property != GDK_NONE)
Packit Service fb6fa5
    length = gdk_selection_property_get (widget->window, &buffer, 
Packit Service fb6fa5
					 &type, &format);
Packit Service fb6fa5
  else
Packit Service fb6fa5
    length = 0; /* silence gcc */
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (event->property == GDK_NONE || buffer == NULL)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      current_retrievals = g_list_remove_link (current_retrievals, tmp_list);
Packit Service fb6fa5
      g_list_free (tmp_list);
Packit Service fb6fa5
      /* structure will be freed in timeout */
Packit Service fb6fa5
      gtk_selection_retrieval_report (info,
Packit Service fb6fa5
				      GDK_NONE, 0, NULL, -1, event->time);
Packit Service fb6fa5
      
Packit Service fb6fa5
      return TRUE;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (type == gtk_selection_atoms[INCR])
Packit Service fb6fa5
    {
Packit Service fb6fa5
      /* The remainder of the selection will come through PropertyNotify
Packit Service fb6fa5
	 events */
Packit Service fb6fa5
Packit Service fb6fa5
      info->notify_time = event->time;
Packit Service fb6fa5
      info->idle_time = 0;
Packit Service fb6fa5
      info->offset = 0;		/* Mark as OK to proceed */
Packit Service fb6fa5
      gdk_window_set_events (widget->window,
Packit Service fb6fa5
			     gdk_window_get_events (widget->window)
Packit Service fb6fa5
			     | GDK_PROPERTY_CHANGE_MASK);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    {
Packit Service fb6fa5
      /* We don't delete the info structure - that will happen in timeout */
Packit Service fb6fa5
      current_retrievals = g_list_remove_link (current_retrievals, tmp_list);
Packit Service fb6fa5
      g_list_free (tmp_list);
Packit Service fb6fa5
      
Packit Service fb6fa5
      info->offset = length;
Packit Service fb6fa5
      gtk_selection_retrieval_report (info,
Packit Service fb6fa5
				      type, format, 
Packit Service fb6fa5
				      buffer, length, event->time);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  gdk_property_delete (widget->window, event->property);
Packit Service fb6fa5
  
Packit Service fb6fa5
  g_free (buffer);
Packit Service fb6fa5
  
Packit Service fb6fa5
  return TRUE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/*************************************************************
Packit Service fb6fa5
 * _gtk_selection_property_notify:
Packit Service fb6fa5
 *     Handler for "property-notify-event" signals on windows
Packit Service fb6fa5
 *     where a retrieval is currently in process. The selection
Packit Service fb6fa5
 *     owner has added more data.
Packit Service fb6fa5
 *   arguments:
Packit Service fb6fa5
 *     widget:		Widget getting signal
Packit Service fb6fa5
 *     event:		Property event structure
Packit Service fb6fa5
 *     info:		Information about this retrieval
Packit Service fb6fa5
 *   results:
Packit Service fb6fa5
 *     was event handled?
Packit Service fb6fa5
 *************************************************************/
Packit Service fb6fa5
Packit Service fb6fa5
gboolean
Packit Service fb6fa5
_gtk_selection_property_notify (GtkWidget	*widget,
Packit Service fb6fa5
				GdkEventProperty *event)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GList *tmp_list;
Packit Service fb6fa5
  GtkRetrievalInfo *info = NULL;
Packit Service fb6fa5
  guchar *new_buffer;
Packit Service fb6fa5
  int length;
Packit Service fb6fa5
  GdkAtom type;
Packit Service fb6fa5
  gint	  format;
Packit Service fb6fa5
  
Packit Service fb6fa5
  g_return_val_if_fail (widget != NULL, FALSE);
Packit Service fb6fa5
  g_return_val_if_fail (event != NULL, FALSE);
Packit Service fb6fa5
Packit Service fb6fa5
#if defined(GDK_WINDOWING_WIN32) || defined(GDK_WINDOWING_X11)
Packit Service fb6fa5
  if ((event->state != GDK_PROPERTY_NEW_VALUE) ||  /* property was deleted */
Packit Service fb6fa5
      (event->atom != gdk_atom_intern_static_string ("GDK_SELECTION"))) /* not the right property */
Packit Service fb6fa5
#endif
Packit Service fb6fa5
    return FALSE;
Packit Service fb6fa5
  
Packit Service fb6fa5
#ifdef DEBUG_SELECTION
Packit Service fb6fa5
  g_message ("PropertyNewValue, property %ld",
Packit Service fb6fa5
	     event->atom);
Packit Service fb6fa5
#endif
Packit Service fb6fa5
  
Packit Service fb6fa5
  tmp_list = current_retrievals;
Packit Service fb6fa5
  while (tmp_list)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      info = (GtkRetrievalInfo *)tmp_list->data;
Packit Service fb6fa5
      if (info->widget == widget)
Packit Service fb6fa5
	break;
Packit Service fb6fa5
      tmp_list = tmp_list->next;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (!tmp_list)		/* No retrieval in progress */
Packit Service fb6fa5
    return FALSE;
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (info->offset < 0)		/* We haven't got the SelectionNotify
Packit Service fb6fa5
				   for this retrieval yet */
Packit Service fb6fa5
    return FALSE;
Packit Service fb6fa5
  
Packit Service fb6fa5
  info->idle_time = 0;
Packit Service fb6fa5
  
Packit Service fb6fa5
  length = gdk_selection_property_get (widget->window, &new_buffer, 
Packit Service fb6fa5
				       &type, &format);
Packit Service fb6fa5
  gdk_property_delete (widget->window, event->atom);
Packit Service fb6fa5
  
Packit Service fb6fa5
  /* We could do a lot better efficiency-wise by paying attention to
Packit Service fb6fa5
     what length was sent in the initial INCR transaction, instead of
Packit Service fb6fa5
     doing memory allocation at every step. But its only guaranteed to
Packit Service fb6fa5
     be a _lower bound_ (pretty useless!) */
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (length == 0 || type == GDK_NONE)		/* final zero length portion */
Packit Service fb6fa5
    {
Packit Service fb6fa5
      /* Info structure will be freed in timeout */
Packit Service fb6fa5
      current_retrievals = g_list_remove_link (current_retrievals, tmp_list);
Packit Service fb6fa5
      g_list_free (tmp_list);
Packit Service fb6fa5
      gtk_selection_retrieval_report (info,
Packit Service fb6fa5
				      type, format, 
Packit Service fb6fa5
				      (type == GDK_NONE) ?  NULL : info->buffer,
Packit Service fb6fa5
				      (type == GDK_NONE) ?  -1 : info->offset,
Packit Service fb6fa5
				      info->notify_time);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else				/* append on newly arrived data */
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (!info->buffer)
Packit Service fb6fa5
	{
Packit Service fb6fa5
#ifdef DEBUG_SELECTION
Packit Service fb6fa5
	  g_message ("Start - Adding %d bytes at offset 0",
Packit Service fb6fa5
		     length);
Packit Service fb6fa5
#endif
Packit Service fb6fa5
	  info->buffer = new_buffer;
Packit Service fb6fa5
	  info->offset = length;
Packit Service fb6fa5
	}
Packit Service fb6fa5
      else
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  
Packit Service fb6fa5
#ifdef DEBUG_SELECTION
Packit Service fb6fa5
	  g_message ("Appending %d bytes at offset %d",
Packit Service fb6fa5
		     length,info->offset);
Packit Service fb6fa5
#endif
Packit Service fb6fa5
	  /* We copy length+1 bytes to preserve guaranteed null termination */
Packit Service fb6fa5
	  info->buffer = g_realloc (info->buffer, info->offset+length+1);
Packit Service fb6fa5
	  memcpy (info->buffer + info->offset, new_buffer, length+1);
Packit Service fb6fa5
	  info->offset += length;
Packit Service fb6fa5
	  g_free (new_buffer);
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  return TRUE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/*************************************************************
Packit Service fb6fa5
 * gtk_selection_retrieval_timeout:
Packit Service fb6fa5
 *     Timeout callback while receiving a selection.
Packit Service fb6fa5
 *   arguments:
Packit Service fb6fa5
 *     info:	Information about this retrieval
Packit Service fb6fa5
 *   results:
Packit Service fb6fa5
 *************************************************************/
Packit Service fb6fa5
Packit Service fb6fa5
static gboolean
Packit Service fb6fa5
gtk_selection_retrieval_timeout (GtkRetrievalInfo *info)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GList *tmp_list;
Packit Service fb6fa5
  gboolean retval;
Packit Service fb6fa5
Packit Service fb6fa5
  /* Determine if retrieval has finished by checking if it still in
Packit Service fb6fa5
     list of pending retrievals */
Packit Service fb6fa5
  
Packit Service fb6fa5
  tmp_list = current_retrievals;
Packit Service fb6fa5
  while (tmp_list)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (info == (GtkRetrievalInfo *)tmp_list->data)
Packit Service fb6fa5
	break;
Packit Service fb6fa5
      tmp_list = tmp_list->next;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  /* If retrieval is finished */
Packit Service fb6fa5
  if (!tmp_list || info->idle_time >= IDLE_ABORT_TIME)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (tmp_list && info->idle_time >= IDLE_ABORT_TIME)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  current_retrievals = g_list_remove_link (current_retrievals, tmp_list);
Packit Service fb6fa5
	  g_list_free (tmp_list);
Packit Service fb6fa5
	  gtk_selection_retrieval_report (info, GDK_NONE, 0, NULL, -1, GDK_CURRENT_TIME);
Packit Service fb6fa5
	}
Packit Service fb6fa5
      
Packit Service fb6fa5
      g_free (info->buffer);
Packit Service fb6fa5
      g_slice_free (GtkRetrievalInfo, info);
Packit Service fb6fa5
      
Packit Service fb6fa5
      retval =  FALSE;		/* remove timeout */
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    {
Packit Service fb6fa5
      info->idle_time++;
Packit Service fb6fa5
      
Packit Service fb6fa5
      retval =  TRUE;		/* timeout will happen again */
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  return retval;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/*************************************************************
Packit Service fb6fa5
 * gtk_selection_retrieval_report:
Packit Service fb6fa5
 *     Emits a "selection-received" signal.
Packit Service fb6fa5
 *   arguments:
Packit Service fb6fa5
 *     info:	  information about the retrieval that completed
Packit Service fb6fa5
 *     buffer:	  buffer containing data (NULL => errror)
Packit Service fb6fa5
 *     time:      timestamp for data in buffer
Packit Service fb6fa5
 *   results:
Packit Service fb6fa5
 *************************************************************/
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gtk_selection_retrieval_report (GtkRetrievalInfo *info,
Packit Service fb6fa5
				GdkAtom type, gint format, 
Packit Service fb6fa5
				guchar *buffer, gint length,
Packit Service fb6fa5
				guint32 time)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkSelectionData data;
Packit Service fb6fa5
  
Packit Service fb6fa5
  data.selection = info->selection;
Packit Service fb6fa5
  data.target = info->target;
Packit Service fb6fa5
  data.type = type;
Packit Service fb6fa5
  data.format = format;
Packit Service fb6fa5
  
Packit Service fb6fa5
  data.length = length;
Packit Service fb6fa5
  data.data = buffer;
Packit Service fb6fa5
  data.display = gtk_widget_get_display (info->widget);
Packit Service fb6fa5
  
Packit Service fb6fa5
  g_signal_emit_by_name (info->widget,
Packit Service fb6fa5
			 "selection-received", 
Packit Service fb6fa5
			 &data, time);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/*************************************************************
Packit Service fb6fa5
 * gtk_selection_invoke_handler:
Packit Service fb6fa5
 *     Finds and invokes handler for specified
Packit Service fb6fa5
 *     widget/selection/target combination, calls 
Packit Service fb6fa5
 *     gtk_selection_default_handler if none exists.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 *   arguments:
Packit Service fb6fa5
 *     widget:	    selection owner
Packit Service fb6fa5
 *     data:	    selection data [INOUT]
Packit Service fb6fa5
 *     time:        time from requeset
Packit Service fb6fa5
 *     
Packit Service fb6fa5
 *   results:
Packit Service fb6fa5
 *     Number of bytes written to buffer, -1 if error
Packit Service fb6fa5
 *************************************************************/
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gtk_selection_invoke_handler (GtkWidget	       *widget,
Packit Service fb6fa5
			      GtkSelectionData *data,
Packit Service fb6fa5
			      guint             time)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkTargetList *target_list;
Packit Service fb6fa5
  guint info;
Packit Service fb6fa5
  
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_if_fail (widget != NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  target_list = gtk_selection_target_list_get (widget, data->selection);
Packit Service fb6fa5
  if (data->target != gtk_selection_atoms[SAVE_TARGETS] &&
Packit Service fb6fa5
      target_list &&
Packit Service fb6fa5
      gtk_target_list_find (target_list, data->target, &info))
Packit Service fb6fa5
    {
Packit Service fb6fa5
      g_signal_emit_by_name (widget,
Packit Service fb6fa5
			     "selection-get",
Packit Service fb6fa5
			     data,
Packit Service fb6fa5
			     info, time);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    gtk_selection_default_handler (widget, data);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/*************************************************************
Packit Service fb6fa5
 * gtk_selection_default_handler:
Packit Service fb6fa5
 *     Handles some default targets that exist for any widget
Packit Service fb6fa5
 *     If it can't fit results into buffer, returns -1. This
Packit Service fb6fa5
 *     won't happen in any conceivable case, since it would
Packit Service fb6fa5
 *     require 1000 selection targets!
Packit Service fb6fa5
 *
Packit Service fb6fa5
 *   arguments:
Packit Service fb6fa5
 *     widget:	    selection owner
Packit Service fb6fa5
 *     data:	    selection data [INOUT]
Packit Service fb6fa5
 *
Packit Service fb6fa5
 *************************************************************/
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gtk_selection_default_handler (GtkWidget	*widget,
Packit Service fb6fa5
			       GtkSelectionData *data)
Packit Service fb6fa5
{
Packit Service fb6fa5
  if (data->target == gtk_selection_atoms[TIMESTAMP])
Packit Service fb6fa5
    {
Packit Service fb6fa5
      /* Time which was used to obtain selection */
Packit Service fb6fa5
      GList *tmp_list;
Packit Service fb6fa5
      GtkSelectionInfo *selection_info;
Packit Service fb6fa5
      
Packit Service fb6fa5
      tmp_list = current_selections;
Packit Service fb6fa5
      while (tmp_list)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  selection_info = (GtkSelectionInfo *)tmp_list->data;
Packit Service fb6fa5
	  if ((selection_info->widget == widget) &&
Packit Service fb6fa5
	      (selection_info->selection == data->selection))
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      gulong time = selection_info->time;
Packit Service fb6fa5
Packit Service fb6fa5
	      gtk_selection_data_set (data,
Packit Service fb6fa5
				      GDK_SELECTION_TYPE_INTEGER,
Packit Service fb6fa5
				      32,
Packit Service fb6fa5
				      (guchar *)&time,
Packit Service fb6fa5
				      sizeof (time));
Packit Service fb6fa5
	      return;
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	  
Packit Service fb6fa5
	  tmp_list = tmp_list->next;
Packit Service fb6fa5
	}
Packit Service fb6fa5
      
Packit Service fb6fa5
      data->length = -1;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else if (data->target == gtk_selection_atoms[TARGETS])
Packit Service fb6fa5
    {
Packit Service fb6fa5
      /* List of all targets supported for this widget/selection pair */
Packit Service fb6fa5
      GdkAtom *p;
Packit Service fb6fa5
      guint count;
Packit Service fb6fa5
      GList *tmp_list;
Packit Service fb6fa5
      GtkTargetList *target_list;
Packit Service fb6fa5
      GtkTargetPair *pair;
Packit Service fb6fa5
      
Packit Service fb6fa5
      target_list = gtk_selection_target_list_get (widget,
Packit Service fb6fa5
						   data->selection);
Packit Service fb6fa5
      count = g_list_length (target_list->list) + 3;
Packit Service fb6fa5
      
Packit Service fb6fa5
      data->type = GDK_SELECTION_TYPE_ATOM;
Packit Service fb6fa5
      data->format = 32;
Packit Service fb6fa5
      data->length = count * sizeof (GdkAtom);
Packit Service fb6fa5
Packit Service fb6fa5
      /* selection data is always terminated by a trailing \0
Packit Service fb6fa5
       */
Packit Service fb6fa5
      p = g_malloc (data->length + 1);
Packit Service fb6fa5
      data->data = (guchar *)p;
Packit Service fb6fa5
      data->data[data->length] = '\0';
Packit Service fb6fa5
      
Packit Service fb6fa5
      *p++ = gtk_selection_atoms[TIMESTAMP];
Packit Service fb6fa5
      *p++ = gtk_selection_atoms[TARGETS];
Packit Service fb6fa5
      *p++ = gtk_selection_atoms[MULTIPLE];
Packit Service fb6fa5
      
Packit Service fb6fa5
      tmp_list = target_list->list;
Packit Service fb6fa5
      while (tmp_list)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  pair = (GtkTargetPair *)tmp_list->data;
Packit Service fb6fa5
	  *p++ = pair->target;
Packit Service fb6fa5
	  
Packit Service fb6fa5
	  tmp_list = tmp_list->next;
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else if (data->target == gtk_selection_atoms[SAVE_TARGETS])
Packit Service fb6fa5
    {
Packit Service fb6fa5
      gtk_selection_data_set (data,
Packit Service fb6fa5
			      gdk_atom_intern_static_string ("NULL"),
Packit Service fb6fa5
			      32, NULL, 0);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    {
Packit Service fb6fa5
      data->length = -1;
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_selection_data_copy:
Packit Service fb6fa5
 * @data: a pointer to a #GtkSelectionData structure.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Makes a copy of a #GtkSelectionData structure and its data.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Return value: a pointer to a copy of @data.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
GtkSelectionData*
Packit Service fb6fa5
gtk_selection_data_copy (GtkSelectionData *data)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkSelectionData *new_data;
Packit Service fb6fa5
  
Packit Service fb6fa5
  g_return_val_if_fail (data != NULL, NULL);
Packit Service fb6fa5
  
Packit Service fb6fa5
  new_data = g_slice_new (GtkSelectionData);
Packit Service fb6fa5
  *new_data = *data;
Packit Service fb6fa5
Packit Service fb6fa5
  if (data->data)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      new_data->data = g_malloc (data->length + 1);
Packit Service fb6fa5
      memcpy (new_data->data, data->data, data->length + 1);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  return new_data;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_selection_data_free:
Packit Service fb6fa5
 * @data: a pointer to a #GtkSelectionData structure.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Frees a #GtkSelectionData structure returned from
Packit Service fb6fa5
 * gtk_selection_data_copy().
Packit Service fb6fa5
 **/
Packit Service fb6fa5
void
Packit Service fb6fa5
gtk_selection_data_free (GtkSelectionData *data)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_if_fail (data != NULL);
Packit Service fb6fa5
  
Packit Service fb6fa5
  g_free (data->data);
Packit Service fb6fa5
  
Packit Service fb6fa5
  g_slice_free (GtkSelectionData, data);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
GType
Packit Service fb6fa5
gtk_selection_data_get_type (void)
Packit Service fb6fa5
{
Packit Service fb6fa5
  static GType our_type = 0;
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (our_type == 0)
Packit Service fb6fa5
    our_type = g_boxed_type_register_static (I_("GtkSelectionData"),
Packit Service fb6fa5
					     (GBoxedCopyFunc) gtk_selection_data_copy,
Packit Service fb6fa5
					     (GBoxedFreeFunc) gtk_selection_data_free);
Packit Service fb6fa5
Packit Service fb6fa5
  return our_type;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
GType
Packit Service fb6fa5
gtk_target_list_get_type (void)
Packit Service fb6fa5
{
Packit Service fb6fa5
  static GType our_type = 0;
Packit Service fb6fa5
Packit Service fb6fa5
  if (our_type == 0)
Packit Service fb6fa5
    our_type = g_boxed_type_register_static (I_("GtkTargetList"),
Packit Service fb6fa5
					     (GBoxedCopyFunc) gtk_target_list_ref,
Packit Service fb6fa5
					     (GBoxedFreeFunc) gtk_target_list_unref);
Packit Service fb6fa5
Packit Service fb6fa5
  return our_type;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static int 
Packit Service fb6fa5
gtk_selection_bytes_per_item (gint format)
Packit Service fb6fa5
{
Packit Service fb6fa5
  switch (format)
Packit Service fb6fa5
    {
Packit Service fb6fa5
    case 8:
Packit Service fb6fa5
      return sizeof (char);
Packit Service fb6fa5
      break;
Packit Service fb6fa5
    case 16:
Packit Service fb6fa5
      return sizeof (short);
Packit Service fb6fa5
      break;
Packit Service fb6fa5
    case 32:
Packit Service fb6fa5
      return sizeof (long);
Packit Service fb6fa5
      break;
Packit Service fb6fa5
    default:
Packit Service fb6fa5
      g_assert_not_reached();
Packit Service fb6fa5
    }
Packit Service fb6fa5
  return 0;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
#define __GTK_SELECTION_C__
Packit Service fb6fa5
#include "gtkaliasdef.c"