Compare commits
15 Commits
install-fr
...
wip/clipbo
Author | SHA1 | Date | |
---|---|---|---|
|
5ffe8e53d2 | ||
|
777673e933 | ||
|
cc5d0d610b | ||
|
7be04cd2b1 | ||
|
867cd7e715 | ||
|
ecac4f0158 | ||
|
308220ed15 | ||
|
99ed426f01 | ||
|
6b074dc0dd | ||
|
0b62a6c7d3 | ||
|
eae294001d | ||
|
11d7532ea5 | ||
|
86bce6197e | ||
|
24e570db39 | ||
|
aa16eee0d1 |
@@ -24,6 +24,7 @@
|
||||
<xi:include href="xml/gdkscreen.xml" />
|
||||
<xi:include href="xml/gdkdevicemanager.xml" />
|
||||
<xi:include href="xml/gdkdevice.xml" />
|
||||
<xi:include href="xml/gdkclipboard.xml" />
|
||||
<xi:include href="xml/regions.xml" />
|
||||
<xi:include href="xml/pixbufs.xml" />
|
||||
<xi:include href="xml/rgba_colors.xml" />
|
||||
|
@@ -156,6 +156,8 @@ gdk_display_supports_input_shapes
|
||||
gdk_display_supports_composite
|
||||
gdk_display_get_app_launch_context
|
||||
gdk_display_notify_startup_complete
|
||||
gdk_display_get_clipboard
|
||||
gdk_display_get_primary
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GDK_DISPLAY
|
||||
@@ -1273,3 +1275,28 @@ gdk_frame_timings_get_predicted_presentation_time
|
||||
<SUBSECTION Private>
|
||||
gdk_frame_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<TITLE>GdkClipboard</TITLE>
|
||||
<FILE>gdkclipboard</FILE>
|
||||
GdkClipboard
|
||||
gdk_clipboard_get_text_async
|
||||
gdk_clipboard_get_text_finish
|
||||
gdk_clipboard_set_text
|
||||
gdk_clipboard_text_available
|
||||
gdk_clipboard_get_image_async
|
||||
gdk_clipboard_get_image_finish
|
||||
gdk_clipboard_set_image
|
||||
gdk_clipboard_image_available
|
||||
gdk_clipboard_get_bytes_async
|
||||
gdk_clipboard_get_bytes_finish
|
||||
gdk_clipboard_set_bytes
|
||||
gdk_clipboard_get_data_async
|
||||
gdk_clipboard_get_data_finish
|
||||
gdk_clipboard_set_data
|
||||
gdk_clipboard_data_available
|
||||
gdk_clipboard_clear
|
||||
gdk_clipboard_get_content_types
|
||||
<SUBSECTION Private>
|
||||
gdk_clipboard_get_type
|
||||
</SECTION>
|
||||
|
@@ -67,6 +67,8 @@ gdk_public_h_sources = \
|
||||
gdk.h \
|
||||
gdkapplaunchcontext.h \
|
||||
gdkcairo.h \
|
||||
gdkclipboard.h \
|
||||
gdkclipboardfallback.h \
|
||||
gdkcursor.h \
|
||||
gdkdevice.h \
|
||||
gdkdevicemanager.h \
|
||||
@@ -103,6 +105,7 @@ gdk_h_sources = \
|
||||
|
||||
gdk_private_headers = \
|
||||
gdkapplaunchcontextprivate.h \
|
||||
gdkclipboardprivate.h \
|
||||
gdkcursorprivate.h \
|
||||
gdkdevicemanagerprivate.h \
|
||||
gdkdeviceprivate.h \
|
||||
@@ -111,9 +114,9 @@ gdk_private_headers = \
|
||||
gdkdndprivate.h \
|
||||
gdkframeclockidle.h \
|
||||
gdkframeclockprivate.h \
|
||||
gdkscreenprivate.h \
|
||||
gdkinternals.h \
|
||||
gdkintl.h \
|
||||
gdkscreenprivate.h \
|
||||
gdkkeysprivate.h \
|
||||
gdkvisualprivate.h \
|
||||
gdkx.h
|
||||
@@ -126,6 +129,8 @@ gdk_c_sources = \
|
||||
gdk.c \
|
||||
gdkapplaunchcontext.c \
|
||||
gdkcairo.c \
|
||||
gdkclipboard.c \
|
||||
gdkclipboardfallback.c \
|
||||
gdkcursor.c \
|
||||
gdkdeprecated.c \
|
||||
gdkdevice.c \
|
||||
|
@@ -31,6 +31,8 @@
|
||||
#include <gdk/gdkversionmacros.h>
|
||||
#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>
|
||||
|
681
gdk/gdkclipboard.c
Normal file
681
gdk/gdkclipboard.c
Normal file
@@ -0,0 +1,681 @@
|
||||
/* 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>
|
||||
|
||||
|
||||
/**
|
||||
* SECTION:gdkclipboard
|
||||
* @Short_description: A clipboard class
|
||||
* @Title: GdkClipboard
|
||||
*
|
||||
* The #GdkClipboard object represent a clipboard of data that
|
||||
* is shared between different processes or between different widgets
|
||||
* in the same process. GDK backends are responsible for implementing
|
||||
* the #GdkClipboard API using their platforms data exchange mechanisms.
|
||||
*
|
||||
* GDK supports two different clipboards, which are historically named
|
||||
* CLIPBOARD and PRIMARY. To obtain these clipboards, use
|
||||
* gdk_display_get_clipboard() and gdk_display_get_primary(). The
|
||||
* CLIPBOARD is supposed to be controlled explicitly by the user (e.g.
|
||||
* using the common Ctrl-X/Ctrl-V shortcuts). The PRIMARY clipboard
|
||||
* is supposed to always correspond to 'the current selection', which
|
||||
* is a somewhat fuzzy concept. On platforms that don't support this
|
||||
* distinction, GDK will provide a fallback implementation for the
|
||||
* PRIMARY clipboard that only allows local data exchange inside the
|
||||
* application.
|
||||
*
|
||||
* A GdkClipboard can hold data in different formats and types. Content
|
||||
* types are represented as strings with mime types, such as "application/pdf".
|
||||
*
|
||||
* The most important data types, text and images, are supported explicitly
|
||||
* with the functions gdk_clipboard_set_text(), gdk_clipboard_get_text_async(),
|
||||
* gdk_clipboard_text_available() for text and gdk_clipboard_set_image(),
|
||||
* gdk_clipboard_get_image_async() and gdk_clipboard_image_available()
|
||||
* for images.
|
||||
*
|
||||
* To store other content in a GdkClipboard, use gdk_clipboard_set_bytes()
|
||||
* or gdk_clipboard_set_data() and their corresponding getter functions.
|
||||
*
|
||||
* GdkClipboard was introduced in GTK+ 3.14.
|
||||
*/
|
||||
|
||||
typedef struct _GdkClipboardPrivate GdkClipboardPrivate;
|
||||
|
||||
struct _GdkClipboardPrivate
|
||||
{
|
||||
GdkClipboardContent content;
|
||||
gchar **content_types;
|
||||
};
|
||||
|
||||
enum {
|
||||
CHANGED,
|
||||
N_SIGNALS
|
||||
};
|
||||
|
||||
static guint signals[N_SIGNALS] = { 0 };
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GdkClipboard, gdk_clipboard, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
gdk_clipboard_init (GdkClipboard *clipboard)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_clipboard_finalize (GObject *object)
|
||||
{
|
||||
GdkClipboard *clipboard = GDK_CLIPBOARD (object);
|
||||
GdkClipboardPrivate *priv = gdk_clipboard_get_instance_private (clipboard);
|
||||
|
||||
g_strfreev (priv->content_types);
|
||||
|
||||
G_OBJECT_CLASS (gdk_clipboard_parent_class)->finalize (object);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_clipboard_class_init (GdkClipboardClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->finalize = gdk_clipboard_finalize;
|
||||
|
||||
signals[CHANGED] =
|
||||
g_signal_new ("changed",
|
||||
G_TYPE_FROM_CLASS (class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GdkClipboardClass, changed),
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_clipboard_set_available_content (GdkClipboard *clipboard,
|
||||
GdkClipboardContent content,
|
||||
const gchar **content_types)
|
||||
{
|
||||
GdkClipboardPrivate *priv = gdk_clipboard_get_instance_private (clipboard);
|
||||
const gchar *text_content_types[] = { "text/plain", NULL };
|
||||
const gchar *image_content_types[] = { "image/png", NULL };
|
||||
|
||||
if (content_types == NULL)
|
||||
{
|
||||
if (content == TEXT_CONTENT)
|
||||
content_types = text_content_types;
|
||||
else if (content == IMAGE_CONTENT)
|
||||
content_types = image_content_types;
|
||||
}
|
||||
|
||||
priv->content = content;
|
||||
g_strfreev (priv->content_types);
|
||||
priv->content_types = g_strdupv ((gchar **)content_types);
|
||||
|
||||
g_signal_emit (clipboard, signals[CHANGED], 0);
|
||||
}
|
||||
|
||||
GdkClipboardContent
|
||||
_gdk_clipboard_get_available_content (GdkClipboard *clipboard)
|
||||
{
|
||||
GdkClipboardPrivate *priv = gdk_clipboard_get_instance_private (clipboard);
|
||||
|
||||
return priv->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_clipboard_get_content_types:
|
||||
* @clipboard: a #GdkClipboard
|
||||
*
|
||||
* Gets the content types for which the clipboard can currently
|
||||
* provide content.
|
||||
*
|
||||
* Note that text and image data is not represented by content types.
|
||||
* Instead, use gdk_clipboard_text_available() and
|
||||
* gdk_clipboard_image_available() to check for text or image
|
||||
* content.
|
||||
*
|
||||
* Returns: (transfer none): Content type of the current content
|
||||
*
|
||||
* Since: 3.14
|
||||
*/
|
||||
const gchar **
|
||||
gdk_clipboard_get_content_types (GdkClipboard *clipboard)
|
||||
{
|
||||
GdkClipboardPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_CLIPBOARD (clipboard), NULL);
|
||||
|
||||
priv = gdk_clipboard_get_instance_private (clipboard);
|
||||
|
||||
return (const gchar **)priv->content_types;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
strv_contains (const gchar **strv, const gchar *s)
|
||||
{
|
||||
gint i;
|
||||
|
||||
for (i = 0; strv[i]; i++)
|
||||
{
|
||||
if (g_strcmp0 (strv[i], s) == 0)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_clipboard_data_available:
|
||||
* @clipboard: a #GdkClipboard
|
||||
* @content_type: the content type to check for
|
||||
*
|
||||
* Returns whether the clipboard can currently provide content
|
||||
* of the given type.
|
||||
*
|
||||
* Note that text and image data is not represented by content types.
|
||||
* Instead, use gdk_clipboard_text_available() and
|
||||
* gdk_clipboard_image_available() to check for text or image
|
||||
* content.
|
||||
*
|
||||
* Returns: (transfer none): %TRUE if content of the given type is available
|
||||
*
|
||||
* Since: 3.14
|
||||
*/
|
||||
gboolean
|
||||
gdk_clipboard_data_available (GdkClipboard *clipboard,
|
||||
const gchar *content_type)
|
||||
{
|
||||
GdkClipboardPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_CLIPBOARD (clipboard), FALSE);
|
||||
|
||||
priv = gdk_clipboard_get_instance_private (clipboard);
|
||||
|
||||
return priv->content_types != NULL &&
|
||||
strv_contains ((const gchar **)priv->content_types, content_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_clipboard_get_text_async:
|
||||
* @clipboard: a #GdkClipboard
|
||||
* @cancellable: (allow-none): a #GCancellable
|
||||
* @callback: the callback to call when the text is available
|
||||
* @user_data: data that gets passed to @callback
|
||||
*
|
||||
* Retrieves the text content of the clipboard. This may involve
|
||||
* inter-process communication with the current owner of the system
|
||||
* clipboard. Therefore, it is implemented as an asynchronous
|
||||
* operation.
|
||||
*
|
||||
* When the asynchronous operation is completed, @callback is called.
|
||||
* It should call gdk_clipboard_get_text_finish() to retrieve the text.
|
||||
*
|
||||
* Since: 3.14
|
||||
*/
|
||||
void
|
||||
gdk_clipboard_get_text_async (GdkClipboard *clipboard,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_CLIPBOARD (clipboard));
|
||||
|
||||
GDK_CLIPBOARD_GET_CLASS (clipboard)->get_text_async (clipboard, cancellable, callback, user_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_clipboard_get_text_finish:
|
||||
* @clipboard: a #GdkClipboard
|
||||
* @res: the #GAsyncResult
|
||||
* @error: return location for an error
|
||||
*
|
||||
* Obtains the result of a gdk_clipboard_get_text_async() call.
|
||||
* This function may only be called from a callback passed
|
||||
* to gdk_clipboard_get_text_async().
|
||||
*
|
||||
* If the clipboard does not contain text, %NULL is returned.
|
||||
*
|
||||
* Returns: (transfer full): the current text content of the clipboard
|
||||
*
|
||||
* Since: 3.14
|
||||
*/
|
||||
gchar *
|
||||
gdk_clipboard_get_text_finish (GdkClipboard *clipboard,
|
||||
GAsyncResult *res,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_CLIPBOARD (clipboard), NULL);
|
||||
|
||||
return GDK_CLIPBOARD_GET_CLASS (clipboard)->get_text_finish (clipboard, res, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_clipboard_set_text:
|
||||
* @clipboard: a #GdkClipboard
|
||||
* @text: the text to store in the clipboard
|
||||
*
|
||||
* Sets the clipboard content to the given text.
|
||||
*
|
||||
* The clipboard makes a copy of the text and provides it
|
||||
* to requestors until the clipboard gets overwritten with
|
||||
* new content from this or another process, or until
|
||||
* gdk_clipboard_clear() is called.
|
||||
*
|
||||
* Since: 3.14
|
||||
*/
|
||||
void
|
||||
gdk_clipboard_set_text (GdkClipboard *clipboard,
|
||||
const gchar *text)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_CLIPBOARD (clipboard));
|
||||
|
||||
GDK_CLIPBOARD_GET_CLASS (clipboard)->set_text (clipboard, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_clipboard_text_available:
|
||||
* @clipboard:
|
||||
*
|
||||
* Returns whether the clipboard currently contains text.
|
||||
*
|
||||
* Returns: %TRUE if the clipboard contains text
|
||||
*
|
||||
* Since: 3.14
|
||||
*/
|
||||
gboolean
|
||||
gdk_clipboard_text_available (GdkClipboard *clipboard)
|
||||
{
|
||||
GdkClipboardPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_CLIPBOARD (clipboard), FALSE);
|
||||
|
||||
priv = gdk_clipboard_get_instance_private (clipboard);
|
||||
|
||||
return ((priv->content & TEXT_CONTENT) != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_clipboard_get_image_async:
|
||||
* @clipboard: a #GdkClipboard
|
||||
* @cancellable: (allow-none): a #GCancellable
|
||||
* @callback: the callback to call when the text is available
|
||||
* @user_data: data that gets passed to @callback
|
||||
*
|
||||
* Retrieves the image content of the clipboard. This may involve
|
||||
* inter-process communication with the current owner of the system
|
||||
* clipboard. Therefore, it is implemented as an asynchronous
|
||||
* operation.
|
||||
*
|
||||
* When the asynchronous operation is completed, @callback is called.
|
||||
* It should call gdk_clipboard_get_image_finish() to retrieve the text.
|
||||
*
|
||||
* Since: 3.14
|
||||
*/
|
||||
void
|
||||
gdk_clipboard_get_image_async (GdkClipboard *clipboard,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_CLIPBOARD (clipboard));
|
||||
|
||||
GDK_CLIPBOARD_GET_CLASS (clipboard)->get_image_async (clipboard, cancellable, callback, user_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_clipboard_get_image_finish:
|
||||
* @clipboard: a #GdkClipboard
|
||||
* @res: the #GAsyncResult
|
||||
* @error: return location for an error
|
||||
*
|
||||
* Obtains the result of a gdk_clipboard_get_image_async() call.
|
||||
* This function may only be called from a callback passed
|
||||
* to gdk_clipboard_get_image_async().
|
||||
*
|
||||
* If the clipboard does not contain an image, %NULL is returned.
|
||||
*
|
||||
* Returns: (transfer full): the current image content of the clipboard
|
||||
*
|
||||
* Since: 3.14
|
||||
*/
|
||||
GdkPixbuf *
|
||||
gdk_clipboard_get_image_finish (GdkClipboard *clipboard,
|
||||
GAsyncResult *res,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_CLIPBOARD (clipboard), NULL);
|
||||
|
||||
return GDK_CLIPBOARD_GET_CLASS (clipboard)->get_image_finish (clipboard, res, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_clipboard_set_image:
|
||||
* @clipboard: a #GdkClipboard
|
||||
* @pixbuf: the image to store in the clipboard
|
||||
*
|
||||
* Sets the clipboard content to the given image.
|
||||
*
|
||||
* The clipboard takes a reference on @pixbuf and provides it
|
||||
* to requestors until the clipboard gets overwritten with
|
||||
* new content from this or another process, or until
|
||||
* gdk_clipboard_clear() is called.
|
||||
*
|
||||
* Since: 3.14
|
||||
*/
|
||||
void
|
||||
gdk_clipboard_set_image (GdkClipboard *clipboard,
|
||||
GdkPixbuf *pixbuf)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_CLIPBOARD (clipboard));
|
||||
|
||||
GDK_CLIPBOARD_GET_CLASS (clipboard)->set_image (clipboard, pixbuf);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_clipboard_image_available:
|
||||
* @clipboard:
|
||||
*
|
||||
* Returns whether the clipboard currently contains an image.
|
||||
*
|
||||
* Returns: %TRUE if the clipboard contains an image
|
||||
*
|
||||
* Since: 3.14
|
||||
*/
|
||||
gboolean
|
||||
gdk_clipboard_image_available (GdkClipboard *clipboard)
|
||||
{
|
||||
GdkClipboardPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_CLIPBOARD (clipboard), FALSE);
|
||||
|
||||
priv = gdk_clipboard_get_instance_private (clipboard);
|
||||
|
||||
return (priv->content & IMAGE_CONTENT) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_clipboard_get_data_async:
|
||||
* @clipboard: a #GdkClipboard
|
||||
* @content_type: the type of content to retrieve
|
||||
* @cancellable: (allow-none): a #GCancellable
|
||||
* @callback: the callback to call when the text is available
|
||||
* @user_data: data that gets passed to @callback
|
||||
*
|
||||
* Retrieves the content of the clipboard with the given content type.
|
||||
* This may involve inter-process communication with the current owner
|
||||
* of the system clipboard. Therefore, it is implemented as an
|
||||
* asynchronous operation.
|
||||
*
|
||||
* When the asynchronous operation is completed, @callback is called.
|
||||
* It should call gdk_clipboard_get_data_finish() to retrieve the text.
|
||||
*
|
||||
* Since: 3.14
|
||||
*/
|
||||
void
|
||||
gdk_clipboard_get_data_async (GdkClipboard *clipboard,
|
||||
const gchar *content_type,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_CLIPBOARD (clipboard));
|
||||
|
||||
GDK_CLIPBOARD_GET_CLASS (clipboard)->get_data_async (clipboard, content_type, cancellable, callback, user_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_clipboard_get_data_finish:
|
||||
* @clipboard: a #GdkClipboard
|
||||
* @res: the #GAsyncResult
|
||||
* @error: return location for an error
|
||||
*
|
||||
* Obtains the result of a gdk_clipboard_get_data_async() call.
|
||||
* This function may only be called from a callback passed
|
||||
* to gdk_clipboard_get_data_async().
|
||||
*
|
||||
* If the clipboard does not contain content with the type that
|
||||
* was passed to gdk_clipboard_get_data_async(), %NULL is returned.
|
||||
*
|
||||
* Returns: (transfer full): an input stream from which the current
|
||||
* content of the clipboard can be read
|
||||
*
|
||||
* Since: 3.14
|
||||
*/
|
||||
GInputStream *
|
||||
gdk_clipboard_get_data_finish (GdkClipboard *clipboard,
|
||||
GAsyncResult *res,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_CLIPBOARD (clipboard), NULL);
|
||||
|
||||
return GDK_CLIPBOARD_GET_CLASS (clipboard)->get_data_finish (clipboard, res, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_clipboard_set_data:
|
||||
* @clipboard: a #GdkClipboard
|
||||
* @content_types: content types that can be provided
|
||||
* @callback: the function that will be called to retrieve the content
|
||||
* @user_data: user data that gets passed to @callback
|
||||
* @destroy: destroy notify for @user_data
|
||||
*
|
||||
* Sets the clipboard content. The content will be retrieved on demand
|
||||
* by the @callback function.
|
||||
*
|
||||
* Since: 3.14
|
||||
*/
|
||||
void
|
||||
gdk_clipboard_set_data (GdkClipboard *clipboard,
|
||||
const gchar **content_types,
|
||||
GdkClipboardProvider callback,
|
||||
gpointer user_data,
|
||||
GDestroyNotify destroy)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_CLIPBOARD (clipboard));
|
||||
|
||||
GDK_CLIPBOARD_GET_CLASS (clipboard)->set_data (clipboard, content_types, callback, user_data, destroy);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_clipboard_clear:
|
||||
* @clipboard: a #GdkClipboard
|
||||
*
|
||||
* Clears the clipboard.
|
||||
*
|
||||
* If the clipboard is currently holding the system clipboard,
|
||||
* this implies that the clipboard will no longer provide content
|
||||
* to other processes. If the system clipboard is currently held
|
||||
* by another process, this call will drop any cached content,
|
||||
* and the next call to get content will retrieve it from the
|
||||
* other process again.
|
||||
*
|
||||
* Since: 3.14
|
||||
*/
|
||||
void
|
||||
gdk_clipboard_clear (GdkClipboard *clipboard)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_CLIPBOARD (clipboard));
|
||||
|
||||
GDK_CLIPBOARD_GET_CLASS (clipboard)->clear (clipboard);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GAsyncReadyCallback callback;
|
||||
gpointer user_data;
|
||||
} GetBytesData;
|
||||
|
||||
static void
|
||||
get_bytes (GObject *object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkClipboard *clipboard = GDK_CLIPBOARD (object);
|
||||
GetBytesData *data = user_data;
|
||||
GError *error;
|
||||
GBytes *bytes;
|
||||
GInputStream *istream;
|
||||
GOutputStream *ostream;
|
||||
|
||||
error = NULL;
|
||||
bytes = NULL;
|
||||
|
||||
istream = gdk_clipboard_get_data_finish (clipboard, res, &error);
|
||||
if (istream)
|
||||
{
|
||||
ostream = g_memory_output_stream_new_resizable ();
|
||||
g_output_stream_splice (ostream, istream, G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, NULL, NULL);
|
||||
bytes = g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (ostream));
|
||||
g_object_unref (ostream);
|
||||
g_object_unref (istream);
|
||||
}
|
||||
|
||||
g_object_set_data (G_OBJECT (res), "error", error);
|
||||
g_object_set_data (G_OBJECT (res), "bytes", bytes);
|
||||
|
||||
data->callback (object, res, data->user_data);
|
||||
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_clipboard_get_bytes_async:
|
||||
* @clipboard: a #GdkClipboard
|
||||
* @content_type: the type of content to retrieve
|
||||
* @cancellable: (allow-none): a #GCancellable
|
||||
* @callback: the callback to call when the text is available
|
||||
* @user_data: data that gets passed to @callback
|
||||
*
|
||||
* Retrieves the content of the clipboard with the given content type
|
||||
* as a #GBytes. This may involve inter-process communication with the
|
||||
* current owner of the system clipboard. Therefore, it is implemented
|
||||
* as an asynchronous operation.
|
||||
*
|
||||
* When the asynchronous operation is completed, @callback is called.
|
||||
* It should call gdk_clipboard_get_bytes_finish() to retrieve the text.
|
||||
*
|
||||
* Since: 3.14
|
||||
*/
|
||||
void
|
||||
gdk_clipboard_get_bytes_async (GdkClipboard *clipboard,
|
||||
const gchar *content_type,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GetBytesData *data;
|
||||
|
||||
g_return_if_fail (GDK_IS_CLIPBOARD (clipboard));
|
||||
|
||||
data = g_new (GetBytesData, 1);
|
||||
data->callback = callback;
|
||||
data->user_data = user_data;
|
||||
|
||||
gdk_clipboard_get_data_async (clipboard, content_type, cancellable, get_bytes, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_clipboard_get_bytes_finish:
|
||||
* @clipboard: a #GdkClipboard
|
||||
* @res: the #GAsyncResult
|
||||
* @error: return location for an error
|
||||
*
|
||||
* Obtains the result of a gdk_clipboard_get_bytes_async() call.
|
||||
* This function may only be called from a callback passed
|
||||
* to gdk_clipboard_get_bytes_async().
|
||||
*
|
||||
* If the clipboard does not contain content with the type that
|
||||
* was passed to gdk_clipboard_get_bytes_async(), %NULL is returned.
|
||||
*
|
||||
* Returns: (transfer full): a #GBytes with the current
|
||||
* content of the clipboard
|
||||
*
|
||||
* Since: 3.14
|
||||
*/
|
||||
GBytes *
|
||||
gdk_clipboard_get_bytes_finish (GdkClipboard *clipboard,
|
||||
GAsyncResult *res,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_CLIPBOARD (clipboard), NULL);
|
||||
GError *inner;
|
||||
GBytes *bytes;
|
||||
|
||||
inner = g_object_get_data (G_OBJECT (res), "error");
|
||||
bytes = g_object_get_data (G_OBJECT (res), "bytes");
|
||||
|
||||
if (inner)
|
||||
g_propagate_error (error, inner);
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
static void
|
||||
set_bytes (GdkClipboard *clipboard,
|
||||
const gchar *content_type,
|
||||
GOutputStream *stream,
|
||||
gpointer user_data)
|
||||
{
|
||||
GBytes *bytes = user_data;
|
||||
GBytes *rest;
|
||||
gssize written;
|
||||
|
||||
g_bytes_ref (bytes);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
written = g_output_stream_write_bytes (stream, bytes, NULL, NULL);
|
||||
if (written == g_bytes_get_size (bytes) || written == -1)
|
||||
break;
|
||||
rest = g_bytes_new_from_bytes (bytes, written, g_bytes_get_size (bytes) - written);
|
||||
g_bytes_unref (bytes);
|
||||
bytes = rest;
|
||||
}
|
||||
|
||||
g_bytes_unref (bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_clipboard_set_bytes:
|
||||
* @clipboard: a #GdkClipboard
|
||||
* @bytes: the content in a #GBytes
|
||||
* @content_types: content types that can be provided
|
||||
*
|
||||
* Sets the clipboard content from a #GBytes.
|
||||
*
|
||||
* The clipboard takes a reference on @bytes and provides
|
||||
* its content to requestors until the clipboard gets
|
||||
* overwritten with new content from this or another
|
||||
* process, or until gdk_clipboard_clear() is called.
|
||||
*
|
||||
* Since: 3.14
|
||||
*/
|
||||
void
|
||||
gdk_clipboard_set_bytes (GdkClipboard *clipboard,
|
||||
GBytes *bytes,
|
||||
const gchar *content_type)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_CLIPBOARD (clipboard));
|
||||
const gchar *ctypes[2];
|
||||
|
||||
ctypes[0] = content_type;
|
||||
ctypes[1] = NULL;
|
||||
|
||||
/* create stream from bytes */
|
||||
gdk_clipboard_set_data (clipboard, ctypes, set_bytes, g_bytes_ref (bytes), (GDestroyNotify) g_bytes_unref);
|
||||
}
|
||||
|
124
gdk/gdkclipboard.h
Normal file
124
gdk/gdkclipboard.h
Normal file
@@ -0,0 +1,124 @@
|
||||
/* 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_H__
|
||||
#define __GDK_CLIPBOARD_H__
|
||||
|
||||
#if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION)
|
||||
#error "Only <gdk/gdk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdkversionmacros.h>
|
||||
#include <gdk/gdktypes.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_CLIPBOARD (gdk_clipboard_get_type ())
|
||||
#define GDK_CLIPBOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_CLIPBOARD, GdkClipboard))
|
||||
#define GDK_IS_CLIPBOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_CLIPBOARD))
|
||||
|
||||
typedef struct _GdkClipboard GdkClipboard;
|
||||
|
||||
typedef void (* GdkClipboardProvider) (GdkClipboard *clipboard,
|
||||
const gchar *content_type,
|
||||
GOutputStream *output,
|
||||
gpointer user_data);
|
||||
|
||||
GDK_AVAILABLE_IN_3_14
|
||||
GType gdk_clipboard_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_3_14
|
||||
void gdk_clipboard_get_text_async (GdkClipboard *clipboard,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GDK_AVAILABLE_IN_3_14
|
||||
gchar * gdk_clipboard_get_text_finish (GdkClipboard *clipboard,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
GDK_AVAILABLE_IN_3_14
|
||||
void gdk_clipboard_set_text (GdkClipboard *clipboard,
|
||||
const gchar *text);
|
||||
|
||||
GDK_AVAILABLE_IN_3_14
|
||||
gboolean gdk_clipboard_text_available (GdkClipboard *clipboard);
|
||||
|
||||
GDK_AVAILABLE_IN_3_14
|
||||
void gdk_clipboard_get_image_async (GdkClipboard *clipboard,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GDK_AVAILABLE_IN_3_14
|
||||
GdkPixbuf * gdk_clipboard_get_image_finish (GdkClipboard *clipboard,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
GDK_AVAILABLE_IN_3_14
|
||||
void gdk_clipboard_set_image (GdkClipboard *clipboard,
|
||||
GdkPixbuf *pixbuf);
|
||||
|
||||
GDK_AVAILABLE_IN_3_14
|
||||
gboolean gdk_clipboard_image_available (GdkClipboard *clipboard);
|
||||
|
||||
GDK_AVAILABLE_IN_3_14
|
||||
void gdk_clipboard_get_bytes_async (GdkClipboard *clipboard,
|
||||
const gchar *content_type,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GDK_AVAILABLE_IN_3_14
|
||||
GBytes * gdk_clipboard_get_bytes_finish (GdkClipboard *clipboard,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
GDK_AVAILABLE_IN_3_14
|
||||
void gdk_clipboard_set_bytes (GdkClipboard *clipboard,
|
||||
GBytes *data,
|
||||
const gchar *content_type);
|
||||
|
||||
GDK_AVAILABLE_IN_3_14
|
||||
void gdk_clipboard_get_data_async (GdkClipboard *clipboard,
|
||||
const gchar *content_type,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GDK_AVAILABLE_IN_3_14
|
||||
GInputStream * gdk_clipboard_get_data_finish (GdkClipboard *clipboard,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
|
||||
GDK_AVAILABLE_IN_3_14
|
||||
void gdk_clipboard_set_data (GdkClipboard *clipboard,
|
||||
const gchar **content_types,
|
||||
GdkClipboardProvider callback,
|
||||
gpointer user_data,
|
||||
GDestroyNotify destroy);
|
||||
|
||||
GDK_AVAILABLE_IN_3_14
|
||||
gboolean gdk_clipboard_data_available (GdkClipboard *clipboard,
|
||||
const gchar *content_type);
|
||||
|
||||
GDK_AVAILABLE_IN_3_14
|
||||
void gdk_clipboard_clear (GdkClipboard *clipboard);
|
||||
|
||||
GDK_AVAILABLE_IN_3_14
|
||||
const gchar **gdk_clipboard_get_content_types (GdkClipboard *clipboard);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_CLIPBOARD_H__ */
|
333
gdk/gdkclipboardfallback.c
Normal file
333
gdk/gdkclipboardfallback.c
Normal 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));
|
||||
}
|
44
gdk/gdkclipboardfallback.h
Normal file
44
gdk/gdkclipboardfallback.h
Normal 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__ */
|
99
gdk/gdkclipboardprivate.h
Normal file
99
gdk/gdkclipboardprivate.h
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* 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_PRIVATE_H__
|
||||
#define __GDK_CLIPBOARD_PRIVATE_H__
|
||||
|
||||
#include <gdk/gdkclipboard.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_CLIPBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_CLIPBOARD, GdkClipboardClass))
|
||||
#define GDK_IS_CLIPBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_CLIPBOARD))
|
||||
#define GDK_CLIPBOARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_CLIPBOARD, GdkClipboardClass))
|
||||
|
||||
typedef struct _GdkClipboardClass GdkClipboardClass;
|
||||
|
||||
struct _GdkClipboard
|
||||
{
|
||||
GObject parent;
|
||||
};
|
||||
|
||||
struct _GdkClipboardClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
/* signals */
|
||||
void (* changed) (GdkClipboard *clipboard);
|
||||
|
||||
/* vfuncs */
|
||||
void (* get_text_async) (GdkClipboard *clipboard,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
gchar * (* get_text_finish) (GdkClipboard *clipboard,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
void (* set_text) (GdkClipboard *clipboard,
|
||||
const gchar *text);
|
||||
|
||||
void (* get_image_async) (GdkClipboard *clipboard,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GdkPixbuf * (* get_image_finish) (GdkClipboard *clipboard,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
void (* set_image) (GdkClipboard *clipboard,
|
||||
GdkPixbuf *pixbuf);
|
||||
|
||||
void (* get_data_async) (GdkClipboard *clipboard,
|
||||
const gchar *content_type,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GInputStream * (* get_data_finish) (GdkClipboard *clipboard,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
void (* set_data) (GdkClipboard *clipboard,
|
||||
const gchar **content_types,
|
||||
GdkClipboardProvider provider,
|
||||
gpointer data,
|
||||
GDestroyNotify destroy);
|
||||
|
||||
void (* clear) (GdkClipboard *clipboard);
|
||||
};
|
||||
|
||||
|
||||
typedef enum {
|
||||
NO_CONTENT = 0,
|
||||
OTHER_CONTENT = 1 << 0,
|
||||
TEXT_CONTENT = 1 << 1,
|
||||
IMAGE_CONTENT = 1 << 2
|
||||
} GdkClipboardContent;
|
||||
|
||||
void
|
||||
_gdk_clipboard_set_available_content (GdkClipboard *clipboard,
|
||||
GdkClipboardContent content,
|
||||
const gchar **content_types);
|
||||
|
||||
GdkClipboardContent
|
||||
_gdk_clipboard_get_available_content (GdkClipboard *clipboard);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_CLIPBOARD_PRIVATE_H__ */
|
@@ -2225,3 +2225,44 @@ gdk_error_trap_pop (void)
|
||||
{
|
||||
return gdk_error_trap_pop_internal (TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_display_get_clipboard:
|
||||
* @display: a #GdkDisplay
|
||||
*
|
||||
* Returns the #GdkClipboard for this display. This is a per-display
|
||||
* singleton object and is backed by the system CLIPBOARD, if the
|
||||
* platform supports it.
|
||||
*
|
||||
* Returns: (transfer none): the #GdkClipboard representing the system CLIPBOARD
|
||||
*
|
||||
* Since: 3.14
|
||||
*/
|
||||
GdkClipboard *
|
||||
gdk_display_get_clipboard (GdkDisplay *display)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
|
||||
|
||||
return GDK_DISPLAY_GET_CLASS (display)->get_clipboard (display);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_display_get_primary:
|
||||
* @display: a #GdkDisplay
|
||||
*
|
||||
* Returns the 'primary' #GdkClipboard for this display. This is a
|
||||
* per-display singleton object and is backed by the system PRIMARY clipboard,
|
||||
* if the platform supports it.
|
||||
*
|
||||
* Returns: (transfer none): the #GdkClipboard representing the system
|
||||
* PRIMARY clipboard
|
||||
*
|
||||
* Since: 3.14
|
||||
*/
|
||||
GdkClipboard *
|
||||
gdk_display_get_primary (GdkDisplay *display)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
|
||||
|
||||
return GDK_DISPLAY_GET_CLASS (display)->get_primary (display);
|
||||
}
|
||||
|
@@ -30,6 +30,7 @@
|
||||
#include <gdk/gdktypes.h>
|
||||
#include <gdk/gdkevents.h>
|
||||
#include <gdk/gdkdevicemanager.h>
|
||||
#include <gdk/gdkclipboard.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -171,6 +172,12 @@ GdkDeviceManager * gdk_display_get_device_manager (GdkDisplay *display);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkAppLaunchContext *gdk_display_get_app_launch_context (GdkDisplay *display);
|
||||
|
||||
GDK_AVAILABLE_IN_3_14
|
||||
GdkClipboard * gdk_display_get_clipboard (GdkDisplay *display);
|
||||
|
||||
GDK_AVAILABLE_IN_3_14
|
||||
GdkClipboard * gdk_display_get_primary (GdkDisplay *display);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_DISPLAY_H__ */
|
||||
|
@@ -225,6 +225,9 @@ struct _GdkDisplayClass
|
||||
gchar * (*utf8_to_string_target) (GdkDisplay *display,
|
||||
const gchar *text);
|
||||
|
||||
GdkClipboard * (*get_clipboard) (GdkDisplay *display);
|
||||
GdkClipboard * (*get_primary) (GdkDisplay *display);
|
||||
|
||||
/* Signals */
|
||||
void (*opened) (GdkDisplay *display);
|
||||
void (*closed) (GdkDisplay *display,
|
||||
|
@@ -23,6 +23,7 @@ libgdk_x11_la_SOURCES = \
|
||||
gdkapplaunchcontext-x11.c \
|
||||
gdkasync.c \
|
||||
gdkasync.h \
|
||||
gdkclipboard-x11.c \
|
||||
gdkcursor-x11.c \
|
||||
gdkdevice-core-x11.c \
|
||||
gdkdevice-xi2.c \
|
||||
|
1014
gdk/x11/gdkclipboard-x11.c
Normal file
1014
gdk/x11/gdkclipboard-x11.c
Normal file
File diff suppressed because it is too large
Load Diff
49
gdk/x11/gdkclipboard-x11.h
Normal file
49
gdk/x11/gdkclipboard-x11.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/* 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_X11_H__
|
||||
#define __GDK_CLIPBOARD_X11_H__
|
||||
|
||||
#include "gdk/gdkclipboard.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_CLIPBOARD_X11 (gdk_clipboard_x11_get_type ())
|
||||
#define GDK_CLIPBOARD_X11(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_CLIPBOARD_X11, GdkClipboardX11))
|
||||
#define GDK_IS_CLIPBOARD_X11(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_CLIPBOARD_X11))
|
||||
|
||||
typedef struct _GdkClipboardX11 GdkClipboardX11;
|
||||
|
||||
GType gdk_clipboard_x11_get_type (void) G_GNUC_CONST;
|
||||
GdkClipboardX11 *gdk_clipboard_x11_new (GdkDisplay *display,
|
||||
const gchar *selection);
|
||||
|
||||
gboolean gdk_clipboard_x11_handle_selection_clear (GdkClipboardX11 *cb,
|
||||
XSelectionClearEvent *event);
|
||||
gboolean gdk_clipboard_x11_handle_selection_request (GdkClipboardX11 *cb,
|
||||
XSelectionRequestEvent *event);
|
||||
gboolean gdk_clipboard_x11_handle_selection_notify (GdkClipboardX11 *cb,
|
||||
XSelectionEvent *event);
|
||||
gboolean gdk_clipboard_x11_handle_selection_owner_change (GdkClipboardX11 *cb,
|
||||
XEvent *event);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_CLIPBOARD_X11_H__ */
|
@@ -886,7 +886,11 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
|
||||
g_message ("selection clear:\twindow: %ld",
|
||||
xevent->xproperty.window));
|
||||
|
||||
if (_gdk_x11_selection_filter_clear_event (&xevent->xselectionclear))
|
||||
if (gdk_clipboard_x11_handle_selection_clear (display_x11->clipboard, &xevent->xselectionclear))
|
||||
return_val = FALSE;
|
||||
else if (gdk_clipboard_x11_handle_selection_clear (display_x11->primary, &xevent->xselectionclear))
|
||||
return_val = FALSE;
|
||||
else if (_gdk_x11_selection_filter_clear_event (&xevent->xselectionclear))
|
||||
{
|
||||
event->selection.type = GDK_SELECTION_CLEAR;
|
||||
event->selection.window = window;
|
||||
@@ -895,7 +899,6 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
|
||||
}
|
||||
else
|
||||
return_val = FALSE;
|
||||
|
||||
break;
|
||||
|
||||
case SelectionRequest:
|
||||
@@ -903,18 +906,24 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
|
||||
g_message ("selection request:\twindow: %ld",
|
||||
xevent->xproperty.window));
|
||||
|
||||
event->selection.type = GDK_SELECTION_REQUEST;
|
||||
event->selection.window = window;
|
||||
event->selection.selection = gdk_x11_xatom_to_atom_for_display (display, xevent->xselectionrequest.selection);
|
||||
event->selection.target = gdk_x11_xatom_to_atom_for_display (display, xevent->xselectionrequest.target);
|
||||
event->selection.property = gdk_x11_xatom_to_atom_for_display (display, xevent->xselectionrequest.property);
|
||||
if (xevent->xselectionrequest.requestor != None)
|
||||
event->selection.requestor = gdk_x11_window_foreign_new_for_display (display,
|
||||
xevent->xselectionrequest.requestor);
|
||||
if (gdk_clipboard_x11_handle_selection_request (display_x11->clipboard, &xevent->xselectionrequest))
|
||||
return_val = FALSE;
|
||||
else if (gdk_clipboard_x11_handle_selection_request (display_x11->primary, &xevent->xselectionrequest))
|
||||
return_val = FALSE;
|
||||
else
|
||||
event->selection.requestor = NULL;
|
||||
event->selection.time = xevent->xselectionrequest.time;
|
||||
|
||||
{
|
||||
event->selection.type = GDK_SELECTION_REQUEST;
|
||||
event->selection.window = window;
|
||||
event->selection.selection = gdk_x11_xatom_to_atom_for_display (display, xevent->xselectionrequest.selection);
|
||||
event->selection.target = gdk_x11_xatom_to_atom_for_display (display, xevent->xselectionrequest.target);
|
||||
event->selection.property = gdk_x11_xatom_to_atom_for_display (display, xevent->xselectionrequest.property);
|
||||
if (xevent->xselectionrequest.requestor != None)
|
||||
event->selection.requestor = gdk_x11_window_foreign_new_for_display (display,
|
||||
xevent->xselectionrequest.requestor);
|
||||
else
|
||||
event->selection.requestor = NULL;
|
||||
event->selection.time = xevent->xselectionrequest.time;
|
||||
}
|
||||
break;
|
||||
|
||||
case SelectionNotify:
|
||||
@@ -922,16 +931,22 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
|
||||
g_message ("selection notify:\twindow: %ld",
|
||||
xevent->xproperty.window));
|
||||
|
||||
event->selection.type = GDK_SELECTION_NOTIFY;
|
||||
event->selection.window = window;
|
||||
event->selection.selection = gdk_x11_xatom_to_atom_for_display (display, xevent->xselection.selection);
|
||||
event->selection.target = gdk_x11_xatom_to_atom_for_display (display, xevent->xselection.target);
|
||||
if (xevent->xselection.property == None)
|
||||
event->selection.property = GDK_NONE;
|
||||
if (gdk_clipboard_x11_handle_selection_notify (display_x11->clipboard, &xevent->xselection))
|
||||
return_val = FALSE;
|
||||
else if (gdk_clipboard_x11_handle_selection_notify (display_x11->primary, &xevent->xselection))
|
||||
return_val = FALSE;
|
||||
else
|
||||
event->selection.property = gdk_x11_xatom_to_atom_for_display (display, xevent->xselection.property);
|
||||
event->selection.time = xevent->xselection.time;
|
||||
|
||||
{
|
||||
event->selection.type = GDK_SELECTION_NOTIFY;
|
||||
event->selection.window = window;
|
||||
event->selection.selection = gdk_x11_xatom_to_atom_for_display (display, xevent->xselection.selection);
|
||||
event->selection.target = gdk_x11_xatom_to_atom_for_display (display, xevent->xselection.target);
|
||||
if (xevent->xselection.property == None)
|
||||
event->selection.property = GDK_NONE;
|
||||
else
|
||||
event->selection.property = gdk_x11_xatom_to_atom_for_display (display, xevent->xselection.property);
|
||||
event->selection.time = xevent->xselection.time;
|
||||
}
|
||||
break;
|
||||
|
||||
case ColormapNotify:
|
||||
@@ -970,6 +985,8 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
|
||||
XFixesSelectionNotifyEvent *selection_notify = (XFixesSelectionNotifyEvent *)xevent;
|
||||
|
||||
_gdk_x11_screen_process_owner_change (screen, xevent);
|
||||
gdk_clipboard_x11_handle_selection_owner_change (display_x11->clipboard, xevent);
|
||||
gdk_clipboard_x11_handle_selection_owner_change (display_x11->primary, xevent);
|
||||
|
||||
event->owner_change.type = GDK_OWNER_CHANGE;
|
||||
event->owner_change.window = window;
|
||||
@@ -1870,6 +1887,12 @@ gdk_x11_display_finalize (GObject *object)
|
||||
{
|
||||
GdkX11Display *display_x11 = GDK_X11_DISPLAY (object);
|
||||
|
||||
/* Clipboards */
|
||||
if (display_x11->clipboard)
|
||||
g_object_unref (display_x11->clipboard);
|
||||
if (display_x11->primary)
|
||||
g_object_unref (display_x11->primary);
|
||||
|
||||
/* Keymap */
|
||||
if (display_x11->keymap)
|
||||
g_object_unref (display_x11->keymap);
|
||||
@@ -2202,7 +2225,7 @@ gdk_x11_display_supports_selection_notification (GdkDisplay *display)
|
||||
return display_x11->have_xfixes;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gboolean
|
||||
gdk_x11_display_request_selection_notification (GdkDisplay *display,
|
||||
GdkAtom selection)
|
||||
|
||||
@@ -2847,6 +2870,32 @@ gdk_x11_display_get_keymap (GdkDisplay *display)
|
||||
return display_x11->keymap;
|
||||
}
|
||||
|
||||
static GdkClipboard *
|
||||
gdk_x11_display_get_clipboard (GdkDisplay *display)
|
||||
{
|
||||
GdkX11Display *display_x11;
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
|
||||
display_x11 = GDK_X11_DISPLAY (display);
|
||||
|
||||
if (!display_x11->clipboard)
|
||||
display_x11->clipboard = gdk_clipboard_x11_new (display, "CLIPBOARD");
|
||||
|
||||
return GDK_CLIPBOARD (display_x11->clipboard);
|
||||
}
|
||||
|
||||
static GdkClipboard *
|
||||
gdk_x11_display_get_primary (GdkDisplay *display)
|
||||
{
|
||||
GdkX11Display *display_x11;
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
|
||||
display_x11 = GDK_X11_DISPLAY (display);
|
||||
|
||||
if (!display_x11->primary)
|
||||
display_x11->primary = gdk_clipboard_x11_new (display, "PRIMARY");
|
||||
|
||||
return GDK_CLIPBOARD (display_x11->primary);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_x11_display_class_init (GdkX11DisplayClass * class)
|
||||
{
|
||||
@@ -2901,6 +2950,8 @@ gdk_x11_display_class_init (GdkX11DisplayClass * class)
|
||||
display_class->convert_selection = _gdk_x11_display_convert_selection;
|
||||
display_class->text_property_to_utf8_list = _gdk_x11_display_text_property_to_utf8_list;
|
||||
display_class->utf8_to_string_target = _gdk_x11_display_utf8_to_string_target;
|
||||
display_class->get_clipboard = gdk_x11_display_get_clipboard;
|
||||
display_class->get_primary = gdk_x11_display_get_primary;
|
||||
|
||||
_gdk_x11_windowing_init ();
|
||||
}
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#include "gdkwindow.h"
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkmain.h"
|
||||
#include "gdkclipboard-x11.h"
|
||||
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xlib.h>
|
||||
@@ -124,6 +125,9 @@ struct _GdkX11Display
|
||||
GSList *error_traps;
|
||||
|
||||
gint wm_moveresize_button;
|
||||
|
||||
GdkClipboardX11 *clipboard;
|
||||
GdkClipboardX11 *primary;
|
||||
};
|
||||
|
||||
struct _GdkX11DisplayClass
|
||||
|
@@ -321,6 +321,10 @@ cairo_surface_t * _gdk_x11_window_create_bitmap_surface (GdkWindow *window,
|
||||
extern const gint _gdk_x11_event_mask_table[];
|
||||
extern const gint _gdk_x11_event_mask_table_size;
|
||||
|
||||
gboolean gdk_x11_display_request_selection_notification (GdkDisplay *display,
|
||||
GdkAtom selection);
|
||||
|
||||
|
||||
#define GDK_SCREEN_DISPLAY(screen) (GDK_X11_SCREEN (screen)->display)
|
||||
#define GDK_SCREEN_XROOTWIN(screen) (GDK_X11_SCREEN (screen)->xroot_window)
|
||||
#define GDK_WINDOW_SCREEN(win) (gdk_window_get_screen (win))
|
||||
|
@@ -45,6 +45,7 @@ noinst_PROGRAMS = $(TEST_PROGS) \
|
||||
testcairo \
|
||||
testcalendar \
|
||||
testclipboard \
|
||||
testclipboard2 \
|
||||
testcolorchooser \
|
||||
testcombo \
|
||||
testcombochange \
|
||||
@@ -189,6 +190,7 @@ testbuttons_DEPENDENCIES = $(TEST_DEPS)
|
||||
testcairo_DEPENDENCIES = $(TEST_DEPS)
|
||||
testcalendar_DEPENDENCIES = $(TEST_DEPS)
|
||||
testclipboard_DEPENDENCIES = $(TEST_DEPS)
|
||||
testclipboard2_DEPENDENCIES = $(TEST_DEPS)
|
||||
testcolorchooser_DEPENDENCIES = $(TEST_DEPS)
|
||||
testcombo_DEPENDENCIES = $(TEST_DEPS)
|
||||
testcombochange_DEPENDENCIES = $(TEST_DEPS)
|
||||
|
243
tests/testclipboard2.c
Normal file
243
tests/testclipboard2.c
Normal file
@@ -0,0 +1,243 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include <string.h>
|
||||
|
||||
static GdkClipboard *clipboard;
|
||||
|
||||
static void
|
||||
clear (GtkWidget *entry)
|
||||
{
|
||||
gdk_clipboard_clear (clipboard);
|
||||
}
|
||||
|
||||
/* text */
|
||||
|
||||
static void
|
||||
copy_text (GtkWidget *w)
|
||||
{
|
||||
gdk_clipboard_set_text (clipboard, gtk_entry_get_text (GTK_ENTRY (w)));
|
||||
}
|
||||
|
||||
static void
|
||||
text_received (GObject *source,
|
||||
GAsyncResult *res,
|
||||
gpointer data)
|
||||
{
|
||||
gchar *text;
|
||||
GtkWidget *entry = data;
|
||||
GError *error = NULL;
|
||||
|
||||
text = gdk_clipboard_get_text_finish (GDK_CLIPBOARD (source), res, &error);
|
||||
if (!text)
|
||||
{
|
||||
g_print ("error receiving text: %s\n", error ? error->message : "no error set");
|
||||
if (error)
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_entry_set_text (GTK_ENTRY (entry), text);
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
static void
|
||||
paste_text (GtkWidget *w)
|
||||
{
|
||||
gdk_clipboard_get_text_async (clipboard, NULL, text_received, w);
|
||||
}
|
||||
|
||||
static void
|
||||
has_text (GtkWidget *w)
|
||||
{
|
||||
gtk_widget_set_sensitive (w, gdk_clipboard_text_available (clipboard));
|
||||
}
|
||||
|
||||
/* image */
|
||||
|
||||
static void
|
||||
copy_image (GtkWidget *w)
|
||||
{
|
||||
gdk_clipboard_set_image (clipboard, gtk_image_get_pixbuf (GTK_IMAGE (w)));
|
||||
}
|
||||
|
||||
static void
|
||||
image_received (GObject *source,
|
||||
GAsyncResult *res,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *image = data;
|
||||
GdkPixbuf *pixbuf;
|
||||
GError *error = NULL;
|
||||
|
||||
pixbuf = gdk_clipboard_get_image_finish (GDK_CLIPBOARD (source), res, &error);
|
||||
if (!pixbuf)
|
||||
{
|
||||
g_print ("error receiving image: %s\n", error ? error->message : "no error set");
|
||||
if (error)
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf);
|
||||
g_object_unref (pixbuf);
|
||||
}
|
||||
|
||||
static void
|
||||
paste_image (GtkWidget *w)
|
||||
{
|
||||
gdk_clipboard_get_image_async (clipboard, NULL, image_received, w);
|
||||
}
|
||||
|
||||
static void
|
||||
has_image (GtkWidget *w)
|
||||
{
|
||||
gtk_widget_set_sensitive (w, gdk_clipboard_image_available (clipboard));
|
||||
}
|
||||
|
||||
/* data */
|
||||
|
||||
static void
|
||||
provider (GdkClipboard *clipboard,
|
||||
const gchar *content_type,
|
||||
GOutputStream *output,
|
||||
gpointer data)
|
||||
{
|
||||
gchar *text = data;
|
||||
|
||||
g_output_stream_write_all (output, text, strlen (text), NULL, NULL, NULL);
|
||||
g_output_stream_close (output, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
copy_data (GtkWidget *w)
|
||||
{
|
||||
const gchar *types[2] = { "foo/bar", NULL };
|
||||
|
||||
gdk_clipboard_set_data (clipboard, types, provider,
|
||||
(gpointer)g_strdup (gtk_entry_get_text (GTK_ENTRY (w))), g_free);
|
||||
}
|
||||
|
||||
static void
|
||||
data_received (GObject *source,
|
||||
GAsyncResult *res,
|
||||
gpointer data)
|
||||
{
|
||||
GInputStream *is;
|
||||
GError *error = NULL;
|
||||
gchar buffer[128];
|
||||
gssize size;
|
||||
GtkWidget *w = data;
|
||||
|
||||
is = gdk_clipboard_get_data_finish (GDK_CLIPBOARD (source), res, &error);
|
||||
if (!is)
|
||||
return;
|
||||
|
||||
size = g_input_stream_read (is, buffer, 128, NULL, NULL);
|
||||
if (size == -1)
|
||||
{
|
||||
g_object_unref (is);
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_entry_set_text (GTK_ENTRY (w), buffer);
|
||||
g_object_unref (is);
|
||||
}
|
||||
|
||||
static void
|
||||
paste_data (GtkWidget *w)
|
||||
{
|
||||
gdk_clipboard_get_data_async (clipboard, "foo/bar", NULL, data_received, w);
|
||||
}
|
||||
|
||||
static void
|
||||
has_data (GtkWidget *w)
|
||||
{
|
||||
gtk_widget_set_sensitive (w, gdk_clipboard_data_available (clipboard, "foo/bar"));
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *grid;
|
||||
GtkWidget *entry;
|
||||
GtkWidget *button;
|
||||
GtkWidget *image;
|
||||
GtkWidget *label;
|
||||
|
||||
gtk_init (NULL, NULL);
|
||||
|
||||
clipboard = gdk_display_get_clipboard (gdk_display_get_default ());
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
g_signal_connect (window, "delete-event", G_CALLBACK (gtk_main_quit), NULL);
|
||||
|
||||
grid = gtk_grid_new ();
|
||||
gtk_grid_set_row_spacing (GTK_GRID (grid), 10);
|
||||
gtk_grid_set_column_spacing (GTK_GRID (grid), 10);
|
||||
g_object_set (grid, "margin", 10, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (window), grid);
|
||||
|
||||
label = gtk_label_new ("Text");
|
||||
gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
|
||||
entry = gtk_entry_new ();
|
||||
gtk_widget_set_valign (entry, GTK_ALIGN_BASELINE);
|
||||
gtk_grid_attach (GTK_GRID (grid), entry, 1, 0, 1, 1);
|
||||
button = gtk_button_new_with_label ("Copy");
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_BASELINE);
|
||||
gtk_grid_attach (GTK_GRID (grid), button, 2, 0, 1, 1);
|
||||
g_signal_connect_swapped (button, "clicked", G_CALLBACK (copy_text), entry);
|
||||
button = gtk_button_new_with_label ("Paste");
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_BASELINE);
|
||||
gtk_grid_attach (GTK_GRID (grid), button, 3, 0, 1, 1);
|
||||
g_signal_connect_swapped (button, "clicked", G_CALLBACK (paste_text), entry);
|
||||
g_signal_connect_swapped (clipboard, "changed", G_CALLBACK (has_text), button);
|
||||
|
||||
label = gtk_label_new ("Image");
|
||||
gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 0, 1, 1, 1);
|
||||
image = gtk_image_new ();
|
||||
gtk_widget_set_valign (image, GTK_ALIGN_CENTER);
|
||||
if (argc > 1)
|
||||
gtk_image_set_from_file (GTK_IMAGE (image), argv[1]);
|
||||
else
|
||||
gtk_image_set_from_resource (GTK_IMAGE (image), "/org/gtk/libgtk/theme/Adwaita/assets/slider-vert-scale-has-marks-above@2.png");
|
||||
gtk_grid_attach (GTK_GRID (grid), image, 1, 1, 1, 1);
|
||||
button = gtk_button_new_with_label ("Copy");
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
|
||||
gtk_grid_attach (GTK_GRID (grid), button, 2, 1, 1, 1);
|
||||
g_signal_connect_swapped (button, "clicked", G_CALLBACK (copy_image), image);
|
||||
button = gtk_button_new_with_label ("Paste");
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
|
||||
gtk_grid_attach (GTK_GRID (grid), button, 3, 1, 1, 1);
|
||||
g_signal_connect_swapped (button, "clicked", G_CALLBACK (paste_image), image);
|
||||
g_signal_connect_swapped (clipboard, "changed", G_CALLBACK (has_image), button);
|
||||
|
||||
label = gtk_label_new ("Data");
|
||||
gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 0, 2, 1, 1);
|
||||
entry = gtk_entry_new ();
|
||||
gtk_widget_set_valign (entry, GTK_ALIGN_BASELINE);
|
||||
gtk_grid_attach (GTK_GRID (grid), entry, 1, 2, 1, 1);
|
||||
button = gtk_button_new_with_label ("Copy");
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_BASELINE);
|
||||
gtk_grid_attach (GTK_GRID (grid), button, 2, 2, 1, 1);
|
||||
g_signal_connect_swapped (button, "clicked", G_CALLBACK (copy_data), entry);
|
||||
button = gtk_button_new_with_label ("Paste");
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_BASELINE);
|
||||
gtk_grid_attach (GTK_GRID (grid), button, 3, 2, 1, 1);
|
||||
g_signal_connect_swapped (button, "clicked", G_CALLBACK (paste_data), entry);
|
||||
g_signal_connect_swapped (clipboard, "changed", G_CALLBACK (has_data), button);
|
||||
|
||||
button = gtk_button_new_with_label ("Clear Clipboard");
|
||||
gtk_grid_attach (GTK_GRID (grid), button, 2, 3, 2, 1);
|
||||
g_signal_connect_swapped (button, "clicked", G_CALLBACK (clear), entry);
|
||||
|
||||
g_signal_emit_by_name (clipboard, "changed", 0);
|
||||
|
||||
gtk_widget_show_all (window);
|
||||
|
||||
gtk_main ();
|
||||
|
||||
return 0;
|
||||
}
|
@@ -22,6 +22,7 @@ TEST_PROGS += \
|
||||
encoding \
|
||||
display \
|
||||
keysyms \
|
||||
clipboard \
|
||||
$(NULL)
|
||||
|
||||
CLEANFILES = \
|
||||
|
295
testsuite/gdk/clipboard.c
Normal file
295
testsuite/gdk/clipboard.c
Normal file
@@ -0,0 +1,295 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
static void
|
||||
count_changed (GdkClipboard *clipboard, gpointer data)
|
||||
{
|
||||
gint *count = data;
|
||||
|
||||
*count += 1;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
gboolean called;
|
||||
gchar *text;
|
||||
GdkPixbuf *pixbuf;
|
||||
GBytes *bytes;
|
||||
GError *error;
|
||||
GMainLoop *loop;
|
||||
} GetData;
|
||||
|
||||
static void
|
||||
get_text (GObject *source, GAsyncResult *res, gpointer data)
|
||||
{
|
||||
GetData *gd = data;
|
||||
|
||||
gd->text = gdk_clipboard_get_text_finish (GDK_CLIPBOARD (source), res, &gd->error);
|
||||
gd->called = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
get_image (GObject *source, GAsyncResult *res, gpointer data)
|
||||
{
|
||||
GetData *gd = data;
|
||||
|
||||
gd->pixbuf = gdk_clipboard_get_image_finish (GDK_CLIPBOARD (source), res, &gd->error);
|
||||
gd->called = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
get_bytes (GObject *source, GAsyncResult *res, gpointer data)
|
||||
{
|
||||
GetData *gd = data;
|
||||
|
||||
gd->bytes = gdk_clipboard_get_bytes_finish (GDK_CLIPBOARD (source), res, &gd->error);
|
||||
gd->called = TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
wait_get (gpointer data)
|
||||
{
|
||||
GetData *gd = data;
|
||||
|
||||
if (gd->called)
|
||||
{
|
||||
g_main_loop_quit (gd->loop);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
test_clipboard_text (void)
|
||||
{
|
||||
GdkClipboard *clipboard;
|
||||
const gchar **content_types;
|
||||
gint count;
|
||||
GetData *gd;
|
||||
|
||||
count = 0;
|
||||
|
||||
clipboard = gdk_clipboard_fallback_new ();
|
||||
g_signal_connect (clipboard, "changed", G_CALLBACK (count_changed), &count);
|
||||
|
||||
g_assert (!gdk_clipboard_text_available (clipboard));
|
||||
g_assert (!gdk_clipboard_image_available (clipboard));
|
||||
g_assert (!gdk_clipboard_data_available (clipboard, "application/octet-stream"));
|
||||
|
||||
content_types = gdk_clipboard_get_content_types (clipboard);
|
||||
g_assert (content_types == NULL);
|
||||
|
||||
gdk_clipboard_set_text (clipboard, "ABC");
|
||||
|
||||
g_assert (gdk_clipboard_text_available (clipboard));
|
||||
g_assert (!gdk_clipboard_image_available (clipboard));
|
||||
g_assert (!gdk_clipboard_data_available (clipboard, "application/octet-stream"));
|
||||
g_assert_cmpint (count, ==, 1);
|
||||
|
||||
gd = g_new0 (GetData, 1);
|
||||
gdk_clipboard_get_text_async (clipboard, NULL, get_text, gd);
|
||||
|
||||
gd->loop = g_main_loop_new (NULL, FALSE);
|
||||
g_idle_add (wait_get, gd);
|
||||
g_main_loop_run (gd->loop);
|
||||
|
||||
g_assert_cmpstr (gd->text, ==, "ABC");
|
||||
g_assert_no_error (gd->error);
|
||||
|
||||
g_free (gd->text);
|
||||
g_main_loop_unref (gd->loop);
|
||||
g_free (gd);
|
||||
|
||||
gdk_clipboard_clear (clipboard);
|
||||
|
||||
g_assert (!gdk_clipboard_text_available (clipboard));
|
||||
g_assert (!gdk_clipboard_image_available (clipboard));
|
||||
g_assert (!gdk_clipboard_data_available (clipboard, "application/octet-stream"));
|
||||
g_assert_cmpint (count, ==, 2);
|
||||
|
||||
g_object_unref (clipboard);
|
||||
}
|
||||
|
||||
static void
|
||||
test_clipboard_image (void)
|
||||
{
|
||||
GdkClipboard *clipboard;
|
||||
const gchar **content_types;
|
||||
gint count;
|
||||
GdkPixbuf *pixbuf;
|
||||
GetData *gd;
|
||||
|
||||
count = 0;
|
||||
|
||||
clipboard = gdk_clipboard_fallback_new ();
|
||||
g_signal_connect (clipboard, "changed", G_CALLBACK (count_changed), &count);
|
||||
|
||||
g_assert (!gdk_clipboard_text_available (clipboard));
|
||||
g_assert (!gdk_clipboard_image_available (clipboard));
|
||||
g_assert (!gdk_clipboard_data_available (clipboard, "application/octet-stream"));
|
||||
|
||||
content_types = gdk_clipboard_get_content_types (clipboard);
|
||||
g_assert (content_types == NULL);
|
||||
|
||||
pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, 16, 16);
|
||||
gdk_clipboard_set_image (clipboard, pixbuf);
|
||||
|
||||
g_assert (!gdk_clipboard_text_available (clipboard));
|
||||
g_assert (gdk_clipboard_image_available (clipboard));
|
||||
g_assert (!gdk_clipboard_data_available (clipboard, "application/octet-stream"));
|
||||
g_assert_cmpint (count, ==, 1);
|
||||
|
||||
g_assert_cmpint (G_OBJECT (pixbuf)->ref_count, >=, 2);
|
||||
|
||||
gd = g_new0 (GetData, 1);
|
||||
gdk_clipboard_get_image_async (clipboard, NULL, get_image, gd);
|
||||
|
||||
gd->loop = g_main_loop_new (NULL, FALSE);
|
||||
g_idle_add (wait_get, gd);
|
||||
g_main_loop_run (gd->loop);
|
||||
|
||||
g_assert (gd->pixbuf == pixbuf);
|
||||
g_assert_no_error (gd->error);
|
||||
|
||||
g_assert_cmpint (G_OBJECT (pixbuf)->ref_count, >=, 3);
|
||||
|
||||
g_object_unref (gd->pixbuf);
|
||||
|
||||
g_main_loop_unref (gd->loop);
|
||||
g_free (gd);
|
||||
|
||||
gdk_clipboard_clear (clipboard);
|
||||
|
||||
g_assert_cmpint (G_OBJECT (pixbuf)->ref_count, ==, 1);
|
||||
g_object_unref (pixbuf);
|
||||
|
||||
g_assert (!gdk_clipboard_text_available (clipboard));
|
||||
g_assert (!gdk_clipboard_image_available (clipboard));
|
||||
g_assert (!gdk_clipboard_data_available (clipboard, "application/octet-stream"));
|
||||
g_assert_cmpint (count, ==, 2);
|
||||
|
||||
g_object_unref (clipboard);
|
||||
}
|
||||
|
||||
static void
|
||||
test_clipboard_bytes (void)
|
||||
{
|
||||
GdkClipboard *clipboard;
|
||||
const gchar **content_types;
|
||||
gint count;
|
||||
GBytes *bytes;
|
||||
GetData *gd;
|
||||
|
||||
count = 0;
|
||||
|
||||
clipboard = gdk_clipboard_fallback_new ();
|
||||
g_signal_connect (clipboard, "changed", G_CALLBACK (count_changed), &count);
|
||||
|
||||
g_assert (!gdk_clipboard_text_available (clipboard));
|
||||
g_assert (!gdk_clipboard_image_available (clipboard));
|
||||
g_assert (!gdk_clipboard_data_available (clipboard, "application/octet-stream"));
|
||||
|
||||
content_types = gdk_clipboard_get_content_types (clipboard);
|
||||
g_assert (content_types == NULL);
|
||||
|
||||
bytes = g_bytes_new_static ("012346789", 10);
|
||||
gdk_clipboard_set_bytes (clipboard, bytes, "application/octet-stream");
|
||||
|
||||
g_assert (!gdk_clipboard_text_available (clipboard));
|
||||
g_assert (!gdk_clipboard_image_available (clipboard));
|
||||
g_assert (gdk_clipboard_data_available (clipboard, "application/octet-stream"));
|
||||
g_assert_cmpint (count, ==, 1);
|
||||
|
||||
gd = g_new0 (GetData, 1);
|
||||
gdk_clipboard_get_bytes_async (clipboard, "application/octet-stream", NULL, get_bytes, gd);
|
||||
|
||||
gd->loop = g_main_loop_new (NULL, FALSE);
|
||||
g_idle_add (wait_get, gd);
|
||||
g_main_loop_run (gd->loop);
|
||||
|
||||
g_assert (g_bytes_equal (gd->bytes, bytes));
|
||||
g_assert_no_error (gd->error);
|
||||
|
||||
g_bytes_unref (gd->bytes);
|
||||
|
||||
g_main_loop_unref (gd->loop);
|
||||
g_free (gd);
|
||||
|
||||
gdk_clipboard_clear (clipboard);
|
||||
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
g_assert (!gdk_clipboard_text_available (clipboard));
|
||||
g_assert (!gdk_clipboard_image_available (clipboard));
|
||||
g_assert (!gdk_clipboard_data_available (clipboard, "application/octet-stream"));
|
||||
g_assert_cmpint (count, ==, 2);
|
||||
|
||||
g_object_unref (clipboard);
|
||||
}
|
||||
|
||||
static gboolean freed;
|
||||
|
||||
static void
|
||||
free_data (gpointer data)
|
||||
{
|
||||
freed = TRUE;
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static void
|
||||
provider (GdkClipboard *clipboard,
|
||||
const gchar *content_type,
|
||||
GOutputStream *output,
|
||||
gpointer user_data)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
test_clipboard_data (void)
|
||||
{
|
||||
GdkClipboard *clipboard;
|
||||
gint count;
|
||||
const gchar *content_types[3] = {
|
||||
"application/octet-stream",
|
||||
"application/pdf",
|
||||
NULL
|
||||
};
|
||||
|
||||
count = 0;
|
||||
|
||||
clipboard = gdk_clipboard_fallback_new ();
|
||||
g_signal_connect (clipboard, "changed", G_CALLBACK (count_changed), &count);
|
||||
|
||||
g_assert (!gdk_clipboard_text_available (clipboard));
|
||||
g_assert (!gdk_clipboard_image_available (clipboard));
|
||||
g_assert (!gdk_clipboard_data_available (clipboard, "application/octet-stream"));
|
||||
|
||||
gdk_clipboard_set_data (clipboard, content_types,
|
||||
provider, g_strdup ("0123456789"), free_data);
|
||||
|
||||
g_assert (!gdk_clipboard_text_available (clipboard));
|
||||
g_assert (!gdk_clipboard_image_available (clipboard));
|
||||
g_assert (gdk_clipboard_data_available (clipboard, "application/octet-stream"));
|
||||
g_assert (gdk_clipboard_data_available (clipboard, "application/pdf"));
|
||||
g_assert (!gdk_clipboard_data_available (clipboard, "yellow submarine"));
|
||||
g_assert_cmpint (count, ==, 1);
|
||||
|
||||
g_object_unref (clipboard);
|
||||
|
||||
g_assert (freed);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
gdk_init (NULL, NULL);
|
||||
|
||||
g_test_add_func ("/clipboard/text", test_clipboard_text);
|
||||
g_test_add_func ("/clipboard/image", test_clipboard_image);
|
||||
g_test_add_func ("/clipboard/bytes", test_clipboard_bytes);
|
||||
g_test_add_func ("/clipboard/data", test_clipboard_data);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
Reference in New Issue
Block a user