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.
This commit is contained in:
Matthias Clasen
2014-05-28 23:56:49 -04:00
parent 24e570db39
commit 86bce6197e
4 changed files with 380 additions and 0 deletions

View File

@@ -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 \

View File

@@ -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>

333
gdk/gdkclipboardfallback.c Normal file
View File

@@ -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));
}

View File

@@ -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__ */