#include <string.h>
#include "gdk.h"
-#if defined (GDK_WINDOWING_X11)
-#include "x11/gdkx.h" /* For gdk_window_lookup() */
-#elif defined (GDK_WINDOWING_WIN32)
-#include "win32/gdkwin32.h" /* For gdk_window_lookup() */
-#elif defined (GDK_WINDOWING_NANOX)
-#include "nanox/gdkprivate-nanox.h" /* For gdk_window_lookup() */
-#endif
-
#include "gtkmain.h"
#include "gtkselection.h"
#include "gtksignal.h"
struct _GtkIncrInfo
{
- GtkWidget *widget; /* Selection owner */
GdkWindow *requestor; /* Requestor window - we create a GdkWindow
so we can receive events */
GdkAtom selection; /* Selection we're sending */
/* Remove pending requests/incrs for this widget */
- tmp_list = current_incrs;
- while (tmp_list)
- {
- next = tmp_list->next;
- if (((GtkIncrInfo *)tmp_list->data)->widget == widget)
- {
- current_incrs = g_list_remove_link (current_incrs, tmp_list);
- /* structure will be freed in timeout */
- g_list_free (tmp_list);
- }
- tmp_list = next;
- }
-
tmp_list = current_retrievals;
while (tmp_list)
{
* this widget).
*************************************************************/
-gint
+gboolean
gtk_selection_convert (GtkWidget *widget,
GdkAtom selection,
GdkAtom target,
* gtk_selection_data_set_text:
* @selection_data: a #GtkSelectionData
* @str: a UTF-8 string
+ * @len: the length of @str, or -1 if @str is nul-terminated.
*
* Sets the contents of the selection from a UTF-8 encoded string.
* The string is converted to the form determined by
* @selection_data->target.
*
- * Return value: %TRUE if the selection was succesfully set,
+ * Return value: %TRUE if the selection was successfully set,
* otherwise %FALSE.
**/
gboolean
gtk_selection_data_set_text (GtkSelectionData *selection_data,
- const guchar *str)
+ const gchar *str,
+ gint len)
{
+ gboolean result = FALSE;
+
+ if (len < 0)
+ len = strlen (str);
+
init_atoms ();
if (selection_data->target == utf8_atom)
{
gtk_selection_data_set (selection_data,
utf8_atom,
- 8, (guchar *)str, strlen (str));
- return TRUE;
+ 8, (guchar *)str, len);
+ result = TRUE;
}
else if (selection_data->target == GDK_TARGET_STRING)
{
- gchar *latin1 = gdk_utf8_to_string_target (str);
+ gchar *tmp = g_strndup (str, len);
+ gchar *latin1 = gdk_utf8_to_string_target (tmp);
+ g_free (tmp);
if (latin1)
{
gtk_selection_data_set (selection_data,
GDK_SELECTION_TYPE_STRING,
8, latin1, strlen (latin1));
- g_free(latin1);
+ g_free (latin1);
- return TRUE;
+ result = TRUE;
}
}
else if (selection_data->target == ctext_atom ||
selection_data->target == text_atom)
{
+ gchar *tmp;
guchar *text;
GdkAtom encoding;
gint format;
gint new_length;
-
- if (gdk_utf8_to_compound_text (str, &encoding, &format, &text, &new_length))
+
+ tmp = g_strndup (str, len);
+ if (gdk_utf8_to_compound_text (tmp, &encoding, &format, &text, &new_length))
{
gtk_selection_data_set (selection_data, encoding, format, text, new_length);
gdk_free_compound_text (text);
-
- return TRUE;
+
+ result = TRUE;
}
+
+ g_free (tmp);
}
- return FALSE;
+ return result;
}
/**
return result;
}
+/**
+ * gtk_selection_data_get_targets:
+ * @selection_data: a #GtkSelectionData object
+ * @targets: location to store an array of targets. The result
+ * stored here must be freed with g_free().
+ * @n_atoms: location to store number of items in @targets.
+ *
+ * Gets the contents of @selection_data as an array of targets.
+ * This can be used to interpret the results of getting
+ * the standard TARGETS target that is always supplied for
+ * any selection.
+ *
+ * Return value: %TRUE if @selection_data contains a valid
+ * array of targets, otherwise %FALSE.
+ **/
+gboolean
+gtk_selection_data_get_targets (GtkSelectionData *selection_data,
+ GdkAtom **targets,
+ gint *n_atoms)
+{
+ if (selection_data->length >= 0 &&
+ selection_data->format == 32 &&
+ selection_data->type == GDK_SELECTION_TYPE_ATOM)
+ {
+ if (targets)
+ *targets = g_memdup (selection_data->data, selection_data->length);
+ if (n_atoms)
+ *n_atoms = selection_data->length / sizeof (GdkAtom);
+
+ return TRUE;
+ }
+ else
+ {
+ if (targets)
+ *targets = NULL;
+ if (n_atoms)
+ *n_atoms = -1;
+
+ return FALSE;
+ }
+}
+
+/**
+ * gtk_selection_data_targets_include_text:
+ * @selection_data: a #GtkSelectionData object
+ *
+ * Given a #GtkSelectionData object holding a list of targets,
+ * determines if any of the targets in @targets can be used to
+ * provide text.
+ *
+ * Return value: %TRUE if @selection_data holds a list of targets,
+ * and a suitable target for text is included, otherwise %FALSE.
+ **/
+gboolean
+gtk_selection_data_targets_include_text (GtkSelectionData *selection_data)
+{
+ GdkAtom *targets;
+ gint n_targets;
+ gint i;
+ gboolean result = FALSE;
+
+ if (gtk_selection_data_get_targets (selection_data, &targets, &n_targets))
+ {
+ for (i=0; i < n_targets; i++)
+ {
+ if (targets[i] == gdk_atom_intern ("STRING", FALSE) ||
+ targets[i] == gdk_atom_intern ("TEXT", FALSE) ||
+ targets[i] == gdk_atom_intern ("COMPOUND_TEXT", FALSE) ||
+ targets[i] == gdk_atom_intern ("UTF8_STRING", FALSE))
+ result = TRUE;
+ }
+
+ g_free (targets);
+ }
+
+ return result;
+}
+
/*************************************************************
* gtk_selection_init:
* Initialize local variables
* results:
*************************************************************/
-gint
+gboolean
gtk_selection_clear (GtkWidget *widget,
GdkEventSelection *event)
{
* results:
*************************************************************/
-gint
+gboolean
gtk_selection_request (GtkWidget *widget,
GdkEventSelection *event)
{
if (tmp_list == NULL)
return FALSE;
- info = g_new(GtkIncrInfo, 1);
+ info = g_new (GtkIncrInfo, 1);
+
+ g_object_ref (widget);
- info->widget = widget;
info->selection = event->selection;
info->num_incrs = 0;
/* Create GdkWindow structure for the requestor */
-
-#if defined(GDK_WINDOWING_WIN32) || defined(GDK_WINDOWING_X11)
info->requestor = gdk_window_lookup (event->requestor);
if (!info->requestor)
info->requestor = gdk_window_foreign_new (event->requestor);
-#else
- info->requestor = NULL;
-#endif
/* Determine conversions we need to perform */
mult_atoms = NULL;
- gdk_error_trap_push();
+ gdk_error_trap_push ();
if (!gdk_property_get (info->requestor, event->property, 0, /* AnyPropertyType */
0, GTK_SELECTION_MAX_SIZE, FALSE,
&type, &format, &length, &mult_atoms))
g_free (info);
return TRUE;
}
- gdk_error_trap_pop();
+ gdk_error_trap_pop ();
info->num_conversions = length / (2*sizeof (GdkAtom));
info->conversions = g_new (GtkIncrConversion, info->num_conversions);
#ifdef DEBUG_SELECTION
g_message ("Selection %ld, target %ld (%s) requested by 0x%x (property = %ld)",
event->selection, info->conversions[i].target,
- gdk_atom_name(info->conversions[i].target),
+ gdk_atom_name (info->conversions[i].target),
event->requestor, event->property);
#endif
if (event->target == gtk_selection_atoms[MULTIPLE])
{
gdk_property_change (info->requestor, event->property,
- GDK_SELECTION_TYPE_ATOM, 32,
+ gdk_atom_intern ("ATOM_PAIR", FALSE), 32,
GDK_PROP_MODE_REPLACE,
mult_atoms, 2*info->num_conversions);
g_free (mult_atoms);
gdk_selection_send_notify (event->requestor, event->selection,
event->target, event->property, event->time);
}
-
+
if (info->num_incrs == 0)
{
g_free (info->conversions);
g_free (info);
}
+
+ g_object_unref (widget);
return TRUE;
}
* results:
*************************************************************/
-gint
+gboolean
gtk_selection_incr_event (GdkWindow *window,
GdkEventProperty *event)
{
* was event handled?
*************************************************************/
-gint
+gboolean
gtk_selection_notify (GtkWidget *widget,
GdkEventSelection *event)
{
if (event->property != GDK_NONE)
length = gdk_selection_property_get (widget->window, &buffer,
&type, &format);
-
+ else
+ length = 0; /* silence gcc */
+
if (event->property == GDK_NONE || buffer == NULL)
{
current_retrievals = g_list_remove_link (current_retrievals, tmp_list);
* was event handled?
*************************************************************/
-gint
+gboolean
gtk_selection_property_notify (GtkWidget *widget,
GdkEventProperty *event)
{
#if defined(GDK_WINDOWING_WIN32) || defined(GDK_WINDOWING_X11)
if ((event->state != GDK_PROPERTY_NEW_VALUE) || /* property was deleted */
- (event->atom != gdk_selection_property)) /* not the right property */
+ (event->atom != gdk_atom_intern ("GDK_SELECTION", FALSE))) /* not the right property */
#endif
return FALSE;
}
-GtkSelectioData*
+GtkSelectionData*
gtk_selection_data_copy (GtkSelectionData *selection_data)
{
GtkSelectionData *new_data;
g_free (data);
}
+GType
+gtk_selection_data_get_type (void)
+{
+ static GType our_type = 0;
+
+ if (our_type == 0)
+ our_type = g_boxed_type_register_static ("GtkTypeSelectionData",
+ (GBoxedCopyFunc) gtk_selection_data_copy,
+ (GBoxedFreeFunc) gtk_selection_data_free);
+
+ return our_type;
+}
+
static int
gtk_selection_bytes_per_item (gint format)
{