[gtk/dnd-gestures-2: 12/62] Add (de)serializers for GdkRGBA



commit 2e0ffa3af6f43dd95049af929bcb755b2d3d924c
Author: Matthias Clasen <mclasen redhat com>
Date:   Tue Dec 31 10:10:49 2019 -0500

    Add (de)serializers for GdkRGBA
    
    This is a format that we use in various
    color picker widgets, so support it in GDK.

 gdk/gdkcontentdeserializer.c | 64 ++++++++++++++++++++++++++++++++++++++++++++
 gdk/gdkcontentserializer.c   | 49 +++++++++++++++++++++++++++++++++
 2 files changed, 113 insertions(+)
---
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 <gdk-pixbuf/gdk-pixbuf.h>
 
@@ -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 <gdk-pixbuf/gdk-pixbuf.h>
 #include <string.h>
@@ -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);
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]