mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-26 13:41:07 +00:00
Add more clipboard tests
This tests the simple cases of copying text, files, colors or images between processes.
This commit is contained in:
parent
604d171d56
commit
be42644091
364
testsuite/gdk/clipboard-client.c
Normal file
364
testsuite/gdk/clipboard-client.c
Normal file
@ -0,0 +1,364 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#ifdef GDK_WINDOWING_WAYLAND
|
||||
#include "wayland/gdkwayland.h"
|
||||
#endif
|
||||
|
||||
static void
|
||||
got_string_cb (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GdkClipboard *clipboard = GDK_CLIPBOARD (source);
|
||||
GError *error = NULL;
|
||||
char *text;
|
||||
|
||||
text = gdk_clipboard_read_text_finish (clipboard, result, &error);
|
||||
if (text)
|
||||
{
|
||||
g_print ("%s", text);
|
||||
g_free (text);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_print ("ERROR: %s", error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
static void
|
||||
got_text_cb (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GdkClipboard *clipboard = GDK_CLIPBOARD (source);
|
||||
GError *error = NULL;
|
||||
char *text;
|
||||
|
||||
text = gdk_clipboard_read_text_finish (clipboard, result, &error);
|
||||
if (text)
|
||||
{
|
||||
int fd;
|
||||
char *name;
|
||||
|
||||
fd = g_file_open_tmp ("XXXXXX.out", &name, &error);
|
||||
if (error)
|
||||
g_error ("Failed to create tmp file: %s", error->message);
|
||||
close (fd);
|
||||
g_file_set_contents (name, text, -1, &error);
|
||||
g_print ("%s", name);
|
||||
g_free (text);
|
||||
g_free (name);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_print ("ERROR: %s", error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
static void
|
||||
got_texture_cb (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GdkClipboard *clipboard = GDK_CLIPBOARD (source);
|
||||
GError *error = NULL;
|
||||
GdkTexture *texture;
|
||||
|
||||
texture = gdk_clipboard_read_texture_finish (clipboard, result, &error);
|
||||
if (texture)
|
||||
{
|
||||
int fd;
|
||||
char *name;
|
||||
|
||||
fd = g_file_open_tmp ("XXXXXX.out", &name, &error);
|
||||
if (error)
|
||||
g_error ("Failed to create tmp file: %s", error->message);
|
||||
close (fd);
|
||||
gdk_texture_save_to_png (texture, name);
|
||||
g_print ("%s", name);
|
||||
g_object_unref (texture);
|
||||
g_free (name);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_print ("ERROR: %s", error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
static void
|
||||
got_file (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GdkClipboard *clipboard = GDK_CLIPBOARD (source);
|
||||
GError *error = NULL;
|
||||
const GValue *value;
|
||||
|
||||
value = gdk_clipboard_read_value_finish (clipboard, result, &error);
|
||||
if (value)
|
||||
{
|
||||
GFile *file = g_value_get_object (value);
|
||||
char *path = g_file_get_path (file);
|
||||
g_print ("%s", path);
|
||||
g_free (path);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_print ("ERROR: %s", error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
static void
|
||||
got_files (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GdkClipboard *clipboard = GDK_CLIPBOARD (source);
|
||||
GError *error = NULL;
|
||||
const GValue *value;
|
||||
|
||||
value = gdk_clipboard_read_value_finish (clipboard, result, &error);
|
||||
if (value)
|
||||
{
|
||||
GSList *files = g_value_get_boxed (value);
|
||||
for (GSList *l = files; l; l = l->next)
|
||||
{
|
||||
GFile *file = l->data;
|
||||
char *path = g_file_get_path (file);
|
||||
if (l != files)
|
||||
g_print (":");
|
||||
g_print ("%s", path);
|
||||
g_free (path);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_print ("ERROR: %s", error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
static void
|
||||
got_color (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GdkClipboard *clipboard = GDK_CLIPBOARD (source);
|
||||
GError *error = NULL;
|
||||
const GValue *value;
|
||||
|
||||
value = gdk_clipboard_read_value_finish (clipboard, result, &error);
|
||||
if (value)
|
||||
{
|
||||
GdkRGBA *color = g_value_get_boxed (value);
|
||||
char *s = gdk_rgba_to_string (color);
|
||||
g_print ("%s", s);
|
||||
g_free (s);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_print ("ERROR: %s", error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
static const char *action;
|
||||
static const char *type;
|
||||
static const char *value;
|
||||
static gulong handler;
|
||||
|
||||
static void
|
||||
do_it (GObject *object,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkClipboard *clipboard;
|
||||
|
||||
g_signal_handler_disconnect (object, handler);
|
||||
|
||||
clipboard = gdk_display_get_clipboard (gdk_display_get_default ());
|
||||
|
||||
if (strcmp (action, "info") == 0)
|
||||
{
|
||||
GdkContentFormats *formats;
|
||||
char *s;
|
||||
|
||||
formats = gdk_clipboard_get_formats (clipboard);
|
||||
s = gdk_content_formats_to_string (formats);
|
||||
g_print ("%s\n", s);
|
||||
g_free (s);
|
||||
}
|
||||
else if (strcmp (action, "set") == 0)
|
||||
{
|
||||
GdkContentFormats *formats;
|
||||
char *s;
|
||||
|
||||
if (strcmp (type, "string") == 0)
|
||||
{
|
||||
gdk_clipboard_set_text (clipboard, value);
|
||||
}
|
||||
else if (strcmp (type, "text") == 0)
|
||||
{
|
||||
char *contents;
|
||||
gsize len;
|
||||
|
||||
if (!g_file_get_contents (value, &contents, &len, NULL))
|
||||
g_error ("Failed to read %s\n", value);
|
||||
|
||||
gdk_clipboard_set_text (clipboard, contents);
|
||||
g_free (contents);
|
||||
}
|
||||
else if (strcmp (type, "image") == 0)
|
||||
{
|
||||
GFile *file;
|
||||
GdkTexture *texture;
|
||||
|
||||
file = g_file_new_for_commandline_arg (value);
|
||||
texture = gdk_texture_new_from_file (file, NULL);
|
||||
if (!texture)
|
||||
g_error ("Failed to read %s\n", value);
|
||||
|
||||
gdk_clipboard_set_texture (clipboard, texture);
|
||||
g_object_unref (texture);
|
||||
g_object_unref (file);
|
||||
}
|
||||
else if (strcmp (type, "file") == 0)
|
||||
{
|
||||
GFile *file;
|
||||
|
||||
file = g_file_new_for_commandline_arg (value);
|
||||
gdk_clipboard_set (clipboard, G_TYPE_FILE, file);
|
||||
g_object_unref (file);
|
||||
}
|
||||
else if (strcmp (type, "files") == 0)
|
||||
{
|
||||
char **strv;
|
||||
GSList *files;
|
||||
|
||||
strv = g_strsplit (value, ":", 0);
|
||||
|
||||
files = NULL;
|
||||
for (int i = 0; strv[i]; i++)
|
||||
files = g_slist_append (files, g_file_new_for_commandline_arg (strv[i]));
|
||||
|
||||
gdk_clipboard_set (clipboard, GDK_TYPE_FILE_LIST, files);
|
||||
|
||||
g_slist_free_full (files, g_object_unref);
|
||||
g_strfreev (strv);
|
||||
}
|
||||
else if (strcmp (type, "color") == 0)
|
||||
{
|
||||
GdkRGBA color;
|
||||
|
||||
gdk_rgba_parse (&color, value);
|
||||
gdk_clipboard_set (clipboard, GDK_TYPE_RGBA, &color);
|
||||
}
|
||||
else
|
||||
g_error ("can't set %s", type);
|
||||
|
||||
formats = gdk_clipboard_get_formats (clipboard);
|
||||
s = gdk_content_formats_to_string (formats);
|
||||
g_print ("%s\n", s);
|
||||
g_free (s);
|
||||
}
|
||||
else if (strcmp (action, "get") == 0)
|
||||
{
|
||||
if (strcmp (type, "string") == 0)
|
||||
{
|
||||
gdk_clipboard_read_text_async (clipboard, NULL, got_string_cb, NULL);
|
||||
}
|
||||
else if (strcmp (type, "text") == 0)
|
||||
{
|
||||
gdk_clipboard_read_text_async (clipboard, NULL, got_text_cb, NULL);
|
||||
}
|
||||
else if (strcmp (type, "image") == 0)
|
||||
{
|
||||
gdk_clipboard_read_texture_async (clipboard, NULL, got_texture_cb, NULL);
|
||||
}
|
||||
else if (strcmp (type, "file") == 0)
|
||||
{
|
||||
gdk_clipboard_read_value_async (clipboard, G_TYPE_FILE, 0, NULL, got_file, NULL);
|
||||
}
|
||||
else if (strcmp (type, "files") == 0)
|
||||
{
|
||||
gdk_clipboard_read_value_async (clipboard, GDK_TYPE_FILE_LIST, 0, NULL, got_files, NULL);
|
||||
}
|
||||
else if (strcmp (type, "color") == 0)
|
||||
{
|
||||
gdk_clipboard_read_value_async (clipboard, GDK_TYPE_RGBA, 0, NULL, got_color, NULL);
|
||||
}
|
||||
else
|
||||
g_error ("can't get %s", type);
|
||||
}
|
||||
else
|
||||
g_error ("can only set, get or info");
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
GtkWidget *window;
|
||||
gboolean done = FALSE;
|
||||
|
||||
if (argc < 2)
|
||||
g_error ("too few arguments");
|
||||
|
||||
action = argv[1];
|
||||
|
||||
if (strcmp (action, "info") == 0)
|
||||
{
|
||||
}
|
||||
else if (strcmp (action, "set") == 0)
|
||||
{
|
||||
if (argc < 4)
|
||||
g_error ("too few arguments for set");
|
||||
|
||||
type = argv[2];
|
||||
value = argv[3];
|
||||
}
|
||||
else if (strcmp (action, "get") == 0)
|
||||
{
|
||||
if (argc < 3)
|
||||
g_error ("too few arguments for get");
|
||||
|
||||
type = argv[2];
|
||||
}
|
||||
else
|
||||
g_error ("can only set or get");
|
||||
|
||||
gtk_init ();
|
||||
|
||||
/* Don't wait for a window manager to give us focus when
|
||||
* we may be running on bare wm-less X.
|
||||
*/
|
||||
#ifdef GDK_WINDOWING_WAYLAND
|
||||
if (GDK_IS_WAYLAND_DISPLAY (gdk_display_get_default ()))
|
||||
{
|
||||
window = gtk_window_new ();
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
handler = g_signal_connect (window, "notify::is-active", G_CALLBACK (do_it), NULL);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
do_it (NULL, NULL);
|
||||
|
||||
while (!done)
|
||||
g_main_context_iteration (NULL, TRUE);
|
||||
|
||||
return 0;
|
||||
}
|
@ -70,6 +70,199 @@ test_clipboard_basic (void)
|
||||
g_value_unset (&value);
|
||||
}
|
||||
|
||||
static void
|
||||
read_upto_done (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GDataInputStream *out = G_DATA_INPUT_STREAM (source);
|
||||
gboolean *done = data;
|
||||
char *str;
|
||||
GError *error = NULL;
|
||||
|
||||
str = g_data_input_stream_read_upto_finish (out, result, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_free (str);
|
||||
|
||||
*done = TRUE;
|
||||
g_main_context_wakeup (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
assert_texture_equal (GdkTexture *t1,
|
||||
GdkTexture *t2)
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
int stride;
|
||||
guchar *d1;
|
||||
guchar *d2;
|
||||
|
||||
width = gdk_texture_get_width (t1);
|
||||
height = gdk_texture_get_height (t1);
|
||||
stride = 4 * width;
|
||||
|
||||
g_assert_cmpint (width, ==, gdk_texture_get_width (t2));
|
||||
g_assert_cmpint (height, ==, gdk_texture_get_height (t2));
|
||||
|
||||
d1 = g_malloc (stride * height);
|
||||
d2 = g_malloc (stride * height);
|
||||
|
||||
gdk_texture_download (t1, d1, stride);
|
||||
gdk_texture_download (t2, d2, stride);
|
||||
|
||||
g_assert_cmpmem (d1, stride * height, d2, stride * height);
|
||||
|
||||
g_free (d1);
|
||||
g_free (d2);
|
||||
}
|
||||
|
||||
static void
|
||||
test_clipboard_roundtrip (const char *type,
|
||||
const char *value,
|
||||
const char *result)
|
||||
{
|
||||
GSubprocess *source, *target;
|
||||
char *clipboard_client;
|
||||
GError *error = NULL;
|
||||
GDataInputStream *out;
|
||||
gboolean done = FALSE;
|
||||
char *stdout_buf = NULL;
|
||||
char *stderr_buf = NULL;
|
||||
|
||||
clipboard_client = g_test_build_filename (G_TEST_BUILT, "/clipboard-client", NULL);
|
||||
|
||||
source = g_subprocess_new (G_SUBPROCESS_FLAGS_STDOUT_PIPE,
|
||||
&error,
|
||||
clipboard_client,
|
||||
"set", type, value, NULL);
|
||||
g_assert_no_error (error);
|
||||
|
||||
/* Wait until the first child has claimed the clipboard */
|
||||
out = g_data_input_stream_new (g_subprocess_get_stdout_pipe (source));
|
||||
g_data_input_stream_read_upto_async (out, "\n", 1, 0, NULL, read_upto_done, &done);
|
||||
|
||||
while (!done)
|
||||
g_main_context_iteration (NULL, TRUE);
|
||||
|
||||
g_object_unref (out);
|
||||
|
||||
target = g_subprocess_new (G_SUBPROCESS_FLAGS_STDOUT_PIPE,
|
||||
&error,
|
||||
clipboard_client,
|
||||
"get", type, NULL);
|
||||
|
||||
g_free (clipboard_client);
|
||||
|
||||
if (!target)
|
||||
{
|
||||
g_test_fail ();
|
||||
g_error_free (error);
|
||||
|
||||
g_subprocess_force_exit (source);
|
||||
g_object_unref (source);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
g_subprocess_communicate_utf8 (target, NULL, NULL, &stdout_buf, &stderr_buf, &error);
|
||||
|
||||
g_subprocess_force_exit (source);
|
||||
g_object_unref (source);
|
||||
|
||||
g_assert_no_error (error);
|
||||
|
||||
if (result)
|
||||
g_assert_cmpstr (stdout_buf, ==, result);
|
||||
else if (g_str_has_prefix (stdout_buf, "ERROR"))
|
||||
{
|
||||
g_test_fail ();
|
||||
}
|
||||
else if (g_str_has_suffix (value, ".png"))
|
||||
{
|
||||
GFile *f1, *f2;
|
||||
GdkTexture *t1, *t2;
|
||||
|
||||
f1 = g_file_new_for_path (value);
|
||||
f2 = g_file_new_for_path (stdout_buf);
|
||||
|
||||
t1 = gdk_texture_new_from_file (f1, &error);
|
||||
g_assert_no_error (error);
|
||||
t2 = gdk_texture_new_from_file (f2, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
assert_texture_equal (t1, t2);
|
||||
|
||||
g_object_unref (t1);
|
||||
g_object_unref (t2);
|
||||
g_object_unref (f1);
|
||||
g_object_unref (f2);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *m1, *m2;
|
||||
gsize l1, l2;
|
||||
|
||||
g_file_get_contents (value, &m1, &l1, &error);
|
||||
g_assert_no_error (error);
|
||||
g_file_get_contents (stdout_buf, &m2, &l2, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
g_assert_cmpmem (m1, l1, m2, l2);
|
||||
|
||||
g_free (m1);
|
||||
g_free (m2);
|
||||
}
|
||||
|
||||
g_assert_null (stderr_buf);
|
||||
g_free (stdout_buf);
|
||||
g_object_unref (target);
|
||||
}
|
||||
|
||||
static void
|
||||
test_clipboard_string (void)
|
||||
{
|
||||
test_clipboard_roundtrip ("string", "abcdef1230", "abcdef1230");
|
||||
}
|
||||
|
||||
static void
|
||||
test_clipboard_text (void)
|
||||
{
|
||||
char *filename;
|
||||
|
||||
filename = g_test_build_filename (G_TEST_DIST, "../../../gtk/gtkwidget.h", NULL);
|
||||
|
||||
test_clipboard_roundtrip ("text", filename, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
test_clipboard_image (void)
|
||||
{
|
||||
char *filename;
|
||||
|
||||
filename = g_test_build_filename (G_TEST_DIST, "../../../gtk/icons/32x32/places/network-workgroup.png", NULL);
|
||||
|
||||
test_clipboard_roundtrip ("image", filename, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
test_clipboard_color (void)
|
||||
{
|
||||
test_clipboard_roundtrip ("color", "red", "rgb(255,0,0)");
|
||||
}
|
||||
|
||||
static void
|
||||
test_clipboard_file (void)
|
||||
{
|
||||
test_clipboard_roundtrip ("file", "/etc/passwd", "/etc/passwd");
|
||||
}
|
||||
|
||||
static void
|
||||
test_clipboard_files (void)
|
||||
{
|
||||
test_clipboard_roundtrip ("files", "/etc/passwd:/boot/ostree", "/etc/passwd:/boot/ostree");
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
@ -78,6 +271,12 @@ main (int argc, char *argv[])
|
||||
gtk_init ();
|
||||
|
||||
g_test_add_func ("/clipboard/basic", test_clipboard_basic);
|
||||
g_test_add_func ("/clipboard/string", test_clipboard_string);
|
||||
g_test_add_func ("/clipboard/text", test_clipboard_text);
|
||||
g_test_add_func ("/clipboard/image", test_clipboard_image);
|
||||
g_test_add_func ("/clipboard/color", test_clipboard_color);
|
||||
g_test_add_func ("/clipboard/file", test_clipboard_file);
|
||||
g_test_add_func ("/clipboard/files", test_clipboard_files);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
@ -1,3 +1,10 @@
|
||||
clipboard_client = executable('clipboard-client',
|
||||
sources: ['clipboard-client.c'],
|
||||
include_directories: [confinc],
|
||||
c_args: common_cflags,
|
||||
dependencies: [ libgtk_dep ],
|
||||
install: false)
|
||||
|
||||
testexecdir = join_paths(installed_test_bindir, 'gdk')
|
||||
testdatadir = join_paths(installed_test_datadir, 'gdk')
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user