[gtk+/wip/clipboard: 2/4] Add a fallback implementation



commit 36be420b1b22b7f72667a9f2bebb3f7bbd08cf67
Author: Matthias Clasen <mclasen redhat com>
Date:   Wed May 28 23:56:49 2014 -0400

    Add a fallback implementation
    
    This is a local-only GdkClipboard implementation. It is useful for
    test purposes, and as a fallback for 'primary' on platforms that
    don't have a primary clipboard.

 gdk/Makefile.am            |    2 +
 gdk/gdk.h                  |    1 +
 gdk/gdkclipboardfallback.c |  333 ++++++++++++++++++++++++++++++++++++++++++++
 gdk/gdkclipboardfallback.h |   44 ++++++
 4 files changed, 380 insertions(+), 0 deletions(-)
---
diff --git a/gdk/Makefile.am b/gdk/Makefile.am
index 0705f28..3efc1da 100644
--- a/gdk/Makefile.am
+++ b/gdk/Makefile.am
@@ -68,6 +68,7 @@ gdk_public_h_sources =                                \
        gdkapplaunchcontext.h                   \
        gdkcairo.h                              \
        gdkclipboard.h                          \
+       gdkclipboardfallback.h                  \
        gdkcursor.h                             \
        gdkdevice.h                             \
        gdkdevicemanager.h                      \
@@ -129,6 +130,7 @@ gdk_c_sources =                             \
        gdkapplaunchcontext.c                   \
        gdkcairo.c                              \
        gdkclipboard.c                          \
+       gdkclipboardfallback.c                  \
        gdkcursor.c                             \
        gdkdeprecated.c                         \
        gdkdevice.c                             \
diff --git a/gdk/gdk.h b/gdk/gdk.h
index bdf402d..ec87425 100644
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -32,6 +32,7 @@
 #include <gdk/gdkapplaunchcontext.h>
 #include <gdk/gdkcairo.h>
 #include <gdk/gdkclipboard.h>
+#include <gdk/gdkclipboardfallback.h>
 #include <gdk/gdkcursor.h>
 #include <gdk/gdkdevice.h>
 #include <gdk/gdkdevicemanager.h>
