summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc-André Lureau <marcandre.lureau@redhat.com>2012-07-05 01:24:44 +0200
committerMarc-André Lureau <marcandre.lureau@redhat.com>2012-07-16 17:46:41 +0200
commit2a2900267f4f1b94213e856c793509d897cb50cd (patch)
tree0c50c56d0505eead358753ace8fd72cdd3bf0776
parentfe842771b2e2400fbc5ba8efd74550cde44276ee (diff)
Add SpiceDisplay:ready property
There are several condition to meet in order to have a widget ready to be displayed: the monitor must exist, the area must intersect, and the display mark must be reached. This property will help clients to know when the widget display is ready. Until now, it was relying on the channel mark signal only, and had to deal with the rest of the conditions without much help.
-rw-r--r--gtk/spice-widget-priv.h2
-rw-r--r--gtk/spice-widget.c60
2 files changed, 56 insertions, 6 deletions
diff --git a/gtk/spice-widget-priv.h b/gtk/spice-widget-priv.h
index a44e5fe..87cf34e 100644
--- a/gtk/spice-widget-priv.h
+++ b/gtk/spice-widget-priv.h
@@ -52,6 +52,8 @@ struct _SpiceDisplayPrivate {
bool resize_guest_enable;
/* state */
+ gboolean ready;
+ gboolean monitor_ready;
enum SpiceSurfaceFmt format;
gint width, height, stride;
gint shmid;
diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c
index 048770c..5c12db9 100644
--- a/gtk/spice-widget.c
+++ b/gtk/spice-widget.c
@@ -102,7 +102,8 @@ enum {
PROP_SCALING,
PROP_DISABLE_INPUTS,
PROP_ZOOM_LEVEL,
- PROP_MONITOR_ID
+ PROP_MONITOR_ID,
+ PROP_READY
};
/* Signals */
@@ -175,6 +176,9 @@ static void spice_display_get_property(GObject *object,
case PROP_ZOOM_LEVEL:
g_value_set_int(value, d->zoom_level);
break;
+ case PROP_READY:
+ g_value_set_boolean(value, d->ready);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
@@ -227,6 +231,31 @@ static void update_keyboard_focus(SpiceDisplay *display, gboolean state)
spice_gtk_session_request_auto_usbredir(d->gtk_session, state);
}
+static void update_ready(SpiceDisplay *display)
+{
+ SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
+ gboolean ready;
+
+ ready = d->mark != 0 && d->monitor_ready;
+
+ if (d->ready == ready)
+ return;
+
+ if (ready && gtk_widget_get_window(GTK_WIDGET(display)))
+ gtk_widget_queue_draw(GTK_WIDGET(display));
+
+ d->ready = ready;
+ g_object_notify(G_OBJECT(display), "ready");
+}
+
+static void set_monitor_ready(SpiceDisplay *self, gboolean ready)
+{
+ SpiceDisplayPrivate *d = self->priv;
+
+ d->monitor_ready = ready;
+ update_ready(self);
+}
+
static void update_monitor_area(SpiceDisplay *display)
{
SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
@@ -240,11 +269,11 @@ static void update_monitor_area(SpiceDisplay *display)
g_object_get(d->display, "monitors", &monitors, NULL);
if (monitors == NULL || d->monitor_id >= monitors->len) {
SPICE_DEBUG("update monitor: no monitor %d", d->monitor_id);
+ set_monitor_ready(display, false);
if (spice_channel_test_capability(d->display, SPICE_DISPLAY_CAP_MONITORS_CONFIG)) {
SPICE_DEBUG("waiting until MonitorsConfig is received");
return;
}
- /* FIXME: mark false */
goto whole;
}
@@ -263,6 +292,7 @@ static void update_monitor_area(SpiceDisplay *display)
whole:
/* by display whole surface */
update_area(display, 0, 0, d->width, d->height);
+ set_monitor_ready(display, true);
}
static void spice_display_set_property(GObject *object,
@@ -1477,6 +1507,24 @@ static void spice_display_class_init(SpiceDisplayClass *klass)
G_PARAM_STATIC_STRINGS));
/**
+ * SpiceDisplay:ready:
+ *
+ * Indicate whether the display is ready to be shown. It takes
+ * into account several conditions, such as the channel display
+ * "mark" state, whether the monitor area is visible..
+ *
+ * Since: 0.13
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_READY,
+ g_param_spec_boolean("ready",
+ "Ready",
+ "Ready to display",
+ FALSE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
* SpiceDisplay:auto-clipboard:
*
* When this is true the clipboard gets automatically shared between host
@@ -1660,7 +1708,7 @@ static void update_area(SpiceDisplay *display,
if (!gdk_rectangle_intersect(&primary, &area, &area)) {
SPICE_DEBUG("The monitor area is not intersecting primary surface");
memset(&d->area, '\0', sizeof(d->area));
- /* FIXME mark false? */
+ set_monitor_ready(display, false);
return;
}
@@ -1669,7 +1717,7 @@ static void update_area(SpiceDisplay *display,
spicex_image_create(display);
update_size_request(display);
- gtk_widget_queue_draw(GTK_WIDGET(display));
+ set_monitor_ready(display, true);
}
static void primary_create(SpiceChannel *channel, gint format,
@@ -1701,6 +1749,7 @@ static void primary_destroy(SpiceChannel *channel, gpointer data)
d->shmid = 0;
d->data = NULL;
d->data_origin = NULL;
+ set_monitor_ready(display, false);
}
static void invalidate(SpiceChannel *channel,
@@ -1742,8 +1791,7 @@ static void mark(SpiceDisplay *display, gint mark)
SPICE_DEBUG("widget mark: %d, %d:%d %p", mark, d->channel_id, d->monitor_id, display);
d->mark = mark;
spice_main_set_display_enabled(d->main, get_display_id(display), d->mark != 0);
- if (mark != 0 && gtk_widget_get_window(GTK_WIDGET(display)))
- gtk_widget_queue_draw(GTK_WIDGET(display));
+ update_ready(display);
}
static void cursor_set(SpiceCursorChannel *channel,