diff options
author | Benjamin Otte <otte@redhat.com> | 2017-11-22 10:44:30 +0100 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2017-12-03 05:46:27 +0100 |
commit | 91910ba01319447243784a85fefad0fa17c19db7 (patch) | |
tree | cf9410387bc20b6f01457f7c421041ccdb1e43bf /gdk | |
parent | 970cb100aff72679b15c3c8b27b168335d0e5a50 (diff) | |
download | gtk+-91910ba01319447243784a85fefad0fa17c19db7.tar.gz |
gdk: Im[plement content deserializing
Add infrastructure to do GInputStream => GType conversions. Use that to
implement gdk_clipboard_read_value() which reads into GValues.
Diffstat (limited to 'gdk')
-rw-r--r-- | gdk/gdk.h | 1 | ||||
-rw-r--r-- | gdk/gdkclipboard.c | 124 | ||||
-rw-r--r-- | gdk/gdkclipboard.h | 11 | ||||
-rw-r--r-- | gdk/gdkcontentdeserializer.c | 487 | ||||
-rw-r--r-- | gdk/gdkcontentdeserializer.h | 90 | ||||
-rw-r--r-- | gdk/meson.build | 2 |
6 files changed, 714 insertions, 1 deletions
@@ -32,6 +32,7 @@ #include <gdk/gdkapplaunchcontext.h> #include <gdk/gdkcairo.h> #include <gdk/gdkclipboard.h> +#include <gdk/gdkcontentdeserializer.h> #include <gdk/gdkcontentformats.h> #include <gdk/gdkcursor.h> #include <gdk/gdkdevice.h> diff --git a/gdk/gdkclipboard.c b/gdk/gdkclipboard.c index 30b81fff3e..0fb39268bc 100644 --- a/gdk/gdkclipboard.c +++ b/gdk/gdkclipboard.c @@ -20,6 +20,7 @@ #include "gdkclipboardprivate.h" +#include "gdkcontentdeserializer.h" #include "gdkcontentformats.h" #include "gdkdisplay.h" @@ -339,6 +340,125 @@ gdk_clipboard_read_finish (GdkClipboard *clipboard, return GDK_CLIPBOARD_GET_CLASS (clipboard)->read_finish (clipboard, out_mime_type, result, error); } +static void +gdk_clipboard_read_value_done (GObject *source, + GAsyncResult *result, + gpointer data) +{ + GTask *task = data; + GError *error = NULL; + const GValue *value; + + value = gdk_content_deserialize_finish (result, &error); + if (value == NULL) + g_task_return_error (task, error); + else + g_task_return_pointer (task, (gpointer) 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), &mime_type, result, &error); + if (stream == NULL) + { + g_task_return_error (task, error); + return; + } + + gdk_content_deserialize_async (stream, + mime_type, + GPOINTER_TO_SIZE (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); +} + +/** + * gdk_clipboard_read_value_async: + * @clipboard: a #GdkClipboard + * @type: a #GType to read + * @io_priority: the [I/O priority][io-priority] + * of the request. + * @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 the given + * @type. When the operation is finished @callback will be called. + * You can then call 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 + * gdk_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) +{ + GdkContentFormatsBuilder *builder; + GdkContentFormats *formats; + GTask *task; + + builder = gdk_content_formats_builder_new (); + gdk_content_formats_builder_add_gtype (builder, type); + formats = gdk_content_formats_builder_free (builder); + formats = gdk_content_formats_union_deserialize_mime_types (formats); + + 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_value_async); + g_task_set_task_data (task, GSIZE_TO_POINTER (type), NULL); + + 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_finish: + * @clipboard: a #GdkClipboard + * @result: a #GAsyncResult + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Finishes an asynchronous clipboard read started with + * gdk_clipboard_read_value_async(). + * + * Returns: (transfer none): a #GValue containing the result. + **/ +const GValue * +gdk_clipboard_read_value_finish (GdkClipboard *clipboard, + GAsyncResult *res, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (res, clipboard), NULL); + g_return_val_if_fail (g_task_get_source_tag (G_TASK (res)) == gdk_clipboard_read_value_async, NULL); + + return g_task_propagate_pointer (G_TASK (res), error); +} + GdkClipboard * gdk_clipboard_new (GdkDisplay *display) { @@ -357,7 +477,9 @@ gdk_clipboard_claim_remote (GdkClipboard *clipboard, g_return_if_fail (formats != NULL); gdk_content_formats_unref (priv->formats); - priv->formats = gdk_content_formats_ref (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) { diff --git a/gdk/gdkclipboard.h b/gdk/gdkclipboard.h index 5721fd10ff..2a357602ab 100644 --- a/gdk/gdkclipboard.h +++ b/gdk/gdkclipboard.h @@ -54,6 +54,17 @@ GInputStream * gdk_clipboard_read_finish (GdkClipboard * const char **out_mime_type, GAsyncResult *result, GError **error); +GDK_AVAILABLE_IN_3_94 +void gdk_clipboard_read_value_async (GdkClipboard *clipboard, + GType type, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GDK_AVAILABLE_IN_3_94 +const GValue * gdk_clipboard_read_value_finish (GdkClipboard *clipboard, + GAsyncResult *res, + GError **error); G_END_DECLS diff --git a/gdk/gdkcontentdeserializer.c b/gdk/gdkcontentdeserializer.c new file mode 100644 index 0000000000..d6ec674b27 --- /dev/null +++ b/gdk/gdkcontentdeserializer.c @@ -0,0 +1,487 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 2017 Benjamin Otte + * + * 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 <gio/gio.h> + +#include "gdkcontentdeserializer.h" + +#include "gdkcontentformats.h" + +#include <gdk-pixbuf/gdk-pixbuf.h> + +typedef struct _Deserializer Deserializer; + +struct _Deserializer +{ + const char * mime_type; /* interned */ + GType type; + GdkContentDeserializeFunc deserialize; + gpointer data; + GDestroyNotify notify; +}; + +GQueue deserializers = G_QUEUE_INIT; + +static void init (void); + +#define GDK_CONTENT_DESERIALIZER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_CONTENT_DESERIALIZER, GdkContentDeserializerClass)) +#define GDK_IS_CONTENT_DESERIALIZER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_CONTENT_DESERIALIZER)) +#define GDK_CONTENT_DESERIALIZER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_CONTENT_DESERIALIZER, GdkContentDeserializerClass)) + +typedef struct _GdkContentDeserializerClass GdkContentDeserializerClass; + +struct _GdkContentDeserializer +{ + GObject parent_instance; + + const char *mime_type; /* interned */ + GValue value; + GInputStream *stream; + int priority; + GCancellable *cancellable; + gpointer user_data; + GAsyncReadyCallback callback; + gpointer callback_data; + + GError *error; + gboolean returned; +}; + +struct _GdkContentDeserializerClass +{ + GObjectClass parent_class; +}; + +static gpointer +gdk_content_deserializer_async_result_get_user_data (GAsyncResult *res) +{ + return GDK_CONTENT_DESERIALIZER (res)->callback_data; +} + +static GObject * +gdk_content_deserializer_async_result_get_source_object (GAsyncResult *res) +{ + return NULL; +} + +static void +gdk_content_deserializer_async_result_iface_init (GAsyncResultIface *iface) +{ + iface->get_user_data = gdk_content_deserializer_async_result_get_user_data; + iface->get_source_object = gdk_content_deserializer_async_result_get_source_object; +} + +G_DEFINE_TYPE_WITH_CODE (GdkContentDeserializer, gdk_content_deserializer, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_RESULT, gdk_content_deserializer_async_result_iface_init)) + +static void +gdk_content_deserializer_finalize (GObject *object) +{ + GdkContentDeserializer *deserializer = GDK_CONTENT_DESERIALIZER (object); + + g_value_unset (&deserializer->value); + g_clear_object (&deserializer->stream); + g_clear_object (&deserializer->cancellable); + g_clear_error (&deserializer->error); + + G_OBJECT_CLASS (gdk_content_deserializer_parent_class)->finalize (object); +} + +static void +gdk_content_deserializer_class_init (GdkContentDeserializerClass *content_deserializer_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (content_deserializer_class); + + object_class->finalize = gdk_content_deserializer_finalize; +} + +static void +gdk_content_deserializer_init (GdkContentDeserializer *content_deserializer) +{ +} + +static void +gdk_content_deserializer_run (const char *mime_type, + GType type, + GInputStream *stream, + int priority, + GCancellable *cancellable, + GdkContentDeserializeFunc deserialize_func, + gpointer user_data, + GAsyncReadyCallback callback, + gpointer callback_data) +{ + GdkContentDeserializer *deserializer; + + deserializer = g_object_new (GDK_TYPE_CONTENT_DESERIALIZER, NULL); + + deserializer->mime_type = mime_type; + g_value_init (&deserializer->value, type); + deserializer->stream = g_object_ref (stream); + deserializer->priority = priority; + if (cancellable) + deserializer->cancellable = g_object_ref (cancellable); + deserializer->user_data = user_data; + deserializer->callback = callback; + deserializer->callback_data = callback_data; + + deserialize_func (deserializer); +} + +const char * +gdk_content_deserializer_get_mime_type (GdkContentDeserializer *deserializer) +{ + g_return_val_if_fail (GDK_IS_CONTENT_DESERIALIZER (deserializer), NULL); + + return deserializer->mime_type; +} + +GType +gdk_content_deserializer_get_gtype (GdkContentDeserializer *deserializer) +{ + g_return_val_if_fail (GDK_IS_CONTENT_DESERIALIZER (deserializer), G_TYPE_INVALID); + + return G_VALUE_TYPE (&deserializer->value); +} + +GValue * +gdk_content_deserializer_get_value (GdkContentDeserializer *deserializer) +{ + g_return_val_if_fail (GDK_IS_CONTENT_DESERIALIZER (deserializer), NULL); + + return &deserializer->value; +} + +GInputStream * +gdk_content_deserializer_get_input_stream (GdkContentDeserializer *deserializer) +{ + g_return_val_if_fail (GDK_IS_CONTENT_DESERIALIZER (deserializer), NULL); + + return deserializer->stream; +} + +int +gdk_content_deserializer_get_priority (GdkContentDeserializer *deserializer) +{ + g_return_val_if_fail (GDK_IS_CONTENT_DESERIALIZER (deserializer), G_PRIORITY_DEFAULT); + + return deserializer->priority; +} + +GCancellable * +gdk_content_deserializer_get_cancellable (GdkContentDeserializer *deserializer) +{ + g_return_val_if_fail (GDK_IS_CONTENT_DESERIALIZER (deserializer), NULL); + + return deserializer->cancellable; +} + +gpointer +gdk_content_deserializer_get_user_data (GdkContentDeserializer *deserializer) +{ + g_return_val_if_fail (GDK_IS_CONTENT_DESERIALIZER (deserializer), NULL); + + return deserializer->user_data; +} + +static gboolean +gdk_content_deserializer_emit_callback (gpointer data) +{ + GdkContentDeserializer *deserializer = data; + + if (deserializer->callback) + { + deserializer->callback (NULL, G_ASYNC_RESULT (deserializer), deserializer->callback_data); + } + + return G_SOURCE_REMOVE; +} + +void +gdk_content_deserializer_return_success (GdkContentDeserializer *deserializer) +{ + g_return_if_fail (GDK_IS_CONTENT_DESERIALIZER (deserializer)); + g_return_if_fail (!deserializer->returned); + + deserializer->returned = TRUE; + g_idle_add_full (deserializer->priority, + gdk_content_deserializer_emit_callback, + deserializer, + g_object_unref); + /* NB: the idle will destroy our reference */ +} + +void +gdk_content_deserializer_return_error (GdkContentDeserializer *deserializer, + GError *error) +{ + g_return_if_fail (GDK_IS_CONTENT_DESERIALIZER (deserializer)); + g_return_if_fail (!deserializer->returned); + g_return_if_fail (error != NULL); + + deserializer->error = error; + /* FIXME: naming */ + gdk_content_deserializer_return_success (deserializer); +} + +void +gdk_content_register_deserializer (const char *mime_type, + GType type, + GdkContentDeserializeFunc deserialize, + gpointer data, + GDestroyNotify notify) +{ + Deserializer *deserializer; + + g_return_if_fail (mime_type != NULL); + g_return_if_fail (deserialize != NULL); + + init (); + + deserializer = g_slice_new0 (Deserializer); + + deserializer->mime_type = g_intern_string (mime_type); + deserializer->type = type; + deserializer->deserialize = deserialize; + deserializer->data = data; + deserializer->notify = notify; + + g_queue_push_tail (&deserializers, deserializer); +} + +static Deserializer * +lookup_deserializer (const char *mime_type, + GType type) +{ + GList *l; + + g_return_val_if_fail (mime_type != NULL, NULL); + + init (); + + mime_type = g_intern_string (mime_type); + + for (l = g_queue_peek_head_link (&deserializers); l; l = l->next) + { + Deserializer *deserializer = l->data; + + if (deserializer->mime_type == mime_type && + deserializer->type == type) + return deserializer; + } + + return NULL; +} + +GdkContentFormats * +gdk_content_formats_union_deserialize_gtypes (GdkContentFormats *formats) +{ + GdkContentFormatsBuilder *builder; + GList *l; + + g_return_val_if_fail (formats != NULL, NULL); + + init (); + + builder = gdk_content_formats_builder_new (); + gdk_content_formats_builder_add_formats (builder, formats); + + for (l = g_queue_peek_head_link (&deserializers); l; l = l->next) + { + Deserializer *deserializer = l->data; + + if (gdk_content_formats_contain_mime_type (formats, deserializer->mime_type)) + gdk_content_formats_builder_add_gtype (builder, deserializer->type); + } + + gdk_content_formats_unref (formats); + + return gdk_content_formats_builder_free (builder); +} + +GdkContentFormats * +gdk_content_formats_union_deserialize_mime_types (GdkContentFormats *formats) +{ + GdkContentFormatsBuilder *builder; + GList *l; + + g_return_val_if_fail (formats != NULL, NULL); + + init (); + + builder = gdk_content_formats_builder_new (); + gdk_content_formats_builder_add_formats (builder, formats); + + for (l = g_queue_peek_head_link (&deserializers); l; l = l->next) + { + Deserializer *deserializer = l->data; + + if (gdk_content_formats_contain_gtype (formats, deserializer->type)) + gdk_content_formats_builder_add_mime_type (builder, deserializer->mime_type); + } + + gdk_content_formats_unref (formats); + + return gdk_content_formats_builder_free (builder); +} + +static void +deserialize_not_found (GdkContentDeserializer *deserializer) +{ + GError *error = g_error_new (G_IO_ERROR, + G_IO_ERROR_NOT_FOUND, + "Could not convert data from %s to %s", + gdk_content_deserializer_get_mime_type (deserializer), + g_type_name (gdk_content_deserializer_get_gtype (deserializer))); + gdk_content_deserializer_return_error (deserializer, error); +} + +void +gdk_content_deserialize_async (GInputStream *stream, + const char *mime_type, + GType type, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + Deserializer *deserializer; + + g_return_if_fail (G_IS_INPUT_STREAM (stream)); + g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + g_return_if_fail (callback != NULL); + + deserializer = lookup_deserializer (mime_type, type); + + gdk_content_deserializer_run (mime_type, + type, + stream, + io_priority, + cancellable, + deserializer ? deserializer->deserialize : deserialize_not_found, + deserializer ? deserializer->data : NULL, + callback, + user_data); +} + +const GValue * +gdk_content_deserialize_finish (GAsyncResult *result, + GError **error) +{ + GdkContentDeserializer *deserializer; + + g_return_val_if_fail (GDK_IS_CONTENT_DESERIALIZER (result), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + deserializer = GDK_CONTENT_DESERIALIZER (result); + + if (deserializer->error) + { + if (error) + *error = g_error_copy (deserializer->error); + return NULL; + } + + return &deserializer->value; +} + +/*** DESERIALIZERS ***/ + +static void +pixbuf_deserializer_finish (GObject *source, + GAsyncResult *res, + gpointer deserializer) +{ + GdkPixbuf *pixbuf; + GError *error = NULL; + + pixbuf = gdk_pixbuf_new_from_stream_finish (res, &error); + if (pixbuf == NULL) + { + gdk_content_deserializer_return_error (deserializer, error); + return; + } + + g_value_take_object (gdk_content_deserializer_get_value (deserializer), + pixbuf); + gdk_content_deserializer_return_success (deserializer); +} + +static void +pixbuf_deserializer (GdkContentDeserializer *deserializer) +{ + gdk_pixbuf_new_from_stream_async (gdk_content_deserializer_get_input_stream (deserializer), + gdk_content_deserializer_get_cancellable (deserializer), + pixbuf_deserializer_finish, + deserializer); +} + +static void +init (void) +{ + static gboolean initialized = FALSE; + GSList *formats, *f; + + if (initialized) + return; + + initialized = TRUE; + + formats = gdk_pixbuf_get_formats (); + + /* Make sure png comes first */ + for (f = formats; f; f = f->next) + { + GdkPixbufFormat *fmt = f->data; + gchar *name; + + name = gdk_pixbuf_format_get_name (fmt); + if (g_str_equal (name, "png")) + { + formats = g_slist_delete_link (formats, f); + formats = g_slist_prepend (formats, fmt); + + g_free (name); + + break; + } + + g_free (name); + } + + for (f = formats; f; f = f->next) + { + GdkPixbufFormat *fmt = f->data; + gchar **mimes, **m; + + mimes = gdk_pixbuf_format_get_mime_types (fmt); + for (m = mimes; *m; m++) + { + gdk_content_register_deserializer (*m, + GDK_TYPE_PIXBUF, + pixbuf_deserializer, + NULL, + NULL); + } + g_strfreev (mimes); + } + + g_slist_free (formats); +} + diff --git a/gdk/gdkcontentdeserializer.h b/gdk/gdkcontentdeserializer.h new file mode 100644 index 0000000000..481f15a838 --- /dev/null +++ b/gdk/gdkcontentdeserializer.h @@ -0,0 +1,90 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 2017 Benjamin Otte + * + * 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/>. + */ + +#ifndef __GTK_CONTENT_DESERIALIZER_H__ +#define __GTK_CONTENT_DESERIALIZER_H__ + +#if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION) +#error "Only <gdk/gdk.h> can be included directly." +#endif + + +#include <gdk/gdkversionmacros.h> +#include <gdk/gdktypes.h> +#include <gio/gio.h> + +G_BEGIN_DECLS + +#define GDK_TYPE_CONTENT_DESERIALIZER (gdk_content_deserializer_get_type ()) +#define GDK_CONTENT_DESERIALIZER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_CONTENT_DESERIALIZER, GdkContentDeserializer)) +#define GDK_IS_CONTENT_DESERIALIZER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_CONTENT_DESERIALIZER)) + +typedef struct _GdkContentDeserializer GdkContentDeserializer; + +typedef void (* GdkContentDeserializeFunc) (GdkContentDeserializer *deserializer); + +GDK_AVAILABLE_IN_3_94 +GType gdk_content_deserializer_get_type (void) G_GNUC_CONST; + +GDK_AVAILABLE_IN_3_94 +const char * gdk_content_deserializer_get_mime_type (GdkContentDeserializer *deserializer); +GDK_AVAILABLE_IN_3_94 +GType gdk_content_deserializer_get_gtype (GdkContentDeserializer *deserializer); +GDK_AVAILABLE_IN_3_94 +GValue * gdk_content_deserializer_get_value (GdkContentDeserializer *deserializer); +GDK_AVAILABLE_IN_3_94 +GInputStream * gdk_content_deserializer_get_input_stream (GdkContentDeserializer *deserializer); +GDK_AVAILABLE_IN_3_94 +int gdk_content_deserializer_get_priority (GdkContentDeserializer *deserializer); +GDK_AVAILABLE_IN_3_94 +GCancellable * gdk_content_deserializer_get_cancellable (GdkContentDeserializer *deserializer); +GDK_AVAILABLE_IN_3_94 +gpointer gdk_content_deserializer_get_user_data (GdkContentDeserializer *deserializer); + +GDK_AVAILABLE_IN_3_94 +void gdk_content_deserializer_return_success (GdkContentDeserializer *deserializer); +GDK_AVAILABLE_IN_3_94 +void gdk_content_deserializer_return_error (GdkContentDeserializer *deserializer, + GError *error); + +GDK_AVAILABLE_IN_3_94 +GdkContentFormats * gdk_content_formats_union_deserialize_gtypes (GdkContentFormats *formats); +GDK_AVAILABLE_IN_3_94 +GdkContentFormats * gdk_content_formats_union_deserialize_mime_types(GdkContentFormats *formats); + +GDK_AVAILABLE_IN_3_94 +void gdk_content_register_deserializer (const char *mime_type, + GType type, + GdkContentDeserializeFunc deserialize, + gpointer data, + GDestroyNotify notify); +GDK_AVAILABLE_IN_3_94 +void gdk_content_deserialize_async (GInputStream *stream, + const char *mime_type, + GType type, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GDK_AVAILABLE_IN_3_94 +const GValue * gdk_content_deserialize_finish (GAsyncResult *result, + GError **error); + + +G_END_DECLS + +#endif /* __GDK_CONTENT_DESERIALIZER_H__ */ diff --git a/gdk/meson.build b/gdk/meson.build index d1e75ce5b2..88045c38c6 100644 --- a/gdk/meson.build +++ b/gdk/meson.build @@ -3,6 +3,7 @@ gdk_public_sources = files([ 'gdkapplaunchcontext.c', 'gdkcairo.c', 'gdkclipboard.c', + 'gdkcontentdeserializer.c', 'gdkcontentformats.c', 'gdkcursor.c', 'gdkdevice.c', @@ -43,6 +44,7 @@ gdk_public_headers = files([ 'gdkapplaunchcontext.h', 'gdkcairo.h', 'gdkclipboard.h', + 'gdkcontentdeserializer.h', 'gdkcontentformats.h', 'gdkcursor.h', 'gdkdevice.h', |