summaryrefslogtreecommitdiffstats
path: root/tools/gimp-test-clipboard.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--tools/gimp-test-clipboard.c443
1 files changed, 443 insertions, 0 deletions
diff --git a/tools/gimp-test-clipboard.c b/tools/gimp-test-clipboard.c
new file mode 100644
index 0000000..04f02e3
--- /dev/null
+++ b/tools/gimp-test-clipboard.c
@@ -0,0 +1,443 @@
+/*
+ * gimp-test-clipboard.c -- do clipboard things
+ *
+ * Copyright (C) 2005 Michael Natterer <mitch@gimp.org>
+ *
+ * Use this code for whatever you like.
+ */
+
+#include "config.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <glib/gstdio.h>
+#ifndef _O_BINARY
+#define _O_BINARY 0
+#endif
+
+#include <gtk/gtk.h>
+
+#include "libgimpbase/gimpbase.h"
+
+
+typedef struct _CopyData CopyData;
+
+struct _CopyData
+{
+ const gchar *filename;
+ gboolean file_copied;
+ GError *error;
+};
+
+
+static void test_clipboard_show_version (void) G_GNUC_NORETURN;
+static gboolean test_clipboard_parse_selection (const gchar *option_name,
+ const gchar *value,
+ gpointer data,
+ GError **error);
+static gboolean test_clipboard_list_targets (GtkClipboard *clipboard);
+static gboolean test_clipboard_copy (GtkClipboard *clipboard,
+ const gchar *target,
+ const gchar *filename);
+static gboolean test_clipboard_store (GtkClipboard *clipboard,
+ const gchar *target,
+ const gchar *filename);
+static gboolean test_clipboard_paste (GtkClipboard *clipboard,
+ const gchar *target,
+ const gchar *filename);
+static void test_clipboard_copy_callback (GtkClipboard *clipboard,
+ GtkSelectionData *selection,
+ guint info,
+ gpointer data);
+
+
+static GdkAtom option_selection_type = GDK_SELECTION_CLIPBOARD;
+static gboolean option_list_targets = FALSE;
+static gchar *option_target = NULL;
+static gchar *option_copy_filename = NULL;
+static gchar *option_store_filename = NULL;
+static gchar *option_paste_filename = NULL;
+
+static const GOptionEntry main_entries[] =
+{
+ {
+ "selection-type", 's', 0,
+ G_OPTION_ARG_CALLBACK, test_clipboard_parse_selection,
+ "Selection type (primary|secondary|clipboard)", "<type>"
+ },
+ {
+ "list-targets", 'l', 0,
+ G_OPTION_ARG_NONE, &option_list_targets,
+ "List the targets offered by the clipboard", NULL
+ },
+ {
+ "target", 't', 0,
+ G_OPTION_ARG_STRING, &option_target,
+ "The target format to copy or paste", "<target>"
+ },
+ {
+ "copy", 'c', 0,
+ G_OPTION_ARG_STRING, &option_copy_filename,
+ "Copy <file> to clipboard", "<file>"
+ },
+ {
+ "store", 'S', 0,
+ G_OPTION_ARG_STRING, &option_store_filename,
+ "Store <file> in the clipboard manager", "<file>"
+ },
+ {
+ "paste", 'p', 0,
+ G_OPTION_ARG_STRING, &option_paste_filename,
+ "Paste clipoard into <file> ('-' pastes to STDOUT)", "<file>"
+ },
+ {
+ "version", 'v', G_OPTION_FLAG_NO_ARG,
+ G_OPTION_ARG_CALLBACK, test_clipboard_show_version,
+ "Show version information and exit", NULL
+ },
+ { NULL }
+};
+
+
+gint
+main (gint argc,
+ gchar *argv[])
+{
+ GOptionContext *context;
+ GtkClipboard *clipboard;
+ GError *error = NULL;
+
+ context = g_option_context_new (NULL);
+ g_option_context_add_main_entries (context, main_entries, NULL);
+ g_option_context_add_group (context, gtk_get_option_group (TRUE));
+
+ if (! g_option_context_parse (context, &argc, &argv, &error))
+ {
+ if (error)
+ {
+ g_printerr ("%s\n", error->message);
+ g_error_free (error);
+ }
+ else
+ {
+ g_print ("%s\n",
+ "Could not initialize the graphical user interface.\n"
+ "Make sure a proper setup for your display environment "
+ "exists.");
+ }
+
+ return EXIT_FAILURE;
+ }
+
+ gtk_init (&argc, &argv);
+
+ clipboard = gtk_clipboard_get_for_display (gdk_display_get_default (),
+ option_selection_type);
+
+ if (! clipboard)
+ g_error ("gtk_clipboard_get_for_display");
+
+ if (option_list_targets)
+ {
+ if (! test_clipboard_list_targets (clipboard))
+ return EXIT_FAILURE;
+
+ return EXIT_SUCCESS;
+ }
+
+ if ((option_copy_filename && option_paste_filename) ||
+ (option_copy_filename && option_store_filename) ||
+ (option_paste_filename && option_store_filename))
+ {
+ g_printerr ("Can't perform two operations at the same time\n");
+ return EXIT_FAILURE;
+ }
+
+ if (option_copy_filename)
+ {
+ if (! option_target)
+ {
+ g_printerr ("Usage: %s -t <target> -c <file>\n", argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ if (! test_clipboard_copy (clipboard, option_target,
+ option_copy_filename))
+ return EXIT_FAILURE;
+ }
+
+ if (option_store_filename)
+ {
+ if (! option_target)
+ {
+ g_printerr ("Usage: %s -t <target> -S <file>\n", argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ if (! test_clipboard_store (clipboard, option_target,
+ option_store_filename))
+ return EXIT_FAILURE;
+ }
+
+ if (option_paste_filename)
+ {
+ if (! option_target)
+ {
+ g_printerr ("Usage: %s -t <target> -p <file>\n", argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ if (! test_clipboard_paste (clipboard, option_target,
+ option_paste_filename))
+ return EXIT_FAILURE;
+ }
+
+ return EXIT_SUCCESS;
+}
+
+static void
+test_clipboard_show_version (void)
+{
+ g_print ("gimp-test-clipboard (GIMP clipboard testbed) version %s\n",
+ GIMP_VERSION);
+
+ exit (EXIT_SUCCESS);
+}
+
+static gboolean
+test_clipboard_parse_selection (const gchar *option_name,
+ const gchar *value,
+ gpointer data,
+ GError **error)
+{
+ if (! strcmp (value, "primary"))
+ option_selection_type = GDK_SELECTION_PRIMARY;
+ else if (! strcmp (value, "secondary"))
+ option_selection_type = GDK_SELECTION_SECONDARY;
+ else if (! strcmp (value, "clipboard"))
+ option_selection_type = GDK_SELECTION_CLIPBOARD;
+ else
+ return FALSE;
+
+ return TRUE;
+}
+
+static gboolean
+test_clipboard_list_targets (GtkClipboard *clipboard)
+{
+ GtkSelectionData *data;
+
+ data = gtk_clipboard_wait_for_contents (clipboard,
+ gdk_atom_intern ("TARGETS",
+ FALSE));
+ if (data)
+ {
+ GdkAtom *targets;
+ gint n_targets;
+ gboolean success;
+
+ success = gtk_selection_data_get_targets (data, &targets, &n_targets);
+
+ gtk_selection_data_free (data);
+
+ if (success)
+ {
+ gint i;
+
+ for (i = 0; i < n_targets; i++)
+ g_print ("%s\n", gdk_atom_name (targets[i]));
+
+ g_free (targets);
+ }
+ }
+
+ return TRUE;
+}
+
+static gboolean
+test_clipboard_copy (GtkClipboard *clipboard,
+ const gchar *target,
+ const gchar *filename)
+{
+ GtkTargetEntry entry;
+ CopyData data;
+
+ entry.target = g_strdup (target);
+ entry.flags = 0;
+ entry.info = 1;
+
+ data.filename = filename;
+ data.file_copied = FALSE;
+ data.error = NULL;
+
+ if (! gtk_clipboard_set_with_data (clipboard, &entry, 1,
+ test_clipboard_copy_callback,
+ NULL,
+ &data))
+ {
+ g_printerr ("%s: gtk_clipboard_set_with_data() failed\n",
+ g_get_prgname());
+ return FALSE;
+ }
+
+ gtk_main ();
+
+ if (! data.file_copied)
+ {
+ if (data.error)
+ {
+ g_printerr ("%s: copying failed: %s\n",
+ g_get_prgname (), data.error->message);
+ g_error_free (data.error);
+ }
+ else
+ {
+ g_printerr ("%s: copying failed\n",
+ g_get_prgname ());
+ }
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+test_clipboard_store (GtkClipboard *clipboard,
+ const gchar *target,
+ const gchar *filename)
+{
+ GtkTargetEntry entry;
+ CopyData data;
+
+ entry.target = g_strdup (target);
+ entry.flags = 0;
+ entry.info = 1;
+
+ data.filename = filename;
+ data.file_copied = FALSE;
+ data.error = NULL;
+
+ if (! gtk_clipboard_set_with_data (clipboard, &entry, 1,
+ test_clipboard_copy_callback,
+ NULL,
+ &data))
+ {
+ g_printerr ("%s: gtk_clipboard_set_with_data() failed\n",
+ g_get_prgname ());
+ return FALSE;
+ }
+
+ gtk_clipboard_set_can_store (clipboard, &entry, 1);
+ gtk_clipboard_store (clipboard);
+
+ if (! data.file_copied)
+ {
+ if (data.error)
+ {
+ g_printerr ("%s: storing failed: %s\n",
+ g_get_prgname (), data.error->message);
+ g_error_free (data.error);
+ }
+ else
+ {
+ g_printerr ("%s: could not contact clipboard manager\n",
+ g_get_prgname ());
+ }
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+test_clipboard_paste (GtkClipboard *clipboard,
+ const gchar *target,
+ const gchar *filename)
+{
+ GtkSelectionData *sel_data;
+
+ sel_data = gtk_clipboard_wait_for_contents (clipboard,
+ gdk_atom_intern (target,
+ FALSE));
+ if (sel_data)
+ {
+ const guchar *data;
+ gint length;
+ gint fd;
+
+ if (! strcmp (filename, "-"))
+ fd = 1;
+ else
+ fd = g_open (filename, O_WRONLY | O_CREAT | O_TRUNC | _O_BINARY, 0666);
+
+ if (fd < 0)
+ {
+ g_printerr ("%s: open() filed: %s",
+ g_get_prgname (), g_strerror (errno));
+ return FALSE;
+ }
+
+ data = gtk_selection_data_get_data (sel_data);
+ length = gtk_selection_data_get_length (sel_data);
+
+ if (write (fd, data, length) < length)
+ {
+ close (fd);
+ g_printerr ("%s: write() failed: %s",
+ g_get_prgname (), g_strerror (errno));
+ return FALSE;
+ }
+
+ if (close (fd) < 0)
+ {
+ g_printerr ("%s: close() failed: %s",
+ g_get_prgname (), g_strerror (errno));
+ return FALSE;
+ }
+
+ gtk_selection_data_free (sel_data);
+ }
+
+ return TRUE;
+}
+
+static void
+test_clipboard_copy_callback (GtkClipboard *clipboard,
+ GtkSelectionData *selection,
+ guint info,
+ gpointer data)
+{
+ CopyData *copy_data = data;
+ gchar *buf;
+ gsize buf_size;
+
+ if (! g_file_get_contents (copy_data->filename, &buf, &buf_size,
+ &copy_data->error))
+ {
+ if (! option_store_filename)
+ gtk_main_quit ();
+
+ return;
+ }
+
+ gtk_selection_data_set (selection,
+ gtk_selection_data_get_target (selection),
+ 8, (guchar *) buf, buf_size);
+
+ g_free (buf);
+
+ copy_data->file_copied = TRUE;
+
+ g_print ("%s: data transfer in progress, hit <ctrl>+c when pasted...",
+ G_STRFUNC);
+}