[virt-tools-list] [PATCH] Do all display alignment in virt-viewer

Marc-André Lureau marcandre.lureau at gmail.com
Mon Nov 4 18:38:29 UTC 2013


On Thu, Oct 31, 2013 at 11:28 PM, Jonathon Jongsma <jjongsma at redhat.com> wrote:
> +static int displays_cmp(const void *p1, const void *p2, gpointer user_data)
> +{
> +    GHashTable *displays = user_data;
> +    guint i = *(guint*)p1;
> +    guint j = *(guint*)p2;
> +    GdkRectangle *m1 = g_hash_table_lookup(displays, GINT_TO_POINTER(i));
> +    GdkRectangle *m2 = g_hash_table_lookup(displays, GINT_TO_POINTER(j));
> +    double d1 = sqrt(m1->x * m1->x + m1->y * m1->y);
> +    double d2 = sqrt(m2->x * m2->x + m2->y * m2->y);
> +    int diff = d1 - d2;
> +
> +    return diff == 0 ? i - j : diff;
> +}

My gut feeling is that all this code is not clean enough. Probably if
moving most of the logic in session, that would help a lot. You could
also change the GList of displays there to a GArray, add a
GdkRectangle directly to VirtViewerDisplay. Then all the align could
be done there, and once over, update spice-session (via signals or
vtable).

At least I don't really get why you use a hash table here, and not
just an array (since monitors are indexed, and even if sparse, you
could easily detect that, 0x0 == disabled in spice)

> +static void align_displays(GHashTable *displays)
> +{
> +    gint i, j, x = 0;
> +    guint *sorted_displays;
> +    guint ndisplays = 0;
> +
> +    g_return_if_fail(displays != NULL);
> +
> +    ndisplays = g_hash_table_size(displays);
> +
> +    if (ndisplays == 0)
> +        return;
> +
> +    /* sort by distance from origin */
> +    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);
> +
> +    for (i = 0; i < ndisplays; i++) {
> +        j = sorted_displays[i];
> +        g_assert(j < ndisplays);
> +        GdkRectangle *rect = g_hash_table_lookup(displays, GINT_TO_POINTER(j));
> +        rect->x = x;
> +        rect->y = 0;
> +        x += rect->width;
> +        if (rect->width || rect->height)
> +            DEBUG_LOG("%s: monitor config: #%d %dx%d+%d+%d", G_STRFUNC,
> +                      j, rect->width, rect->height, rect->x, rect->y);
> +    }
> +    g_free(sorted_displays);
> +}
> +
> +void
> +virt_viewer_session_spice_update_displays(VirtViewerSessionSpice *self)
> +{
> +    gboolean all_fullscreen = TRUE;
> +    GHashTable *display_rects = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
> +    GHashTableIter iter;
> +    gpointer key, value;
> +    GList *displays = virt_viewer_session_get_displays(VIRT_VIEWER_SESSION(self));
> +    for (GList *l = displays; l; l = l->next) {
> +        GdkRectangle *rect = g_new0(GdkRectangle, 1);
> +        VirtViewerDisplay *d = VIRT_VIEWER_DISPLAY(l->data);
> +        gint nth;
> +        gboolean enabled = virt_viewer_display_get_enabled(d);
> +
> +        g_object_get(d, "nth-display", &nth, NULL);
> +
> +        spice_main_set_display_enabled(self->priv->main_channel, nth, enabled);
> +        if (enabled && !virt_viewer_display_get_fullscreen(d))
> +            all_fullscreen = FALSE;
> +
> +        virt_viewer_display_spice_get_requested_size(VIRT_VIEWER_DISPLAY_SPICE(d), rect);
> +        DEBUG_LOG("%s: Got requested size for display %d: (%dx%d) @ (%d,%d)",
> +                  G_STRFUNC, nth, rect->width, rect->height, rect->x, rect->y);
> +        g_hash_table_insert(display_rects, GINT_TO_POINTER(nth), rect);
> +    }
> +
> +    if (!all_fullscreen)
> +        align_displays(display_rects);
> +
> +    g_hash_table_iter_init(&iter, display_rects);
> +    while (g_hash_table_iter_next(&iter, &key, &value)) {
> +        gint nth = GPOINTER_TO_INT(key);
> +        GdkRectangle* rect = (GdkRectangle*) value;
> +        spice_main_set_display(self->priv->main_channel, nth, rect->x,
> +                               rect->y, rect->width, rect->height);
> +    }
> +    g_hash_table_unref(display_rects);
> +}
> +




-- 
Marc-André Lureau




More information about the virt-tools-list mailing list