[virt-tools-list] [PATCH virt-viewer 2/4] spice: implement --fullscreen=auto-conf
Marc-André Lureau
marcandre.lureau at gmail.com
Sun Mar 18 18:59:15 UTC 2012
---
src/remote-viewer-main.c | 32 +++++++++++++++++--
src/virt-viewer-app.c | 30 +++++++++++++++---
src/virt-viewer-session-spice.c | 62 +++++++++++++++++++++++++++++++++++++-
src/virt-viewer-session-spice.h | 2 +-
src/virt-viewer-session.c | 30 ++++++++++++++++++-
src/virt-viewer-session.h | 2 +
src/virt-viewer-window.c | 18 ++++++-----
7 files changed, 155 insertions(+), 21 deletions(-)
diff --git a/src/remote-viewer-main.c b/src/remote-viewer-main.c
index 6d26605..d857e45 100644
--- a/src/remote-viewer-main.c
+++ b/src/remote-viewer-main.c
@@ -43,6 +43,28 @@ remote_viewer_version(void)
exit(EXIT_SUCCESS);
}
+gboolean fullscreen = FALSE;
+gboolean fullscreen_auto_conf = FALSE;
+
+static gboolean
+option_fullscreen(G_GNUC_UNUSED const gchar *option_name,
+ const gchar *value,
+ G_GNUC_UNUSED gpointer data, GError **error)
+{
+ fullscreen = TRUE;
+
+ if (value == NULL)
+ return TRUE;
+
+ if (g_str_equal(value, "auto-conf")) {
+ fullscreen_auto_conf = TRUE;
+ return TRUE;
+ }
+
+ g_set_error(error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED, _("Invalid full-screen argument: %s"), value);
+ return FALSE;
+}
+
int
main(int argc, char **argv)
{
@@ -54,7 +76,6 @@ main(int argc, char **argv)
gboolean verbose = FALSE;
gboolean debug = FALSE;
gboolean direct = FALSE;
- gboolean fullscreen = FALSE;
RemoteViewer *viewer = NULL;
#if HAVE_SPICE_GTK
gboolean controller = FALSE;
@@ -72,8 +93,8 @@ main(int argc, char **argv)
N_("Zoom level of window, in percentage"), "ZOOM" },
{ "debug", '\0', 0, G_OPTION_ARG_NONE, &debug,
N_("Display debugging information"), NULL },
- { "full-screen", 'f', 0, G_OPTION_ARG_NONE, &fullscreen,
- N_("Open in full screen mode"), NULL },
+ { "full-screen", 'f', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, option_fullscreen,
+ N_("Open in full screen mode (=<auto-conf>)"), NULL },
#if HAVE_SPICE_GTK
{ "spice-controller", '\0', 0, G_OPTION_ARG_NONE, &controller,
N_("Open connection using Spice controller communication"), NULL },
@@ -144,7 +165,10 @@ main(int argc, char **argv)
goto cleanup;
app = VIRT_VIEWER_APP(viewer);
- g_object_set(app, "fullscreen", fullscreen, NULL);
+ g_object_set(app,
+ "fullscreen", fullscreen,
+ "fullscreen-auto-conf", fullscreen_auto_conf,
+ NULL);
virt_viewer_window_set_zoom_level(virt_viewer_app_get_main_window(app), zoom);
virt_viewer_app_set_direct(app, direct);
diff --git a/src/virt-viewer-app.c b/src/virt-viewer-app.c
index e30df85..9cffedb 100644
--- a/src/virt-viewer-app.c
+++ b/src/virt-viewer-app.c
@@ -116,6 +116,7 @@ struct _VirtViewerAppPrivate {
gboolean authretry;
gboolean started;
gboolean fullscreen;
+ gboolean fullscreen_auto_conf;
gboolean attach;
gboolean quiting;
@@ -157,6 +158,7 @@ enum {
PROP_TITLE,
PROP_ENABLE_ACCEL,
PROP_HAS_FOCUS,
+ PROP_FULLSCREEN_AUTO_CONF,
};
enum {
@@ -684,7 +686,7 @@ virt_viewer_app_create_session(VirtViewerApp *self, const gchar *type)
GtkWindow *window = virt_viewer_window_get_window(priv->main_window);
virt_viewer_app_trace(self, "Guest %s has a %s display\n",
priv->guest_name, type);
- priv->session = virt_viewer_session_spice_new(window);
+ priv->session = virt_viewer_session_spice_new(self, window);
} else
#endif
{
@@ -1170,6 +1172,10 @@ virt_viewer_app_get_property (GObject *object, guint property_id,
g_value_set_boolean(value, priv->focused > 0);
break;
+ case PROP_FULLSCREEN_AUTO_CONF:
+ g_value_set_boolean(value, priv->fullscreen_auto_conf);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
@@ -1218,6 +1224,10 @@ virt_viewer_app_set_property (GObject *object, guint property_id,
priv->enable_accel = g_value_get_boolean(value);
break;
+ case PROP_FULLSCREEN_AUTO_CONF:
+ priv->fullscreen_auto_conf = g_value_get_boolean(value);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
@@ -1377,8 +1387,16 @@ virt_viewer_app_class_init (VirtViewerAppClass *klass)
"Fullscreen",
"Fullscreen",
FALSE,
- G_PARAM_READABLE |
- G_PARAM_WRITABLE |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property(object_class,
+ PROP_FULLSCREEN_AUTO_CONF,
+ g_param_spec_boolean("fullscreen-auto-conf",
+ "auto conf",
+ "Automatic display configuration in full screen",
+ FALSE,
+ G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property(object_class,
@@ -1503,7 +1521,7 @@ static void fullscreen_cb(gpointer key,
DEBUG_LOG("fullscreen display %d: %d", nth, options->fullscreen);
if (options->fullscreen) {
- GdkScreen *screen = gdk_screen_get_default ();
+ GdkScreen *screen = gdk_screen_get_default();
GdkRectangle mon;
if (nth >= gdk_screen_get_n_monitors(screen)) {
@@ -1522,12 +1540,14 @@ virt_viewer_app_set_fullscreen(VirtViewerApp *self, gboolean fullscreen)
VirtViewerAppPrivate *priv = self->priv;
FullscreenOptions options = {
.fullscreen = fullscreen,
- .move = virt_viewer_app_get_n_windows_visible(self) > 1,
+ .move = virt_viewer_app_get_n_windows_visible(self) > 1 || self->priv->fullscreen_auto_conf,
};
/* we iterate unconditionnaly, even if it was set before to update new windows */
priv->fullscreen = fullscreen;
g_hash_table_foreach(priv->windows, fullscreen_cb, &options);
+
+ g_object_notify(G_OBJECT(self), "fullscreen");
}
static void
diff --git a/src/virt-viewer-session-spice.c b/src/virt-viewer-session-spice.c
index a4b3a1f..7d14db4 100644
--- a/src/virt-viewer-session-spice.c
+++ b/src/virt-viewer-session-spice.c
@@ -74,6 +74,7 @@ static void virt_viewer_session_spice_channel_destroy(SpiceSession *s,
VirtViewerSession *session);
static void virt_viewer_session_spice_smartcard_insert(VirtViewerSession *session);
static void virt_viewer_session_spice_smartcard_remove(VirtViewerSession *session);
+static gboolean virt_viewer_session_spice_fullscreen_auto_conf(VirtViewerSessionSpice *self);
static void
virt_viewer_session_spice_get_property(GObject *object, guint property_id,
@@ -394,6 +395,15 @@ virt_viewer_session_spice_usb_device_selection(VirtViewerSession *session,
}
static void
+agent_connected_changed(SpiceChannel *cmain,
+ GParamSpec *pspec G_GNUC_UNUSED,
+ VirtViewerSessionSpice *self)
+{
+ if (virt_viewer_session_spice_fullscreen_auto_conf(self))
+ g_signal_handlers_disconnect_by_func(cmain, agent_connected_changed, self);
+}
+
+static void
virt_viewer_session_spice_channel_new(SpiceSession *s,
SpiceChannel *channel,
VirtViewerSession *session)
@@ -416,6 +426,9 @@ virt_viewer_session_spice_channel_new(SpiceSession *s,
g_signal_connect(channel, "channel-event",
G_CALLBACK(virt_viewer_session_spice_main_channel_event), self);
self->priv->main_channel = SPICE_MAIN_CHANNEL(channel);
+
+ g_signal_connect(channel, "notify::agent-connected", G_CALLBACK(agent_connected_changed), self);
+ agent_connected_changed(channel, NULL, self);
}
if (SPICE_IS_DISPLAY_CHANNEL(channel)) {
@@ -447,6 +460,41 @@ virt_viewer_session_spice_channel_new(SpiceSession *s,
self->priv->channel_count++;
}
+static gboolean
+virt_viewer_session_spice_fullscreen_auto_conf(VirtViewerSessionSpice *self)
+{
+ GdkScreen *screen = gdk_screen_get_default();
+ SpiceMainChannel* cmain = virt_viewer_session_spice_get_main_channel(self);
+ VirtViewerApp *app = NULL;
+ GdkRectangle dest;
+ gboolean auto_conf, agent_connected;
+ gint i;
+
+ app = virt_viewer_session_get_app(VIRT_VIEWER_SESSION(self));
+ g_return_val_if_fail(VIRT_VIEWER_IS_APP(app), TRUE);
+
+ g_object_get(app, "fullscreen-auto-conf", &auto_conf, NULL);
+ if (!auto_conf)
+ return TRUE;
+
+ if (cmain == NULL)
+ return FALSE;
+
+ g_object_get(cmain, "agent-connected", &agent_connected, NULL);
+ if (!agent_connected)
+ return FALSE;
+
+ spice_main_set_display_enabled(cmain, -1, FALSE);
+ for (i = 0; i < gdk_screen_get_n_monitors(screen); i++) {
+ gdk_screen_get_monitor_geometry(screen, i, &dest);
+ spice_main_set_display(cmain, i, dest.x, dest.y, dest.width, dest.height);
+ spice_main_set_display_enabled(cmain, i, TRUE);
+ }
+
+ spice_main_send_monitor_config(cmain);
+ return TRUE;
+}
+
static void
virt_viewer_session_spice_channel_destroy(G_GNUC_UNUSED SpiceSession *s,
SpiceChannel *channel,
@@ -479,16 +527,26 @@ virt_viewer_session_spice_channel_destroy(G_GNUC_UNUSED SpiceSession *s,
g_signal_emit_by_name(self, "session-disconnected");
}
+static void
+fullscreen_changed(GObject *gobject G_GNUC_UNUSED,
+ GParamSpec *pspec G_GNUC_UNUSED,
+ VirtViewerSessionSpice *self)
+{
+ virt_viewer_session_spice_fullscreen_auto_conf(self);
+}
+
VirtViewerSession *
-virt_viewer_session_spice_new(GtkWindow *main_window)
+virt_viewer_session_spice_new(VirtViewerApp *app, GtkWindow *main_window)
{
VirtViewerSessionSpice *self;
- self = g_object_new(VIRT_VIEWER_TYPE_SESSION_SPICE, NULL);
+ self = g_object_new(VIRT_VIEWER_TYPE_SESSION_SPICE, "app", app, NULL);
create_spice_session(self);
self->priv->main_window = g_object_ref(main_window);
+ g_signal_connect(app, "notify::fullscreen", G_CALLBACK(fullscreen_changed), self);
+
return VIRT_VIEWER_SESSION(self);
}
diff --git a/src/virt-viewer-session-spice.h b/src/virt-viewer-session-spice.h
index f0d7e89..95bdcdf 100644
--- a/src/virt-viewer-session-spice.h
+++ b/src/virt-viewer-session-spice.h
@@ -65,7 +65,7 @@ struct _VirtViewerSessionSpiceClass {
GType virt_viewer_session_spice_get_type(void);
-VirtViewerSession* virt_viewer_session_spice_new(GtkWindow *main_window);
+VirtViewerSession* virt_viewer_session_spice_new(VirtViewerApp *app, GtkWindow *main_window);
SpiceMainChannel* virt_viewer_session_spice_get_main_channel(VirtViewerSessionSpice *self);
G_END_DECLS
diff --git a/src/virt-viewer-session.c b/src/virt-viewer-session.c
index c0d6e65..f139c48 100644
--- a/src/virt-viewer-session.c
+++ b/src/virt-viewer-session.c
@@ -35,7 +35,7 @@
struct _VirtViewerSessionPrivate
{
GList *displays;
-
+ VirtViewerApp *app;
gboolean auto_usbredir;
};
@@ -44,6 +44,7 @@ G_DEFINE_ABSTRACT_TYPE(VirtViewerSession, virt_viewer_session, G_TYPE_OBJECT)
enum {
PROP_0,
+ PROP_APP,
PROP_AUTO_USBREDIR,
};
@@ -74,6 +75,11 @@ virt_viewer_session_set_property(GObject *object,
case PROP_AUTO_USBREDIR:
virt_viewer_session_set_auto_usbredir(self, g_value_get_boolean(value));
break;
+
+ case PROP_APP:
+ self->priv->app = g_value_get_object(value);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
@@ -92,6 +98,11 @@ virt_viewer_session_get_property(GObject *object,
case PROP_AUTO_USBREDIR:
g_value_set_boolean(value, virt_viewer_session_get_auto_usbredir(self));
break;
+
+ case PROP_APP:
+ g_value_set_object(value, self->priv->app);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
@@ -117,6 +128,16 @@ virt_viewer_session_class_init(VirtViewerSessionClass *class)
G_PARAM_CONSTRUCT |
G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property(object_class,
+ PROP_APP,
+ g_param_spec_object("app",
+ "VirtViewerApp",
+ "VirtViewerApp",
+ VIRT_VIEWER_TYPE_APP,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
g_signal_new("session-connected",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_FIRST,
@@ -408,6 +429,13 @@ void virt_viewer_session_smartcard_remove(VirtViewerSession *self)
klass->smartcard_remove(self);
}
+VirtViewerApp* virt_viewer_session_get_app(VirtViewerSession *self)
+{
+ g_return_val_if_fail(VIRT_VIEWER_IS_SESSION(self), NULL);
+
+ return self->priv->app;
+}
+
/*
* Local variables:
* c-indent-level: 4
diff --git a/src/virt-viewer-session.h b/src/virt-viewer-session.h
index c20f23d..c53c8b5 100644
--- a/src/virt-viewer-session.h
+++ b/src/virt-viewer-session.h
@@ -26,6 +26,7 @@
#include <gtk/gtk.h>
+#include "virt-viewer-app.h"
#include "virt-viewer-display.h"
G_BEGIN_DECLS
@@ -118,6 +119,7 @@ gboolean virt_viewer_session_has_usb(VirtViewerSession *self);
void virt_viewer_session_usb_device_selection(VirtViewerSession *self, GtkWindow *parent);
void virt_viewer_session_smartcard_insert(VirtViewerSession *self);
void virt_viewer_session_smartcard_remove(VirtViewerSession *self);
+VirtViewerApp* virt_viewer_session_get_app(VirtViewerSession *self);
G_END_DECLS
diff --git a/src/virt-viewer-window.c b/src/virt-viewer-window.c
index f539fb5..62b6052 100644
--- a/src/virt-viewer-window.c
+++ b/src/virt-viewer-window.c
@@ -493,15 +493,17 @@ virt_viewer_window_enter_fullscreen(VirtViewerWindow *self, gboolean move, gint
priv->before_saved = TRUE;
}
- if (!priv->fullscreen) {
- gtk_check_menu_item_set_active(check, TRUE);
- priv->fullscreen = TRUE;
- gtk_widget_hide(menu);
- gtk_widget_show(priv->toolbar);
- ViewAutoDrawer_SetActive(VIEW_AUTODRAWER(priv->layout), TRUE);
- ViewAutoDrawer_Close(VIEW_AUTODRAWER(priv->layout));
- }
+ if (priv->fullscreen)
+ return;
+ priv->fullscreen = TRUE;
+
+ gtk_check_menu_item_set_active(check, TRUE);
+ gtk_widget_hide(menu);
+ gtk_widget_show(priv->toolbar);
+ ViewAutoDrawer_SetActive(VIEW_AUTODRAWER(priv->layout), TRUE);
+ ViewAutoDrawer_Close(VIEW_AUTODRAWER(priv->layout));
+ /* g_debug("enter fullscreen move:%d %d+%d", move, x, y); */
if (move)
gtk_window_move(GTK_WINDOW(priv->window), x, y);
--
1.7.7.6
More information about the virt-tools-list
mailing list