summaryrefslogtreecommitdiffstats
path: root/src/virt-viewer-util.c
diff options
context:
space:
mode:
authorJonathon Jongsma <jjongsma@redhat.com>2015-10-07 17:05:01 -0500
committerJonathon Jongsma <jjongsma@redhat.com>2015-10-09 09:17:52 -0500
commitaff6c79ae080db286e4cb853cdfa02f2da0d0398 (patch)
tree92d902e32e03b82d669492a8f3c552289f35eac7 /src/virt-viewer-util.c
parent63317571648089595e66e8dadfae955481c4c3d4 (diff)
downloadvirt-viewer-aff6c79ae080db286e4cb853cdfa02f2da0d0398.tar.gz
virt-viewer-aff6c79ae080db286e4cb853cdfa02f2da0d0398.tar.xz
virt-viewer-aff6c79ae080db286e4cb853cdfa02f2da0d0398.zip
Use the display ID to configure fullscreen monitors
When starting virt-viewer in fullscreen mode, we generally try to arrange guest displays exactly the same as client monitors. So if a client machine has two monitors, we'll try to enable display 0 and 1 on the guest (in that order). However, when using the configuration file to map fullscreen displays to different monitors, the guest displays may not be sequential, or there may be displays missing. For example, consider the following configuration: monitor-mapping=1:2;2:1 In virt_viewer_session_spice_fullscreen_auto_conf(), we were building an array of GdkRectangles for the initial monitors that we want to enable on the guest. We then configured the guest displays using the index of the array for the as the id of the guest display. But when displays are sparse or are out-of-sequence, the array index will not match the >ntended display ID. This created problems where displays were arranged incorrectly. By changing the simple array into a GHashTable, we can keep the display ID together with the GdkRectangle until we need to use it, and things will be configured correctly. This regression was introduced by c586dc8c. Fixes: rhbz#1267184
Diffstat (limited to 'src/virt-viewer-util.c')
-rw-r--r--src/virt-viewer-util.c58
1 files changed, 39 insertions, 19 deletions
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;