summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2004-10-31 05:40:25 +0000
committerMatthias Clasen <matthiasc@src.gnome.org>2004-10-31 05:40:25 +0000
commit1c8e6a0e4fe16dcb9dafc5f1c90bc34bd7b3a9c4 (patch)
tree14b23a3036bf2d423b0b5eca44b7e5c40ae64e6e
parent20d47e6c56a43fbb9890c8a06b359984c7ad1086 (diff)
downloadgtk+-1c8e6a0e4fe16dcb9dafc5f1c90bc34bd7b3a9c4.tar.gz
Add api for image transfer via copy-and-paste (#156408)
2004-10-31 Matthias Clasen <mclasen@redhat.com> Add api for image transfer via copy-and-paste (#156408) * gtk/gtkclipboard.c (gtk_clipboard_set_image) (gtk_clipboard_request_image, gtk_clipboard_wait_for_image) (gtk_clipboard_wait_is_image_available): New functions for image transfer. * gtk/gtkselection.h: * gtk/gtkselection.c (gtk_selection_data_targets_include_image): New function, similar to gtk_selection_data_targets_include_text().
-rw-r--r--ChangeLog11
-rw-r--r--ChangeLog.pre-2-1011
-rw-r--r--ChangeLog.pre-2-611
-rw-r--r--ChangeLog.pre-2-811
-rw-r--r--docs/reference/gtk/gtk-sections.txt5
-rw-r--r--gtk/gtkclipboard.c252
-rw-r--r--gtk/gtkclipboard.h10
-rw-r--r--gtk/gtkselection.c53
-rw-r--r--gtk/gtkselection.h8
9 files changed, 358 insertions, 14 deletions
diff --git a/ChangeLog b/ChangeLog
index 3fb4d9189b..4d9f121d30 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
2004-10-31 Matthias Clasen <mclasen@redhat.com>
+ Add api for image transfer via copy-and-paste (#156408)
+
+ * gtk/gtkclipboard.c (gtk_clipboard_set_image)
+ (gtk_clipboard_request_image, gtk_clipboard_wait_for_image)
+ (gtk_clipboard_wait_is_image_available): New functions for image
+ transfer.
+
+ * gtk/gtkselection.h:
+ * gtk/gtkselection.c (gtk_selection_data_targets_include_image):
+ New function, similar to gtk_selection_data_targets_include_text().
+
* gtk/gtkprogressbar.[hc]: Add an ellipsize property with
getter and setter. (#156845, Morten Welinder)
diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10
index 3fb4d9189b..4d9f121d30 100644
--- a/ChangeLog.pre-2-10
+++ b/ChangeLog.pre-2-10
@@ -1,5 +1,16 @@
2004-10-31 Matthias Clasen <mclasen@redhat.com>
+ Add api for image transfer via copy-and-paste (#156408)
+
+ * gtk/gtkclipboard.c (gtk_clipboard_set_image)
+ (gtk_clipboard_request_image, gtk_clipboard_wait_for_image)
+ (gtk_clipboard_wait_is_image_available): New functions for image
+ transfer.
+
+ * gtk/gtkselection.h:
+ * gtk/gtkselection.c (gtk_selection_data_targets_include_image):
+ New function, similar to gtk_selection_data_targets_include_text().
+
* gtk/gtkprogressbar.[hc]: Add an ellipsize property with
getter and setter. (#156845, Morten Welinder)
diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6
index 3fb4d9189b..4d9f121d30 100644
--- a/ChangeLog.pre-2-6
+++ b/ChangeLog.pre-2-6
@@ -1,5 +1,16 @@
2004-10-31 Matthias Clasen <mclasen@redhat.com>
+ Add api for image transfer via copy-and-paste (#156408)
+
+ * gtk/gtkclipboard.c (gtk_clipboard_set_image)
+ (gtk_clipboard_request_image, gtk_clipboard_wait_for_image)
+ (gtk_clipboard_wait_is_image_available): New functions for image
+ transfer.
+
+ * gtk/gtkselection.h:
+ * gtk/gtkselection.c (gtk_selection_data_targets_include_image):
+ New function, similar to gtk_selection_data_targets_include_text().
+
* gtk/gtkprogressbar.[hc]: Add an ellipsize property with
getter and setter. (#156845, Morten Welinder)
diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8
index 3fb4d9189b..4d9f121d30 100644
--- a/ChangeLog.pre-2-8
+++ b/ChangeLog.pre-2-8
@@ -1,5 +1,16 @@
2004-10-31 Matthias Clasen <mclasen@redhat.com>
+ Add api for image transfer via copy-and-paste (#156408)
+
+ * gtk/gtkclipboard.c (gtk_clipboard_set_image)
+ (gtk_clipboard_request_image, gtk_clipboard_wait_for_image)
+ (gtk_clipboard_wait_is_image_available): New functions for image
+ transfer.
+
+ * gtk/gtkselection.h:
+ * gtk/gtkselection.c (gtk_selection_data_targets_include_image):
+ New function, similar to gtk_selection_data_targets_include_text().
+
* gtk/gtkprogressbar.[hc]: Add an ellipsize property with
getter and setter. (#156845, Morten Welinder)
diff --git a/docs/reference/gtk/gtk-sections.txt b/docs/reference/gtk/gtk-sections.txt
index b235fdd7ac..7127b856b9 100644
--- a/docs/reference/gtk/gtk-sections.txt
+++ b/docs/reference/gtk/gtk-sections.txt
@@ -5033,6 +5033,7 @@ gtk_selection_data_get_pixbuf
gtk_selection_data_set_uris
gtk_selection_data_get_uris
gtk_selection_data_get_targets
+gtk_selection_data_targets_include_image
gtk_selection_data_targets_include_text
gtk_selection_remove_all
gtk_selection_clear
@@ -5062,12 +5063,16 @@ gtk_clipboard_set_with_owner
gtk_clipboard_get_owner
gtk_clipboard_clear
gtk_clipboard_set_text
+gtk_clipboard_set_image
gtk_clipboard_request_contents
gtk_clipboard_request_text
+gtk_clipboard_request_image
gtk_clipboard_request_targets
gtk_clipboard_wait_for_contents
gtk_clipboard_wait_for_text
+gtk_clipboard_wait_for_image
gtk_clipboard_wait_is_text_available
+gtk_clipboard_wait_is_image_available
gtk_clipboard_wait_for_targets
gtk_clipboard_wait_is_target_available
gtk_clipboard_set_can_store
diff --git a/gtk/gtkclipboard.c b/gtk/gtkclipboard.c
index cc78e1f847..6a23db7e83 100644
--- a/gtk/gtkclipboard.c
+++ b/gtk/gtkclipboard.c
@@ -46,6 +46,7 @@ typedef struct _GtkClipboardClass GtkClipboardClass;
typedef struct _RequestContentsInfo RequestContentsInfo;
typedef struct _RequestTextInfo RequestTextInfo;
+typedef struct _RequestImageInfo RequestImageInfo;
typedef struct _RequestTargetsInfo RequestTargetsInfo;
struct _GtkClipboard
@@ -95,6 +96,12 @@ struct _RequestTextInfo
gpointer user_data;
};
+struct _RequestImageInfo
+{
+ GtkClipboardImageReceivedFunc callback;
+ gpointer user_data;
+};
+
struct _RequestTargetsInfo
{
GtkClipboardTargetsReceivedFunc callback;
@@ -702,6 +709,7 @@ text_clear_func (GtkClipboard *clipboard,
g_free (data);
}
+
/**
* gtk_clipboard_set_text:
* @clipboard: a #GtkClipboard object
@@ -731,15 +739,13 @@ gtk_clipboard_set_text (GtkClipboard *clipboard,
gtk_target_list_add_text_targets (list, 0);
n_targets = g_list_length (list->list);
- targets = g_new (GtkTargetEntry, n_targets);
+ targets = g_new0 (GtkTargetEntry, n_targets);
for (l = list->list, i = 0; l; l = l->next, i++)
{
GtkTargetPair *pair = (GtkTargetPair *)l->data;
targets[i].target = gdk_atom_name (pair->target);
- targets[i].flags = 0;
- targets[i].info = 0;
}
-
+
if (len < 0)
len = strlen (text);
@@ -753,6 +759,67 @@ gtk_clipboard_set_text (GtkClipboard *clipboard,
gtk_target_list_unref (list);
}
+static void
+pixbuf_get_func (GtkClipboard *clipboard,
+ GtkSelectionData *selection_data,
+ guint info,
+ gpointer data)
+{
+ gtk_selection_data_set_pixbuf (selection_data, data);
+}
+
+static void
+pixbuf_clear_func (GtkClipboard *clipboard,
+ gpointer data)
+{
+ g_object_unref (data);
+}
+
+/**
+ * gtk_clipboard_set_image:
+ * @clipboard: a #GtkClipboard object
+ * @pixbuf: a #GdkPixbuf
+ *
+ * Sets the contents of the clipboard to the given #GdkPixbuf.
+ * GTK+ will take responsibility for responding for requests
+ * for the image, and for converting the image into the
+ * requested format.
+ *
+ * Since: 2.6
+ **/
+void
+gtk_clipboard_set_image (GtkClipboard *clipboard,
+ GdkPixbuf *pixbuf)
+{
+ GtkTargetList *list;
+ GList *l;
+ GtkTargetEntry *targets;
+ gint n_targets, i;
+
+ g_return_if_fail (clipboard != NULL);
+ g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
+
+ list = gtk_target_list_new (NULL, 0);
+ gtk_target_list_add_image_targets (list, 0, TRUE);
+
+ n_targets = g_list_length (list->list);
+ targets = g_new0 (GtkTargetEntry, n_targets);
+ for (l = list->list, i = 0; l; l = l->next, i++)
+ {
+ GtkTargetPair *pair = (GtkTargetPair *)l->data;
+ targets[i].target = gdk_atom_name (pair->target);
+ }
+
+ gtk_clipboard_set_with_data (clipboard,
+ targets, n_targets,
+ pixbuf_get_func, pixbuf_clear_func,
+ g_object_ref (pixbuf));
+ gtk_clipboard_set_can_store (clipboard, NULL, 0);
+
+ g_free (targets);
+ gtk_target_list_unref (list);
+}
+
static void
set_request_contents_info (GtkWidget *widget,
RequestContentsInfo *info)
@@ -910,6 +977,83 @@ gtk_clipboard_request_text (GtkClipboard *clipboard,
}
static void
+request_image_received_func (GtkClipboard *clipboard,
+ GtkSelectionData *selection_data,
+ gpointer data)
+{
+ RequestImageInfo *info = data;
+ GdkPixbuf *result = NULL;
+
+ result = gtk_selection_data_get_pixbuf (selection_data);
+
+ if (!result)
+ {
+ /* If we asked for image/png and didn't get it, try image/jpeg;
+ * if we asked for image/jpeg and didn't get it, try image/gif;
+ * If we asked for anything else and didn't get it, give up.
+ */
+ if (selection_data->target == gdk_atom_intern ("image/png", FALSE))
+ {
+ gtk_clipboard_request_contents (clipboard,
+ gdk_atom_intern ("image/jpeg", FALSE),
+ request_image_received_func, info);
+ return;
+ }
+ else if (selection_data->target == gdk_atom_intern ("image/jpeg", FALSE))
+ {
+ gtk_clipboard_request_contents (clipboard,
+ gdk_atom_intern ("image/gif", FALSE),
+ request_text_received_func, info);
+ return;
+ }
+ }
+
+ info->callback (clipboard, result, info->user_data);
+ g_free (info);
+ g_object_unref (result);
+}
+
+/**
+ * gtk_clipboard_request_image:
+ * @clipboard: a #GtkClipboard
+ * @callback: a function to call when the image is received,
+ * or the retrieval fails. (It will always be called
+ * one way or the other.)
+ * @user_data: user data to pass to @callback.
+ *
+ * Requests the contents of the clipboard as image. When the image is
+ * later received, it will be converted to a #GdkPixbuf, and
+ * @callback will be called.
+ *
+ * The @pixbuf parameter to @callback will contain the resulting
+ * #GdkPixbuf if the request succeeded, or %NULL if it failed. This
+ * could happen for various reasons, in particular if the clipboard
+ * was empty or if the contents of the clipboard could not be
+ * converted into an image.
+ *
+ * Since: 2.6
+ **/
+void
+gtk_clipboard_request_image (GtkClipboard *clipboard,
+ GtkClipboardImageReceivedFunc callback,
+ gpointer user_data)
+{
+ RequestImageInfo *info;
+
+ g_return_if_fail (clipboard != NULL);
+ g_return_if_fail (callback != NULL);
+
+ info = g_new (RequestImageInfo, 1);
+ info->callback = callback;
+ info->user_data = user_data;
+
+ gtk_clipboard_request_contents (clipboard,
+ gdk_atom_intern ("image/png", FALSE),
+ request_image_received_func,
+ info);
+}
+
+static void
request_targets_received_func (GtkClipboard *clipboard,
GtkSelectionData *selection_data,
gpointer data)
@@ -1042,7 +1186,6 @@ clipboard_text_received_func (GtkClipboard *clipboard,
g_main_loop_quit (results->loop);
}
-
/**
* gtk_clipboard_wait_for_text:
* @clipboard: a #GtkClipboard
@@ -1065,7 +1208,6 @@ gtk_clipboard_wait_for_text (GtkClipboard *clipboard)
WaitResults results;
g_return_val_if_fail (clipboard != NULL, NULL);
- g_return_val_if_fail (clipboard != NULL, NULL);
results.data = NULL;
results.loop = g_main_loop_new (NULL, TRUE);
@@ -1085,6 +1227,62 @@ gtk_clipboard_wait_for_text (GtkClipboard *clipboard)
return results.data;
}
+
+static void
+clipboard_image_received_func (GtkClipboard *clipboard,
+ GdkPixbuf *pixbuf,
+ gpointer data)
+{
+ WaitResults *results = data;
+
+ results->data = g_object_ref (pixbuf);
+ g_main_loop_quit (results->loop);
+}
+
+/**
+ * gtk_clipboard_wait_for_image:
+ * @clipboard: a #GtkClipboard
+ *
+ * Requests the contents of the clipboard as image and converts
+ * the result to a #GdkPixbuf. This function waits for
+ * the data to be received using the main loop, so events,
+ * timeouts, etc, may be dispatched during the wait.
+ *
+ * Return value: a newly-allocated #GdkPixbuf object which must
+ * be disposed with g_object_unref(), or %NULL if
+ * retrieving the selection data failed. (This
+ * could happen for various reasons, in particular
+ * if the clipboard was empty or if the contents of
+ * the clipboard could not be converted into an image.)
+ *
+ * Since: 2.6
+ **/
+GdkPixbuf *
+gtk_clipboard_wait_for_image (GtkClipboard *clipboard)
+{
+ WaitResults results;
+
+ g_return_val_if_fail (clipboard != NULL, NULL);
+
+ results.data = NULL;
+ results.loop = g_main_loop_new (NULL, TRUE);
+
+ gtk_clipboard_request_image (clipboard,
+ clipboard_image_received_func,
+ &results);
+
+ if (g_main_loop_is_running (results.loop))
+ {
+ GDK_THREADS_LEAVE ();
+ g_main_loop_run (results.loop);
+ GDK_THREADS_ENTER ();
+ }
+
+ g_main_loop_unref (results.loop);
+
+ return results.data;
+}
+
/**
* gtk_clipboard_get_display:
* @clipboard: a #GtkClipboard
@@ -1109,10 +1307,9 @@ gtk_clipboard_get_display (GtkClipboard *clipboard)
*
* Test to see if there is text available to be pasted
* This is done by requesting the TARGETS atom and checking
- * if it contains any of the names: STRING, TEXT, COMPOUND_TEXT,
- * UTF8_STRING. This function waits for the data to be received
- * using the main loop, so events, timeouts, etc, may be dispatched
- * during the wait.
+ * if it contains any of the supported text targets. This function
+ * waits for the data to be received using the main loop, so events,
+ * timeouts, etc, may be dispatched during the wait.
*
* This function is a little faster than calling
* gtk_clipboard_wait_for_text() since it doesn't need to retrieve
@@ -1137,6 +1334,41 @@ gtk_clipboard_wait_is_text_available (GtkClipboard *clipboard)
}
/**
+ * gtk_clipboard_wait_is_image_available:
+ * @clipboard: a #GtkClipboard
+ *
+ * Test to see if there is an image available to be pasted
+ * This is done by requesting the TARGETS atom and checking
+ * if it contains any of the supported image targets. This function
+ * waits for the data to be received using the main loop, so events,
+ * timeouts, etc, may be dispatched during the wait.
+ *
+ * This function is a little faster than calling
+ * gtk_clipboard_wait_for_image() since it doesn't need to retrieve
+ * the actual image data.
+ *
+ * Return value: %TRUE is there is an image available, %FALSE otherwise.
+ *
+ * Since: 2.6
+ **/
+gboolean
+gtk_clipboard_wait_is_image_available (GtkClipboard *clipboard)
+{
+ GtkSelectionData *data;
+ gboolean result = FALSE;
+
+ data = gtk_clipboard_wait_for_contents (clipboard,
+ gdk_atom_intern ("TARGETS", FALSE));
+ if (data)
+ {
+ result = gtk_selection_data_targets_include_image (data, FALSE);
+ gtk_selection_data_free (data);
+ }
+
+ return result;
+}
+
+/**
* gtk_clipboard_wait_for_targets
* @clipboard: a #GtkClipboard
* @targets: location to store an array of targets. The result
diff --git a/gtk/gtkclipboard.h b/gtk/gtkclipboard.h
index c05e63cc4f..319c38aca6 100644
--- a/gtk/gtkclipboard.h
+++ b/gtk/gtkclipboard.h
@@ -38,6 +38,9 @@ typedef void (* GtkClipboardReceivedFunc) (GtkClipboard *clipboard,
typedef void (* GtkClipboardTextReceivedFunc) (GtkClipboard *clipboard,
const gchar *text,
gpointer data);
+typedef void (* GtkClipboardImageReceivedFunc) (GtkClipboard *clipboard,
+ GdkPixbuf *pixbuf,
+ gpointer data);
typedef void (* GtkClipboardTargetsReceivedFunc) (GtkClipboard *clipboard,
GdkAtom *atoms,
gint n_atoms,
@@ -82,6 +85,8 @@ void gtk_clipboard_clear (GtkClipboard *clipboard);
void gtk_clipboard_set_text (GtkClipboard *clipboard,
const gchar *text,
gint len);
+void gtk_clipboard_set_image (GtkClipboard *clipboard,
+ GdkPixbuf *pixbuf);
void gtk_clipboard_request_contents (GtkClipboard *clipboard,
GdkAtom target,
@@ -90,6 +95,9 @@ void gtk_clipboard_request_contents (GtkClipboard *clipboard,
void gtk_clipboard_request_text (GtkClipboard *clipboard,
GtkClipboardTextReceivedFunc callback,
gpointer user_data);
+void gtk_clipboard_request_image (GtkClipboard *clipboard,
+ GtkClipboardImageReceivedFunc callback,
+ gpointer user_data);
void gtk_clipboard_request_targets (GtkClipboard *clipboard,
GtkClipboardTargetsReceivedFunc callback,
gpointer user_data);
@@ -97,11 +105,13 @@ void gtk_clipboard_request_targets (GtkClipboard *clipboard,
GtkSelectionData *gtk_clipboard_wait_for_contents (GtkClipboard *clipboard,
GdkAtom target);
gchar * gtk_clipboard_wait_for_text (GtkClipboard *clipboard);
+GdkPixbuf * gtk_clipboard_wait_for_image (GtkClipboard *clipboard);
gboolean gtk_clipboard_wait_for_targets (GtkClipboard *clipboard,
GdkAtom **targets,
gint *n_targets);
gboolean gtk_clipboard_wait_is_text_available (GtkClipboard *clipboard);
+gboolean gtk_clipboard_wait_is_image_available (GtkClipboard *clipboard);
gboolean gtk_clipboard_wait_is_target_available (GtkClipboard *clipboard,
GdkAtom target);
diff --git a/gtk/gtkselection.c b/gtk/gtkselection.c
index ac8836975b..ab60873811 100644
--- a/gtk/gtkselection.c
+++ b/gtk/gtkselection.c
@@ -1496,7 +1496,10 @@ gtk_selection_data_targets_include_text (GtkSelectionData *selection_data)
targets[i] == text_plain_atom ||
targets[i] == text_plain_utf8_atom ||
targets[i] == text_plain_locale_atom)
- result = TRUE;
+ {
+ result = TRUE;
+ break;
+ }
}
g_free (targets);
@@ -1504,6 +1507,54 @@ gtk_selection_data_targets_include_text (GtkSelectionData *selection_data)
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;
+ gint i;
+ gboolean result = FALSE;
+ GtkTargetList *list;
+ GList *l;
+
+ init_atoms ();
+
+ if (gtk_selection_data_get_targets (selection_data, &targets, &n_targets))
+ {
+ 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 && !result; l = l->next)
+ {
+ GtkTargetPair *pair = (GtkTargetPair *)l->data;
+ if (pair->target == targets[i])
+ result = TRUE;
+ }
+ }
+ gtk_target_list_unref (list);
+ g_free (targets);
+ }
+
+ return result;
+}
/*************************************************************
* gtk_selection_init:
diff --git a/gtk/gtkselection.h b/gtk/gtkselection.h
index 5623b440e4..f3df99e10b 100644
--- a/gtk/gtkselection.h
+++ b/gtk/gtkselection.h
@@ -144,9 +144,9 @@ gboolean gtk_selection_data_set_text (GtkSelectionData *selection_data,
const gchar *str,
gint len);
guchar * gtk_selection_data_get_text (GtkSelectionData *selection_data);
-gboolean gtk_selection_data_set_pixbuf (GtkSelectionData *selection_data,
- GdkPixbuf *pixbuf);
-GdkPixbuf *gtk_selection_data_get_pixbuf (GtkSelectionData *selection_data);
+gboolean gtk_selection_data_set_pixbuf (GtkSelectionData *selection_data,
+ GdkPixbuf *pixbuf);
+GdkPixbuf *gtk_selection_data_get_pixbuf (GtkSelectionData *selection_data);
gboolean gtk_selection_data_set_uris (GtkSelectionData *selection_data,
gchar **uris);
gchar **gtk_selection_data_get_uris (GtkSelectionData *selection_data);
@@ -155,6 +155,8 @@ gboolean gtk_selection_data_get_targets (GtkSelectionData *selection_d
GdkAtom **targets,
gint *n_atoms);
gboolean gtk_selection_data_targets_include_text (GtkSelectionData *selection_data);
+gboolean gtk_selection_data_targets_include_image (GtkSelectionData *selection_data,
+ gboolean writable);
/* Called when a widget is destroyed */