diff --git a/gdk/gdkcontentdeserializer.c b/gdk/gdkcontentdeserializer.c index 79b7df86a2..0015520b3c 100644 --- a/gdk/gdkcontentdeserializer.c +++ b/gdk/gdkcontentdeserializer.c @@ -24,6 +24,7 @@ #include "gdkcontentformats.h" #include "filetransferportalprivate.h" #include "gdktexture.h" +#include "gdkrgbaprivate.h" #include @@ -848,6 +849,63 @@ file_uri_deserializer (GdkContentDeserializer *deserializer) g_object_unref (output); } +static void +color_deserializer_finish (GObject *source, + GAsyncResult *result, + gpointer deserializer) +{ + GOutputStream *stream = G_OUTPUT_STREAM (source); + GError *error = NULL; + gssize written; + + written = g_output_stream_splice_finish (stream, result, &error); + if (written < 0) + { + gdk_content_deserializer_return_error (deserializer, error); + return; + } + else if (written == 0) + { + GdkRGBA black = GDK_RGBA ("000"); + + /* Never return NULL, we only return that on error */ + g_value_set_boxed (gdk_content_deserializer_get_value (deserializer), &black); + } + else + { + guint16 *data; + GdkRGBA rgba; + + data = (guint16 *)g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (stream)); + rgba.red = data[0] / 65535.0; + rgba.green = data[1] / 65535.0; + rgba.blue = data[2] / 65535.0; + rgba.alpha = data[3] / 65535.0; + + g_value_set_boxed (gdk_content_deserializer_get_value (deserializer), &rgba); + } + gdk_content_deserializer_return_success (deserializer); +} + +static void +color_deserializer (GdkContentDeserializer *deserializer) +{ + GOutputStream *output; + guint16 *data; + + data = g_new0 (guint16, 4); + output = g_memory_output_stream_new (data, 4 * sizeof (guint16), NULL, g_free); + + 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), + color_deserializer_finish, + deserializer); + g_object_unref (output); +} + static void init (void) { @@ -956,5 +1014,11 @@ init (void) string_deserializer, (gpointer) "ASCII", NULL); + + gdk_content_register_deserializer ("application/x-color", + GDK_TYPE_RGBA, + color_deserializer, + NULL, + NULL); } diff --git a/gdk/gdkcontentserializer.c b/gdk/gdkcontentserializer.c index b78818a75f..6caea1edef 100644 --- a/gdk/gdkcontentserializer.c +++ b/gdk/gdkcontentserializer.c @@ -25,6 +25,7 @@ #include "gdkpixbuf.h" #include "filetransferportalprivate.h" #include "gdktextureprivate.h" +#include "gdkrgba.h" #include #include @@ -862,6 +863,48 @@ file_text_serializer (GdkContentSerializer *serializer) gdk_content_serializer_set_task_data (serializer, path, g_free); } +static void +color_serializer_finish (GObject *source, + GAsyncResult *result, + gpointer serializer) +{ + GOutputStream *stream = G_OUTPUT_STREAM (source); + GError *error = NULL; + + if (!g_output_stream_write_all_finish (stream, result, NULL, &error)) + gdk_content_serializer_return_error (serializer, error); + else + gdk_content_serializer_return_success (serializer); +} + +static void +color_serializer (GdkContentSerializer *serializer) +{ + const GValue *value; + GdkRGBA *rgba; + guint16 *data; + + value = gdk_content_serializer_get_value (serializer); + rgba = g_value_get_boxed (value); + data = g_new0 (guint16, 4); + if (rgba) + { + data[0] = (guint16) (rgba->red * 65535); + data[1] = (guint16) (rgba->green * 65535); + data[2] = (guint16) (rgba->blue * 65535); + data[3] = (guint16) (rgba->alpha * 65535); + } + + g_output_stream_write_all_async (gdk_content_serializer_get_output_stream (serializer), + data, + 4 * sizeof (guint16), + gdk_content_serializer_get_priority (serializer), + gdk_content_serializer_get_cancellable (serializer), + color_serializer_finish, + serializer); + gdk_content_serializer_set_task_data (serializer, data, g_free); +} + static void init (void) { @@ -984,5 +1027,11 @@ init (void) string_serializer, (gpointer) "ASCII", NULL); + + gdk_content_register_serializer (GDK_TYPE_RGBA, + "application/x-color", + color_serializer, + NULL, + NULL); }