* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
-#include <config.h>
+#include "config.h"
#include <stdarg.h>
#include <string.h>
#include "gdk.h"
-#include "gtkalias.h"
#include "gtkmain.h"
#include "gtkselection.h"
+#include "gtktextbufferrichtext.h"
+#include "gtkintl.h"
#include "gdk-pixbuf/gdk-pixbuf.h"
#ifdef GDK_WINDOWING_X11
#include "x11/gdkx.h"
#endif
+#ifdef GDK_WINDOWING_WIN32
+#include "win32/gdkwin32.h"
+#endif
+
+#include "gtkalias.h"
+
#undef DEBUG_SELECTION
/* Maximum size of a sent chunk, in bytes. Also the default size of
#define GTK_SELECTION_MAX_SIZE(display) G_MAXINT
#endif
-#define IDLE_ABORT_TIME 300
+#define IDLE_ABORT_TIME 30
enum {
INCR,
/* Local Functions */
static void gtk_selection_init (void);
-static gint gtk_selection_incr_timeout (GtkIncrInfo *info);
-static gint gtk_selection_retrieval_timeout (GtkRetrievalInfo *info);
+static gboolean gtk_selection_incr_timeout (GtkIncrInfo *info);
+static gboolean gtk_selection_retrieval_timeout (GtkRetrievalInfo *info);
static void gtk_selection_retrieval_report (GtkRetrievalInfo *info,
GdkAtom type,
gint format,
* Target lists
*/
+
+/**
+ * gtk_target_list_new:
+ * @targets: Pointer to an array of #GtkTargetEntry
+ * @ntargets: number of entries in @targets.
+ *
+ * Creates a new #GtkTargetList from an array of #GtkTargetEntry.
+ *
+ * Return value: the new #GtkTargetList.
+ **/
GtkTargetList *
gtk_target_list_new (const GtkTargetEntry *targets,
guint ntargets)
{
- GtkTargetList *result = g_new (GtkTargetList, 1);
+ GtkTargetList *result = g_slice_new (GtkTargetList);
result->list = NULL;
result->ref_count = 1;
return result;
}
-void
+/**
+ * gtk_target_list_ref:
+ * @list: a #GtkTargetList
+ *
+ * Increases the reference count of a #GtkTargetList by one.
+ *
+ * Return value: the passed in #GtkTargetList.
+ **/
+GtkTargetList *
gtk_target_list_ref (GtkTargetList *list)
{
- g_return_if_fail (list != NULL);
+ g_return_val_if_fail (list != NULL, NULL);
list->ref_count++;
+
+ return list;
}
+/**
+ * gtk_target_list_unref:
+ * @list: a #GtkTargetList
+ *
+ * Decreases the reference count of a #GtkTargetList by one.
+ * If the resulting reference count is zero, frees the list.
+ **/
void
gtk_target_list_unref (GtkTargetList *list)
{
while (tmp_list)
{
GtkTargetPair *pair = tmp_list->data;
- g_free (pair);
+ g_slice_free (GtkTargetPair, pair);
tmp_list = tmp_list->next;
}
g_list_free (list->list);
- g_free (list);
+ g_slice_free (GtkTargetList, list);
}
}
+/**
+ * gtk_target_list_add:
+ * @list: a #GtkTargetList
+ * @target: the interned atom representing the target
+ * @flags: the flags for this target
+ * @info: an ID that will be passed back to the application
+ *
+ * Appends another target to a #GtkTargetList.
+ **/
void
gtk_target_list_add (GtkTargetList *list,
GdkAtom target,
g_return_if_fail (list != NULL);
- pair = g_new (GtkTargetPair, 1);
+ pair = g_slice_new (GtkTargetPair);
pair->target = target;
pair->flags = flags;
pair->info = info;
if (!utf8_atom)
{
- utf8_atom = gdk_atom_intern ("UTF8_STRING", FALSE);
- text_atom = gdk_atom_intern ("TEXT", FALSE);
- ctext_atom = gdk_atom_intern ("COMPOUND_TEXT", FALSE);
- text_plain_atom = gdk_atom_intern ("text/plain", FALSE);
- text_plain_utf8_atom = gdk_atom_intern ("text/plain;charset=utf-8", FALSE);
+ utf8_atom = gdk_atom_intern_static_string ("UTF8_STRING");
+ text_atom = gdk_atom_intern_static_string ("TEXT");
+ ctext_atom = gdk_atom_intern_static_string ("COMPOUND_TEXT");
+ text_plain_atom = gdk_atom_intern_static_string ("text/plain");
+ text_plain_utf8_atom = gdk_atom_intern_static_string ("text/plain;charset=utf-8");
g_get_charset (&charset);
tmp = g_strdup_printf ("text/plain;charset=%s", charset);
text_plain_locale_atom = gdk_atom_intern (tmp, FALSE);
g_free (tmp);
- text_uri_list_atom = gdk_atom_intern ("text/uri-list", FALSE);
+ text_uri_list_atom = gdk_atom_intern_static_string ("text/uri-list");
}
}
* @list: a #GtkTargetList
* @info: an ID that will be passed back to the application
*
- * Adds the text targets supported by #GtkSelection to
+ * Appends the text targets supported by #GtkSelection to
* the target list. All targets are added with the same @info.
*
* Since: 2.6
gtk_target_list_add (list, text_atom, 0, info);
gtk_target_list_add (list, GDK_TARGET_STRING, 0, info);
gtk_target_list_add (list, text_plain_utf8_atom, 0, info);
- gtk_target_list_add (list, text_plain_locale_atom, 0, info);
+ if (!g_get_charset (NULL))
+ gtk_target_list_add (list, text_plain_locale_atom, 0, info);
gtk_target_list_add (list, text_plain_atom, 0, info);
}
+/**
+ * gtk_target_list_add_rich_text_targets:
+ * @list: a #GtkTargetList
+ * @info: an ID that will be passed back to the application
+ * @deserializable: if %TRUE, then deserializable rich text formats
+ * will be added, serializable formats otherwise.
+ * @buffer: a #GtkTextBuffer.
+ *
+ * Appends the rich text targets registered with
+ * gtk_text_buffer_register_serialize_format() or
+ * gtk_text_buffer_register_deserialize_format() to the target list. All
+ * targets are added with the same @info.
+ *
+ * Since: 2.10
+ **/
+void
+gtk_target_list_add_rich_text_targets (GtkTargetList *list,
+ guint info,
+ gboolean deserializable,
+ GtkTextBuffer *buffer)
+{
+ GdkAtom *atoms;
+ gint n_atoms;
+ gint i;
+
+ g_return_if_fail (list != NULL);
+ g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
+
+ if (deserializable)
+ atoms = gtk_text_buffer_get_deserialize_formats (buffer, &n_atoms);
+ else
+ atoms = gtk_text_buffer_get_serialize_formats (buffer, &n_atoms);
+
+ for (i = 0; i < n_atoms; i++)
+ gtk_target_list_add (list, atoms[i], 0, info);
+
+ g_free (atoms);
+}
+
/**
* gtk_target_list_add_image_targets:
* @list: a #GtkTargetList
* @writable: whether to add only targets for which GTK+ knows
* how to convert a pixbuf into the format
*
- * Adds the image targets supported by #GtkSelection to
+ * Appends the image targets supported by #GtkSelection to
* the target list. All targets are added with the same @info.
*
* Since: 2.6
formats = gdk_pixbuf_get_formats ();
+ /* Make sure png comes first */
+ for (f = formats; f; f = f->next)
+ {
+ GdkPixbufFormat *fmt = f->data;
+ gchar *name;
+
+ name = gdk_pixbuf_format_get_name (fmt);
+ if (strcmp (name, "png") == 0)
+ {
+ formats = g_slist_delete_link (formats, f);
+ formats = g_slist_prepend (formats, fmt);
+
+ g_free (name);
+
+ break;
+ }
+
+ g_free (name);
+ }
+
for (f = formats; f; f = f->next)
{
GdkPixbufFormat *fmt = f->data;
* @list: a #GtkTargetList
* @info: an ID that will be passed back to the application
*
- * Adds the URI targets supported by #GtkSelection to
+ * Appends the URI targets supported by #GtkSelection to
* the target list. All targets are added with the same @info.
*
* Since: 2.6
gtk_target_list_add (list, text_uri_list_atom, 0, info);
}
+/**
+ * gtk_target_list_add_table:
+ * @list: a #GtkTargetList
+ * @targets: the table of #GtkTargetEntry
+ * @ntargets: number of targets in the table
+ *
+ * Prepends a table of #GtkTargetEntry to a target list.
+ **/
void
gtk_target_list_add_table (GtkTargetList *list,
const GtkTargetEntry *targets,
for (i=ntargets-1; i >= 0; i--)
{
- GtkTargetPair *pair = g_new (GtkTargetPair, 1);
+ GtkTargetPair *pair = g_slice_new (GtkTargetPair);
pair->target = gdk_atom_intern (targets[i].target, FALSE);
pair->flags = targets[i].flags;
pair->info = targets[i].info;
}
}
+/**
+ * gtk_target_list_remove:
+ * @list: a #GtkTargetList
+ * @target: the interned atom representing the target
+ *
+ * Removes a target from a target list.
+ **/
void
gtk_target_list_remove (GtkTargetList *list,
GdkAtom target)
if (pair->target == target)
{
- g_free (pair);
+ g_slice_free (GtkTargetPair, pair);
list->list = g_list_remove_link (list->list, tmp_list);
g_list_free_1 (tmp_list);
}
}
+/**
+ * gtk_target_list_find:
+ * @list: a #GtkTargetList
+ * @target: an interned atom representing the target to search for
+ * @info: a pointer to the location to store application info for target,
+ * or %NULL
+ *
+ * Looks up a given target in a #GtkTargetList.
+ *
+ * Return value: %TRUE if the target was found, otherwise %FALSE
+ **/
gboolean
gtk_target_list_find (GtkTargetList *list,
GdkAtom target,
guint *info)
{
- GList *tmp_list = list->list;
+ GList *tmp_list;
+
+ g_return_val_if_fail (list != NULL, FALSE);
+
+ tmp_list = list->list;
while (tmp_list)
{
GtkTargetPair *pair = tmp_list->data;
if (pair->target == target)
{
- *info = pair->info;
+ if (info)
+ *info = pair->info;
+
return TRUE;
}
+
tmp_list = tmp_list->next;
}
return FALSE;
}
+/**
+ * gtk_target_table_new_from_list:
+ * @list: a #GtkTargetList
+ * @n_targets: return location for the number ot targets in the table
+ *
+ * This function creates an #GtkTargetEntry array that contains the
+ * same targets as the passed %list. The returned table is newly
+ * allocated and should be freed using gtk_target_table_free() when no
+ * longer needed.
+ *
+ * Return value: the new table.
+ *
+ * Since: 2.10
+ **/
+GtkTargetEntry *
+gtk_target_table_new_from_list (GtkTargetList *list,
+ gint *n_targets)
+{
+ GtkTargetEntry *targets;
+ GList *tmp_list;
+ gint i;
+
+ g_return_val_if_fail (list != NULL, NULL);
+ g_return_val_if_fail (n_targets != NULL, NULL);
+
+ *n_targets = g_list_length (list->list);
+ targets = g_new0 (GtkTargetEntry, *n_targets);
+
+ for (i = 0, tmp_list = list->list;
+ i < *n_targets;
+ i++, tmp_list = g_list_next (tmp_list))
+ {
+ GtkTargetPair *pair = tmp_list->data;
+
+ targets[i].target = gdk_atom_name (pair->target);
+ targets[i].flags = pair->flags;
+ targets[i].info = pair->info;
+ }
+
+ return targets;
+}
+
+/**
+ * gtk_target_table_free:
+ * @targets: a #GtkTargetEntry array
+ * @n_targets: the number of entries in the array
+ *
+ * This function frees a target table as returned by
+ * gtk_target_table_new_from_list()
+ *
+ * Since: 2.10
+ **/
+void
+gtk_target_table_free (GtkTargetEntry *targets,
+ gint n_targets)
+{
+ gint i;
+
+ g_return_if_fail (targets == NULL || n_targets > 0);
+
+ for (i = 0; i < n_targets; i++)
+ g_free (targets[i].target);
+
+ g_free (targets);
+}
+
/**
* gtk_selection_owner_set_for_display:
* @display: the #Gdkdisplay where the selection is set
current_selections = g_list_remove_link (current_selections,
tmp_list);
g_list_free (tmp_list);
- g_free (selection_info);
+ g_slice_free (GtkSelectionInfo, selection_info);
}
}
else
{
if (selection_info == NULL)
{
- selection_info = g_new (GtkSelectionInfo, 1);
+ selection_info = g_slice_new (GtkSelectionInfo);
selection_info->selection = selection;
selection_info->widget = widget;
selection_info->time = time;
selection, time);
}
-/*************************************************************
- * gtk_selection_add_target
- * Add specified target to list of supported targets
- *
- * arguments:
- * widget: The widget for which this target applies
- * selection:
- * target:
- * info: guint to pass to to the selection_get signal
- *
- * results:
- *************************************************************/
-
typedef struct _GtkSelectionTargetList GtkSelectionTargetList;
struct _GtkSelectionTargetList {
tmp_list = tmp_list->next;
}
- sellist = g_new (GtkSelectionTargetList, 1);
+ sellist = g_slice_new (GtkSelectionTargetList);
sellist->selection = selection;
sellist->list = gtk_target_list_new (NULL, 0);
lists = g_list_prepend (lists, sellist);
- g_object_set_data (G_OBJECT (widget), gtk_selection_handler_key, lists);
+ g_object_set_data (G_OBJECT (widget), I_(gtk_selection_handler_key), lists);
return sellist->list;
}
gtk_target_list_unref (sellist->list);
- g_free (sellist);
+ g_slice_free (GtkSelectionTargetList, sellist);
tmp_list = tmp_list->next;
}
g_list_free (lists);
- g_object_set_data (G_OBJECT (widget), gtk_selection_handler_key, NULL);
+ g_object_set_data (G_OBJECT (widget), I_(gtk_selection_handler_key), NULL);
}
/**
{
lists = g_list_delete_link (lists, tmp_list);
gtk_target_list_unref (sellist->list);
- g_free (sellist);
+ g_slice_free (GtkSelectionTargetList, sellist);
break;
}
tmp_list = tmp_list->next;
}
- g_object_set_data (G_OBJECT (widget), gtk_selection_handler_key, lists);
+ g_object_set_data (G_OBJECT (widget), I_(gtk_selection_handler_key), lists);
}
+/**
+ * gtk_selection_add_target:
+ * @widget: a #GtkTarget
+ * @selection: the selection
+ * @target: target to add.
+ * @info: A unsigned integer which will be passed back to the application.
+ *
+ * Appends a specified target to the list of supported targets for a
+ * given widget and selection.
+ **/
void
gtk_selection_add_target (GtkWidget *widget,
GdkAtom selection,
list = gtk_selection_target_list_get (widget, selection);
gtk_target_list_add (list, target, 0, info);
+#ifdef GDK_WINDOWING_WIN32
+ gdk_win32_selection_add_targets (widget->window, selection, 1, &target);
+#endif
}
+/**
+ * gtk_selection_add_targets:
+ * @widget: a #GtkWidget
+ * @selection: the selection
+ * @targets: a table of targets to add
+ * @ntargets: number of entries in @targets
+ *
+ * Prepends a table of targets to the list of supported targets
+ * for a given widget and selection.
+ **/
void
gtk_selection_add_targets (GtkWidget *widget,
GdkAtom selection,
list = gtk_selection_target_list_get (widget, selection);
gtk_target_list_add_table (list, targets, ntargets);
+
+#ifdef GDK_WINDOWING_WIN32
+ {
+ int i;
+ GdkAtom *atoms = g_new (GdkAtom, ntargets);
+
+ for (i = 0; i < ntargets; ++i)
+ atoms[i] = gdk_atom_intern (targets[i].target, FALSE);
+ gdk_win32_selection_add_targets (widget->window, selection, ntargets, atoms);
+ g_free (atoms);
+ }
+#endif
}
-/*************************************************************
+/**
* gtk_selection_remove_all:
- * Removes all handlers and unsets ownership of all
- * selections for a widget. Called when widget is being
- * destroyed
- *
- * arguments:
- * widget: The widget
- * results:
- *************************************************************/
-
+ * @widget: a #GtkWidget
+ *
+ * Removes all handlers and unsets ownership of all
+ * selections for a widget. Called when widget is being
+ * destroyed. This function will not generally be
+ * called by applications.
+ **/
void
gtk_selection_remove_all (GtkWidget *widget)
{
GList *tmp_list;
GList *next;
GtkSelectionInfo *selection_info;
-
+
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+
/* Remove pending requests/incrs for this widget */
tmp_list = current_retrievals;
current_selections = g_list_remove_link (current_selections,
tmp_list);
g_list_free (tmp_list);
- g_free (selection_info);
+ g_slice_free (GtkSelectionInfo, selection_info);
}
tmp_list = next;
gtk_selection_target_list_remove (widget);
}
-/*************************************************************
- * gtk_selection_convert:
- * Request the contents of a selection. When received,
- * a "selection_received" signal will be generated.
- *
- * arguments:
- * widget: The widget which acts as requestor
- * selection: Which selection to get
- * target: Form of information desired (e.g., STRING)
- * time: Time of request (usually of triggering event)
- * In emergency, you could use GDK_CURRENT_TIME
- *
- * results:
- * TRUE if requested succeeded. FALSE if we could not process
- * request. (e.g., there was already a request in process for
- * this widget).
- *************************************************************/
+/**
+ * gtk_selection_convert:
+ * @widget: The widget which acts as requestor
+ * @selection: Which selection to get
+ * @target: Form of information desired (e.g., STRING)
+ * @time_: Time of request (usually of triggering event)
+ In emergency, you could use #GDK_CURRENT_TIME
+ *
+ * Requests the contents of a selection. When received,
+ * a "selection_received" signal will be generated.
+ *
+ * Return value: %TRUE if requested succeeded. %FALSE if we could not process
+ * request. (e.g., there was already a request in process for
+ * this widget).
+ **/
gboolean
gtk_selection_convert (GtkWidget *widget,
GdkAtom selection,
GdkAtom target,
- guint32 time)
+ guint32 time_)
{
GtkRetrievalInfo *info;
GList *tmp_list;
tmp_list = tmp_list->next;
}
- info = g_new (GtkRetrievalInfo, 1);
+ info = g_slice_new (GtkRetrievalInfo);
info->widget = widget;
info->selection = selection;
{
gtk_selection_invoke_handler (owner_widget,
&selection_data,
- time);
+ time_);
gtk_selection_retrieval_report (info,
selection_data.type,
selection_data.format,
selection_data.data,
selection_data.length,
- time);
+ time_);
g_free (selection_data.data);
+ selection_data.data = NULL;
+ selection_data.length = -1;
- g_free (info);
+ g_slice_free (GtkRetrievalInfo, info);
return TRUE;
}
}
/* Otherwise, we need to go through X */
current_retrievals = g_list_append (current_retrievals, info);
- gdk_selection_convert (widget->window, selection, target, time);
- g_timeout_add (1000, (GSourceFunc) gtk_selection_retrieval_timeout, info);
+ gdk_selection_convert (widget->window, selection, target, time_);
+ gdk_threads_add_timeout (1000,
+ (GSourceFunc) gtk_selection_retrieval_timeout, info);
return TRUE;
}
-/*************************************************************
- * gtk_selection_data_set:
- * Store new data into a GtkSelectionData object. Should
- * _only_ by called from a selection handler callback.
- * Null terminates the stored data.
- * arguments:
- * type: the type of selection data
- * format: format (number of bits in a unit)
- * data: pointer to the data (will be copied)
- * length: length of the data
- * results:
- *************************************************************/
+/**
+ * gtk_selection_data_get_target:
+ * @selection_data: a pointer to a #GtkSelectionData structure.
+ *
+ * Retrieves the target of the selection.
+ *
+ * Since: 2.14
+ **/
+GdkAtom
+gtk_selection_data_get_target (GtkSelectionData *selection_data)
+{
+ g_return_val_if_fail (selection_data != NULL, 0);
+ return selection_data->target;
+}
+
+/**
+ * gtk_selection_data_get_data_type:
+ * @selection_data: a pointer to a #GtkSelectionData structure.
+ *
+ * Retrieves the data type of the selection.
+ *
+ * Since: 2.14
+ **/
+GdkAtom
+gtk_selection_data_get_data_type (GtkSelectionData *selection_data)
+{
+ g_return_val_if_fail (selection_data != NULL, 0);
+
+ return selection_data->type;
+}
+
+/**
+ * gtk_selection_data_get_format:
+ * @selection_data: a pointer to a #GtkSelectionData structure.
+ *
+ * Retrieves the format of the selection.
+ *
+ * Since: 2.14
+ **/
+gint
+gtk_selection_data_get_format (GtkSelectionData *selection_data)
+{
+ g_return_val_if_fail (selection_data != NULL, 0);
+
+ return selection_data->format;
+}
+
+/**
+ * gtk_selection_data_get_data:
+ * @selection_data: a pointer to a #GtkSelectionData structure.
+ * @length: an integer to be filled in, or %NULL
+ *
+ * Retrieves the raw data of the selection.
+ *
+ * If @length is not %NULL it is filled with the length of data.
+ *
+ * Since: 2.14
+ **/
+const guchar*
+gtk_selection_data_get_data (GtkSelectionData *selection_data,
+ guint *length)
+{
+ g_return_val_if_fail (selection_data != NULL, NULL);
+
+ if (length)
+ *length = selection_data->length;
+
+ return selection_data->data;
+}
+
+/**
+ * gtk_selection_data_get_display:
+ * @selection_data: a pointer to a #GtkSelectionData structure.
+ *
+ * Retrieves the display of the selection.
+ *
+ * Since: 2.14
+ **/
+GdkDisplay *
+gtk_selection_data_get_display (GtkSelectionData *selection_data)
+{
+ g_return_val_if_fail (selection_data != NULL, NULL);
+
+ return selection_data->display;
+}
+
+/**
+ * gtk_selection_data_set:
+ * @selection_data: a pointer to a #GtkSelectionData structure.
+ * @type: the type of selection data
+ * @format: format (number of bits in a unit)
+ * @data: pointer to the data (will be copied)
+ * @length: length of the data
+ *
+ * Stores new data into a #GtkSelectionData object. Should
+ * <emphasis>only</emphasis> be called from a selection handler callback.
+ * Zero-terminates the stored data.
+ **/
void
gtk_selection_data_set (GtkSelectionData *selection_data,
GdkAtom type,
const guchar *data,
gint length)
{
- if (selection_data->data)
- g_free (selection_data->data);
+ g_return_if_fail (selection_data != NULL);
+
+ g_free (selection_data->data);
selection_data->type = type;
selection_data->format = format;
if (length < 0)
selection_data->data = NULL;
else
- selection_data->data = g_strdup("");
+ selection_data->data = (guchar *) g_strdup ("");
}
selection_data->length = length;
{
gtk_selection_data_set (selection_data,
GDK_SELECTION_TYPE_STRING,
- 8, latin1, strlen (latin1));
+ 8, (guchar *) latin1, strlen (latin1));
g_free (latin1);
return TRUE;
{
GString *result = g_string_sized_new (len);
const gchar *p = str;
+ const gchar *end = str + len;
- while (1)
+ while (p < end)
{
if (*p == '\n')
g_string_append_c (result, '\r');
{
g_string_append_c (result, *p);
p++;
- if (*p != '\n')
+ if (p == end || *p != '\n')
g_string_append_c (result, '\n');
+ if (p == end)
+ break;
}
- if (*p == '\0')
- break;
-
g_string_append_c (result, *p);
p++;
}
if (!result)
{
- g_warning ("Error converting from UTF-8 to %s: %s",
- charset, error->message);
+ g_warning ("Error converting from %s to %s: %s",
+ "UTF-8", charset, error->message);
g_error_free (error);
return FALSE;
gtk_selection_data_set (selection_data,
selection_data->target,
- 8, result, strlen (result));
+ 8, (guchar *) result, strlen (result));
g_free (result);
return TRUE;
}
-static gchar *
+static guchar *
selection_get_text_plain (GtkSelectionData *selection_data)
{
const gchar *charset = NULL;
gsize len;
GError *error = NULL;
- str = g_strdup (selection_data->data);
+ str = g_strdup ((const gchar *) selection_data->data);
len = selection_data->length;
if (selection_data->type == text_plain_atom)
{
gchar *tmp = str;
str = g_convert_with_fallback (tmp, len,
- charset, "UTF-8",
+ "UTF-8", charset,
NULL, NULL, &len, &error);
g_free (tmp);
if (!str)
{
- g_warning ("Error converting from %s to UTF-8: %s",
- charset, error->message);
+ g_warning ("Error converting from %s to %s: %s",
+ charset, "UTF-8", error->message);
g_error_free (error);
return NULL;
}
else if (!g_utf8_validate (str, -1, NULL))
{
- g_warning ("Error converting from text/plain;charset=utf-8 to UTF-8");
+ g_warning ("Error converting from %s to %s: %s",
+ "text/plain;charset=utf-8", "UTF-8", "invalid UTF-8");
g_free (str);
return NULL;
result = normalize_to_lf (str, len);
g_free (str);
- return result;
+ return (guchar *) result;
}
/**
const gchar *str,
gint len)
{
+ g_return_val_if_fail (selection_data != NULL, FALSE);
+
if (len < 0)
len = strlen (str);
{
guchar *result = NULL;
+ g_return_val_if_fail (selection_data != NULL, NULL);
+
init_atoms ();
if (selection_data->length >= 0 &&
selection_data->length,
&list);
if (count > 0)
- result = list[0];
+ result = (guchar *) list[0];
for (i = 1; i < count; i++)
g_free (list[i]);
gchar *str, *type;
gsize len;
+ g_return_val_if_fail (selection_data != NULL, FALSE);
+ g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), FALSE);
+
formats = gdk_pixbuf_get_formats ();
for (f = formats; f; f = f->next)
if (selection_data->target == atom)
{
str = NULL;
- type = gdk_pixbuf_format_get_name (fmt),
- result = gdk_pixbuf_save_to_buffer (pixbuf,
- &str,
- &len,
- type,
- NULL);
- if (result)
+ type = gdk_pixbuf_format_get_name (fmt);
+ result = gdk_pixbuf_save_to_buffer (pixbuf, &str, &len,
+ type, NULL,
+ ((strcmp (type, "png") == 0) ?
+ "compression" : NULL), "2",
+ NULL);
+ if (result)
gtk_selection_data_set (selection_data,
atom, 8, (guchar *)str, len);
g_free (type);
g_free (str);
g_strfreev (mimes);
g_slist_free (formats);
-
+
return result;
}
}
GdkPixbufLoader *loader;
GdkPixbuf *result = NULL;
- loader = gdk_pixbuf_loader_new ();
-
- if (gdk_pixbuf_loader_write (loader,
+ g_return_val_if_fail (selection_data != NULL, NULL);
+
+ if (selection_data->length > 0)
+ {
+ loader = gdk_pixbuf_loader_new ();
+
+ gdk_pixbuf_loader_write (loader,
selection_data->data,
selection_data->length,
- NULL))
- result = gdk_pixbuf_loader_get_pixbuf (loader);
-
- if (result)
- g_object_ref (result);
+ NULL);
+ gdk_pixbuf_loader_close (loader, NULL);
+ result = gdk_pixbuf_loader_get_pixbuf (loader);
+
+ if (result)
+ g_object_ref (result);
+
+ g_object_unref (loader);
+ }
- gdk_pixbuf_loader_close (loader, NULL);
- g_object_unref (loader);
-
return result;
}
gtk_selection_data_set_uris (GtkSelectionData *selection_data,
gchar **uris)
{
+ g_return_val_if_fail (selection_data != NULL, FALSE);
+ g_return_val_if_fail (uris != NULL, FALSE);
+
init_atoms ();
if (selection_data->target == text_uri_list_atom)
gchar *result;
gsize length;
- list = g_string_new (0);
+ list = g_string_new (NULL);
for (i = 0; uris[i]; i++)
{
g_string_append (list, uris[i]);
text_uri_list_atom,
8, (guchar *)result, length);
+ g_free (result);
+
return TRUE;
}
}
{
gchar **result = NULL;
+ g_return_val_if_fail (selection_data != NULL, NULL);
+
init_atoms ();
if (selection_data->length >= 0 &&
selection_data->type == text_uri_list_atom)
{
gchar **list;
- gint i;
gint count = gdk_text_property_to_utf8_list_for_display (selection_data->display,
utf8_atom,
selection_data->format,
if (count > 0)
result = g_uri_list_extract_uris (list[0]);
- for (i = 1; i < count; i++)
- g_free (list[i]);
- g_free (list);
+ g_strfreev (list);
}
return result;
GdkAtom **targets,
gint *n_atoms)
{
+ g_return_val_if_fail (selection_data != NULL, FALSE);
+
if (selection_data->length >= 0 &&
selection_data->format == 32 &&
selection_data->type == GDK_SELECTION_TYPE_ATOM)
}
}
+/**
+ * gtk_targets_include_text:
+ * @targets: an array of #GdkAtom<!-- -->s
+ * @n_targets: the length of @targets
+ *
+ * Determines if any of the targets in @targets can be used to
+ * provide text.
+ *
+ * Return value: %TRUE if @targets include a suitable target for text,
+ * otherwise %FALSE.
+ *
+ * Since: 2.10
+ **/
+gboolean
+gtk_targets_include_text (GdkAtom *targets,
+ gint n_targets)
+{
+ gint i;
+ gboolean result = FALSE;
+
+ g_return_val_if_fail (targets != NULL || n_targets == 0, FALSE);
+
+ /* Keep in sync with gtk_target_list_add_text_targets()
+ */
+
+ init_atoms ();
+
+ for (i = 0; i < n_targets; i++)
+ {
+ if (targets[i] == utf8_atom ||
+ targets[i] == text_atom ||
+ targets[i] == GDK_TARGET_STRING ||
+ targets[i] == ctext_atom ||
+ targets[i] == text_plain_atom ||
+ targets[i] == text_plain_utf8_atom ||
+ targets[i] == text_plain_locale_atom)
+ {
+ result = TRUE;
+ break;
+ }
+ }
+
+ return result;
+}
+
+/**
+ * gtk_targets_include_rich_text:
+ * @targets: an array of #GdkAtom<!-- -->s
+ * @n_targets: the length of @targets
+ * @buffer: a #GtkTextBuffer
+ *
+ * Determines if any of the targets in @targets can be used to
+ * provide rich text.
+ *
+ * Return value: %TRUE if @targets include a suitable target for rich text,
+ * otherwise %FALSE.
+ *
+ * Since: 2.10
+ **/
+gboolean
+gtk_targets_include_rich_text (GdkAtom *targets,
+ gint n_targets,
+ GtkTextBuffer *buffer)
+{
+ GdkAtom *rich_targets;
+ gint n_rich_targets;
+ gint i, j;
+ gboolean result = FALSE;
+
+ g_return_val_if_fail (targets != NULL || n_targets == 0, FALSE);
+ g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
+
+ init_atoms ();
+
+ rich_targets = gtk_text_buffer_get_deserialize_formats (buffer,
+ &n_rich_targets);
+
+ for (i = 0; i < n_targets; i++)
+ {
+ for (j = 0; j < n_rich_targets; j++)
+ {
+ if (targets[i] == rich_targets[j])
+ {
+ result = TRUE;
+ goto done;
+ }
+ }
+ }
+
+ done:
+ g_free (rich_targets);
+
+ return result;
+}
+
/**
* gtk_selection_data_targets_include_text:
* @selection_data: a #GtkSelectionData object
{
GdkAtom *targets;
gint n_targets;
+ gboolean result = FALSE;
+
+ g_return_val_if_fail (selection_data != NULL, FALSE);
+
+ init_atoms ();
+
+ if (gtk_selection_data_get_targets (selection_data, &targets, &n_targets))
+ {
+ result = gtk_targets_include_text (targets, n_targets);
+ g_free (targets);
+ }
+
+ return result;
+}
+
+/**
+ * gtk_selection_data_targets_include_rich_text:
+ * @selection_data: a #GtkSelectionData object
+ * @buffer: a #GtkTextBuffer
+ *
+ * Given a #GtkSelectionData object holding a list of targets,
+ * determines if any of the targets in @targets can be used to
+ * provide rich text.
+ *
+ * Return value: %TRUE if @selection_data holds a list of targets,
+ * and a suitable target for rich text is included,
+ * otherwise %FALSE.
+ *
+ * Since: 2.10
+ **/
+gboolean
+gtk_selection_data_targets_include_rich_text (GtkSelectionData *selection_data,
+ GtkTextBuffer *buffer)
+{
+ GdkAtom *targets;
+ gint n_targets;
+ gboolean result = FALSE;
+
+ g_return_val_if_fail (selection_data != NULL, FALSE);
+ g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
+
+ init_atoms ();
+
+ if (gtk_selection_data_get_targets (selection_data, &targets, &n_targets))
+ {
+ result = gtk_targets_include_rich_text (targets, n_targets, buffer);
+ g_free (targets);
+ }
+
+ return result;
+}
+
+/**
+ * gtk_targets_include_image:
+ * @targets: an array of #GdkAtom<!-- -->s
+ * @n_targets: the length of @targets
+ * @writable: whether to accept only targets for which GTK+ knows
+ * how to convert a pixbuf into the format
+ *
+ * Determines if any of the targets in @targets can be used to
+ * provide a #GdkPixbuf.
+ *
+ * Return value: %TRUE if @targets include a suitable target for images,
+ * otherwise %FALSE.
+ *
+ * Since: 2.10
+ **/
+gboolean
+gtk_targets_include_image (GdkAtom *targets,
+ gint n_targets,
+ gboolean writable)
+{
+ GtkTargetList *list;
+ GList *l;
gint i;
gboolean result = FALSE;
+ g_return_val_if_fail (targets != NULL || n_targets == 0, FALSE);
+
+ list = gtk_target_list_new (NULL, 0);
+ gtk_target_list_add_image_targets (list, 0, writable);
+ for (i = 0; i < n_targets && !result; i++)
+ {
+ for (l = list->list; l; l = l->next)
+ {
+ GtkTargetPair *pair = (GtkTargetPair *)l->data;
+ if (pair->target == targets[i])
+ {
+ result = TRUE;
+ break;
+ }
+ }
+ }
+ gtk_target_list_unref (list);
+
+ return result;
+}
+
+/**
+ * gtk_selection_data_targets_include_image:
+ * @selection_data: a #GtkSelectionData object
+ * @writable: whether to accept only targets for which GTK+ knows
+ * how to convert a pixbuf into the format
+ *
+ * Given a #GtkSelectionData object holding a list of targets,
+ * determines if any of the targets in @targets can be used to
+ * provide a #GdkPixbuf.
+ *
+ * Return value: %TRUE if @selection_data holds a list of targets,
+ * and a suitable target for images is included, otherwise %FALSE.
+ *
+ * Since: 2.6
+ **/
+gboolean
+gtk_selection_data_targets_include_image (GtkSelectionData *selection_data,
+ gboolean writable)
+{
+ GdkAtom *targets;
+ gint n_targets;
+ gboolean result = FALSE;
+
+ g_return_val_if_fail (selection_data != NULL, FALSE);
+
init_atoms ();
if (gtk_selection_data_get_targets (selection_data, &targets, &n_targets))
{
- for (i=0; i < n_targets; i++)
+ result = gtk_targets_include_image (targets, n_targets, writable);
+ g_free (targets);
+ }
+
+ return result;
+}
+
+/**
+ * gtk_targets_include_uri:
+ * @targets: an array of #GdkAtom<!-- -->s
+ * @n_targets: the length of @targets
+ *
+ * Determines if any of the targets in @targets can be used to
+ * provide an uri list.
+ *
+ * Return value: %TRUE if @targets include a suitable target for uri lists,
+ * otherwise %FALSE.
+ *
+ * Since: 2.10
+ **/
+gboolean
+gtk_targets_include_uri (GdkAtom *targets,
+ gint n_targets)
+{
+ gint i;
+ gboolean result = FALSE;
+
+ g_return_val_if_fail (targets != NULL || n_targets == 0, FALSE);
+
+ /* Keep in sync with gtk_target_list_add_uri_targets()
+ */
+
+ init_atoms ();
+
+ for (i = 0; i < n_targets; i++)
+ {
+ if (targets[i] == text_uri_list_atom)
{
- if (targets[i] == utf8_atom ||
- targets[i] == text_atom ||
- targets[i] == GDK_TARGET_STRING ||
- targets[i] == ctext_atom ||
- targets[i] == text_plain_atom ||
- targets[i] == text_plain_utf8_atom ||
- targets[i] == text_plain_locale_atom)
- result = TRUE;
+ result = TRUE;
+ break;
}
+ }
+
+ return result;
+}
+/**
+ * gtk_selection_data_targets_include_uri:
+ * @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 a list or URIs.
+ *
+ * Return value: %TRUE if @selection_data holds a list of targets,
+ * and a suitable target for URI lists is included, otherwise %FALSE.
+ *
+ * Since: 2.10
+ **/
+gboolean
+gtk_selection_data_targets_include_uri (GtkSelectionData *selection_data)
+{
+ GdkAtom *targets;
+ gint n_targets;
+ gboolean result = FALSE;
+
+ g_return_val_if_fail (selection_data != NULL, FALSE);
+
+ init_atoms ();
+
+ if (gtk_selection_data_get_targets (selection_data, &targets, &n_targets))
+ {
+ result = gtk_targets_include_uri (targets, n_targets);
g_free (targets);
}
return result;
}
+
/*************************************************************
* gtk_selection_init:
static void
gtk_selection_init (void)
{
- gtk_selection_atoms[INCR] = gdk_atom_intern ("INCR", FALSE);
- gtk_selection_atoms[MULTIPLE] = gdk_atom_intern ("MULTIPLE", FALSE);
- gtk_selection_atoms[TIMESTAMP] = gdk_atom_intern ("TIMESTAMP", FALSE);
- gtk_selection_atoms[TARGETS] = gdk_atom_intern ("TARGETS", FALSE);
+ gtk_selection_atoms[INCR] = gdk_atom_intern_static_string ("INCR");
+ gtk_selection_atoms[MULTIPLE] = gdk_atom_intern_static_string ("MULTIPLE");
+ gtk_selection_atoms[TIMESTAMP] = gdk_atom_intern_static_string ("TIMESTAMP");
+ gtk_selection_atoms[TARGETS] = gdk_atom_intern_static_string ("TARGETS");
initialize = FALSE;
}
*
* Since: 2.2
*
- * Deprecated: Instead of calling this function, chain up from
+ * Deprecated: 2.4: Instead of calling this function, chain up from
* your selection_clear_event handler. Calling this function
* from any other context is illegal.
**/
{
current_selections = g_list_remove_link (current_selections, tmp_list);
g_list_free (tmp_list);
- g_free (selection_info);
+ g_slice_free (GtkSelectionInfo, selection_info);
}
return TRUE;
if (tmp_list == NULL)
return FALSE;
- info = g_new (GtkIncrInfo, 1);
+ info = g_slice_new (GtkIncrInfo);
g_object_ref (widget);
GDK_NONE,
event->time);
g_free (mult_atoms);
- g_free (info);
+ g_slice_free (GtkIncrInfo, info);
+ gdk_error_trap_pop ();
return TRUE;
}
gdk_error_trap_pop ();
*/
#ifdef GDK_WINDOWING_X11
if (type != GDK_SELECTION_TYPE_ATOM &&
- type != gdk_atom_intern ("ATOM_PAIR", FALSE))
+ type != gdk_atom_intern_static_string ("ATOM_PAIR"))
{
info->num_conversions = length / (2*sizeof (glong));
info->conversions = g_new (GtkIncrConversion, info->num_conversions);
info->conversions[i].property = gdk_x11_xatom_to_atom_for_display (display,
((glong *)mult_atoms)[2*i + 1]);
}
+
+ g_free (mult_atoms);
}
else
#endif
info->conversions[i].target = ((GdkAtom *)mult_atoms)[2*i];
info->conversions[i].property = ((GdkAtom *)mult_atoms)[2*i+1];
}
+
+ g_free (mult_atoms);
}
}
else /* only a single conversion */
gdk_window_get_events (info->requestor) |
GDK_PROPERTY_CHANGE_MASK);
current_incrs = g_list_append (current_incrs, info);
- g_timeout_add (1000, (GSourceFunc) gtk_selection_incr_timeout, info);
+ gdk_threads_add_timeout (1000, (GSourceFunc) gtk_selection_incr_timeout, info);
}
/* If it was a MULTIPLE request, set the property to indicate which
}
gdk_property_change (info->requestor, event->property,
- gdk_atom_intern ("ATOM_PAIR", FALSE), 32,
+ gdk_atom_intern_static_string ("ATOM_PAIR"), 32,
GDK_PROP_MODE_REPLACE,
(guchar *)mult_atoms, 2*info->num_conversions);
g_free (mult_atoms);
if (info->num_incrs == 0)
{
g_free (info->conversions);
- g_free (info);
+ g_slice_free (GtkIncrInfo, info);
}
g_object_unref (widget);
GList *tmp_list;
gboolean retval;
- GDK_THREADS_ENTER ();
-
/* Determine if retrieval has finished by checking if it still in
list of pending retrievals */
/* FIXME: we should check if requestor window is still in use,
and if not, remove it? */
- g_free (info);
+ g_slice_free (GtkIncrInfo, info);
retval = FALSE; /* remove timeout */
}
retval = TRUE; /* timeout will happen again */
}
- GDK_THREADS_LEAVE ();
-
return retval;
}
#if defined(GDK_WINDOWING_WIN32) || defined(GDK_WINDOWING_X11)
if ((event->state != GDK_PROPERTY_NEW_VALUE) || /* property was deleted */
- (event->atom != gdk_atom_intern ("GDK_SELECTION", FALSE))) /* not the right property */
+ (event->atom != gdk_atom_intern_static_string ("GDK_SELECTION"))) /* not the right property */
#endif
return FALSE;
* results:
*************************************************************/
-static gint
+static gboolean
gtk_selection_retrieval_timeout (GtkRetrievalInfo *info)
{
GList *tmp_list;
gboolean retval;
- GDK_THREADS_ENTER ();
-
/* Determine if retrieval has finished by checking if it still in
list of pending retrievals */
}
g_free (info->buffer);
- g_free (info);
+ g_slice_free (GtkRetrievalInfo, info);
retval = FALSE; /* remove timeout */
}
retval = TRUE; /* timeout will happen again */
}
- GDK_THREADS_LEAVE ();
-
return retval;
}
}
+/**
+ * gtk_selection_data_copy:
+ * @data: a pointer to a #GtkSelectionData structure.
+ *
+ * Makes a copy of a #GtkSelectionData structure and its data.
+ *
+ * Return value: a pointer to a copy of @data.
+ **/
GtkSelectionData*
-gtk_selection_data_copy (GtkSelectionData *selection_data)
+gtk_selection_data_copy (GtkSelectionData *data)
{
GtkSelectionData *new_data;
- g_return_val_if_fail (selection_data != NULL, NULL);
+ g_return_val_if_fail (data != NULL, NULL);
- new_data = g_new (GtkSelectionData, 1);
- *new_data = *selection_data;
+ new_data = g_slice_new (GtkSelectionData);
+ *new_data = *data;
- if (selection_data->data)
+ if (data->data)
{
- new_data->data = g_malloc (selection_data->length + 1);
- memcpy (new_data->data, selection_data->data, selection_data->length + 1);
+ new_data->data = g_malloc (data->length + 1);
+ memcpy (new_data->data, data->data, data->length + 1);
}
return new_data;
}
+/**
+ * gtk_selection_data_free:
+ * @data: a pointer to a #GtkSelectionData structure.
+ *
+ * Frees a #GtkSelectionData structure returned from
+ * gtk_selection_data_copy().
+ **/
void
gtk_selection_data_free (GtkSelectionData *data)
{
g_return_if_fail (data != NULL);
- if (data->data)
- g_free (data->data);
+ g_free (data->data);
- g_free (data);
+ g_slice_free (GtkSelectionData, data);
}
GType
static GType our_type = 0;
if (our_type == 0)
- our_type = g_boxed_type_register_static ("GtkSelectionData",
+ our_type = g_boxed_type_register_static (I_("GtkSelectionData"),
(GBoxedCopyFunc) gtk_selection_data_copy,
(GBoxedFreeFunc) gtk_selection_data_free);
return our_type;
}
+GType
+gtk_target_list_get_type (void)
+{
+ static GType our_type = 0;
+
+ if (our_type == 0)
+ our_type = g_boxed_type_register_static (I_("GtkTargetList"),
+ (GBoxedCopyFunc) gtk_target_list_ref,
+ (GBoxedFreeFunc) gtk_target_list_unref);
+
+ return our_type;
+}
+
static int
gtk_selection_bytes_per_item (gint format)
{
}
return 0;
}
+
+#define __GTK_SELECTION_C__
+#include "gtkaliasdef.c"