[gtk/clipboard-test] Add more clipboard tests




commit 177a035fc156178e72cf25090aedf5bbf6e7ea91
Author: Matthias Clasen <mclasen redhat com>
Date:   Mon Apr 26 17:02:50 2021 -0400

    Add more clipboard tests
    
    This tests the simplest cases of copying text,
    files, or colors between processes.
    
    Currently, the tests work under X11. Under mutter,
    only the text copying works. Under weston, text
    and color works.

 testsuite/gdk/clipboard-client.c | 309 +++++++++++++++++++++++++++++++++++++++
 testsuite/gdk/clipboard.c        | 137 +++++++++++++++++
 testsuite/gdk/meson.build        |   7 +
 3 files changed, 453 insertions(+)
---
diff --git a/testsuite/gdk/clipboard-client.c b/testsuite/gdk/clipboard-client.c
new file mode 100644
index 0000000000..06a5a6be09
--- /dev/null
+++ b/testsuite/gdk/clipboard-client.c
@@ -0,0 +1,309 @@
+#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_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 void
+do_it (GObject    *object,
+       GParamSpec *pspec)
+{
+  GdkClipboard *clipboard;
+
+  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, "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, "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));
+      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;
+}
diff --git a/testsuite/gdk/clipboard.c b/testsuite/gdk/clipboard.c
index aa3b1055f2..ec2ffae735 100644
--- a/testsuite/gdk/clipboard.c
+++ b/testsuite/gdk/clipboard.c
@@ -70,6 +70,138 @@ 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
+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
+    {
+      char *s1, *s2;
+
+      g_file_get_contents (value, &s1, NULL, &error);
+      g_assert_no_error (error);
+      g_file_get_contents (stdout_buf, &s2, NULL, &error);
+      g_assert_no_error (error);
+
+      g_assert_cmpstr (s1, ==, s2);
+      g_free (s1);
+      g_free (s2);
+    }
+
+  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");
+}
+
 int
 main (int argc, char *argv[])
 {
@@ -78,6 +210,11 @@ 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);
 
   return g_test_run ();
 }
diff --git a/testsuite/gdk/meson.build b/testsuite/gdk/meson.build
index 5216d7a518..edc290ff7a 100644
--- a/testsuite/gdk/meson.build
+++ b/testsuite/gdk/meson.build
@@ -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')
 


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