forked from AuroraMiddleware/gtk
a546ae32d7
Those property features don't seem to be in use anywhere. They are redundant since the docs cover the same information and more. They also created unnecessary translation work. Closes #4904
1362 lines
44 KiB
C
1362 lines
44 KiB
C
/* GDK - The GIMP Drawing Kit
|
|
*
|
|
* Copyright (C) 2017 Benjamin Otte <otte@gnome.org>
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include "gdkclipboardprivate.h"
|
|
|
|
#include "gdkcontentdeserializer.h"
|
|
#include "gdkcontentformats.h"
|
|
#include "gdkcontentproviderimpl.h"
|
|
#include "gdkcontentproviderprivate.h"
|
|
#include "gdkcontentserializer.h"
|
|
#include "gdkdisplay.h"
|
|
#include "gdkintl.h"
|
|
#include "gdkpipeiostreamprivate.h"
|
|
#include "gdktexture.h"
|
|
|
|
#include <gobject/gvaluecollector.h>
|
|
|
|
/**
|
|
* GdkClipboard:
|
|
*
|
|
* The `GdkClipboard` object represents data shared between applications or
|
|
* inside an application.
|
|
*
|
|
* To get a `GdkClipboard` object, use [method@Gdk.Display.get_clipboard] or
|
|
* [method@Gdk.Display.get_primary_clipboard]. You can find out about the data
|
|
* that is currently available in a clipboard using
|
|
* [method@Gdk.Clipboard.get_formats].
|
|
*
|
|
* To make text or image data available in a clipboard, use
|
|
* [method@Gdk.Clipboard.set_text] or [method@Gdk.Clipboard.set_texture].
|
|
* For other data, you can use [method@Gdk.Clipboard.set_content], which
|
|
* takes a [class@Gdk.ContentProvider] object.
|
|
*
|
|
* To read textual or image data from a clipboard, use
|
|
* [method@Gdk.Clipboard.read_text_async] or
|
|
* [method@Gdk.Clipboard.read_texture_async]. For other data, use
|
|
* [method@Gdk.Clipboard.read_async], which provides a `GInputStream` object.
|
|
*/
|
|
|
|
typedef struct _GdkClipboardPrivate GdkClipboardPrivate;
|
|
|
|
struct _GdkClipboardPrivate
|
|
{
|
|
GdkDisplay *display;
|
|
GdkContentFormats *formats;
|
|
GdkContentProvider *content;
|
|
|
|
guint local : 1;
|
|
};
|
|
|
|
enum {
|
|
PROP_0,
|
|
PROP_DISPLAY,
|
|
PROP_FORMATS,
|
|
PROP_LOCAL,
|
|
PROP_CONTENT,
|
|
N_PROPERTIES
|
|
};
|
|
|
|
enum {
|
|
CHANGED,
|
|
N_SIGNALS
|
|
};
|
|
|
|
static GParamSpec *properties[N_PROPERTIES] = { NULL, };
|
|
static guint signals[N_SIGNALS] = { 0 };
|
|
|
|
G_DEFINE_TYPE_WITH_PRIVATE (GdkClipboard, gdk_clipboard, G_TYPE_OBJECT)
|
|
|
|
static void
|
|
gdk_clipboard_set_property (GObject *gobject,
|
|
guint prop_id,
|
|
const GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
GdkClipboard *clipboard = GDK_CLIPBOARD (gobject);
|
|
GdkClipboardPrivate *priv = gdk_clipboard_get_instance_private (clipboard);
|
|
|
|
switch (prop_id)
|
|
{
|
|
case PROP_DISPLAY:
|
|
priv->display = g_value_get_object (value);
|
|
g_assert (priv->display != NULL);
|
|
break;
|
|
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
gdk_clipboard_get_property (GObject *gobject,
|
|
guint prop_id,
|
|
GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
GdkClipboard *clipboard = GDK_CLIPBOARD (gobject);
|
|
GdkClipboardPrivate *priv = gdk_clipboard_get_instance_private (clipboard);
|
|
|
|
switch (prop_id)
|
|
{
|
|
case PROP_DISPLAY:
|
|
g_value_set_object (value, priv->display);
|
|
break;
|
|
|
|
case PROP_FORMATS:
|
|
g_value_set_boxed (value, priv->formats);
|
|
break;
|
|
|
|
case PROP_CONTENT:
|
|
g_value_set_object (value, priv->content);
|
|
break;
|
|
|
|
case PROP_LOCAL:
|
|
g_value_set_boolean (value, priv->local);
|
|
break;
|
|
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
gdk_clipboard_finalize (GObject *object)
|
|
{
|
|
GdkClipboard *clipboard = GDK_CLIPBOARD (object);
|
|
GdkClipboardPrivate *priv = gdk_clipboard_get_instance_private (clipboard);
|
|
|
|
g_clear_pointer (&priv->formats, gdk_content_formats_unref);
|
|
|
|
G_OBJECT_CLASS (gdk_clipboard_parent_class)->finalize (object);
|
|
}
|
|
|
|
static void
|
|
gdk_clipboard_content_changed_cb (GdkContentProvider *provider,
|
|
GdkClipboard *clipboard);
|
|
|
|
static gboolean
|
|
gdk_clipboard_real_claim (GdkClipboard *clipboard,
|
|
GdkContentFormats *formats,
|
|
gboolean local,
|
|
GdkContentProvider *content)
|
|
{
|
|
GdkClipboardPrivate *priv = gdk_clipboard_get_instance_private (clipboard);
|
|
|
|
g_object_freeze_notify (G_OBJECT (clipboard));
|
|
|
|
gdk_content_formats_unref (priv->formats);
|
|
gdk_content_formats_ref (formats);
|
|
formats = gdk_content_formats_union_deserialize_gtypes (formats);
|
|
priv->formats = formats;
|
|
g_object_notify_by_pspec (G_OBJECT (clipboard), properties[PROP_FORMATS]);
|
|
if (priv->local != local)
|
|
{
|
|
priv->local = local;
|
|
g_object_notify_by_pspec (G_OBJECT (clipboard), properties[PROP_LOCAL]);
|
|
}
|
|
|
|
if (priv->content != content)
|
|
{
|
|
GdkContentProvider *old_content = priv->content;
|
|
|
|
if (content)
|
|
priv->content = g_object_ref (content);
|
|
else
|
|
priv->content = NULL;
|
|
|
|
if (old_content)
|
|
{
|
|
g_signal_handlers_disconnect_by_func (old_content,
|
|
gdk_clipboard_content_changed_cb,
|
|
clipboard);
|
|
gdk_content_provider_detach_clipboard (old_content, clipboard);
|
|
g_object_unref (old_content);
|
|
}
|
|
if (content)
|
|
{
|
|
gdk_content_provider_attach_clipboard (content, clipboard);
|
|
g_signal_connect (content,
|
|
"content-changed",
|
|
G_CALLBACK (gdk_clipboard_content_changed_cb),
|
|
clipboard);
|
|
}
|
|
|
|
g_object_notify_by_pspec (G_OBJECT (clipboard), properties[PROP_CONTENT]);
|
|
}
|
|
|
|
g_object_thaw_notify (G_OBJECT (clipboard));
|
|
|
|
g_signal_emit (clipboard, signals[CHANGED], 0);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
gdk_clipboard_store_default_async (GdkClipboard *clipboard,
|
|
int io_priority,
|
|
GCancellable *cancellable,
|
|
GAsyncReadyCallback callback,
|
|
gpointer user_data)
|
|
{
|
|
GdkClipboardPrivate *priv = gdk_clipboard_get_instance_private (clipboard);
|
|
GTask *task;
|
|
|
|
task = g_task_new (clipboard, cancellable, callback, user_data);
|
|
g_task_set_priority (task, io_priority);
|
|
g_task_set_source_tag (task, gdk_clipboard_store_default_async);
|
|
|
|
if (priv->local)
|
|
{
|
|
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
|
_("This clipboard cannot store data."));
|
|
}
|
|
else
|
|
{
|
|
g_task_return_boolean (task, TRUE);
|
|
}
|
|
|
|
g_object_unref (task);
|
|
}
|
|
|
|
static gboolean
|
|
gdk_clipboard_store_default_finish (GdkClipboard *clipboard,
|
|
GAsyncResult *result,
|
|
GError **error)
|
|
{
|
|
g_return_val_if_fail (g_task_is_valid (result, clipboard), FALSE);
|
|
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gdk_clipboard_store_default_async, FALSE);
|
|
|
|
return g_task_propagate_boolean (G_TASK (result), error);
|
|
}
|
|
|
|
static void
|
|
gdk_clipboard_read_local_write_done (GObject *clipboard,
|
|
GAsyncResult *result,
|
|
gpointer stream)
|
|
{
|
|
/* we don't care about the error, we just want to clean up */
|
|
gdk_clipboard_write_finish (GDK_CLIPBOARD (clipboard), result, NULL);
|
|
|
|
/* XXX: Do we need to close_async() here? */
|
|
g_output_stream_close (stream, NULL, NULL);
|
|
|
|
g_object_unref (stream);
|
|
}
|
|
|
|
static void
|
|
gdk_clipboard_read_local_async (GdkClipboard *clipboard,
|
|
GdkContentFormats *formats,
|
|
int io_priority,
|
|
GCancellable *cancellable,
|
|
GAsyncReadyCallback callback,
|
|
gpointer user_data)
|
|
{
|
|
GdkClipboardPrivate *priv = gdk_clipboard_get_instance_private (clipboard);
|
|
GdkContentFormats *content_formats;
|
|
const char *mime_type;
|
|
GTask *task;
|
|
|
|
task = g_task_new (clipboard, cancellable, callback, user_data);
|
|
g_task_set_priority (task, io_priority);
|
|
g_task_set_source_tag (task, gdk_clipboard_read_local_async);
|
|
|
|
if (priv->content == NULL)
|
|
{
|
|
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
|
|
_("Cannot read from empty clipboard."));
|
|
g_object_unref (task);
|
|
return;
|
|
}
|
|
|
|
content_formats = gdk_content_provider_ref_formats (priv->content);
|
|
content_formats = gdk_content_formats_union_serialize_mime_types (content_formats);
|
|
mime_type = gdk_content_formats_match_mime_type (content_formats, formats);
|
|
|
|
if (mime_type != NULL)
|
|
{
|
|
GOutputStream *output_stream;
|
|
GIOStream *stream;
|
|
|
|
stream = gdk_pipe_io_stream_new ();
|
|
output_stream = g_io_stream_get_output_stream (stream);
|
|
gdk_clipboard_write_async (clipboard,
|
|
mime_type,
|
|
output_stream,
|
|
io_priority,
|
|
cancellable,
|
|
gdk_clipboard_read_local_write_done,
|
|
g_object_ref (output_stream));
|
|
g_task_set_task_data (task, (gpointer) mime_type, NULL);
|
|
g_task_return_pointer (task, g_object_ref (g_io_stream_get_input_stream (stream)), g_object_unref);
|
|
|
|
g_object_unref (stream);
|
|
}
|
|
else
|
|
{
|
|
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
|
_("No compatible formats to transfer clipboard contents."));
|
|
}
|
|
|
|
gdk_content_formats_unref (content_formats);
|
|
g_object_unref (task);
|
|
}
|
|
|
|
static GInputStream *
|
|
gdk_clipboard_read_local_finish (GdkClipboard *clipboard,
|
|
GAsyncResult *result,
|
|
const char **out_mime_type,
|
|
GError **error)
|
|
{
|
|
g_return_val_if_fail (g_task_is_valid (result, clipboard), NULL);
|
|
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gdk_clipboard_read_local_async, NULL);
|
|
|
|
if (out_mime_type)
|
|
*out_mime_type = g_task_get_task_data (G_TASK (result));
|
|
|
|
return g_task_propagate_pointer (G_TASK (result), error);
|
|
}
|
|
|
|
static void
|
|
gdk_clipboard_class_init (GdkClipboardClass *class)
|
|
{
|
|
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
|
|
|
object_class->get_property = gdk_clipboard_get_property;
|
|
object_class->set_property = gdk_clipboard_set_property;
|
|
object_class->finalize = gdk_clipboard_finalize;
|
|
|
|
class->claim = gdk_clipboard_real_claim;
|
|
class->store_async = gdk_clipboard_store_default_async;
|
|
class->store_finish = gdk_clipboard_store_default_finish;
|
|
class->read_async = gdk_clipboard_read_local_async;
|
|
class->read_finish = gdk_clipboard_read_local_finish;
|
|
|
|
/**
|
|
* GdkClipboard:display: (attributes org.gtk.Property.get=gdk_clipboard_get_display)
|
|
*
|
|
* The `GdkDisplay` that the clipboard belongs to.
|
|
*/
|
|
properties[PROP_DISPLAY] =
|
|
g_param_spec_object ("display", NULL, NULL,
|
|
GDK_TYPE_DISPLAY,
|
|
G_PARAM_READWRITE |
|
|
G_PARAM_CONSTRUCT_ONLY |
|
|
G_PARAM_STATIC_STRINGS |
|
|
G_PARAM_EXPLICIT_NOTIFY);
|
|
|
|
/**
|
|
* GdkClipboard:formats: (attributes org.gtk.Property.get=gdk_clipboard_get_formats)
|
|
*
|
|
* The possible formats that the clipboard can provide its data in.
|
|
*/
|
|
properties[PROP_FORMATS] =
|
|
g_param_spec_boxed ("formats", NULL, NULL,
|
|
GDK_TYPE_CONTENT_FORMATS,
|
|
G_PARAM_READABLE |
|
|
G_PARAM_STATIC_STRINGS |
|
|
G_PARAM_EXPLICIT_NOTIFY);
|
|
|
|
/**
|
|
* GdkClipboard:local: (attributes org.gtk.Property.get=gdk_clipboard_is_local)
|
|
*
|
|
* %TRUE if the contents of the clipboard are owned by this process.
|
|
*/
|
|
properties[PROP_LOCAL] =
|
|
g_param_spec_boolean ("local", NULL, NULL,
|
|
TRUE,
|
|
G_PARAM_READABLE |
|
|
G_PARAM_STATIC_STRINGS |
|
|
G_PARAM_EXPLICIT_NOTIFY);
|
|
|
|
/**
|
|
* GdkClipboard:content: (attributes org.gtk.Property.get=gdk_clipboard_get_content)
|
|
*
|
|
* The `GdkContentProvider` or %NULL if the clipboard is empty or contents are
|
|
* provided otherwise.
|
|
*/
|
|
properties[PROP_CONTENT] =
|
|
g_param_spec_object ("content", NULL, NULL,
|
|
GDK_TYPE_CONTENT_PROVIDER,
|
|
G_PARAM_READABLE |
|
|
G_PARAM_STATIC_STRINGS |
|
|
G_PARAM_EXPLICIT_NOTIFY);
|
|
|
|
/**
|
|
* GdkClipboard::changed:
|
|
* @clipboard: the object on which the signal was emitted
|
|
*
|
|
* Emitted when the clipboard changes ownership.
|
|
*/
|
|
signals[CHANGED] =
|
|
g_signal_new ("changed",
|
|
G_TYPE_FROM_CLASS (class),
|
|
G_SIGNAL_RUN_LAST,
|
|
G_STRUCT_OFFSET (GdkClipboardClass, changed),
|
|
NULL, NULL, NULL,
|
|
G_TYPE_NONE, 0);
|
|
|
|
g_object_class_install_properties (object_class, N_PROPERTIES, properties);
|
|
}
|
|
|
|
static void
|
|
gdk_clipboard_init (GdkClipboard *clipboard)
|
|
{
|
|
GdkClipboardPrivate *priv = gdk_clipboard_get_instance_private (clipboard);
|
|
|
|
priv->formats = gdk_content_formats_new (NULL, 0);
|
|
priv->local = TRUE;
|
|
}
|
|
|
|
/**
|
|
* gdk_clipboard_get_display: (attributes org.gtk.Method.get_property=display)
|
|
* @clipboard: a `GdkClipboard`
|
|
*
|
|
* Gets the `GdkDisplay` that the clipboard was created for.
|
|
*
|
|
* Returns: (transfer none): a `GdkDisplay`
|
|
*/
|
|
GdkDisplay *
|
|
gdk_clipboard_get_display (GdkClipboard *clipboard)
|
|
{
|
|
GdkClipboardPrivate *priv = gdk_clipboard_get_instance_private (clipboard);
|
|
|
|
g_return_val_if_fail (GDK_IS_CLIPBOARD (clipboard), NULL);
|
|
|
|
return priv->display;
|
|
}
|
|
|
|
/**
|
|
* gdk_clipboard_get_formats: (attributes org.gtk.Method.get_property=formats)
|
|
* @clipboard: a `GdkClipboard`
|
|
*
|
|
* Gets the formats that the clipboard can provide its current contents in.
|
|
*
|
|
* Returns: (transfer none): The formats of the clipboard
|
|
*/
|
|
GdkContentFormats *
|
|
gdk_clipboard_get_formats (GdkClipboard *clipboard)
|
|
{
|
|
GdkClipboardPrivate *priv = gdk_clipboard_get_instance_private (clipboard);
|
|
|
|
g_return_val_if_fail (GDK_IS_CLIPBOARD (clipboard), NULL);
|
|
|
|
return priv->formats;
|
|
}
|
|
|
|
/**
|
|
* gdk_clipboard_is_local: (attributes org.gtk.Method.get_property=local)
|
|
* @clipboard: a `GdkClipboard`
|
|
*
|
|
* Returns if the clipboard is local.
|
|
*
|
|
* A clipboard is considered local if it was last claimed
|
|
* by the running application.
|
|
*
|
|
* Note that [method@Gdk.Clipboard.get_content] may return %NULL
|
|
* even on a local clipboard. In this case the clipboard is empty.
|
|
*
|
|
* Returns: %TRUE if the clipboard is local
|
|
*/
|
|
gboolean
|
|
gdk_clipboard_is_local (GdkClipboard *clipboard)
|
|
{
|
|
GdkClipboardPrivate *priv = gdk_clipboard_get_instance_private (clipboard);
|
|
|
|
g_return_val_if_fail (GDK_IS_CLIPBOARD (clipboard), FALSE);
|
|
|
|
return priv->local;
|
|
}
|
|
|
|
/**
|
|
* gdk_clipboard_get_content: (attributes org.gtk.Method.get_property=content)
|
|
* @clipboard: a `GdkClipboard`
|
|
*
|
|
* Returns the `GdkContentProvider` currently set on @clipboard.
|
|
*
|
|
* If the @clipboard is empty or its contents are not owned by the
|
|
* current process, %NULL will be returned.
|
|
*
|
|
* Returns: (transfer none) (nullable): The content of a clipboard
|
|
* if the clipboard does not maintain any content
|
|
*/
|
|
GdkContentProvider *
|
|
gdk_clipboard_get_content (GdkClipboard *clipboard)
|
|
{
|
|
GdkClipboardPrivate *priv = gdk_clipboard_get_instance_private (clipboard);
|
|
|
|
g_return_val_if_fail (GDK_IS_CLIPBOARD (clipboard), NULL);
|
|
|
|
return priv->content;
|
|
}
|
|
|
|
/**
|
|
* gdk_clipboard_store_async:
|
|
* @clipboard: a `GdkClipboard`
|
|
* @io_priority: the I/O priority of the request
|
|
* @cancellable: (nullable): optional `GCancellable` object
|
|
* @callback: (scope async): callback to call when the request is satisfied
|
|
* @user_data: (closure): the data to pass to callback function
|
|
*
|
|
* Asynchronously instructs the @clipboard to store its contents remotely.
|
|
*
|
|
* If the clipboard is not local, this function does nothing but report success.
|
|
*
|
|
* The @callback must call [method@Gdk.Clipboard.store_finish].
|
|
*
|
|
* The purpose of this call is to preserve clipboard contents beyond the
|
|
* lifetime of an application, so this function is typically called on
|
|
* exit. Depending on the platform, the functionality may not be available
|
|
* unless a "clipboard manager" is running.
|
|
*
|
|
* This function is called automatically when a [class@Gtk.Application] is
|
|
* shut down, so you likely don't need to call it.
|
|
*/
|
|
void
|
|
gdk_clipboard_store_async (GdkClipboard *clipboard,
|
|
int io_priority,
|
|
GCancellable *cancellable,
|
|
GAsyncReadyCallback callback,
|
|
gpointer user_data)
|
|
{
|
|
GdkClipboardPrivate *priv = gdk_clipboard_get_instance_private (clipboard);
|
|
|
|
g_return_if_fail (GDK_IS_CLIPBOARD (clipboard));
|
|
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
|
g_return_if_fail (callback != NULL);
|
|
|
|
if (priv->local)
|
|
{
|
|
GDK_CLIPBOARD_GET_CLASS (clipboard)->store_async (clipboard,
|
|
io_priority,
|
|
cancellable,
|
|
callback,
|
|
user_data);
|
|
}
|
|
else
|
|
{
|
|
gdk_clipboard_store_default_async (clipboard,
|
|
io_priority,
|
|
cancellable,
|
|
callback,
|
|
user_data);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* gdk_clipboard_store_finish:
|
|
* @clipboard: a `GdkClipboard`
|
|
* @result: a `GAsyncResult`
|
|
* @error: a `GError` location to store the error occurring
|
|
*
|
|
* Finishes an asynchronous clipboard store.
|
|
*
|
|
* See [method@Gdk.Clipboard.store_async].
|
|
*
|
|
* Returns: %TRUE if storing was successful.
|
|
*/
|
|
gboolean
|
|
gdk_clipboard_store_finish (GdkClipboard *clipboard,
|
|
GAsyncResult *result,
|
|
GError **error)
|
|
{
|
|
g_return_val_if_fail (GDK_IS_CLIPBOARD (clipboard), FALSE);
|
|
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
|
|
|
/* don't check priv->local here because it might have changed while the
|
|
* read was ongoing */
|
|
if (g_async_result_is_tagged (result, gdk_clipboard_store_default_async))
|
|
{
|
|
return gdk_clipboard_store_default_finish (clipboard, result, error);
|
|
}
|
|
else
|
|
{
|
|
return GDK_CLIPBOARD_GET_CLASS (clipboard)->store_finish (clipboard, result, error);
|
|
}
|
|
}
|
|
|
|
static void
|
|
gdk_clipboard_read_internal (GdkClipboard *clipboard,
|
|
GdkContentFormats *formats,
|
|
int io_priority,
|
|
GCancellable *cancellable,
|
|
GAsyncReadyCallback callback,
|
|
gpointer user_data)
|
|
{
|
|
GdkClipboardPrivate *priv = gdk_clipboard_get_instance_private (clipboard);
|
|
|
|
if (priv->local)
|
|
{
|
|
gdk_clipboard_read_local_async (clipboard,
|
|
formats,
|
|
io_priority,
|
|
cancellable,
|
|
callback,
|
|
user_data);
|
|
}
|
|
else
|
|
{
|
|
GDK_CLIPBOARD_GET_CLASS (clipboard)->read_async (clipboard,
|
|
formats,
|
|
io_priority,
|
|
cancellable,
|
|
callback,
|
|
user_data);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* gdk_clipboard_read_async:
|
|
* @clipboard: a `GdkClipboard`
|
|
* @mime_types: (array zero-terminated=1): a %NULL-terminated array of mime types to choose from
|
|
* @io_priority: the I/O priority of the request
|
|
* @cancellable: (nullable): optional `GCancellable` object
|
|
* @callback: (scope async): callback to call when the request is satisfied
|
|
* @user_data: (closure): the data to pass to callback function
|
|
*
|
|
* Asynchronously requests an input stream to read the @clipboard's
|
|
* contents from.
|
|
*
|
|
* When the operation is finished @callback will be called. You must then
|
|
* call [method@Gdk.Clipboard.read_finish] to get the result of the operation.
|
|
*
|
|
* The clipboard will choose the most suitable mime type from the given list
|
|
* to fulfill the request, preferring the ones listed first.
|
|
*/
|
|
void
|
|
gdk_clipboard_read_async (GdkClipboard *clipboard,
|
|
const char **mime_types,
|
|
int io_priority,
|
|
GCancellable *cancellable,
|
|
GAsyncReadyCallback callback,
|
|
gpointer user_data)
|
|
{
|
|
GdkContentFormats *formats;
|
|
|
|
g_return_if_fail (GDK_IS_CLIPBOARD (clipboard));
|
|
g_return_if_fail (mime_types != NULL && mime_types[0] != NULL);
|
|
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
|
g_return_if_fail (callback != NULL);
|
|
|
|
formats = gdk_content_formats_new (mime_types, g_strv_length ((char **) mime_types));
|
|
|
|
gdk_clipboard_read_internal (clipboard, formats, io_priority, cancellable, callback, user_data);
|
|
|
|
gdk_content_formats_unref (formats);
|
|
}
|
|
|
|
/**
|
|
* gdk_clipboard_read_finish:
|
|
* @clipboard: a `GdkClipboard`
|
|
* @result: a `GAsyncResult`
|
|
* @out_mime_type: (out) (optional) (transfer none): location to store
|
|
* the chosen mime type
|
|
* @error: a `GError` location to store the error occurring
|
|
*
|
|
* Finishes an asynchronous clipboard read.
|
|
*
|
|
* See [method@Gdk.Clipboard.read_async].
|
|
*
|
|
* Returns: (transfer full) (nullable): a `GInputStream`
|
|
*/
|
|
GInputStream *
|
|
gdk_clipboard_read_finish (GdkClipboard *clipboard,
|
|
GAsyncResult *result,
|
|
const char **out_mime_type,
|
|
GError **error)
|
|
{
|
|
g_return_val_if_fail (GDK_IS_CLIPBOARD (clipboard), NULL);
|
|
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
|
|
|
/* don't check priv->local here because it might have changed while the
|
|
* read was ongoing */
|
|
if (g_async_result_is_tagged (result, gdk_clipboard_read_local_async))
|
|
{
|
|
return gdk_clipboard_read_local_finish (clipboard, result, out_mime_type, error);
|
|
}
|
|
else
|
|
{
|
|
return GDK_CLIPBOARD_GET_CLASS (clipboard)->read_finish (clipboard, result, out_mime_type, error);
|
|
}
|
|
}
|
|
|
|
static void
|
|
gdk_clipboard_read_value_done (GObject *source,
|
|
GAsyncResult *result,
|
|
gpointer data)
|
|
{
|
|
GTask *task = data;
|
|
GError *error = NULL;
|
|
GValue *value;
|
|
|
|
value = g_task_get_task_data (task);
|
|
|
|
if (!gdk_content_deserialize_finish (result, value, &error))
|
|
g_task_return_error (task, error);
|
|
else
|
|
g_task_return_pointer (task, value, NULL);
|
|
|
|
g_object_unref (task);
|
|
}
|
|
|
|
static void
|
|
gdk_clipboard_read_value_got_stream (GObject *source,
|
|
GAsyncResult *result,
|
|
gpointer data)
|
|
{
|
|
GInputStream *stream;
|
|
GError *error = NULL;
|
|
GTask *task = data;
|
|
const char *mime_type;
|
|
|
|
stream = gdk_clipboard_read_finish (GDK_CLIPBOARD (source), result, &mime_type, &error);
|
|
if (stream == NULL)
|
|
{
|
|
g_task_return_error (task, error);
|
|
return;
|
|
}
|
|
|
|
gdk_content_deserialize_async (stream,
|
|
mime_type,
|
|
G_VALUE_TYPE (g_task_get_task_data (task)),
|
|
g_task_get_priority (task),
|
|
g_task_get_cancellable (task),
|
|
gdk_clipboard_read_value_done,
|
|
task);
|
|
g_object_unref (stream);
|
|
}
|
|
|
|
static void
|
|
free_value (gpointer value)
|
|
{
|
|
g_value_unset (value);
|
|
g_slice_free (GValue, value);
|
|
}
|
|
|
|
static void
|
|
gdk_clipboard_read_value_internal (GdkClipboard *clipboard,
|
|
GType type,
|
|
gpointer source_tag,
|
|
int io_priority,
|
|
GCancellable *cancellable,
|
|
GAsyncReadyCallback callback,
|
|
gpointer user_data)
|
|
{
|
|
GdkClipboardPrivate *priv = gdk_clipboard_get_instance_private (clipboard);
|
|
GdkContentFormatsBuilder *builder;
|
|
GdkContentFormats *formats;
|
|
GValue *value;
|
|
GTask *task;
|
|
|
|
task = g_task_new (clipboard, cancellable, callback, user_data);
|
|
g_task_set_priority (task, io_priority);
|
|
g_task_set_source_tag (task, source_tag);
|
|
value = g_slice_new0 (GValue);
|
|
g_value_init (value, type);
|
|
g_task_set_task_data (task, value, free_value);
|
|
|
|
if (priv->local)
|
|
{
|
|
GError *error = NULL;
|
|
|
|
if (priv->content == NULL)
|
|
{
|
|
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
|
|
_("Cannot read from empty clipboard."));
|
|
g_object_unref (task);
|
|
return;
|
|
}
|
|
|
|
if (gdk_content_provider_get_value (priv->content, value, &error))
|
|
{
|
|
g_task_return_pointer (task, value, NULL);
|
|
g_object_unref (task);
|
|
return;
|
|
}
|
|
else if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED))
|
|
{
|
|
g_task_return_error (task, error);
|
|
g_object_unref (task);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
/* fall through to regular stream transfer */
|
|
g_clear_error (&error);
|
|
}
|
|
}
|
|
|
|
builder = gdk_content_formats_builder_new ();
|
|
gdk_content_formats_builder_add_gtype (builder, type);
|
|
formats = gdk_content_formats_builder_free_to_formats (builder);
|
|
formats = gdk_content_formats_union_deserialize_mime_types (formats);
|
|
|
|
gdk_clipboard_read_internal (clipboard,
|
|
formats,
|
|
io_priority,
|
|
cancellable,
|
|
gdk_clipboard_read_value_got_stream,
|
|
task);
|
|
|
|
gdk_content_formats_unref (formats);
|
|
}
|
|
|
|
/**
|
|
* gdk_clipboard_read_value_async:
|
|
* @clipboard: a `GdkClipboard`
|
|
* @type: a `GType` to read
|
|
* @io_priority: the I/O priority of the request
|
|
* @cancellable: (nullable): optional `GCancellable` object
|
|
* @callback: (scope async): callback to call when the request is satisfied
|
|
* @user_data: (closure): the data to pass to callback function
|
|
*
|
|
* Asynchronously request the @clipboard contents converted to the given
|
|
* @type.
|
|
*
|
|
* When the operation is finished @callback will be called. You must then call
|
|
* [method@Gdk.Clipboard.read_value_finish] to get the resulting `GValue`.
|
|
*
|
|
* For local clipboard contents that are available in the given `GType`,
|
|
* the value will be copied directly. Otherwise, GDK will try to use
|
|
* [func@content_deserialize_async] to convert the clipboard's data.
|
|
*/
|
|
void
|
|
gdk_clipboard_read_value_async (GdkClipboard *clipboard,
|
|
GType type,
|
|
int io_priority,
|
|
GCancellable *cancellable,
|
|
GAsyncReadyCallback callback,
|
|
gpointer user_data)
|
|
{
|
|
g_return_if_fail (GDK_IS_CLIPBOARD (clipboard));
|
|
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
|
g_return_if_fail (callback != NULL);
|
|
|
|
gdk_clipboard_read_value_internal (clipboard,
|
|
type,
|
|
gdk_clipboard_read_value_async,
|
|
io_priority,
|
|
cancellable,
|
|
callback,
|
|
user_data);
|
|
}
|
|
|
|
/**
|
|
* gdk_clipboard_read_value_finish:
|
|
* @clipboard: a `GdkClipboard`
|
|
* @result: a `GAsyncResult`
|
|
* @error: a GError` location to store the error occurring
|
|
*
|
|
* Finishes an asynchronous clipboard read.
|
|
*
|
|
* See [method@Gdk.Clipboard.read_value_async].
|
|
*
|
|
* Returns: (transfer none): a `GValue` containing the result.
|
|
*/
|
|
const GValue *
|
|
gdk_clipboard_read_value_finish (GdkClipboard *clipboard,
|
|
GAsyncResult *result,
|
|
GError **error)
|
|
{
|
|
g_return_val_if_fail (g_task_is_valid (result, clipboard), NULL);
|
|
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gdk_clipboard_read_value_async, NULL);
|
|
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
|
|
|
return g_task_propagate_pointer (G_TASK (result), error);
|
|
}
|
|
|
|
/**
|
|
* gdk_clipboard_read_texture_async:
|
|
* @clipboard: a `GdkClipboard`
|
|
* @cancellable: (nullable): optional `GCancellable` object, %NULL to ignore.
|
|
* @callback: (scope async): callback to call when the request is satisfied
|
|
* @user_data: (closure): the data to pass to callback function
|
|
*
|
|
* Asynchronously request the @clipboard contents converted to a `GdkPixbuf`.
|
|
*
|
|
* When the operation is finished @callback will be called. You must then
|
|
* call [method@Gdk.Clipboard.read_texture_finish] to get the result.
|
|
*
|
|
* This is a simple wrapper around [method@Gdk.Clipboard.read_value_async].
|
|
* Use that function or [method@Gdk.Clipboard.read_async] directly if you
|
|
* need more control over the operation.
|
|
*/
|
|
void
|
|
gdk_clipboard_read_texture_async (GdkClipboard *clipboard,
|
|
GCancellable *cancellable,
|
|
GAsyncReadyCallback callback,
|
|
gpointer user_data)
|
|
{
|
|
g_return_if_fail (GDK_IS_CLIPBOARD (clipboard));
|
|
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
|
g_return_if_fail (callback != NULL);
|
|
|
|
gdk_clipboard_read_value_internal (clipboard,
|
|
GDK_TYPE_TEXTURE,
|
|
gdk_clipboard_read_texture_async,
|
|
G_PRIORITY_DEFAULT,
|
|
cancellable,
|
|
callback,
|
|
user_data);
|
|
}
|
|
|
|
/**
|
|
* gdk_clipboard_read_texture_finish:
|
|
* @clipboard: a `GdkClipboard`
|
|
* @result: a `GAsyncResult`
|
|
* @error: a `GError` location to store the error occurring
|
|
*
|
|
* Finishes an asynchronous clipboard read.
|
|
*
|
|
* See [method@Gdk.Clipboard.read_texture_async].
|
|
*
|
|
* Returns: (transfer full) (nullable): a new `GdkTexture`
|
|
*/
|
|
GdkTexture *
|
|
gdk_clipboard_read_texture_finish (GdkClipboard *clipboard,
|
|
GAsyncResult *result,
|
|
GError **error)
|
|
{
|
|
const GValue *value;
|
|
|
|
g_return_val_if_fail (g_task_is_valid (result, clipboard), NULL);
|
|
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gdk_clipboard_read_texture_async, NULL);
|
|
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
|
|
|
value = g_task_propagate_pointer (G_TASK (result), error);
|
|
if (!value)
|
|
return NULL;
|
|
|
|
return g_value_dup_object (value);
|
|
}
|
|
|
|
/**
|
|
* gdk_clipboard_read_text_async:
|
|
* @clipboard: a `GdkClipboard`
|
|
* @cancellable: (nullable): optional `GCancellable` object
|
|
* @callback: (scope async): callback to call when the request is satisfied
|
|
* @user_data: (closure): the data to pass to callback function
|
|
*
|
|
* Asynchronously request the @clipboard contents converted to a string.
|
|
*
|
|
* When the operation is finished @callback will be called. You must then
|
|
* call [method@Gdk.Clipboard.read_text_finish] to get the result.
|
|
*
|
|
* This is a simple wrapper around [method@Gdk.Clipboard.read_value_async].
|
|
* Use that function or [method@Gdk.Clipboard.read_async] directly if you
|
|
* need more control over the operation.
|
|
*/
|
|
void
|
|
gdk_clipboard_read_text_async (GdkClipboard *clipboard,
|
|
GCancellable *cancellable,
|
|
GAsyncReadyCallback callback,
|
|
gpointer user_data)
|
|
{
|
|
g_return_if_fail (GDK_IS_CLIPBOARD (clipboard));
|
|
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
|
g_return_if_fail (callback != NULL);
|
|
|
|
gdk_clipboard_read_value_internal (clipboard,
|
|
G_TYPE_STRING,
|
|
gdk_clipboard_read_text_async,
|
|
G_PRIORITY_DEFAULT,
|
|
cancellable,
|
|
callback,
|
|
user_data);
|
|
}
|
|
|
|
/**
|
|
* gdk_clipboard_read_text_finish:
|
|
* @clipboard: a `GdkClipboard`
|
|
* @result: a `GAsyncResult`
|
|
* @error: a `GError` location to store the error occurring
|
|
*
|
|
* Finishes an asynchronous clipboard read.
|
|
*
|
|
* See [method@Gdk.Clipboard.read_text_async].
|
|
*
|
|
* Returns: (transfer full) (nullable): a new string
|
|
*/
|
|
char *
|
|
gdk_clipboard_read_text_finish (GdkClipboard *clipboard,
|
|
GAsyncResult *result,
|
|
GError **error)
|
|
{
|
|
const GValue *value;
|
|
|
|
g_return_val_if_fail (g_task_is_valid (result, clipboard), NULL);
|
|
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gdk_clipboard_read_text_async, NULL);
|
|
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
|
|
|
value = g_task_propagate_pointer (G_TASK (result), error);
|
|
if (!value)
|
|
return NULL;
|
|
|
|
return g_value_dup_string (value);
|
|
}
|
|
|
|
GdkClipboard *
|
|
gdk_clipboard_new (GdkDisplay *display)
|
|
{
|
|
return g_object_new (GDK_TYPE_CLIPBOARD,
|
|
"display", display,
|
|
NULL);
|
|
}
|
|
|
|
static void
|
|
gdk_clipboard_write_done (GObject *content,
|
|
GAsyncResult *result,
|
|
gpointer task)
|
|
{
|
|
GError *error = NULL;
|
|
|
|
if (gdk_content_provider_write_mime_type_finish (GDK_CONTENT_PROVIDER (content), result, &error))
|
|
g_task_return_boolean (task, TRUE);
|
|
else
|
|
g_task_return_error (task, error);
|
|
|
|
g_object_unref (task);
|
|
}
|
|
|
|
static void
|
|
gdk_clipboard_write_serialize_done (GObject *content,
|
|
GAsyncResult *result,
|
|
gpointer task)
|
|
{
|
|
GError *error = NULL;
|
|
|
|
if (gdk_content_serialize_finish (result, &error))
|
|
g_task_return_boolean (task, TRUE);
|
|
else
|
|
g_task_return_error (task, error);
|
|
|
|
g_object_unref (task);
|
|
}
|
|
|
|
void
|
|
gdk_clipboard_write_async (GdkClipboard *clipboard,
|
|
const char *mime_type,
|
|
GOutputStream *stream,
|
|
int io_priority,
|
|
GCancellable *cancellable,
|
|
GAsyncReadyCallback callback,
|
|
gpointer user_data)
|
|
{
|
|
GdkClipboardPrivate *priv = gdk_clipboard_get_instance_private (clipboard);
|
|
GdkContentFormats *formats, *mime_formats;
|
|
GTask *task;
|
|
GType gtype;
|
|
|
|
g_return_if_fail (GDK_IS_CLIPBOARD (clipboard));
|
|
g_return_if_fail (priv->local);
|
|
g_return_if_fail (mime_type != NULL);
|
|
g_return_if_fail (mime_type == g_intern_string (mime_type));
|
|
g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
|
|
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
|
g_return_if_fail (callback != NULL);
|
|
|
|
task = g_task_new (clipboard, cancellable, callback, user_data);
|
|
g_task_set_priority (task, io_priority);
|
|
g_task_set_source_tag (task, gdk_clipboard_write_async);
|
|
|
|
if (priv->content == NULL)
|
|
{
|
|
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
|
|
_("Cannot read from empty clipboard."));
|
|
g_object_unref (task);
|
|
return;
|
|
}
|
|
|
|
formats = gdk_content_provider_ref_formats (priv->content);
|
|
if (gdk_content_formats_contain_mime_type (formats, mime_type))
|
|
{
|
|
gdk_content_provider_write_mime_type_async (priv->content,
|
|
mime_type,
|
|
stream,
|
|
io_priority,
|
|
cancellable,
|
|
gdk_clipboard_write_done,
|
|
task);
|
|
gdk_content_formats_unref (formats);
|
|
return;
|
|
}
|
|
|
|
mime_formats = gdk_content_formats_new ((const char *[2]) { mime_type, NULL }, 1);
|
|
mime_formats = gdk_content_formats_union_serialize_gtypes (mime_formats);
|
|
gtype = gdk_content_formats_match_gtype (formats, mime_formats);
|
|
if (gtype != G_TYPE_INVALID)
|
|
{
|
|
GValue value = G_VALUE_INIT;
|
|
GError *error = NULL;
|
|
|
|
g_assert (gtype != G_TYPE_INVALID);
|
|
|
|
g_value_init (&value, gtype);
|
|
if (gdk_content_provider_get_value (priv->content, &value, &error))
|
|
{
|
|
gdk_content_serialize_async (stream,
|
|
mime_type,
|
|
&value,
|
|
io_priority,
|
|
cancellable,
|
|
gdk_clipboard_write_serialize_done,
|
|
g_object_ref (task));
|
|
}
|
|
else
|
|
{
|
|
g_task_return_error (task, error);
|
|
}
|
|
|
|
g_value_unset (&value);
|
|
}
|
|
else
|
|
{
|
|
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
|
_("No compatible formats to transfer clipboard contents."));
|
|
}
|
|
|
|
gdk_content_formats_unref (mime_formats);
|
|
gdk_content_formats_unref (formats);
|
|
g_object_unref (task);
|
|
}
|
|
|
|
gboolean
|
|
gdk_clipboard_write_finish (GdkClipboard *clipboard,
|
|
GAsyncResult *result,
|
|
GError **error)
|
|
{
|
|
g_return_val_if_fail (g_task_is_valid (result, clipboard), FALSE);
|
|
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gdk_clipboard_write_async, FALSE);
|
|
|
|
return g_task_propagate_boolean (G_TASK (result), error);
|
|
}
|
|
|
|
static gboolean
|
|
gdk_clipboard_claim (GdkClipboard *clipboard,
|
|
GdkContentFormats *formats,
|
|
gboolean local,
|
|
GdkContentProvider *content)
|
|
{
|
|
return GDK_CLIPBOARD_GET_CLASS (clipboard)->claim (clipboard, formats, local, content);
|
|
}
|
|
|
|
static void
|
|
gdk_clipboard_content_changed_cb (GdkContentProvider *provider,
|
|
GdkClipboard *clipboard)
|
|
{
|
|
GdkContentFormats *formats;
|
|
|
|
formats = gdk_content_provider_ref_formats (provider);
|
|
formats = gdk_content_formats_union_serialize_mime_types (formats);
|
|
|
|
gdk_clipboard_claim (clipboard, formats, TRUE, provider);
|
|
|
|
gdk_content_formats_unref (formats);
|
|
}
|
|
|
|
void
|
|
gdk_clipboard_claim_remote (GdkClipboard *clipboard,
|
|
GdkContentFormats *formats)
|
|
{
|
|
g_return_if_fail (GDK_IS_CLIPBOARD (clipboard));
|
|
g_return_if_fail (formats != NULL);
|
|
|
|
gdk_clipboard_claim (clipboard, formats, FALSE, NULL);
|
|
}
|
|
|
|
/**
|
|
* gdk_clipboard_set_content:
|
|
* @clipboard: a `GdkClipboard`
|
|
* @provider: (transfer none) (nullable): the new contents of @clipboard
|
|
* or %NULL to clear the clipboard
|
|
*
|
|
* Sets a new content provider on @clipboard.
|
|
*
|
|
* The clipboard will claim the `GdkDisplay`'s resources and advertise
|
|
* these new contents to other applications.
|
|
*
|
|
* In the rare case of a failure, this function will return %FALSE. The
|
|
* clipboard will then continue reporting its old contents and ignore
|
|
* @provider.
|
|
*
|
|
* If the contents are read by either an external application or the
|
|
* @clipboard's read functions, @clipboard will select the best format to
|
|
* transfer the contents and then request that format from @provider.
|
|
*
|
|
* Returns: %TRUE if setting the clipboard succeeded
|
|
*/
|
|
gboolean
|
|
gdk_clipboard_set_content (GdkClipboard *clipboard,
|
|
GdkContentProvider *provider)
|
|
{
|
|
GdkClipboardPrivate *priv = gdk_clipboard_get_instance_private (clipboard);
|
|
GdkContentFormats *formats;
|
|
gboolean result;
|
|
|
|
g_return_val_if_fail (GDK_IS_CLIPBOARD (clipboard), FALSE);
|
|
g_return_val_if_fail (provider == NULL || GDK_IS_CONTENT_PROVIDER (provider), FALSE);
|
|
|
|
if (provider)
|
|
{
|
|
if (priv->content == provider)
|
|
return TRUE;
|
|
|
|
formats = gdk_content_provider_ref_formats (provider);
|
|
formats = gdk_content_formats_union_serialize_mime_types (formats);
|
|
}
|
|
else
|
|
{
|
|
if (priv->content == NULL && priv->local)
|
|
return TRUE;
|
|
|
|
formats = gdk_content_formats_new (NULL, 0);
|
|
}
|
|
|
|
result = gdk_clipboard_claim (clipboard, formats, TRUE, provider);
|
|
|
|
gdk_content_formats_unref (formats);
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* gdk_clipboard_set:
|
|
* @clipboard: a `GdkClipboard`
|
|
* @type: type of value to set
|
|
* @...: value contents conforming to @type
|
|
*
|
|
* Sets the clipboard to contain the value collected from the given varargs.
|
|
*
|
|
* Values should be passed the same way they are passed to other value
|
|
* collecting APIs, such as [`method@GObject.Object.set`] or
|
|
* [`func@GObject.signal_emit`].
|
|
*
|
|
* ```c
|
|
* gdk_clipboard_set (clipboard, GTK_TYPE_STRING, "Hello World");
|
|
*
|
|
* gdk_clipboard_set (clipboard, GDK_TYPE_TEXTURE, some_texture);
|
|
* ```
|
|
*/
|
|
void
|
|
gdk_clipboard_set (GdkClipboard *clipboard,
|
|
GType type,
|
|
...)
|
|
{
|
|
va_list args;
|
|
|
|
g_return_if_fail (GDK_IS_CLIPBOARD (clipboard));
|
|
|
|
va_start (args, type);
|
|
gdk_clipboard_set_valist (clipboard, type, args);
|
|
va_end (args);
|
|
}
|
|
|
|
/**
|
|
* gdk_clipboard_set_valist: (skip)
|
|
* @clipboard: a `GdkClipboard`
|
|
* @type: type of value to set
|
|
* @args: varargs containing the value of @type
|
|
*
|
|
* Sets the clipboard to contain the value collected from the given @args.
|
|
*/
|
|
void
|
|
gdk_clipboard_set_valist (GdkClipboard *clipboard,
|
|
GType type,
|
|
va_list args)
|
|
{
|
|
GValue value = G_VALUE_INIT;
|
|
char *error;
|
|
|
|
g_return_if_fail (GDK_IS_CLIPBOARD (clipboard));
|
|
|
|
G_VALUE_COLLECT_INIT (&value, type,
|
|
args, G_VALUE_NOCOPY_CONTENTS,
|
|
&error);
|
|
if (error)
|
|
{
|
|
g_warning ("%s: %s", G_STRLOC, error);
|
|
g_free (error);
|
|
/* we purposely leak the value here, it might not be
|
|
* in a sane state if an error condition occurred
|
|
*/
|
|
return;
|
|
}
|
|
|
|
gdk_clipboard_set_value (clipboard, &value);
|
|
g_value_unset (&value);
|
|
}
|
|
|
|
/**
|
|
* gdk_clipboard_set_value: (rename-to gdk_clipboard_set)
|
|
* @clipboard: a `GdkClipboard`
|
|
* @value: a `GValue` to set
|
|
*
|
|
* Sets the @clipboard to contain the given @value.
|
|
*/
|
|
void
|
|
gdk_clipboard_set_value (GdkClipboard *clipboard,
|
|
const GValue *value)
|
|
{
|
|
GdkContentProvider *provider;
|
|
|
|
g_return_if_fail (GDK_IS_CLIPBOARD (clipboard));
|
|
g_return_if_fail (G_IS_VALUE (value));
|
|
|
|
provider = gdk_content_provider_new_for_value (value);
|
|
|
|
gdk_clipboard_set_content (clipboard, provider);
|
|
g_object_unref (provider);
|
|
}
|
|
|
|
/**
|
|
* gdk_clipboard_set_text: (skip)
|
|
* @clipboard: a `GdkClipboard`
|
|
* @text: Text to put into the clipboard
|
|
*
|
|
* Puts the given @text into the clipboard.
|
|
*/
|
|
void
|
|
gdk_clipboard_set_text (GdkClipboard *clipboard,
|
|
const char *text)
|
|
{
|
|
g_return_if_fail (GDK_IS_CLIPBOARD (clipboard));
|
|
|
|
gdk_clipboard_set (clipboard, G_TYPE_STRING, text);
|
|
}
|
|
|
|
/**
|
|
* gdk_clipboard_set_texture: (skip)
|
|
* @clipboard: a `GdkClipboard`
|
|
* @texture: a `GdkTexture` to put into the clipboard
|
|
*
|
|
* Puts the given @texture into the clipboard.
|
|
*/
|
|
void
|
|
gdk_clipboard_set_texture (GdkClipboard *clipboard,
|
|
GdkTexture *texture)
|
|
{
|
|
g_return_if_fail (GDK_IS_CLIPBOARD (clipboard));
|
|
g_return_if_fail (GDK_IS_TEXTURE (texture));
|
|
|
|
gdk_clipboard_set (clipboard, GDK_TYPE_TEXTURE, texture);
|
|
}
|