[Spice-devel] [PATCH spice-gtk 5/5] Teach spicy to use a NBD channel
Marc-André Lureau
marcandre.lureau at gmail.com
Wed Jun 5 08:39:59 PDT 2013
---
gtk/spicy.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 95 insertions(+), 7 deletions(-)
diff --git a/gtk/spicy.c b/gtk/spicy.c
index dff9d44..0b5b1ea 100644
--- a/gtk/spicy.c
+++ b/gtk/spicy.c
@@ -97,6 +97,7 @@ struct spice_connection {
SpiceSession *session;
SpiceGtkSession *gtk_session;
SpiceMainChannel *main;
+ SpiceNbdChannel *nbd_channel;
SpiceWindow *wins[CHANNELID_MAX * MONITORID_MAX];
SpiceAudio *audio;
const char *mouse_state;
@@ -121,6 +122,8 @@ static void del_window(spice_connection *conn, SpiceWindow *win);
static gboolean fullscreen = false;
static gboolean version = false;
static char *spicy_title = NULL;
+static gchar *nbd_file = NULL;
+
/* globals */
static GMainLoop *mainloop = NULL;
static int connections = 0;
@@ -373,6 +376,50 @@ static void menu_cb_connect(GtkAction *action, void *data)
connection_connect(conn);
}
+static void nbd_set_file_finished(GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ SpiceNbdChannel *nbd = SPICE_NBD_CHANNEL(source_object);
+ GError *error = NULL;
+
+ if (!spice_nbd_channel_set_file_finish(nbd, res, &error)) {
+ g_warning("Failed to set NBD file: %s", error->message);
+ g_clear_error(&error);
+ }
+}
+
+static void update_nbd_export(struct spice_connection *conn, const gchar *path)
+{
+ GFile *file = NULL;
+
+ g_message("Update nbd export: %s", path);
+ if (path)
+ file = g_file_new_for_path(path);
+
+ spice_nbd_channel_set_file_async(conn->nbd_channel, file, SPICE_NBD_OPEN_NONE,
+ NULL, nbd_set_file_finished, conn);
+}
+
+static void menu_cb_change_nbd(GtkAction *action, void *data)
+{
+ GtkWidget *chooser;
+ SpiceWindow *win = data;
+
+ chooser = gtk_file_chooser_dialog_new(_("Select disk image"),
+ GTK_WINDOW(win->toplevel),
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+ NULL);
+ if (gtk_dialog_run(GTK_DIALOG(chooser)) == GTK_RESPONSE_ACCEPT) {
+ gchar *path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(chooser));
+ update_nbd_export(win->conn, path);
+ g_free(path);
+ }
+ gtk_widget_destroy(chooser);
+}
+
static void menu_cb_close(GtkAction *action, void *data)
{
SpiceWindow *win = data;
@@ -761,6 +808,10 @@ static const GtkActionEntry entries[] = {
.label = N_("_Connect ..."),
.callback = G_CALLBACK(menu_cb_connect),
},{
+ .name = "ChangeNBD",
+ .label = N_("_Change NBD image"),
+ .callback = G_CALLBACK(menu_cb_change_nbd),
+ },{
.name = "Close",
.stock_id = GTK_STOCK_CLOSE,
.label = N_("_Close"),
@@ -878,6 +929,7 @@ static char ui_xml[] =
" <menuitem action='Connect'/>\n"
" <menu action='FileRecentMenu'/>\n"
" <separator/>\n"
+" <menuitem action='ChangeNBD'/>\n"
" <menuitem action='Close'/>\n"
" </menu>\n"
" <menu action='EditMenu'>\n"
@@ -1322,24 +1374,39 @@ static void display_mark(SpiceChannel *channel, gint mark, SpiceWindow *win)
}
}
-static void update_auto_usbredir_sensitive(spice_connection *conn)
+static void update_action_sensitive(spice_connection *conn,
+ const gchar *action, gboolean sensitive)
{
-#ifdef USE_USBREDIR
int i;
GtkAction *ac;
- gboolean sensitive;
- sensitive = spice_session_has_channel_type(conn->session,
- SPICE_CHANNEL_USBREDIR);
for (i = 0; i < SPICE_N_ELEMENTS(conn->wins); i++) {
if (conn->wins[i] == NULL)
continue;
- ac = gtk_action_group_get_action(conn->wins[i]->ag, "auto-usbredir");
+ ac = gtk_action_group_get_action(conn->wins[i]->ag, action);
gtk_action_set_sensitive(ac, sensitive);
}
+}
+
+static void update_auto_usbredir_sensitive(spice_connection *conn)
+{
+#ifdef USE_USBREDIR
+ gboolean sensitive;
+
+ sensitive = spice_session_has_channel_type(conn->session, SPICE_CHANNEL_USBREDIR);
+ update_action_sensitive(conn, "auto-usbredir", sensitive);
#endif
}
+static void update_nbd_sensitive(spice_connection *conn)
+{
+ gboolean sensitive;
+
+ sensitive = spice_session_has_channel_type(conn->session, SPICE_CHANNEL_NBD);
+ update_action_sensitive(conn, "ChangeNBD", sensitive);
+}
+
+
static SpiceWindow* get_window(spice_connection *conn, int channel_id, int monitor_id)
{
g_return_val_if_fail(channel_id < CHANNELID_MAX, NULL);
@@ -1401,6 +1468,7 @@ static void display_monitors(SpiceChannel *display, GParamSpec *pspec,
G_CALLBACK(display_mark), w, 0);
gtk_widget_show(w->toplevel);
update_auto_usbredir_sensitive(conn);
+ update_nbd_sensitive(conn);
}
}
@@ -1475,6 +1543,7 @@ static void port_opened(SpiceChannel *channel, GParamSpec *pspec,
/* only send a break event and disconnect */
if (g_strcmp0(name, "org.spice.spicy.break") == 0) {
spice_port_event(port, SPICE_PORT_EVENT_BREAK);
+ spice_channel_flush_async(channel, NULL, port_flushed_cb, conn);
}
/* handle the first spicy port and connect it to stdin/out */
@@ -1486,7 +1555,6 @@ static void port_opened(SpiceChannel *channel, GParamSpec *pspec,
if (port == stdin_port)
goto end;
- spice_channel_flush_async(channel, NULL, port_flushed_cb, conn);
} else {
if (port == stdin_port)
stdin_port = NULL;
@@ -1565,6 +1633,15 @@ static void channel_new(SpiceSession *s, SpiceChannel *channel, gpointer data)
G_CALLBACK(port_data), conn);
spice_channel_connect(channel);
}
+
+ if (SPICE_IS_NBD_CHANNEL(channel)) {
+ SpiceNbdChannel *nbd = SPICE_NBD_CHANNEL(channel);
+ update_nbd_sensitive(conn);
+ SPICE_DEBUG("new nbd channel");
+ conn->nbd_channel = nbd;
+ spice_channel_connect(channel);
+ update_nbd_export(conn, nbd_file);
+ }
}
static void channel_destroy(SpiceSession *s, SpiceChannel *channel, gpointer data)
@@ -1593,6 +1670,10 @@ static void channel_destroy(SpiceSession *s, SpiceChannel *channel, gpointer dat
update_auto_usbredir_sensitive(conn);
}
+ if (SPICE_IS_NBD_CHANNEL(channel)) {
+ update_nbd_sensitive(conn);
+ }
+
if (SPICE_IS_PORT_CHANNEL(channel)) {
if (SPICE_PORT_CHANNEL(channel) == stdin_port)
stdin_port = NULL;
@@ -1693,6 +1774,12 @@ static GOptionEntry cmd_entries[] = {
.description = N_("Set the window title"),
.arg_description = N_("<title>"),
},{
+ .long_name = "nbd-file",
+ .arg = G_OPTION_ARG_FILENAME,
+ .arg_data = &nbd_file,
+ .description = N_("image file (for NBD channels)"),
+ .arg_description = N_("<FILE>"),
+ },{
/* end of list */
}
};
@@ -1888,6 +1975,7 @@ int main(int argc, char *argv[])
g_key_file_free(keyfile);
g_free(spicy_title);
+ g_free(nbd_file);
setup_terminal(true);
return 0;
--
1.8.3.rc1.49.g8d97506
More information about the Spice-devel
mailing list