[Spice-devel] [PATCH spice-gtk 20/25] widget: use display monitors configuration
Marc-André Lureau
marcandre.lureau at gmail.com
Thu Jul 12 15:29:17 PDT 2012
Use display::monitors property to manage display area. Call
update_area_monitor() to update the widget area depending on monitor
configuration
---
gtk/spice-widget.c | 65 ++++++++++++++++++++++++++++++++++++++++++++--------
spice-common | 2 +-
2 files changed, 57 insertions(+), 10 deletions(-)
diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c
index 6b4ae96..75efa7e 100644
--- a/gtk/spice-widget.c
+++ b/gtk/spice-widget.c
@@ -130,6 +130,7 @@ static void channel_new(SpiceSession *s, SpiceChannel *channel, gpointer data);
static void channel_destroy(SpiceSession *s, SpiceChannel *channel, gpointer data);
static void sync_keyboard_lock_modifiers(SpiceDisplay *display);
static void cursor_invalidate(SpiceDisplay *display);
+static void update_area(SpiceDisplay *display, gint x, gint y, gint width, gint height);
/* ---------------------------------------------------------------- */
@@ -226,6 +227,44 @@ static void update_keyboard_focus(SpiceDisplay *display, gboolean state)
spice_gtk_session_request_auto_usbredir(d->gtk_session, state);
}
+static void update_monitor_area(SpiceDisplay *display)
+{
+ SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
+ SpiceDisplayMonitorConfig *c;
+ GArray *monitors = NULL;
+
+ SPICE_DEBUG("update monitor area %d:%d", d->channel_id, d->monitor_id);
+ if (d->monitor_id < 0)
+ goto whole;
+
+ 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);
+ 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;
+ }
+
+ c = &g_array_index(monitors, SpiceDisplayMonitorConfig, d->monitor_id);
+ g_return_if_fail(c != NULL);
+ if (c->surface_id != 0) {
+ g_warning("FIXME: only support monitor config with primary surface 0, "
+ "but given config surface %d", c->surface_id);
+ goto whole;
+ }
+
+ update_area(display, c->x, c->y, c->width, c->height);
+ g_clear_pointer(&monitors, g_array_unref);
+ return;
+
+whole:
+ /* by display whole surface */
+ update_area(display, 0, 0, d->width, d->height);
+}
+
static void spice_display_set_property(GObject *object,
guint prop_id,
const GValue *value,
@@ -245,6 +284,8 @@ static void spice_display_set_property(GObject *object,
break;
case PROP_MONITOR_ID:
d->monitor_id = g_value_get_int(value);
+ if (d->display) /* if constructed */
+ update_monitor_area(display);
break;
case PROP_KEYBOARD_GRAB:
d->keyboard_grab_enable = g_value_get_boolean(value);
@@ -808,13 +849,13 @@ static void recalc_geometry(GtkWidget *widget)
} else
zoom = (gdouble)d->zoom_level / 100;
- SPICE_DEBUG("monitors: id %d, guest +%d+%d:%dx%d, window %dx%d, zoom %g, offset +%d+%d",
- d->channel_id, d->area.x, d->area.y, d->area.width, d->area.height,
+ SPICE_DEBUG("recalc geom monitor: %d:%d, guest +%d+%d:%dx%d, window %dx%d, zoom %g, offset +%d+%d",
+ d->channel_id, d->monitor_id, d->area.x, d->area.y, d->area.width, d->area.height,
d->ww, d->wh, zoom, d->mx, d->my);
if (d->resize_guest_enable)
spice_main_set_display(d->main, get_display_id(display),
- 0, 0, d->ww / zoom, d->wh / zoom);
+ d->area.x, d->area.y, d->ww / zoom, d->wh / zoom);
}
/* ---------------------------------------------------------------- */
@@ -1645,8 +1686,7 @@ static void primary_create(SpiceChannel *channel, gint format,
d->height = height;
d->data_origin = d->data = imgdata;
- /* by default, display whole surface */
- update_area(display, 0, 0, width, height);
+ update_monitor_area(display);
}
static void primary_destroy(SpiceChannel *channel, gpointer data)
@@ -1694,13 +1734,12 @@ static void invalidate(SpiceChannel *channel,
x, y, w, h);
}
-static void mark(SpiceChannel *channel, gint mark, gpointer data)
+static void mark(SpiceDisplay *display, gint mark)
{
- SpiceDisplay *display = data;
SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
g_return_if_fail(d != NULL);
- SPICE_DEBUG("widget mark: %d, channel %d", mark, d->channel_id);
+ 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)))
@@ -1856,6 +1895,7 @@ static void channel_new(SpiceSession *s, SpiceChannel *channel, gpointer data)
}
if (SPICE_IS_DISPLAY_CHANNEL(channel)) {
+ SpiceDisplayPrimary primary;
if (id != d->channel_id)
return;
d->display = channel;
@@ -1866,7 +1906,14 @@ static void channel_new(SpiceSession *s, SpiceChannel *channel, gpointer data)
spice_g_signal_connect_object(channel, "display-invalidate",
G_CALLBACK(invalidate), display, 0);
spice_g_signal_connect_object(channel, "display-mark",
- G_CALLBACK(mark), display, 0);
+ G_CALLBACK(mark), display, G_CONNECT_AFTER | G_CONNECT_SWAPPED);
+ spice_g_signal_connect_object(channel, "notify::monitors",
+ G_CALLBACK(update_monitor_area), display, G_CONNECT_AFTER | G_CONNECT_SWAPPED);
+ if (spice_display_get_primary(channel, 0, &primary)) {
+ primary_create(channel, primary.format, primary.width, primary.height,
+ primary.stride, primary.shmid, primary.data, display);
+ mark(display, primary.marked);
+ }
spice_channel_connect(channel);
return;
}
diff --git a/spice-common b/spice-common
index 5f44094..6a9d40f 160000
--- a/spice-common
+++ b/spice-common
@@ -1 +1 @@
-Subproject commit 5f4409494066b5f59df58d6207fdbb0441aa9e90
+Subproject commit 6a9d40f7f03756599f4a3880c212a379be9e784e
--
1.7.10.4
More information about the Spice-devel
mailing list