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().
This commit is contained in:
Matthias Clasen 2004-10-31 05:40:25 +00:00 committed by Matthias Clasen
parent 20d47e6c56
commit 1c8e6a0e4f
9 changed files with 358 additions and 14 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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)
@ -909,6 +976,83 @@ gtk_clipboard_request_text (GtkClipboard *clipboard,
info);
}
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,
@ -1042,7 +1186,6 @@ clipboard_text_received_func (GtkClipboard *clipboard,
g_main_loop_quit (results->loop);
}
/**
* gtk_clipboard_wait_for_text:
* @clipboard: a #GtkClipboard
@ -1064,7 +1207,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;
@ -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
@ -1136,6 +1333,41 @@ gtk_clipboard_wait_is_text_available (GtkClipboard *clipboard)
return result;
}
/**
* 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

View File

@ -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);

View File

@ -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:

View File

@ -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 */