[Spice-devel] [PATCH spice-gtk 24/25] Add SpiceDisplay:ready property
Marc-André Lureau
marcandre.lureau at gmail.com
Thu Jul 12 15:29:21 PDT 2012
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.
---
gtk/spice-widget-priv.h | 2 ++
gtk/spice-widget.c | 51 +++++++++++++++++++++++++++++++++++++++++------
2 files changed, 47 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 75efa7e..a874fd4 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,
@@ -1476,6 +1506,15 @@ static void spice_display_class_init(SpiceDisplayClass *klass)
G_PARAM_CONSTRUCT |
G_PARAM_STATIC_STRINGS));
+ 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:
*
@@ -1660,7 +1699,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 +1708,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 +1740,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 +1782,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,
--
1.7.10.4
More information about the Spice-devel
mailing list