summaryrefslogtreecommitdiff
path: root/gdk/gdkcontentdeserializer.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdk/gdkcontentdeserializer.c')
-rw-r--r--gdk/gdkcontentdeserializer.c98
1 files changed, 98 insertions, 0 deletions
diff --git a/gdk/gdkcontentdeserializer.c b/gdk/gdkcontentdeserializer.c
index 93564e2002..ea3c7ad003 100644
--- a/gdk/gdkcontentdeserializer.c
+++ b/gdk/gdkcontentdeserializer.c
@@ -22,6 +22,7 @@
#include "gdkcontentdeserializer.h"
#include "gdkcontentformats.h"
+#include "gfiletransferportal.h"
#include "gdktexture.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
@@ -691,6 +692,93 @@ string_deserializer (GdkContentDeserializer *deserializer)
}
static void
+portal_finish (GObject *object,
+ GAsyncResult *result,
+ gpointer deserializer)
+{
+ char **files = NULL;
+ GError *error = NULL;
+ GValue *value;
+
+ if (!file_transfer_portal_retrieve_files_finish (result, &files, &error))
+ {
+ gdk_content_deserializer_return_error (deserializer, error);
+ return;
+ }
+
+ value = gdk_content_deserializer_get_value (deserializer);
+ if (G_VALUE_HOLDS (value, G_TYPE_FILE))
+ {
+ if (files[0] != NULL)
+ g_value_take_object (value, g_file_new_for_path (files[0]));
+ }
+ else
+ {
+ GSList *l = NULL;
+ gsize i;
+
+ for (i = 0; files[i] != NULL; i++)
+ l = g_slist_prepend (l, g_file_new_for_path (files[i]));
+ g_value_take_boxed (value, g_slist_reverse (l));
+ }
+ g_strfreev (files);
+
+ gdk_content_deserializer_return_success (deserializer);
+}
+
+static void
+portal_file_deserializer_finish (GObject *source,
+ GAsyncResult *result,
+ gpointer deserializer)
+{
+ GOutputStream *stream = G_OUTPUT_STREAM (source);
+ GError *error = NULL;
+ gssize written;
+ char *key;
+
+ written = g_output_stream_splice_finish (stream, result, &error);
+ if (written < 0)
+ {
+ gdk_content_deserializer_return_error (deserializer, error);
+ return;
+ }
+
+ /* write terminating NULL */
+ if (!g_output_stream_write (stream, "", 1, NULL, &error))
+ {
+ gdk_content_deserializer_return_error (deserializer, error);
+ return;
+ }
+
+ key = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (stream));
+ if (key == NULL)
+ {
+ deserialize_not_found (deserializer);
+ return;
+ }
+
+ file_transfer_portal_retrieve_files (key, portal_finish, deserializer);
+ gdk_content_deserializer_set_task_data (deserializer, key, g_free);
+}
+
+static void
+portal_file_deserializer (GdkContentDeserializer *deserializer)
+{
+ GOutputStream *output;
+
+ output = g_memory_output_stream_new_resizable ();
+
+ g_output_stream_splice_async (output,
+ gdk_content_deserializer_get_input_stream (deserializer),
+ G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
+ gdk_content_deserializer_get_priority (deserializer),
+ gdk_content_deserializer_get_cancellable (deserializer),
+ portal_file_deserializer_finish,
+ deserializer);
+ g_object_unref (output);
+}
+
+static void
file_uri_deserializer_finish (GObject *source,
GAsyncResult *result,
gpointer deserializer)
@@ -816,11 +904,21 @@ init (void)
g_slist_free (formats);
+ gdk_content_register_deserializer ("application/vnd.portal.filetransfer",
+ GDK_TYPE_FILE_LIST,
+ portal_file_deserializer,
+ NULL,
+ NULL);
gdk_content_register_deserializer ("text/uri-list",
GDK_TYPE_FILE_LIST,
file_uri_deserializer,
NULL,
NULL);
+ gdk_content_register_deserializer ("application/vnd.portal.filetransfer",
+ G_TYPE_FILE,
+ portal_file_deserializer,
+ NULL,
+ NULL);
gdk_content_register_deserializer ("text/uri-list",
G_TYPE_FILE,
file_uri_deserializer,