summaryrefslogtreecommitdiff
path: root/libgnome-desktop/gnome-rr-output-info.c
diff options
context:
space:
mode:
Diffstat (limited to 'libgnome-desktop/gnome-rr-output-info.c')
-rw-r--r--libgnome-desktop/gnome-rr-output-info.c275
1 files changed, 274 insertions, 1 deletions
diff --git a/libgnome-desktop/gnome-rr-output-info.c b/libgnome-desktop/gnome-rr-output-info.c
index ff8ce780..d50dfa89 100644
--- a/libgnome-desktop/gnome-rr-output-info.c
+++ b/libgnome-desktop/gnome-rr-output-info.c
@@ -98,6 +98,72 @@ void gnome_rr_output_info_set_active (GnomeRROutputInfo *self, gboolean active)
self->priv->on = active;
}
+static void gnome_rr_output_info_get_tiled_geometry (GnomeRROutputInfo *self,
+ int *x,
+ int *y,
+ int *width,
+ int *height)
+{
+ GnomeRROutputInfo **outputs;
+ gboolean active;
+ int i;
+ int ht, vt;
+ int total_w = 0, total_h = 0;
+
+ outputs = gnome_rr_config_get_outputs (self->priv->config);
+
+ /*
+ * iterate over all the outputs from 0,0 -> h,v
+ * find the output for each tile,
+ * if it is the 0 tile, store the x/y offsets.
+ * if the tile is active, add the tile to the total w/h
+ * for the output if the tile is in the 0 row or 0 column.
+ */
+ for (ht = 0; ht < self->priv->tile.max_horiz_tiles; ht++)
+ {
+ for (vt = 0; vt < self->priv->tile.max_vert_tiles; vt++)
+ {
+ for (i = 0; outputs[i]; i++)
+ {
+ GnomeRRTile *this_tile = &outputs[i]->priv->tile;
+
+ if (!outputs[i]->priv->is_tiled)
+ continue;
+
+ if (this_tile->group_id != self->priv->tile.group_id)
+ continue;
+
+ if (this_tile->loc_horiz != ht ||
+ this_tile->loc_vert != vt)
+ continue;
+
+ if (vt == 0 && ht == 0)
+ {
+ if (x)
+ *x = outputs[i]->priv->x;
+ if (y)
+ *y = outputs[i]->priv->y;
+ }
+
+ active = gnome_rr_output_info_is_active (outputs[i]);
+ if (!active)
+ continue;
+
+ if (this_tile->loc_horiz == 0)
+ total_h += outputs[i]->priv->height;
+
+ if (this_tile->loc_vert == 0)
+ total_w += outputs[i]->priv->width;
+ }
+ }
+ }
+
+ if (width)
+ *width = total_w;
+ if (height)
+ *height = total_h;
+}
+
/**
* gnome_rr_output_info_get_geometry:
* @self: a #GnomeRROutputInfo
@@ -105,11 +171,20 @@ void gnome_rr_output_info_set_active (GnomeRROutputInfo *self, gboolean active)
* @y: (out) (allow-none):
* @width: (out) (allow-none):
* @height: (out) (allow-none):
+ *
+ * Get the geometry for the monitor connected to the specified output.
+ * If the monitor is a tiled monitor, it returns the geometry for the complete monitor.
*/
void gnome_rr_output_info_get_geometry (GnomeRROutputInfo *self, int *x, int *y, int *width, int *height)
{
g_return_if_fail (GNOME_IS_RR_OUTPUT_INFO (self));
+ if (self->priv->is_tiled)
+ {
+ gnome_rr_output_info_get_tiled_geometry (self, x, y, width, height);
+ return;
+ }
+
if (x)
*x = self->priv->x;
if (y)
@@ -120,10 +195,106 @@ void gnome_rr_output_info_get_geometry (GnomeRROutputInfo *self, int *x, int *y,
*height = self->priv->height;
}
-void gnome_rr_output_info_set_geometry (GnomeRROutputInfo *self, int x, int y, int width, int height)
+static void gnome_rr_output_info_set_tiled_geometry (GnomeRROutputInfo *self, int x, int y, int width, int height)
+{
+ GnomeRROutputInfo **outputs;
+ gboolean primary_tile_only = FALSE;
+ int ht, vt, i;
+ int x_off;
+
+ primary_tile_only = TRUE;
+
+ if (width == self->priv->total_tiled_width &&
+ height == self->priv->total_tiled_height)
+ primary_tile_only = FALSE;
+
+ outputs = gnome_rr_config_get_outputs (self->priv->config);
+ /*
+ * iterate over all the outputs from 0,0 -> h,v
+ * find the output for each tile,
+ * if only the primary tile is being set, disable
+ * the non-primary tiles, and set the output up
+ * for tile 0 only.
+ * if all tiles are being set, then store the
+ * dimensions for this tile, and increase the offsets.
+ * y_off is reset per column of tiles,
+ * addx is incremented for the first row of tiles
+ * to set the correct x offset.
+ */
+ x_off = 0;
+ for (ht = 0; ht < self->priv->tile.max_horiz_tiles; ht++)
+ {
+ int y_off = 0;
+ int addx = 0;
+ for (vt = 0; vt < self->priv->tile.max_vert_tiles; vt++)
+ {
+ for (i = 0; outputs[i]; i++)
+ {
+ GnomeRRTile *this_tile = &outputs[i]->priv->tile;
+
+ if (!outputs[i]->priv->is_tiled)
+ continue;
+
+ if (this_tile->group_id != self->priv->tile.group_id)
+ continue;
+
+ if (this_tile->loc_horiz != ht ||
+ this_tile->loc_vert != vt)
+ continue;
+
+ /* for primary tile only configs turn off non-primary
+ tiles - turn them on for tiled ones */
+ if (ht != 0 || vt != 0)
+ outputs[i]->priv->on = !primary_tile_only;
+
+ if (primary_tile_only)
+ {
+ if (ht == 0 && vt == 0)
+ {
+ outputs[i]->priv->x = x;
+ outputs[i]->priv->y = y;
+ outputs[i]->priv->width = width;
+ outputs[i]->priv->height = height;
+ }
+ }
+ else
+ {
+ outputs[i]->priv->x = x + x_off;
+ outputs[i]->priv->y = y + y_off;
+ outputs[i]->priv->width = this_tile->width;
+ outputs[i]->priv->height = this_tile->height;
+
+ y_off += this_tile->height;
+ if (vt == 0)
+ addx = this_tile->width;
+ }
+ }
+ }
+ x_off += addx;
+ }
+}
+
+/**
+ * gnome_rr_output_info_set_geometry:
+ * @self: a #GnomeRROutputInfo
+ * @x: x offset for monitor
+ * @y: y offset for monitor
+ * @width: monitor width
+ * @height: monitor height
+ *
+ * Set the geometry for the monitor connected to the specified output.
+ * If the monitor is a tiled monitor, it sets the geometry for the complete monitor.
+ */
+
+void gnome_rr_output_info_set_geometry (GnomeRROutputInfo *self, int x, int y, int width, int height)
{
g_return_if_fail (GNOME_IS_RR_OUTPUT_INFO (self));
+ if (self->priv->is_tiled)
+ {
+ gnome_rr_output_info_set_tiled_geometry (self, x, y, width, height);
+ return;
+ }
self->priv->x = x;
self->priv->y = y;
self->priv->width = width;
@@ -151,10 +322,90 @@ GnomeRRRotation gnome_rr_output_info_get_rotation (GnomeRROutputInfo *self)
return self->priv->rotation;
}
+static void gnome_rr_output_info_set_tiled_rotation (GnomeRROutputInfo *self, GnomeRRRotation rotation)
+{
+ GnomeRROutputInfo **outputs;
+ int x_off;
+ int base_x = 0, base_y = 0;
+ int ht, vt;
+ int i;
+
+ outputs = gnome_rr_config_get_outputs (self->priv->config);
+ x_off = 0;
+ /*
+ * iterate over all the outputs from 0,0 -> h,v
+ * find the output for each tile,
+ * for all tiles set the rotation,
+ * for the 0 tile use the base X/Y offsets
+ * for non-0 tile, rotate the offsets of each
+ * tile so things display correctly.
+ */
+ for (ht = 0; ht < self->priv->tile.max_horiz_tiles; ht++)
+ {
+ int y_off = 0;
+ int addx = 0;
+ for (vt = 0; vt < self->priv->tile.max_vert_tiles; vt++)
+ {
+ for (i = 0; outputs[i] != NULL; i++)
+ {
+ GnomeRRTile *this_tile = &outputs[i]->priv->tile;
+ int new_x, new_y;
+
+ if (!outputs[i]->priv->is_tiled)
+ continue;
+
+ if (this_tile->group_id != self->priv->tile.group_id)
+ continue;
+
+ if (this_tile->loc_horiz != ht ||
+ this_tile->loc_vert != vt)
+ continue;
+
+ /* set tile rotation */
+ outputs[i]->priv->rotation = rotation;
+
+ /* for non-zero tiles - change the offsets */
+ if (ht == 0 && vt == 0)
+ {
+ base_x = outputs[i]->priv->x;
+ base_y = outputs[i]->priv->y;
+ }
+ else
+ {
+ if ((rotation & GNOME_RR_ROTATION_90) || (rotation & GNOME_RR_ROTATION_270))
+ {
+ new_x = base_x + y_off;
+ new_y = base_y + x_off;
+ }
+ else
+ {
+ new_x = base_x + x_off;
+ new_y = base_y + y_off;
+ }
+ outputs[i]->priv->x = new_x;
+ outputs[i]->priv->y = new_y;
+ outputs[i]->priv->width = this_tile->width;
+ outputs[i]->priv->height = this_tile->height;
+ }
+
+ y_off += this_tile->height;
+ if (vt == 0)
+ addx = this_tile->width;
+ }
+ }
+ x_off += addx;
+ }
+}
+
void gnome_rr_output_info_set_rotation (GnomeRROutputInfo *self, GnomeRRRotation rotation)
{
g_return_if_fail (GNOME_IS_RR_OUTPUT_INFO (self));
+ if (self->priv->is_tiled)
+ {
+ gnome_rr_output_info_set_tiled_rotation (self, rotation);
+ return;
+ }
self->priv->rotation = rotation;
}
@@ -266,3 +517,25 @@ void gnome_rr_output_info_set_underscanning (GnomeRROutputInfo *self,
self->priv->underscanning = underscanning;
}
+
+/**
+ * gnome_rr_output_info_is_primary_tile
+ * @self: a #GnomeRROutputInfo
+ *
+ * Returns: %TRUE if the specified output is connected to
+ * the primary tile of a monitor or to an untiled monitor,
+ * %FALSE if the output is connected to a secondary tile.
+ */
+gboolean gnome_rr_output_info_is_primary_tile(GnomeRROutputInfo *self)
+{
+ g_return_val_if_fail (GNOME_IS_RR_OUTPUT_INFO (self), FALSE);
+
+ if (!self->priv->is_tiled)
+ return TRUE;
+
+ if (self->priv->tile.loc_horiz == 0 &&
+ self->priv->tile.loc_vert == 0)
+ return TRUE;
+
+ return FALSE;
+}