diff options
-rw-r--r-- | src/virt-viewer-session-spice.c | 43 | ||||
-rw-r--r-- | src/virt-viewer-session.c | 30 | ||||
-rw-r--r-- | src/virt-viewer-session.h | 3 | ||||
-rw-r--r-- | src/virt-viewer-util.c | 58 | ||||
-rw-r--r-- | src/virt-viewer-util.h | 4 |
5 files changed, 76 insertions, 62 deletions
diff --git a/src/virt-viewer-session-spice.c b/src/virt-viewer-session-spice.c index f792294..eb0761d 100644 --- a/src/virt-viewer-session-spice.c +++ b/src/virt-viewer-session-spice.c @@ -85,7 +85,7 @@ static void virt_viewer_session_spice_channel_destroy(SpiceSession *s, static void virt_viewer_session_spice_smartcard_insert(VirtViewerSession *session); static void virt_viewer_session_spice_smartcard_remove(VirtViewerSession *session); static gboolean virt_viewer_session_spice_fullscreen_auto_conf(VirtViewerSessionSpice *self); -static void virt_viewer_session_spice_apply_monitor_geometry(VirtViewerSession *self, GdkRectangle *monitors, guint nmonitors); +static void virt_viewer_session_spice_apply_monitor_geometry(VirtViewerSession *self, GHashTable *monitors); static void virt_viewer_session_spice_clear_displays(VirtViewerSessionSpice *self) { @@ -966,9 +966,10 @@ virt_viewer_session_spice_fullscreen_auto_conf(VirtViewerSessionSpice *self) GdkScreen *screen = gdk_screen_get_default(); SpiceMainChannel* cmain = virt_viewer_session_spice_get_main_channel(self); VirtViewerApp *app = NULL; - GdkRectangle *displays; + GHashTable *displays; + GHashTableIter iter; + gpointer key, value; gboolean agent_connected; - gint i; GList *initial_displays, *l; guint ndisplays; @@ -1003,29 +1004,32 @@ virt_viewer_session_spice_fullscreen_auto_conf(VirtViewerSessionSpice *self) initial_displays = virt_viewer_app_get_initial_displays(app); ndisplays = g_list_length(initial_displays); g_debug("Performing full screen auto-conf, %u host monitors", ndisplays); - displays = g_new0(GdkRectangle, ndisplays); + displays = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free); - for (i = 0, l = initial_displays; l != NULL; l = l->next, i++) { - GdkRectangle* rect = &displays[i]; + for (l = initial_displays; l != NULL; l = l->next) { + GdkRectangle* rect = g_new0(GdkRectangle, 1);; gint j = virt_viewer_app_get_initial_monitor_for_display(app, GPOINTER_TO_INT(l->data)); if (j == -1) continue; gdk_screen_get_monitor_geometry(screen, j, rect); + g_hash_table_insert(displays, l->data, rect); } - g_list_free(initial_displays); - virt_viewer_shift_monitors_to_origin(displays, ndisplays); + virt_viewer_shift_monitors_to_origin(displays); - for (i = 0; i < ndisplays; i++) { - GdkRectangle *rect = &displays[i]; + g_hash_table_iter_init(&iter, displays); + while (g_hash_table_iter_next(&iter, &key, &value)) { + GdkRectangle *rect = value; + gint j = GPOINTER_TO_INT(key); - spice_main_set_display(cmain, i, rect->x, rect->y, rect->width, rect->height); - spice_main_set_display_enabled(cmain, i, TRUE); + spice_main_set_display(cmain, j, rect->x, rect->y, rect->width, rect->height); + spice_main_set_display_enabled(cmain, j, TRUE); g_debug("Set SPICE display %d to (%d,%d)-(%dx%d)", - i, rect->x, rect->y, rect->width, rect->height); + j, rect->x, rect->y, rect->width, rect->height); } - g_free(displays); + g_list_free(initial_displays); + g_hash_table_unref(displays); spice_main_send_monitor_config(cmain); self->priv->did_auto_conf = TRUE; @@ -1109,13 +1113,16 @@ virt_viewer_session_spice_smartcard_remove(VirtViewerSession *session G_GNUC_UNU } static void -virt_viewer_session_spice_apply_monitor_geometry(VirtViewerSession *session, GdkRectangle *monitors, guint nmonitors) +virt_viewer_session_spice_apply_monitor_geometry(VirtViewerSession *session, GHashTable *monitors) { - guint i; + GHashTableIter iter; + gpointer key = NULL, value = NULL; VirtViewerSessionSpice *self = VIRT_VIEWER_SESSION_SPICE(session); - for (i = 0; i < nmonitors; i++) { - GdkRectangle* rect = &monitors[i]; + g_hash_table_iter_init(&iter, monitors); + while (g_hash_table_iter_next(&iter, &key, &value)) { + gint i = GPOINTER_TO_INT(key); + GdkRectangle* rect = value; spice_main_set_display(self->priv->main_channel, i, rect->x, rect->y, rect->width, rect->height); diff --git a/src/virt-viewer-session.c b/src/virt-viewer-session.c index 9405281..2699f41 100644 --- a/src/virt-viewer-session.c +++ b/src/virt-viewer-session.c @@ -404,49 +404,35 @@ virt_viewer_session_on_monitor_geometry_changed(VirtViewerSession* self, { VirtViewerSessionClass *klass; gboolean all_fullscreen = TRUE; - guint nmonitors = 0; - GdkRectangle *monitors = NULL; + /* GHashTable<gint, GdkRectangle*> */ + GHashTable *monitors = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free); GList *l; klass = VIRT_VIEWER_SESSION_GET_CLASS(self); if (!klass->apply_monitor_geometry) return; - /* find highest monitor ID so we can create the sparse array */ for (l = self->priv->displays; l; l = l->next) { VirtViewerDisplay *d = VIRT_VIEWER_DISPLAY(l->data); guint nth = 0; - g_object_get(d, "nth-display", &nth, NULL); - - nmonitors = MAX(nth + 1, nmonitors); - } - - if (nmonitors == 0) - return; - - monitors = g_new0(GdkRectangle, nmonitors); - for (l = self->priv->displays; l; l = l->next) { - VirtViewerDisplay *d = VIRT_VIEWER_DISPLAY(l->data); - guint nth = 0; - GdkRectangle *rect = NULL; + GdkRectangle *rect = g_new0(GdkRectangle, 1); g_object_get(d, "nth-display", &nth, NULL); - g_return_if_fail(nth < nmonitors); - rect = &monitors[nth]; virt_viewer_display_get_preferred_monitor_geometry(d, rect); if (virt_viewer_display_get_enabled(d) && !virt_viewer_display_get_fullscreen(d)) all_fullscreen = FALSE; + g_hash_table_insert(monitors, GINT_TO_POINTER(nth), rect); } if (!all_fullscreen) - virt_viewer_align_monitors_linear(monitors, nmonitors); + virt_viewer_align_monitors_linear(monitors); - virt_viewer_shift_monitors_to_origin(monitors, nmonitors); + virt_viewer_shift_monitors_to_origin(monitors); - klass->apply_monitor_geometry(self, monitors, nmonitors); - g_free(monitors); + klass->apply_monitor_geometry(self, monitors); + g_hash_table_unref(monitors); } void virt_viewer_session_add_display(VirtViewerSession *session, diff --git a/src/virt-viewer-session.h b/src/virt-viewer-session.h index 85f17cc..d3a9ccc 100644 --- a/src/virt-viewer-session.h +++ b/src/virt-viewer-session.h @@ -94,7 +94,8 @@ struct _VirtViewerSessionClass { void (*session_cut_text)(VirtViewerSession *session, const gchar *str); void (*session_bell)(VirtViewerSession *session); void (*session_cancelled)(VirtViewerSession *session); - void (*apply_monitor_geometry)(VirtViewerSession *session, GdkRectangle* monitors, guint nmonitors); + /* monitors = GHashTable<int, GdkRectangle*> */ + void (*apply_monitor_geometry)(VirtViewerSession *session, GHashTable* monitors); gboolean (*can_share_folder)(VirtViewerSession *session); gboolean (*can_retry_auth)(VirtViewerSession *session); }; diff --git a/src/virt-viewer-util.c b/src/virt-viewer-util.c index 19a475e..e9f771b 100644 --- a/src/virt-viewer-util.c +++ b/src/virt-viewer-util.c @@ -536,11 +536,11 @@ static int displays_cmp(const void *p1, const void *p2, gpointer user_data) { guint diff; - GdkRectangle *displays = user_data; + GHashTable *displays = user_data; guint i = *(guint*)p1; guint j = *(guint*)p2; - GdkRectangle *m1 = &displays[i]; - GdkRectangle *m2 = &displays[j]; + GdkRectangle *m1 = g_hash_table_lookup(displays, GINT_TO_POINTER(i)); + GdkRectangle *m2 = g_hash_table_lookup(displays, GINT_TO_POINTER(j)); diff = m1->x - m2->x; if (diff == 0) diff = m1->y - m2->y; @@ -550,28 +550,44 @@ displays_cmp(const void *p1, const void *p2, gpointer user_data) return diff; } +static void find_max_id(gpointer key, + gpointer value G_GNUC_UNUSED, + gpointer user_data) +{ + guint *max_id = user_data; + guint id = GPOINTER_TO_INT(key); + *max_id = MAX(*max_id, id); +} + void -virt_viewer_align_monitors_linear(GdkRectangle *displays, guint ndisplays) +virt_viewer_align_monitors_linear(GHashTable *displays) { gint i, x = 0; guint *sorted_displays; + guint max_id = 0; + GHashTableIter iter; + gpointer key, value; g_return_if_fail(displays != NULL); - if (ndisplays == 0) + if (g_hash_table_size(displays) == 0) return; - sorted_displays = g_new0(guint, ndisplays); - for (i = 0; i < ndisplays; i++) - sorted_displays[i] = i; - g_qsort_with_data(sorted_displays, ndisplays, sizeof(guint), displays_cmp, displays); + g_hash_table_foreach(displays, find_max_id, &max_id); + sorted_displays = g_new0(guint, max_id); + + g_hash_table_iter_init(&iter, displays); + while (g_hash_table_iter_next(&iter, &key, &value)) + sorted_displays[GPOINTER_TO_INT(key)] = GPOINTER_TO_INT(key); + + g_qsort_with_data(sorted_displays, max_id, sizeof(guint), displays_cmp, displays); /* adjust monitor positions so that there's no gaps or overlap between * monitors */ - for (i = 0; i < ndisplays; i++) { + for (i = 0; i < max_id; i++) { guint nth = sorted_displays[i]; - g_assert(nth < ndisplays); - GdkRectangle *rect = &displays[nth]; + g_assert(nth < max_id); + GdkRectangle *rect = g_hash_table_lookup(displays, GINT_TO_POINTER(nth)); rect->x = x; rect->y = 0; x += rect->width; @@ -591,16 +607,19 @@ virt_viewer_align_monitors_linear(GdkRectangle *displays, guint ndisplays) * screen of that size. */ void -virt_viewer_shift_monitors_to_origin(GdkRectangle *displays, guint ndisplays) +virt_viewer_shift_monitors_to_origin(GHashTable *displays) { gint xmin = G_MAXINT; gint ymin = G_MAXINT; - gint i; + GHashTableIter iter; + gpointer key, value; - g_return_if_fail(ndisplays > 0); + if (g_hash_table_size(displays) == 0) + return; - for (i = 0; i < ndisplays; i++) { - GdkRectangle *display = &displays[i]; + g_hash_table_iter_init(&iter, displays); + while (g_hash_table_iter_next(&iter, &key, &value)) { + GdkRectangle *display = value; if (display->width > 0 && display->height > 0) { xmin = MIN(xmin, display->x); ymin = MIN(ymin, display->y); @@ -610,8 +629,9 @@ virt_viewer_shift_monitors_to_origin(GdkRectangle *displays, guint ndisplays) if (xmin > 0 || ymin > 0) { g_debug("%s: Shifting all monitors by (%i, %i)", G_STRFUNC, xmin, ymin); - for (i = 0; i < ndisplays; i++) { - GdkRectangle *display = &displays[i]; + g_hash_table_iter_init(&iter, displays); + while (g_hash_table_iter_next(&iter, &key, &value)) { + GdkRectangle *display = value; if (display->width > 0 && display->height > 0) { display->x -= xmin; display->y -= ymin; diff --git a/src/virt-viewer-util.h b/src/virt-viewer-util.h index 98badd2..f1cb08b 100644 --- a/src/virt-viewer-util.h +++ b/src/virt-viewer-util.h @@ -57,8 +57,8 @@ gchar* spice_hotkey_to_gtk_accelerator(const gchar *key); gint virt_viewer_compare_buildid(const gchar *s1, const gchar *s2); /* monitor alignment */ -void virt_viewer_align_monitors_linear(GdkRectangle *displays, guint ndisplays); -void virt_viewer_shift_monitors_to_origin(GdkRectangle *displays, guint ndisplays); +void virt_viewer_align_monitors_linear(GHashTable *displays); +void virt_viewer_shift_monitors_to_origin(GHashTable *displays); #endif |