mirror of https://github.com/GNOME/gimp.git
app: add setting/getting and sending/recieving images via GimpClipboard
The new functionality is not used yet.
This commit is contained in:
parent
0740d8d688
commit
1f00b5e70f
|
@ -27,6 +27,8 @@
|
|||
#include "core/gimp.h"
|
||||
#include "core/gimpbuffer.h"
|
||||
#include "core/gimpcurve.h"
|
||||
#include "core/gimpimage.h"
|
||||
#include "core/gimppickable.h"
|
||||
|
||||
#include "gimpclipboard.h"
|
||||
#include "gimppixbuf.h"
|
||||
|
@ -44,8 +46,11 @@ struct _GimpClipboard
|
|||
{
|
||||
GSList *pixbuf_formats;
|
||||
|
||||
GtkTargetEntry *target_entries;
|
||||
gint n_target_entries;
|
||||
GtkTargetEntry *image_target_entries;
|
||||
gint n_image_target_entries;
|
||||
|
||||
GtkTargetEntry *buffer_target_entries;
|
||||
gint n_buffer_target_entries;
|
||||
|
||||
GtkTargetEntry *svg_target_entries;
|
||||
gint n_svg_target_entries;
|
||||
|
@ -53,6 +58,7 @@ struct _GimpClipboard
|
|||
GtkTargetEntry *curve_target_entries;
|
||||
gint n_curve_target_entries;
|
||||
|
||||
GimpImage *image;
|
||||
GimpBuffer *buffer;
|
||||
gchar *svg;
|
||||
GimpCurve *curve;
|
||||
|
@ -65,10 +71,15 @@ static void gimp_clipboard_free (GimpClipboard *gimp_clip);
|
|||
|
||||
static GdkAtom * gimp_clipboard_wait_for_targets (Gimp *gimp,
|
||||
gint *n_targets);
|
||||
static GdkAtom gimp_clipboard_wait_for_image (Gimp *gimp);
|
||||
static GdkAtom gimp_clipboard_wait_for_buffer (Gimp *gimp);
|
||||
static GdkAtom gimp_clipboard_wait_for_svg (Gimp *gimp);
|
||||
static GdkAtom gimp_clipboard_wait_for_curve (Gimp *gimp);
|
||||
|
||||
static void gimp_clipboard_send_image (GtkClipboard *clipboard,
|
||||
GtkSelectionData *selection_data,
|
||||
guint info,
|
||||
Gimp *gimp);
|
||||
static void gimp_clipboard_send_buffer (GtkClipboard *clipboard,
|
||||
GtkSelectionData *selection_data,
|
||||
guint info,
|
||||
|
@ -116,18 +127,29 @@ gimp_clipboard_init (Gimp *gimp)
|
|||
mime_types = gdk_pixbuf_format_get_mime_types (format);
|
||||
|
||||
for (type = mime_types; *type; type++)
|
||||
gimp_clip->n_target_entries++;
|
||||
gimp_clip->n_buffer_target_entries++;
|
||||
|
||||
g_strfreev (mime_types);
|
||||
}
|
||||
}
|
||||
|
||||
if (gimp_clip->n_target_entries > 0)
|
||||
/* the image_target_entries have the XCF target, and all pixbuf
|
||||
* targets that are also in buffer_target_entries
|
||||
*/
|
||||
gimp_clip->n_image_target_entries = gimp_clip->n_buffer_target_entries + 1;
|
||||
gimp_clip->image_target_entries = g_new0 (GtkTargetEntry,
|
||||
gimp_clip->n_image_target_entries);
|
||||
|
||||
gimp_clip->image_target_entries[0].target = g_strdup ("image/x-xcf");
|
||||
gimp_clip->image_target_entries[0].flags = 0;
|
||||
gimp_clip->image_target_entries[0].info = 0;
|
||||
|
||||
if (gimp_clip->n_buffer_target_entries > 0)
|
||||
{
|
||||
gint i = 0;
|
||||
|
||||
gimp_clip->target_entries = g_new0 (GtkTargetEntry,
|
||||
gimp_clip->n_target_entries);
|
||||
gimp_clip->buffer_target_entries = g_new0 (GtkTargetEntry,
|
||||
gimp_clip->n_buffer_target_entries);
|
||||
|
||||
for (list = gimp_clip->pixbuf_formats; list; list = g_slist_next (list))
|
||||
{
|
||||
|
@ -150,9 +172,13 @@ gimp_clipboard_init (Gimp *gimp)
|
|||
g_printerr ("clipboard: writable pixbuf format: %s\n",
|
||||
mime_type);
|
||||
|
||||
gimp_clip->target_entries[i].target = g_strdup (mime_type);
|
||||
gimp_clip->target_entries[i].flags = 0;
|
||||
gimp_clip->target_entries[i].info = i;
|
||||
gimp_clip->image_target_entries[i + 1].target = g_strdup (mime_type);
|
||||
gimp_clip->image_target_entries[i + 1].flags = 0;
|
||||
gimp_clip->image_target_entries[i + 1].info = i + 1;
|
||||
|
||||
gimp_clip->buffer_target_entries[i].target = g_strdup (mime_type);
|
||||
gimp_clip->buffer_target_entries[i].flags = 0;
|
||||
gimp_clip->buffer_target_entries[i].info = i;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
@ -198,6 +224,38 @@ gimp_clipboard_exit (Gimp *gimp)
|
|||
g_object_set_data (G_OBJECT (gimp), GIMP_CLIPBOARD_KEY, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_clipboard_has_image:
|
||||
* @gimp: pointer to #Gimp
|
||||
*
|
||||
* Tests if there's an image in the clipboard. If the global image cut
|
||||
* buffer of @gimp is empty, this function returns %NULL.
|
||||
*
|
||||
* Return value: %TRUE if there's an image in the clipboard, %FALSE otherwise
|
||||
**/
|
||||
gboolean
|
||||
gimp_clipboard_has_image (Gimp *gimp)
|
||||
{
|
||||
GimpClipboard *gimp_clip;
|
||||
GtkClipboard *clipboard;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_GIMP (gimp), FALSE);
|
||||
|
||||
clipboard = gtk_clipboard_get_for_display (gdk_display_get_default (),
|
||||
GDK_SELECTION_CLIPBOARD);
|
||||
|
||||
if (clipboard &&
|
||||
gtk_clipboard_get_owner (clipboard) != G_OBJECT (gimp) &&
|
||||
gimp_clipboard_wait_for_image (gimp) != GDK_NONE)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gimp_clip = gimp_clipboard_get (gimp);
|
||||
|
||||
return (gimp_clip->image != NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_clipboard_has_buffer:
|
||||
* @gimp: pointer to #Gimp
|
||||
|
@ -299,6 +357,59 @@ gimp_clipboard_has_curve (Gimp *gimp)
|
|||
return (gimp_clip->curve != NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_clipboard_get_image:
|
||||
* @gimp: pointer to #Gimp
|
||||
*
|
||||
* Retrieves either an image from the global image cut buffer of @gimp.
|
||||
*
|
||||
* The returned #GimpImage needs to be unref'ed when it's no longer
|
||||
* needed.
|
||||
*
|
||||
* Return value: a reference to a #GimpImage or %NULL if there's no
|
||||
* image in the clipboard
|
||||
**/
|
||||
GimpImage *
|
||||
gimp_clipboard_get_image (Gimp *gimp)
|
||||
{
|
||||
GimpClipboard *gimp_clip;
|
||||
GtkClipboard *clipboard;
|
||||
GdkAtom atom;
|
||||
GimpImage *image = NULL;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
|
||||
|
||||
clipboard = gtk_clipboard_get_for_display (gdk_display_get_default (),
|
||||
GDK_SELECTION_CLIPBOARD);
|
||||
|
||||
if (clipboard &&
|
||||
gtk_clipboard_get_owner (clipboard) != G_OBJECT (gimp) &&
|
||||
(atom = gimp_clipboard_wait_for_image (gimp)) != GDK_NONE)
|
||||
{
|
||||
GtkSelectionData *data;
|
||||
|
||||
gimp_set_busy (gimp);
|
||||
|
||||
data = gtk_clipboard_wait_for_contents (clipboard, atom);
|
||||
|
||||
if (data)
|
||||
{
|
||||
image = gimp_selection_data_get_xcf (data, gimp);
|
||||
|
||||
gtk_selection_data_free (data);
|
||||
}
|
||||
|
||||
gimp_unset_busy (gimp);
|
||||
}
|
||||
|
||||
gimp_clip = gimp_clipboard_get (gimp);
|
||||
|
||||
if (! image && gimp_clip->image)
|
||||
image = g_object_ref (gimp_clip->image);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_clipboard_get_buffer:
|
||||
* @gimp: pointer to #Gimp
|
||||
|
@ -477,6 +588,56 @@ gimp_clipboard_get_curve (Gimp *gimp)
|
|||
return curve;
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_clipboard_set_image:
|
||||
* @gimp: pointer to #Gimp
|
||||
* @image: a #GimpImage, or %NULL.
|
||||
*
|
||||
* Offers the image in %GDK_SELECTION_CLIPBOARD.
|
||||
**/
|
||||
void
|
||||
gimp_clipboard_set_image (Gimp *gimp,
|
||||
GimpImage *image)
|
||||
{
|
||||
GimpClipboard *gimp_clip;
|
||||
GtkClipboard *clipboard;
|
||||
|
||||
g_return_if_fail (GIMP_IS_GIMP (gimp));
|
||||
g_return_if_fail (image == NULL || GIMP_IS_IMAGE (image));
|
||||
|
||||
clipboard = gtk_clipboard_get_for_display (gdk_display_get_default (),
|
||||
GDK_SELECTION_CLIPBOARD);
|
||||
if (! clipboard)
|
||||
return;
|
||||
|
||||
gimp_clip = gimp_clipboard_get (gimp);
|
||||
|
||||
gimp_clipboard_clear (gimp_clip);
|
||||
|
||||
if (image)
|
||||
{
|
||||
gimp_clip->image = g_object_ref (image);
|
||||
|
||||
gtk_clipboard_set_with_owner (clipboard,
|
||||
gimp_clip->image_target_entries,
|
||||
gimp_clip->n_image_target_entries,
|
||||
(GtkClipboardGetFunc) gimp_clipboard_send_image,
|
||||
(GtkClipboardClearFunc) NULL,
|
||||
G_OBJECT (gimp));
|
||||
|
||||
/* mark the first two entries (image/x-xcf and image/png) as
|
||||
* suitable for storing
|
||||
*/
|
||||
gtk_clipboard_set_can_store (clipboard,
|
||||
gimp_clip->image_target_entries,
|
||||
MIN (2, gimp_clip->n_image_target_entries));
|
||||
}
|
||||
else if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (gimp))
|
||||
{
|
||||
gtk_clipboard_clear (clipboard);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_clipboard_set_buffer:
|
||||
* @gimp: pointer to #Gimp
|
||||
|
@ -508,15 +669,15 @@ gimp_clipboard_set_buffer (Gimp *gimp,
|
|||
gimp_clip->buffer = g_object_ref (buffer);
|
||||
|
||||
gtk_clipboard_set_with_owner (clipboard,
|
||||
gimp_clip->target_entries,
|
||||
gimp_clip->n_target_entries,
|
||||
gimp_clip->buffer_target_entries,
|
||||
gimp_clip->n_buffer_target_entries,
|
||||
(GtkClipboardGetFunc) gimp_clipboard_send_buffer,
|
||||
(GtkClipboardClearFunc) NULL,
|
||||
G_OBJECT (gimp));
|
||||
|
||||
/* mark the first entry (image/png) as suitable for storing */
|
||||
if (gimp_clip->n_target_entries > 0)
|
||||
gtk_clipboard_set_can_store (clipboard, gimp_clip->target_entries, 1);
|
||||
if (gimp_clip->n_buffer_target_entries > 0)
|
||||
gtk_clipboard_set_can_store (clipboard, gimp_clip->buffer_target_entries, 1);
|
||||
}
|
||||
else if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (gimp))
|
||||
{
|
||||
|
@ -655,6 +816,12 @@ gimp_clipboard_get (Gimp *gimp)
|
|||
static void
|
||||
gimp_clipboard_clear (GimpClipboard *gimp_clip)
|
||||
{
|
||||
if (gimp_clip->image)
|
||||
{
|
||||
g_object_unref (gimp_clip->image);
|
||||
gimp_clip->image = NULL;
|
||||
}
|
||||
|
||||
if (gimp_clip->buffer)
|
||||
{
|
||||
g_object_unref (gimp_clip->buffer);
|
||||
|
@ -683,10 +850,15 @@ gimp_clipboard_free (GimpClipboard *gimp_clip)
|
|||
|
||||
g_slist_free (gimp_clip->pixbuf_formats);
|
||||
|
||||
for (i = 0; i < gimp_clip->n_target_entries; i++)
|
||||
g_free ((gchar *) gimp_clip->target_entries[i].target);
|
||||
for (i = 0; i < gimp_clip->n_image_target_entries; i++)
|
||||
g_free ((gchar *) gimp_clip->image_target_entries[i].target);
|
||||
|
||||
g_free (gimp_clip->target_entries);
|
||||
g_free (gimp_clip->image_target_entries);
|
||||
|
||||
for (i = 0; i < gimp_clip->n_buffer_target_entries; i++)
|
||||
g_free ((gchar *) gimp_clip->buffer_target_entries[i].target);
|
||||
|
||||
g_free (gimp_clip->buffer_target_entries);
|
||||
|
||||
for (i = 0; i < gimp_clip->n_svg_target_entries; i++)
|
||||
g_free ((gchar *) gimp_clip->svg_target_entries[i].target);
|
||||
|
@ -747,6 +919,35 @@ gimp_clipboard_wait_for_targets (Gimp *gimp,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static GdkAtom
|
||||
gimp_clipboard_wait_for_image (Gimp *gimp)
|
||||
{
|
||||
GdkAtom *targets;
|
||||
gint n_targets;
|
||||
GdkAtom result = GDK_NONE;
|
||||
|
||||
targets = gimp_clipboard_wait_for_targets (gimp, &n_targets);
|
||||
|
||||
if (targets)
|
||||
{
|
||||
GdkAtom image_atom = gdk_atom_intern_static_string ("image/x-xcf");
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < n_targets; i++)
|
||||
{
|
||||
if (targets[i] == image_atom)
|
||||
{
|
||||
result = image_atom;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_free (targets);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static GdkAtom
|
||||
gimp_clipboard_wait_for_buffer (Gimp *gimp)
|
||||
{
|
||||
|
@ -871,6 +1072,52 @@ gimp_clipboard_wait_for_curve (Gimp *gimp)
|
|||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_clipboard_send_image (GtkClipboard *clipboard,
|
||||
GtkSelectionData *selection_data,
|
||||
guint info,
|
||||
Gimp *gimp)
|
||||
{
|
||||
GimpClipboard *gimp_clip = gimp_clipboard_get (gimp);
|
||||
|
||||
gimp_set_busy (gimp);
|
||||
|
||||
if (info == 0)
|
||||
{
|
||||
if (gimp->be_verbose)
|
||||
g_printerr ("clipboard: sending image data as '%s'\n",
|
||||
gimp_clip->image_target_entries[info].target);
|
||||
|
||||
gimp_selection_data_set_xcf (selection_data, gimp_clip->image);
|
||||
}
|
||||
else
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
|
||||
gimp_pickable_flush (GIMP_PICKABLE (gimp_clip->image));
|
||||
|
||||
pixbuf = gimp_viewable_get_pixbuf (GIMP_VIEWABLE (gimp_clip->image),
|
||||
gimp_get_user_context (gimp),
|
||||
gimp_image_get_width (gimp_clip->image),
|
||||
gimp_image_get_height (gimp_clip->image));
|
||||
|
||||
if (pixbuf)
|
||||
{
|
||||
if (gimp->be_verbose)
|
||||
g_printerr ("clipboard: sending image data as '%s'\n",
|
||||
gimp_clip->image_target_entries[info].target);
|
||||
|
||||
gtk_selection_data_set_pixbuf (selection_data, pixbuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("%s: gimp_viewable_get_pixbuf() failed", G_STRFUNC);
|
||||
}
|
||||
}
|
||||
|
||||
gimp_unset_busy (gimp);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_clipboard_send_buffer (GtkClipboard *clipboard,
|
||||
GtkSelectionData *selection_data,
|
||||
|
@ -891,7 +1138,7 @@ gimp_clipboard_send_buffer (GtkClipboard *clipboard,
|
|||
{
|
||||
if (gimp->be_verbose)
|
||||
g_printerr ("clipboard: sending pixbuf data as '%s'\n",
|
||||
gimp_clip->target_entries[info].target);
|
||||
gimp_clip->buffer_target_entries[info].target);
|
||||
|
||||
gtk_selection_data_set_pixbuf (selection_data, pixbuf);
|
||||
}
|
||||
|
|
|
@ -22,15 +22,19 @@
|
|||
void gimp_clipboard_init (Gimp *gimp);
|
||||
void gimp_clipboard_exit (Gimp *gimp);
|
||||
|
||||
gboolean gimp_clipboard_has_image (Gimp *gimp);
|
||||
gboolean gimp_clipboard_has_buffer (Gimp *gimp);
|
||||
gboolean gimp_clipboard_has_svg (Gimp *gimp);
|
||||
gboolean gimp_clipboard_has_curve (Gimp *gimp);
|
||||
|
||||
GimpImage * gimp_clipboard_get_image (Gimp *gimp);
|
||||
GimpBuffer * gimp_clipboard_get_buffer (Gimp *gimp);
|
||||
gchar * gimp_clipboard_get_svg (Gimp *gimp,
|
||||
gsize *svg_length);
|
||||
GimpCurve * gimp_clipboard_get_curve (Gimp *gimp);
|
||||
|
||||
void gimp_clipboard_set_image (Gimp *gimp,
|
||||
GimpImage *image);
|
||||
void gimp_clipboard_set_buffer (Gimp *gimp,
|
||||
GimpBuffer *buffer);
|
||||
void gimp_clipboard_set_svg (Gimp *gimp,
|
||||
|
|
Loading…
Reference in New Issue