diff options
-rw-r--r-- | gtk/channel-main.c | 10 | ||||
-rw-r--r-- | gtk/channel-main.h | 7 | ||||
-rw-r--r-- | gtk/spice-channel.h | 4 | ||||
-rw-r--r-- | gtk/spice-widget.c | 73 |
4 files changed, 81 insertions, 13 deletions
diff --git a/gtk/channel-main.c b/gtk/channel-main.c index 79cf7e8..a8fa093 100644 --- a/gtk/channel-main.c +++ b/gtk/channel-main.c @@ -343,3 +343,13 @@ void spice_main_set_display(SpiceChannel *channel, int id, agent_monitors_config(channel); } } + +void spice_main_clipboard_grab(SpiceChannel *channel, int *types, int ntypes) +{ + fprintf(stderr, "%s: TODO (%d types)\n", __FUNCTION__, ntypes); +} + +void spice_main_clipboard_release(SpiceChannel *channel) +{ + fprintf(stderr, "%s: TODO\n", __FUNCTION__); +} diff --git a/gtk/channel-main.h b/gtk/channel-main.h index c019607..0e6f2c8 100644 --- a/gtk/channel-main.h +++ b/gtk/channel-main.h @@ -34,6 +34,13 @@ struct _SpiceMainChannelClass { GType spice_main_channel_get_type(void); +enum SpiceMouseMode spice_main_get_mouse_mode(SpiceChannel *channel); +void spice_main_set_display(SpiceChannel *channel, int id, + int x, int y, int width, int height); + +void spice_main_clipboard_grab(SpiceChannel *channel, int *types, int ntypes); +void spice_main_clipboard_release(SpiceChannel *channel); + G_END_DECLS #endif /* __SPICE_CLIENT_MAIN_CHANNEL_H__ */ diff --git a/gtk/spice-channel.h b/gtk/spice-channel.h index e12d792..acec0b6 100644 --- a/gtk/spice-channel.h +++ b/gtk/spice-channel.h @@ -83,10 +83,6 @@ gboolean spice_channel_connect(SpiceChannel *channel); void spice_channel_disconnect(SpiceChannel *channel, enum SpiceChannelEvent event); int spice_channel_id(SpiceChannel *channel); -enum SpiceMouseMode spice_main_get_mouse_mode(SpiceChannel *channel); -void spice_main_set_display(SpiceChannel *channel, int id, - int x, int y, int width, int height); - spice_msg_in *spice_msg_in_new(SpiceChannel *channel); spice_msg_in *spice_msg_in_sub_new(SpiceChannel *channel, spice_msg_in *parent, SpiceSubMessage *sub); diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c index 5ba9217..688e37c 100644 --- a/gtk/spice-widget.c +++ b/gtk/spice-widget.c @@ -11,6 +11,8 @@ #include <gdk/gdkx.h> +#include <spice/vd_agent.h> + #define SPICE_DISPLAY_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), SPICE_TYPE_DISPLAY, spice_display)) @@ -804,6 +806,28 @@ static gboolean configure_event(GtkWidget *widget, GdkEventConfigure *conf) /* ---------------------------------------------------------------- */ +static const struct { + const char *x; + int s; +} atom2agent[] = { + { .s = VD_AGENT_CLIPBOARD_UTF8_TEXT, .x = "UTF8_STRING" }, + { .s = VD_AGENT_CLIPBOARD_UTF8_TEXT, .x = "text/plain;charset=utf-8" }, + { .s = VD_AGENT_CLIPBOARD_UTF8_TEXT, .x = "STRING" }, + { .s = VD_AGENT_CLIPBOARD_UTF8_TEXT, .x = "TEXT" }, + { .s = VD_AGENT_CLIPBOARD_UTF8_TEXT, .x = "text/plain" }, + +#if 0 /* gimp */ + { .s = VD_AGENT_CLIPBOARD_BITMAP, .x = "image/bmp" }, + { .s = VD_AGENT_CLIPBOARD_BITMAP, .x = "image/x-bmp" }, + { .s = VD_AGENT_CLIPBOARD_BITMAP, .x = "image/x-MS-bmp" }, + { .s = VD_AGENT_CLIPBOARD_BITMAP, .x = "image/x-win-bitmap" }, +#endif + +#if 0 /* firefox */ + { .s = VD_AGENT_CLIPBOARD_HTML, .x = "text/html" }, +#endif +}; + static void clipboard_get_targets(GtkClipboard *clipboard, GdkAtom *atoms, gint n_atoms, @@ -811,18 +835,49 @@ static void clipboard_get_targets(GtkClipboard *clipboard, { SpiceDisplay *display = data; spice_display *d = SPICE_DISPLAY_GET_PRIVATE(display); - int i; + int types[SPICE_N_ELEMENTS(atom2agent)]; + char *name; + int a, m, t; #if 1 /* debug */ fprintf(stderr, "%s:", __FUNCTION__); - for (i = 0; i < n_atoms; i++) { - fprintf(stderr, " %s",gdk_atom_name(atoms[i])); + for (a = 0; a < n_atoms; a++) { + fprintf(stderr, " %s",gdk_atom_name(atoms[a])); } fprintf(stderr, "\n"); #endif - fprintf(stderr, "%s: TODO: send vdagent grab\n", __FUNCTION__); - d->clip_grabbed = 1; + memset(types, 0, sizeof(types)); + for (a = 0; a < n_atoms; a++) { + name = gdk_atom_name(atoms[a]); + for (m = 0; m < SPICE_N_ELEMENTS(atom2agent); m++) { + if (strcasecmp(name, atom2agent[m].x) != 0) { + continue; + } + /* found match */ + for (t = 0; t < SPICE_N_ELEMENTS(atom2agent); t++) { + if (types[t] == atom2agent[m].s) { + /* type already in list */ + break; + } + if (types[t] == 0) { + /* add type to empty slot */ + types[t] = atom2agent[m].s; + break; + } + } + break; + } + } + for (t = 0; t < SPICE_N_ELEMENTS(atom2agent); t++) { + if (types[t] == 0) { + break; + } + } + if (!d->clip_grabbed && t > 0) { + d->clip_grabbed = true; + spice_main_clipboard_grab(d->main, types, t); + } } static void clipboard_owner_change(GtkClipboard *clipboard, @@ -833,8 +888,8 @@ static void clipboard_owner_change(GtkClipboard *clipboard, spice_display *d = SPICE_DISPLAY_GET_PRIVATE(display); if (d->clip_grabbed) { - fprintf(stderr, "%s: TODO: send vdagent release\n", __FUNCTION__); - d->clip_grabbed = 0; + d->clip_grabbed = false; + spice_main_clipboard_release(d->main); } switch (event->reason) { @@ -1126,12 +1181,12 @@ void spice_display_copy_to_guest(GtkWidget *widget) SpiceDisplay *display = SPICE_DISPLAY(widget); spice_display *d = SPICE_DISPLAY_GET_PRIVATE(display); - if (d->clip_hasdata) { + if (d->clip_hasdata && !d->clip_grabbed) { gtk_clipboard_request_targets(d->clipboard, clipboard_get_targets, display); } } void spice_display_paste_from_guest(GtkWidget *widget) { - fprintf(stderr, "%s: TODO\n"); + fprintf(stderr, "%s: TODO\n", __FUNCTION__); } |