summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYonit Halperin <yhalperi@redhat.com>2013-05-10 16:15:01 -0400
committerAlon Levy <alon@pobox.com>2013-05-13 17:40:55 +0300
commitd2894d192c43dd151436a9d62dc6fcc68d953296 (patch)
tree3a9d90e9dbf7578609f514fdd41dfc9c827ac516
parentde25afdca7fecd69f9ac79f6a2de0c00d02b4f4a (diff)
spice-session: new signal for notifying on a significant change in mm-time
mm-time can change after migration. This can cause video synchronization problems after migration if not handled appropriately (see rhbz#951664).
-rw-r--r--gtk/spice-session.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/gtk/spice-session.c b/gtk/spice-session.c
index f46ac01..8f4e1bd 100644
--- a/gtk/spice-session.c
+++ b/gtk/spice-session.c
@@ -115,11 +115,26 @@ enum {
enum {
SPICE_SESSION_CHANNEL_NEW,
SPICE_SESSION_CHANNEL_DESTROY,
+ SPICE_SESSION_MM_TIME_RESET,
SPICE_SESSION_LAST_SIGNAL,
};
static guint signals[SPICE_SESSION_LAST_SIGNAL];
+struct SPICE_SESSION_MM_TIME_RESET {
+};
+
+/* main context */
+static void do_emit_main_context(GObject *object, int signum, gpointer params)
+{
+ switch (signum) {
+ case SPICE_SESSION_MM_TIME_RESET:
+ g_signal_emit(object, signals[signum], 0);
+ break;
+ default:
+ g_warn_if_reached();
+ }
+}
static void update_proxy(SpiceSession *self, const gchar *str)
{
@@ -1071,6 +1086,23 @@ static void spice_session_class_init(SpiceSessionClass *klass)
SPICE_TYPE_CHANNEL);
/**
+ * SpiceSession::mm-time-reset:
+ * @session: the session that emitted the signal
+ *
+ * The #SpiceSession::mm-time-reset is emitted when we identify discontinuity in mm-time
+ *
+ * Since 0.20
+ **/
+ signals[SPICE_SESSION_MM_TIME_RESET] =
+ g_signal_new("mm-time-reset",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ /**
* SpiceSession:read-only:
*
* Whether this connection is read-only mode.
@@ -1927,16 +1959,26 @@ guint32 spice_session_get_mm_time(SpiceSession *session)
return s->mm_time + (g_get_monotonic_time() - s->mm_time_at_clock) / 1000;
}
+#define MM_TIME_DIFF_RESET_THRESH 500 // 0.5 sec
+
G_GNUC_INTERNAL
void spice_session_set_mm_time(SpiceSession *session, guint32 time)
{
SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session);
+ guint32 old_time;
g_return_if_fail(s != NULL);
+ old_time = spice_session_get_mm_time(session);
+
s->mm_time = time;
s->mm_time_at_clock = g_get_monotonic_time();
SPICE_DEBUG("set mm time: %u", spice_session_get_mm_time(session));
+ if (time > old_time + MM_TIME_DIFF_RESET_THRESH ||
+ time < old_time) {
+ SPICE_DEBUG("%s: mm-time-reset, old %u, new %u", __FUNCTION__, old_time, s->mm_time);
+ emit_main_context(session, SPICE_SESSION_MM_TIME_RESET);
+ }
}
G_GNUC_INTERNAL