summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/virt-viewer-session-spice.c43
-rw-r--r--src/virt-viewer-session.c30
-rw-r--r--src/virt-viewer-session.h3
-rw-r--r--src/virt-viewer-util.c58
-rw-r--r--src/virt-viewer-util.h4
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