[Spice-devel] [RFC spice-vdagent 7/8] clipboard: move code to send_*() functions
Jakub Janků
janku.jakub.jj at gmail.com
Thu May 31 20:52:24 UTC 2018
---
src/vdagent/clipboard.c | 162 ++++++++++++++++++++++++++--------------
1 file changed, 106 insertions(+), 56 deletions(-)
diff --git a/src/vdagent/clipboard.c b/src/vdagent/clipboard.c
index 63f8527..b8bb0ad 100644
--- a/src/vdagent/clipboard.c
+++ b/src/vdagent/clipboard.c
@@ -96,6 +96,83 @@ static guint get_type_from_atom(GdkAtom atom)
return VD_AGENT_CLIPBOARD_NONE;
}
+static gboolean send_grab(VDAgentClipboards *c, guint sel_id,
+ GdkAtom *atoms, gint n_atoms)
+{
+ if (atoms == NULL)
+ return FALSE;
+
+ switch (c->protocol) {
+ case CLIPBOARD_PROTOCOL_COMPATIBILITY: {
+ Selection *sel = &c->selections[sel_id];
+ guint32 types[G_N_ELEMENTS(atom2agent)];
+ guint type, n_types, a;
+
+ for (type = 0; type < TYPE_COUNT; type++)
+ sel->targets[type] = GDK_NONE;
+
+ n_types = 0;
+ for (a = 0; a < n_atoms; a++) {
+ type = get_type_from_atom(atoms[a]);
+ if (type == VD_AGENT_CLIPBOARD_NONE || sel->targets[type] != GDK_NONE)
+ continue;
+
+ sel->targets[type] = atoms[a];
+ types[n_types] = type;
+ n_types++;
+ }
+
+ if (n_types == 0) {
+ syslog(LOG_WARNING, "%s: sel_id=%u: no target supported", __func__, sel_id);
+ return FALSE;
+ }
+
+ udscs_write(c->conn, VDAGENTD_CLIPBOARD_GRAB, sel_id, 0,
+ (guint8 *)types, n_types * sizeof(guint32));
+ break;
+ }
+ }
+ return TRUE;
+}
+
+static gboolean send_request(VDAgentClipboards *c, guint sel_id, GdkAtom target)
+{
+ switch (c->protocol) {
+ case CLIPBOARD_PROTOCOL_COMPATIBILITY: {
+ guint type = get_type_from_atom(target);
+ g_return_val_if_fail(type != VD_AGENT_CLIPBOARD_NONE, FALSE);
+ udscs_write(c->conn, VDAGENTD_CLIPBOARD_REQUEST, sel_id, type, NULL, 0);
+ break;
+ }
+ }
+ return TRUE;
+}
+
+static void send_data(VDAgentClipboards *c, guint sel_id,
+ GdkAtom type, gint format,
+ const guchar *data, gint data_len)
+{
+ if (c->conn == NULL)
+ return;
+ switch (c->protocol) {
+ case CLIPBOARD_PROTOCOL_COMPATIBILITY:
+ udscs_write(c->conn, VDAGENTD_CLIPBOARD_DATA, sel_id,
+ get_type_from_atom(type), data, data_len);
+ break;
+ }
+}
+
+static void send_release(VDAgentClipboards *c, guint sel_id)
+{
+ if (c->conn == NULL)
+ return;
+ switch (c->protocol) {
+ case CLIPBOARD_PROTOCOL_COMPATIBILITY:
+ udscs_write(c->conn, VDAGENTD_CLIPBOARD_RELEASE, sel_id, 0, NULL, 0);
+ break;
+ }
+}
+
/* gtk_clipboard_request_(, callback, user_data) cannot be cancelled.
Instead, gpointer *ref = request_ref_new() is passed to the callback.
Callback can check using request_ref_is_cancelled(ref)
@@ -143,9 +220,7 @@ static void clipboard_new_owner(VDAgentClipboards *c, guint sel_id, guint new_ow
/* respond to pending client's data requests */
for (l = sel->requests_from_client; l != NULL; l = l->next) {
request_ref_cancel(l->data);
- if (c->conn)
- udscs_write(c->conn, VDAGENTD_CLIPBOARD_DATA,
- sel_id, VD_AGENT_CLIPBOARD_NONE, NULL, 0);
+ send_data(c, sel_id, GDK_NONE, 8, NULL, 0);
}
g_clear_pointer(&sel->requests_from_client, g_list_free);
@@ -161,40 +236,13 @@ static void clipboard_targets_received_cb(GtkClipboard *clipboard,
return;
VDAgentClipboards *c = request_ref_free(user_data);
- Selection *sel;
- guint32 types[G_N_ELEMENTS(atom2agent)];
- guint sel_id, type, n_types, a;
+ guint sel_id;
sel_id = sel_id_from_clip(clipboard);
- sel = &c->selections[sel_id];
- sel->last_targets_req = NULL;
-
- if (atoms == NULL)
- return;
-
- for (type = 0; type < TYPE_COUNT; type++)
- sel->targets[type] = GDK_NONE;
-
- n_types = 0;
- for (a = 0; a < n_atoms; a++) {
- type = get_type_from_atom(atoms[a]);
- if (type == VD_AGENT_CLIPBOARD_NONE || sel->targets[type] != GDK_NONE)
- continue;
-
- sel->targets[type] = atoms[a];
- types[n_types] = type;
- n_types++;
- }
-
- if (n_types == 0) {
- syslog(LOG_WARNING, "%s: sel_id=%u: no target supported", __func__, sel_id);
- return;
- }
-
- clipboard_new_owner(c, sel_id, OWNER_GUEST);
+ c->selections[sel_id].last_targets_req = NULL;
- udscs_write(c->conn, VDAGENTD_CLIPBOARD_GRAB, sel_id, 0,
- (guint8 *)types, n_types * sizeof(guint32));
+ if (send_grab(c, sel_id, atoms, n_atoms))
+ clipboard_new_owner(c, sel_id, OWNER_GUEST);
}
static void clipboard_owner_change_cb(GtkClipboard *clipboard,
@@ -211,7 +259,7 @@ static void clipboard_owner_change_cb(GtkClipboard *clipboard,
if (sel->owner == OWNER_GUEST) {
clipboard_new_owner(c, sel_id, OWNER_NONE);
- udscs_write(c->conn, VDAGENTD_CLIPBOARD_RELEASE, sel_id, 0, NULL, 0);
+ send_release(c, sel_id);
}
if (event->reason != GDK_OWNER_CHANGE_NEW_OWNER)
@@ -234,24 +282,29 @@ static void clipboard_contents_received_cb(GtkClipboard *clipboard,
return;
VDAgentClipboards *c = request_ref_free(user_data);
- guint sel_id, type, target;
+ guint sel_id;
+ GdkAtom target, type;
sel_id = sel_id_from_clip(clipboard);
c->selections[sel_id].requests_from_client =
g_list_remove(c->selections[sel_id].requests_from_client, user_data);
- type = get_type_from_atom(gtk_selection_data_get_data_type(sel_data));
- target = get_type_from_atom(gtk_selection_data_get_target(sel_data));
-
- if (type == target) {
- udscs_write(c->conn, VDAGENTD_CLIPBOARD_DATA, sel_id, type,
- gtk_selection_data_get_data(sel_data),
- gtk_selection_data_get_length(sel_data));
+ target = gtk_selection_data_get_target(sel_data);
+ type = gtk_selection_data_get_data_type(sel_data);
+ if (target == type) {
+ send_data(c, sel_id, type,
+ gtk_selection_data_get_format(sel_data),
+ gtk_selection_data_get_data(sel_data),
+ gtk_selection_data_get_length(sel_data));
} else {
- syslog(LOG_WARNING, "%s: sel_id=%u: expected type %u, recieved %u, "
- "skipping", __func__, sel_id, target, type);
- udscs_write(c->conn, VDAGENTD_CLIPBOARD_DATA, sel_id,
- VD_AGENT_CLIPBOARD_NONE, NULL, 0);
+ gchar *target_str, *type_str;
+ target_str = gdk_atom_name(target);
+ type_str = gdk_atom_name(type);
+ syslog(LOG_WARNING, "%s: sel_id=%u: expected type %s, recieved %s, "
+ "skipping", __func__, sel_id, target_str, type_str);
+ g_free(target_str);
+ g_free(type_str);
+ send_data(c, sel_id, GDK_NONE, 8, NULL, 0);
}
}
@@ -262,21 +315,19 @@ static void clipboard_get_cb(GtkClipboard *clipboard,
{
AppRequest req;
VDAgentClipboards *c = user_data;
- guint sel_id, type;
+ guint sel_id;
sel_id = sel_id_from_clip(clipboard);
g_return_if_fail(c->selections[sel_id].owner == OWNER_CLIENT);
- type = get_type_from_atom(gtk_selection_data_get_target(sel_data));
- g_return_if_fail(type != VD_AGENT_CLIPBOARD_NONE);
+ if (!send_request(c, sel_id, gtk_selection_data_get_target(sel_data)))
+ return;
req.sel_data = sel_data;
req.loop = g_main_loop_new(NULL, FALSE);
c->selections[sel_id].requests_from_apps =
g_list_prepend(c->selections[sel_id].requests_from_apps, &req);
- udscs_write(c->conn, VDAGENTD_CLIPBOARD_REQUEST, sel_id, type, NULL, 0);
-
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
gdk_threads_leave();
g_main_loop_run(req.loop);
@@ -370,8 +421,8 @@ void vdagent_clipboards_release_all(VDAgentClipboards *c)
clipboard_new_owner(c, sel_id, OWNER_NONE);
if (owner == OWNER_CLIENT)
gtk_clipboard_clear(c->selections[sel_id].clipboard);
- else if (owner == OWNER_GUEST && c->conn)
- udscs_write(c->conn, VDAGENTD_CLIPBOARD_RELEASE, sel_id, 0, NULL, 0);
+ else if (owner == OWNER_GUEST)
+ send_release(c, sel_id);
}
}
@@ -399,8 +450,7 @@ void vdagent_clipboard_request(VDAgentClipboards *c, guint sel_id, guint type)
clipboard_contents_received_cb, ref);
return;
err:
- udscs_write(c->conn, VDAGENTD_CLIPBOARD_DATA, sel_id,
- VD_AGENT_CLIPBOARD_NONE, NULL, 0);
+ send_data(c, sel_id, GDK_NONE, 8, NULL, 0);
}
void vdagent_clipboards_set_protocol(VDAgentClipboards *c, guint protocol)
--
2.17.0
More information about the Spice-devel
mailing list