From 31f26c2915caa6320af74ba73ebf71491ab80fa3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 21 Oct 2007 17:54:45 +0200 Subject: Basic autoconfization --- src/lassi-clipboard.c | 174 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 src/lassi-clipboard.c (limited to 'src/lassi-clipboard.c') diff --git a/src/lassi-clipboard.c b/src/lassi-clipboard.c new file mode 100644 index 0000000..bdfeff4 --- /dev/null +++ b/src/lassi-clipboard.c @@ -0,0 +1,174 @@ +#include +#include + +#include "lassi-server.h" + +#define LASSI_MARKER "application/x-mango-lassi-marker" + +static void targets_received(GtkClipboard *clipboard, GdkAtom *atoms, int n_atoms, gpointer userdata) { + int j, k; + LassiClipboardInfo *i = userdata; + char **targets; + + g_assert(clipboard); + g_assert(i); + + g_debug("recvd targs %p, %i", atoms, n_atoms); + + if (!atoms) + return; + + targets = g_new0(char*, n_atoms+1); + + for (j = 0, k = 0; j < n_atoms; j++) { + char *c = gdk_atom_name(atoms[j]); + + /* Avoid loops */ + if (strcmp(c, LASSI_MARKER) == 0) { + g_free(c); + goto fail; + } + + if (strcmp(c, "TIMESTAMP") == 0 || + strcmp(c, "TARGETS") == 0 || + strcmp(c, "CLIPBOARD_MANAGER") == 0 || + strcmp(c, "CLIENT_WINDOW") == 0 || + strcmp(c, "DELETE") == 0 || + strcmp(c, "INSERT_PROPERTY") == 0 || + strcmp(c, "INSERT_SELECTION") == 0 || + strcmp(c, "LENGTH") == 0 || + strcmp(c, "TASK") == 0 || + strcmp(c, "MULTIPLE") == 0 || + strcmp(c, "DRAWABLE") == 0) { + g_free(c); + continue; + } + + targets[k++] = c; + } + + g_debug("%p %i", targets, n_atoms); + lassi_server_acquire_clipboard(i->server, clipboard == i->primary, targets); + +fail: + g_strfreev(targets); +} + +static void owner_change(GtkClipboard *clipboard, GdkEventOwnerChange *event, gpointer userdata) { + LassiClipboardInfo *i = userdata; + + g_assert(clipboard); + g_assert(i); + + g_debug("owner change"); + + if (event->reason == GDK_OWNER_CHANGE_NEW_OWNER) + gtk_clipboard_request_targets(clipboard, targets_received, i); + else + lassi_server_return_clipboard(i->server, clipboard == i->primary); +} + +static void get_func(GtkClipboard *clipboard, GtkSelectionData *sd, guint info, gpointer userdata) { + LassiClipboardInfo *i = userdata; + char *t; + int f = 0; + gpointer d = NULL; + gint l = 0; + + g_assert(clipboard); + g_assert(i); + + t = gdk_atom_name(sd->target); + + g_debug("get(%s)", t); + + if (lassi_server_get_clipboard(i->server, clipboard == i->primary, t, &f, &d, &l) >= 0) { + g_debug("successfully got data"); + gtk_selection_data_set(sd, sd->target, f, d, l); + } else + g_debug("failed to get data"); + + g_free(d); + g_free(t); +} + +static void clear_func(GtkClipboard *clipboard, gpointer userdata) { + LassiClipboardInfo *i = userdata; + + g_assert(clipboard); + g_assert(i); + + g_debug("clear"); + + gtk_clipboard_request_targets(clipboard, targets_received, i); +} + +int lassi_clipboard_init(LassiClipboardInfo *i, LassiServer *s) { + g_assert(i); + g_assert(s); + + memset(i, 0, sizeof(*i)); + i->server = s; + + i->clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); + i->primary = gtk_clipboard_get(GDK_SELECTION_PRIMARY); + + g_signal_connect(i->clipboard, "owner_change", G_CALLBACK(owner_change), i); + g_signal_connect(i->primary, "owner_change", G_CALLBACK(owner_change), i); + return 0; +} + +void lassi_clipboard_done(LassiClipboardInfo *i) { + g_assert(i); + + memset(i, 0, sizeof(*i)); +} + +void lassi_clipboard_set(LassiClipboardInfo *i, gboolean primary, char *targets[]) { + int n = 0, j; + gboolean b; + char **t; + GtkTargetEntry *e; + + for (t = targets; *t; t++) + n++; + + e = g_new0(GtkTargetEntry, n+1); + + for (t = targets, j = 0; *t; t++, j++) { + e[j].target = *t; + e[j].info = j; + } + + e[j].target = LASSI_MARKER; + e[j].info = j; + + g_debug("setting %i targets", n+1); + + b = gtk_clipboard_set_with_data(primary ? i->primary : i->clipboard, e, n+1, get_func, clear_func, i); + g_assert(b); +} + +void lassi_clipboard_clear(LassiClipboardInfo *i, gboolean primary) { + g_assert(i); + + gtk_clipboard_clear(primary ? i->primary : i->clipboard); +} + +int lassi_clipboard_get(LassiClipboardInfo *i, gboolean primary, const char *target, int *f, gpointer *p, int *l) { + GtkSelectionData*sd; + g_assert(i); + + if (!(sd = gtk_clipboard_wait_for_contents(primary ? i->primary : i->clipboard, gdk_atom_intern(target, TRUE)))) + return -1; + + g_assert(sd->length > 0); + + *f = sd->format; + *p = g_memdup(sd->data, sd->length); + *l = sd->length; + + gtk_selection_data_free(sd); + + return 0; +} -- cgit