[gtk/clipboard-test: 8/8] Add more clipboard tests




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

    Add more clipboard tests
    
    This tests the simple cases of copying text,
    files, colors or images between processes.

 testsuite/gdk/clipboard-client.c | 364 +++++++++++++++++++++++++++++++++++++++
 testsuite/gdk/clipboard.c        | 199 +++++++++++++++++++++
 testsuite/gdk/meson.build        |   7 +
 3 files changed, 570 insertions(+)
---
diff --git a/testsuite/gdk/clipboard-client.c b/testsuite/gdk/clipboard-client.c
new file mode 100644
index 0000000000..346bac2d7c
--- /dev/null
+++ b/testsuite/gdk/clipboard-client.c
@@ -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;
+}
diff --git a/testsuite/gdk/clipboard.c b/testsuite/gdk/clipboard.c
index aa3b1055f2..9569de927b 100644
--- a/testsuite/gdk/clipboard.c
+++ b/testsuite/gdk/clipboard.c
@@ -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 ();
 }
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]