[Spice-devel] [PATCH spice-gtk 2/3] move SpiceDisplayConfig from main channel to session
Pavel Grunt
pgrunt at redhat.com
Tue Jul 26 15:55:44 UTC 2016
It helps to get the real display configuration from display channels
instead of relying on the last requested monitor config.
Related: https://bugs.freedesktop.org/show_bug.cgi?id=94950
---
src/channel-main.c | 32 +++++++++-----------------
src/spice-session-priv.h | 17 ++++++++++++++
src/spice-session.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 86 insertions(+), 21 deletions(-)
diff --git a/src/channel-main.c b/src/channel-main.c
index 26192ed..cf43649 100644
--- a/src/channel-main.c
+++ b/src/channel-main.c
@@ -54,20 +54,6 @@
typedef struct spice_migrate spice_migrate;
-typedef enum {
- DISPLAY_UNDEFINED,
- DISPLAY_DISABLED,
- DISPLAY_ENABLED,
-} SpiceDisplayState;
-
-typedef struct {
- int x;
- int y;
- int width;
- int height;
- SpiceDisplayState display_state;
-} SpiceDisplayConfig;
-
typedef struct {
GHashTable *xfer_task;
SpiceMainChannel *channel;
@@ -2552,6 +2538,8 @@ void spice_main_update_display(SpiceMainChannel *channel, int id,
gboolean update)
{
SpiceMainChannelPrivate *c;
+ SpiceSession *session;
+ SpiceDisplayConfig display;
g_return_if_fail(channel != NULL);
g_return_if_fail(SPICE_IS_MAIN_CHANNEL(channel));
@@ -2564,15 +2552,17 @@ void spice_main_update_display(SpiceMainChannel *channel, int id,
g_return_if_fail(id < SPICE_N_ELEMENTS(c->display));
- SpiceDisplayConfig display = {
- .x = x, .y = y, .width = width, .height = height,
- .display_state = c->display[id].display_state
- };
+ c->display[id].x = x;
+ c->display[id].y = y;
+ c->display[id].width = width;
+ c->display[id].height = height;
- if (memcmp(&display, &c->display[id], sizeof(SpiceDisplayConfig)) == 0)
+ session = spice_channel_get_session(SPICE_CHANNEL(channel));
+ if (spice_session_get_display_config(session, id, &display) &&
+ memcmp(&display, &c->display[id], sizeof(SpiceDisplayConfig)) == 0) {
+ SPICE_DEBUG("new monitor config matches current config");
return;
-
- c->display[id] = display;
+ }
if (update)
update_display_timer(channel, 1);
diff --git a/src/spice-session-priv.h b/src/spice-session-priv.h
index 049973a..4e6bec4 100644
--- a/src/spice-session-priv.h
+++ b/src/spice-session-priv.h
@@ -37,6 +37,20 @@ typedef struct _PhodavServer PhodavServer;
G_BEGIN_DECLS
+typedef enum {
+ DISPLAY_UNDEFINED,
+ DISPLAY_DISABLED,
+ DISPLAY_ENABLED,
+} SpiceDisplayState;
+
+typedef struct {
+ int x;
+ int y;
+ int width;
+ int height;
+ SpiceDisplayState display_state;
+} SpiceDisplayConfig;
+
#define WEBDAV_MAGIC_SIZE 16
SpiceSession *spice_session_new_from_session(SpiceSession *session);
@@ -99,6 +113,9 @@ guint spice_session_get_n_display_channels(SpiceSession *session);
void spice_session_set_main_channel(SpiceSession *session, SpiceChannel *channel);
gboolean spice_session_set_migration_session(SpiceSession *session, SpiceSession *mig_session);
SpiceAudio *spice_audio_get(SpiceSession *session, GMainContext *context);
+gboolean spice_session_get_display_config(const SpiceSession *session,
+ const guint id,
+ SpiceDisplayConfig *config);
G_END_DECLS
#endif /* __SPICE_CLIENT_SESSION_PRIV_H__ */
diff --git a/src/spice-session.c b/src/spice-session.c
index db283d4..c276227 100644
--- a/src/spice-session.c
+++ b/src/spice-session.c
@@ -2785,3 +2785,61 @@ gboolean spice_session_set_migration_session(SpiceSession *session, SpiceSession
return TRUE;
}
+
+
+static void display_monitor_config_to_display_config(const SpiceDisplayMonitorConfig *monitor,
+ SpiceDisplayConfig *config)
+{
+ config->x = monitor->x;
+ config->y = monitor->y;
+ config->width = monitor->width;
+ config->height = monitor->height;
+ if (monitor->width > 0 && monitor->height > 0)
+ config->display_state = DISPLAY_ENABLED;
+ else
+ config->display_state = DISPLAY_DISABLED;
+}
+
+/*
+ * spice_session_get_display_config:
+ * @session: a Spice session
+ * @id: a display id (zero based)
+ * @config: a #SpiceDisplayConfig to store result
+ *
+ * Goes through all display channels until it finds a display configuration
+ * for display by given id
+ *
+ * Returns: %FALSE if display with the specified id does not exists
+ **/
+G_GNUC_INTERNAL
+gboolean spice_session_get_display_config(const SpiceSession *session,
+ const guint id,
+ SpiceDisplayConfig *config)
+{
+ RingItem *item;
+ struct channel *c;
+ guint checked_displays = 0;
+
+ RING_FOREACH(item, &session->priv->channels) {
+ c = SPICE_CONTAINEROF(item, struct channel, link);
+ if (SPICE_IS_DISPLAY_CHANNEL(c->channel)) {
+ guint monitors_max;
+ g_object_get(c->channel, "monitors-max", &monitors_max, NULL);
+ if (id < checked_displays + monitors_max) {
+ const guint index = id - checked_displays;
+ GArray *monitors = NULL;
+ g_object_get(c->channel, "monitors", &monitors, NULL);
+ if (index < monitors->len) {
+ SpiceDisplayMonitorConfig *monitor;
+ monitor = &g_array_index(monitors, SpiceDisplayMonitorConfig, index);
+ display_monitor_config_to_display_config(monitor, config);
+ }
+ g_array_unref(monitors);
+ return (index < monitors->len); /* monitor has been created for the channel */
+ }
+ checked_displays += monitors_max;
+ }
+ }
+
+ return FALSE;
+}
--
2.9.2
More information about the Spice-devel
mailing list