372 lines
8.6 KiB
C
372 lines
8.6 KiB
C
|
#include <gtk/gtk.h>
|
||
|
|
||
|
#ifdef GDK_WINDOWING_WAYLAND
|
||
|
#include "wayland/gdkwayland.h"
|
||
|
#endif
|
||
|
|
||
|
#ifdef G_OS_WIN32
|
||
|
#include <io.h>
|
||
|
#include <process.h>
|
||
|
#endif
|
||
|
|
||
|
G_GNUC_NORETURN 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);
|
||
|
}
|
||
|
|
||
|
G_GNUC_NORETURN 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);
|
||
|
}
|
||
|
|
||
|
G_GNUC_NORETURN 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);
|
||
|
}
|
||
|
|
||
|
G_GNUC_NORETURN 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);
|
||
|
}
|
||
|
|
||
|
G_GNUC_NORETURN 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);
|
||
|
}
|
||
|
|
||
|
G_GNUC_NORETURN 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;
|
||
|
|
||
|
if (object)
|
||
|
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[])
|
||
|
{
|
||
|
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 ()))
|
||
|
{
|
||
|
GtkWidget *window;
|
||
|
|
||
|
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;
|
||
|
}
|