diff options
author | Matthias Clasen <mclasen@redhat.com> | 2004-10-31 05:40:25 +0000 |
---|---|---|
committer | Matthias Clasen <matthiasc@src.gnome.org> | 2004-10-31 05:40:25 +0000 |
commit | 1c8e6a0e4fe16dcb9dafc5f1c90bc34bd7b3a9c4 (patch) | |
tree | 14b23a3036bf2d423b0b5eca44b7e5c40ae64e6e /gtk/gtkclipboard.c | |
parent | 20d47e6c56a43fbb9890c8a06b359984c7ad1086 (diff) | |
download | gtk+-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().
Diffstat (limited to 'gtk/gtkclipboard.c')
-rw-r--r-- | gtk/gtkclipboard.c | 252 |
1 files changed, 242 insertions, 10 deletions
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 |