diff --git a/gdk/gdkclipboardfallback.c b/gdk/gdkclipboardfallback.c
new file mode 100644
index 0000000..2d65675
--- /dev/null
+++ b/gdk/gdkclipboardfallback.c
@@ -0,0 +1,333 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * 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 <gdk/gdkclipboardprivate.h>
+#include <gdk/gdkclipboardfallback.h>
+
+
+typedef struct _GdkClipboardFallbackClass GdkClipboardFallbackClass;
+
+struct _GdkClipboardFallback
+{
+  GdkClipboard parent;
+
+  gchar                *text;
+  GdkPixbuf            *pixbuf;
+  GdkClipboardProvider  provider;
+  gpointer              data;
+  GDestroyNotify        destroy;
+};
+
+struct _GdkClipboardFallbackClass
+{
+  GdkClipboardClass parent_class;
+};
+
+G_DEFINE_TYPE (GdkClipboardFallback, gdk_clipboard_fallback, GDK_TYPE_CLIPBOARD)
+
+static void
+clear_data (GdkClipboardFallback *cf)
+{
+  if (cf->text)
+    {
+      g_free (cf->text);
+      cf->text = NULL;
+    }
+
+  if (cf->pixbuf)
+    {
+      g_object_unref (cf->pixbuf);
+      cf->pixbuf = NULL;
+    }
+
+  if (cf->provider)
+    {
+      if (cf->destroy)
+        cf->destroy (cf->data);
+
+      cf->provider = NULL;
+      cf->data = NULL;
+      cf->destroy = NULL;
+    }
+}
+
+static void
+gdk_clipboard_fallback_get_text_async (GdkClipboard        *clipboard,
+                                       GCancellable        *cancellable,
+                                       GAsyncReadyCallback  callback,
+                                       gpointer             user_data)
+{
+  GSimpleAsyncResult *res;
+
+  res = g_simple_async_result_new (G_OBJECT (clipboard),
+                                   callback, user_data,
+                                   gdk_clipboard_fallback_get_text_async);
+  g_simple_async_result_complete (res);
+  g_object_unref (res);
+}
+
+static gchar *
+gdk_clipboard_fallback_get_text_finish (GdkClipboard  *clipboard,
+                                        GAsyncResult  *res,
+                                        GError       **error)
+{
+  GdkClipboardFallback *cf = GDK_CLIPBOARD_FALLBACK (clipboard);
+
+  g_return_val_if_fail (g_simple_async_result_is_valid (res, G_OBJECT (cf), 
gdk_clipboard_fallback_get_text_async), NULL);
+
+  if (_gdk_clipboard_get_available_content (clipboard) != TEXT_CONTENT)
+    {
+      /* FIXME: set error ? */
+      return NULL;
+    }
+
+  return g_strdup (cf->text);
+}
+
+static void
+gdk_clipboard_fallback_set_text (GdkClipboard *clipboard,
+                                 const gchar  *text)
+{
+  GdkClipboardFallback *cf = GDK_CLIPBOARD_FALLBACK (clipboard);
+
+  clear_data (cf);
+  cf->text = g_strdup (text);
+  _gdk_clipboard_set_available_content (clipboard, TEXT_CONTENT, NULL);
+}
+
+static void
+gdk_clipboard_fallback_get_image_async (GdkClipboard        *clipboard,
+                                        GCancellable        *cancellable,
+                                        GAsyncReadyCallback  callback,
+                                        gpointer             user_data)
+{
+  GSimpleAsyncResult *res;
+
+  res = g_simple_async_result_new (G_OBJECT (clipboard),
+                                   callback, user_data,
+                                   gdk_clipboard_fallback_get_image_async);
+  g_simple_async_result_complete (res);
+  g_object_unref (res);
+}
+
+static GdkPixbuf *
+gdk_clipboard_fallback_get_image_finish (GdkClipboard  *clipboard,
+                                         GAsyncResult  *res,
+                                         GError       **error)
+{
+  GdkClipboardFallback *cf = GDK_CLIPBOARD_FALLBACK (clipboard);
+
+  g_return_val_if_fail (g_simple_async_result_is_valid (res, G_OBJECT (cf), 
gdk_clipboard_fallback_get_image_async), NULL);
+
+  if (_gdk_clipboard_get_available_content (clipboard) != IMAGE_CONTENT)
+    {
+      /* FIXME: set error ? */
+      return NULL;
+    }
+
+  return g_object_ref (cf->pixbuf);
+}
+
+static void
+gdk_clipboard_fallback_set_image (GdkClipboard *clipboard,
+                                  GdkPixbuf    *pixbuf)
+{
+  GdkClipboardFallback *cf = GDK_CLIPBOARD_FALLBACK (clipboard);
+
+  clear_data (cf);
+  cf->pixbuf = g_object_ref (pixbuf);
+  _gdk_clipboard_set_available_content (clipboard, IMAGE_CONTENT, NULL);
+}
+
+static void
+gdk_clipboard_fallback_get_data_async (GdkClipboard        *clipboard,
+                                       const gchar         *content_type,
+                                       GCancellable        *cancellable,
+                                       GAsyncReadyCallback  callback,
+                                       gpointer             user_data)
+{
+  GSimpleAsyncResult *res;
+
+  res = g_simple_async_result_new (G_OBJECT (clipboard),
+                                   callback, user_data,
+                                   gdk_clipboard_fallback_get_data_async);
+  g_object_set_data (G_OBJECT (res), "ctype", (gpointer) content_type);
+  g_simple_async_result_complete (res);
+  g_object_unref (res);
+}
+
+typedef struct
+{
+  GOutputStream parent;
+  GMemoryInputStream *is;
+} ReadbackOutputStream;
+
+typedef struct
+{
+  GOutputStreamClass parent_class;
+} ReadbackOutputStreamClass;
+
+G_DEFINE_TYPE (ReadbackOutputStream, readback_output_stream, G_TYPE_OUTPUT_STREAM)
+
+static void
+readback_output_stream_init (ReadbackOutputStream *stream)
+{
+}
+
+static gssize
+readback_output_stream_write (GOutputStream  *stream,
+                              const void     *buffer,
+                              gsize           count,
+                              GCancellable   *cancellable,
+                              GError        **error)
+{
+  ReadbackOutputStream *rs = (ReadbackOutputStream *)stream;
+
+  if (count)
+    g_memory_input_stream_add_data (rs->is, g_memdup (buffer, count), count, g_free);
+
+  return count;
+}
+
+static void
+readback_output_stream_finalize (GObject *obj)
+{
+  ReadbackOutputStream *rs = (ReadbackOutputStream *)obj;
+
+  g_object_unref (rs->is);
+
+  G_OBJECT_CLASS (readback_output_stream_parent_class)->finalize (obj);
+}
+
+static void
+readback_output_stream_class_init (ReadbackOutputStreamClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+  GOutputStreamClass *ostream_class = G_OUTPUT_STREAM_CLASS (class);
+
+  object_class->finalize = readback_output_stream_finalize;
+  ostream_class->write_fn = readback_output_stream_write;
+}
+
+static GOutputStream *
+readback_output_stream_new (GMemoryInputStream *is)
+{
+  ReadbackOutputStream *stream;
+
+  stream = g_object_new (readback_output_stream_get_type (), NULL);
+  stream->is = g_object_ref (is);
+
+  return G_OUTPUT_STREAM (stream);
+}
+
+static GInputStream *
+gdk_clipboard_fallback_get_data_finish (GdkClipboard  *clipboard,
+                                        GAsyncResult  *res,
+                                        GError       **error)
+{
+  GdkClipboardFallback *cf = GDK_CLIPBOARD_FALLBACK (clipboard);
+  const gchar *ctype;
+  GOutputStream *ostream = NULL;
+  GInputStream *istream = NULL;
+
+  g_return_val_if_fail (g_simple_async_result_is_valid (res, G_OBJECT (cf), 
gdk_clipboard_fallback_get_data_async), NULL);
+
+  ctype = (const gchar *) g_object_get_data (G_OBJECT (res), "ctype");
+
+  if (!gdk_clipboard_data_available (clipboard, ctype))
+    {
+      /* FIXME: set error ? */
+      return NULL;
+    }
+
+  istream = g_memory_input_stream_new ();
+  ostream = readback_output_stream_new (G_MEMORY_INPUT_STREAM (istream));
+
+  cf->provider (clipboard, ctype, ostream, cf->data);
+
+  g_object_unref (ostream);
+
+  return istream;
+}
+
+static void
+gdk_clipboard_fallback_set_data (GdkClipboard          *clipboard,
+                                 const gchar          **content_types,
+                                 GdkClipboardProvider   provider,
+                                 gpointer               data,
+                                 GDestroyNotify         destroy)
+{
+  GdkClipboardFallback *cf = GDK_CLIPBOARD_FALLBACK (clipboard);
+
+  clear_data (cf);
+  cf->provider = provider;
+  cf->data = data;
+  cf->destroy = destroy;
+  _gdk_clipboard_set_available_content (clipboard, OTHER_CONTENT, content_types);
+}
+
+static void
+gdk_clipboard_fallback_clear (GdkClipboard *clipboard)
+{
+  GdkClipboardFallback *cf = GDK_CLIPBOARD_FALLBACK (clipboard);
+
+  clear_data (cf);
+  _gdk_clipboard_set_available_content (clipboard, NO_CONTENT, NULL);
+}
+
+static void
+gdk_clipboard_fallback_init (GdkClipboardFallback *clipboard)
+{
+}
+
+static void
+gdk_clipboard_fallback_finalize (GObject *object)
+{
+  GdkClipboardFallback *cf = GDK_CLIPBOARD_FALLBACK (object);
+
+  clear_data (cf);
+
+  G_OBJECT_CLASS (gdk_clipboard_fallback_parent_class)->finalize (object);
+
+}
+
+static void
+gdk_clipboard_fallback_class_init (GdkClipboardFallbackClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+  GdkClipboardClass *clipboard_class = GDK_CLIPBOARD_CLASS (class);
+
+  object_class->finalize = gdk_clipboard_fallback_finalize;
+
+  clipboard_class->get_text_async = gdk_clipboard_fallback_get_text_async;
+  clipboard_class->get_text_finish = gdk_clipboard_fallback_get_text_finish;
+  clipboard_class->set_text = gdk_clipboard_fallback_set_text;
+  clipboard_class->get_image_async = gdk_clipboard_fallback_get_image_async;
+  clipboard_class->get_image_finish = gdk_clipboard_fallback_get_image_finish;
+  clipboard_class->set_image = gdk_clipboard_fallback_set_image;
+  clipboard_class->get_data_async = gdk_clipboard_fallback_get_data_async;
+  clipboard_class->get_data_finish = gdk_clipboard_fallback_get_data_finish;
+  clipboard_class->set_data = gdk_clipboard_fallback_set_data;
+  clipboard_class->clear = gdk_clipboard_fallback_clear;
+}
+
+GdkClipboard *
+gdk_clipboard_fallback_new (void)
+{
+  return GDK_CLIPBOARD (g_object_new (GDK_TYPE_CLIPBOARD_FALLBACK, NULL));
+}
diff --git a/gdk/gdkclipboardfallback.h b/gdk/gdkclipboardfallback.h
new file mode 100644
index 0000000..6b00d53
--- /dev/null
+++ b/gdk/gdkclipboardfallback.h
@@ -0,0 +1,44 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * 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 __GDK_CLIPBOARD_FALLBACK_H__
+#define __GDK_CLIPBOARD_FALLBACK_H__
+
+#if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION)
+#error "Only <gdk/gdk.h> can be included directly."
+#endif
+
+#include <gdk/gdkclipboard.h>
+
+
+G_BEGIN_DECLS
+
+#define GDK_TYPE_CLIPBOARD_FALLBACK    (gdk_clipboard_fallback_get_type ())
+#define GDK_CLIPBOARD_FALLBACK(obj)    (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_CLIPBOARD_FALLBACK, 
GdkClipboardFallback))
+#define GDK_IS_CLIPBOARD_FALLBACK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_CLIPBOARD_FALLBACK))
+
+typedef struct _GdkClipboardFallback GdkClipboardFallback;
+
+GDK_AVAILABLE_IN_3_14
+GType         gdk_clipboard_fallback_get_type (void) G_GNUC_CONST;
+
+GDK_AVAILABLE_IN_3_14
+GdkClipboard *gdk_clipboard_fallback_new      (void);
+
+G_END_DECLS
+
+#endif /* __GDK_CLIPBOARD_FALLBACK_H__ */


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