summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2015-03-25 15:18:58 +1000
committerDave Airlie <airlied@redhat.com>2015-03-25 15:22:16 +1000
commit214e9e0f42610dcf3e021d11015e5cc272388f49 (patch)
treebc31acf65b877babc07a635696ed026ce243ce11
parentb308fbbb865124d7a1a6f7cff25870674ce7826c (diff)
mutter: refactor wayland outputs to be backed by monitor infostile-monitor-3
These are more accurate to what wayland clients want to see, esp for tiled monitors.
-rw-r--r--src/backends/meta-monitor-manager-private.h4
-rw-r--r--src/backends/meta-monitor-manager.c16
-rw-r--r--src/wayland/meta-wayland-outputs.c84
3 files changed, 59 insertions, 45 deletions
diff --git a/src/backends/meta-monitor-manager-private.h b/src/backends/meta-monitor-manager-private.h
index ad1c2a92..c5392ffa 100644
--- a/src/backends/meta-monitor-manager-private.h
+++ b/src/backends/meta-monitor-manager-private.h
@@ -197,6 +197,10 @@ struct _MetaMonitorInfo
int number;
int xinerama_index;
MetaRectangle rect;
+ /* for tiled monitors these are calculated, from untiled just copied */
+ float refresh_rate;
+ int width_mm;
+ int height_mm;
gboolean is_primary;
gboolean is_presentation; /* XXX: not yet used */
gboolean in_fullscreen;
diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
index d1f0d514..78211054 100644
--- a/src/backends/meta-monitor-manager.c
+++ b/src/backends/meta-monitor-manager.c
@@ -101,6 +101,9 @@ construct_tile_monitor (MetaMonitorManager *manager,
info.tile_group_id = tile_group_id;
info.is_tiled = True;
info.is_presentation = False;
+ info.refresh_rate = 0.0;
+ info.width_mm = 0;
+ info.height_mm = 0;
info.is_primary = False;
info.rect.x = INT_MAX;
info.rect.y = INT_MAX;
@@ -127,6 +130,12 @@ construct_tile_monitor (MetaMonitorManager *manager,
output->crtc->rect.height != output->tile_h)
continue;
+ if (output->loc_h_tile == 0 && output->loc_v_tile == 0) {
+ info.refresh_rate = output->crtc->current_mode->refresh_rate;
+ info.width_mm = output->width_mm;
+ info.height_mm = output->height_mm;
+ }
+
/* hack */
if (output->crtc->rect.x < info.rect.x)
info.rect.x = output->crtc->rect.x;
@@ -204,6 +213,7 @@ make_logical_config (MetaMonitorManager *manager)
info.number = monitor_infos->len;
info.tile_group_id = 0;
info.rect = crtc->rect;
+ info.refresh_rate = crtc->current_mode->refresh_rate;
info.is_primary = FALSE;
/* This starts true because we want
is_presentation only if all outputs are
@@ -247,6 +257,12 @@ make_logical_config (MetaMonitorManager *manager)
info->is_primary = info->is_primary || output->is_primary;
info->is_presentation = info->is_presentation && output->is_presentation;
+ info->width_mm = output->width_mm;
+ info->height_mm = output->height_mm;
+
+ info->outputs[0] = output;
+ info->n_outputs = 1;
+
if (output->is_primary || info->winsys_id == 0)
info->winsys_id = output->winsys_id;
diff --git a/src/wayland/meta-wayland-outputs.c b/src/wayland/meta-wayland-outputs.c
index 47fc8f5c..c0b04690 100644
--- a/src/wayland/meta-wayland-outputs.c
+++ b/src/wayland/meta-wayland-outputs.c
@@ -32,7 +32,7 @@
#include <string.h>
typedef struct {
- MetaOutput *output;
+ MetaMonitorInfo *monitor_info;
struct wl_global *global;
int x, y;
enum wl_output_transform transform;
@@ -56,9 +56,10 @@ bind_output (struct wl_client *client,
guint32 id)
{
MetaWaylandOutput *wayland_output = data;
- MetaOutput *output = wayland_output->output;
+ MetaMonitorInfo *monitor_info = wayland_output->monitor_info;
struct wl_resource *resource;
guint mode_flags;
+ MetaOutput *output = monitor_info->outputs[0];
resource = wl_resource_create (client, &wl_output_interface, version, id);
wayland_output->resources = g_list_prepend (wayland_output->resources, resource);
@@ -66,17 +67,17 @@ bind_output (struct wl_client *client,
wl_resource_set_user_data (resource, wayland_output);
wl_resource_set_destructor (resource, output_resource_destroy);
- meta_verbose ("Binding output %p/%s (%u, %u, %u, %u) x %f\n",
- output, output->name,
- output->crtc->rect.x, output->crtc->rect.y,
- output->crtc->rect.width, output->crtc->rect.height,
- output->crtc->current_mode->refresh_rate);
+ meta_verbose ("Binding monitor %p/%s (%u, %u, %u, %u) x %f\n",
+ monitor_info, output->name,
+ monitor_info->rect.x, monitor_info->rect.y,
+ monitor_info->rect.width, monitor_info->rect.height,
+ monitor_info->refresh_rate);
wl_output_send_geometry (resource,
- (int)output->crtc->rect.x,
- (int)output->crtc->rect.y,
- output->width_mm,
- output->height_mm,
+ (int)monitor_info->rect.x,
+ (int)monitor_info->rect.y,
+ monitor_info->width_mm,
+ monitor_info->height_mm,
/* Cogl values reflect XRandR values,
and so does wayland */
output->subpixel_order,
@@ -92,9 +93,9 @@ bind_output (struct wl_client *client,
wl_output_send_mode (resource,
mode_flags,
- (int)output->crtc->current_mode->width,
- (int)output->crtc->current_mode->height,
- (int)output->crtc->current_mode->refresh_rate);
+ (int)monitor_info->rect.width,
+ (int)monitor_info->rect.height,
+ (int)monitor_info->refresh_rate);
if (version >= WL_OUTPUT_SCALE_SINCE_VERSION)
wl_output_send_scale (resource, output->scale);
@@ -128,14 +129,13 @@ wl_output_transform_from_meta_monitor_transform (MetaMonitorTransform transform)
static void
wayland_output_update_for_output (MetaWaylandOutput *wayland_output,
- MetaOutput *output)
+ MetaMonitorInfo *monitor_info)
{
GList *iter;
guint mode_flags;
+ MetaOutput *output = monitor_info->outputs[0];
enum wl_output_transform wl_transform = wl_output_transform_from_meta_monitor_transform (output->crtc->transform);
- g_assert (output->crtc->current_mode != NULL);
-
mode_flags = WL_OUTPUT_MODE_CURRENT;
if (output->crtc->current_mode == output->preferred_mode)
mode_flags |= WL_OUTPUT_MODE_PREFERRED;
@@ -144,15 +144,15 @@ wayland_output_update_for_output (MetaWaylandOutput *wayland_output,
{
struct wl_resource *resource = iter->data;
- if (wayland_output->x != output->crtc->rect.x ||
- wayland_output->y != output->crtc->rect.y ||
+ if (wayland_output->x != monitor_info->rect.x ||
+ wayland_output->y != monitor_info->rect.y ||
wayland_output->transform != wl_transform)
{
wl_output_send_geometry (resource,
- (int)output->crtc->rect.x,
- (int)output->crtc->rect.y,
- output->width_mm,
- output->height_mm,
+ (int)monitor_info->rect.x,
+ (int)monitor_info->rect.y,
+ monitor_info->width_mm,
+ monitor_info->height_mm,
output->subpixel_order,
output->vendor,
output->product,
@@ -161,16 +161,16 @@ wayland_output_update_for_output (MetaWaylandOutput *wayland_output,
wl_output_send_mode (resource,
mode_flags,
- (int)output->crtc->current_mode->width,
- (int)output->crtc->current_mode->height,
- (int)output->crtc->current_mode->refresh_rate);
+ (int)monitor_info->rect.width,
+ (int)monitor_info->rect.height,
+ (int)monitor_info->refresh_rate);
}
/* It's very important that we change the output pointer here, as
the old structure is about to be freed by MetaMonitorManager */
- wayland_output->output = output;
- wayland_output->x = output->crtc->rect.x;
- wayland_output->y = output->crtc->rect.y;
+ wayland_output->monitor_info = monitor_info;
+ wayland_output->x = monitor_info->rect.x;
+ wayland_output->y = monitor_info->rect.y;
wayland_output->transform = wl_transform;
}
@@ -178,30 +178,24 @@ static GHashTable *
meta_wayland_compositor_update_outputs (MetaWaylandCompositor *compositor,
MetaMonitorManager *monitors)
{
- MetaOutput *outputs;
- unsigned int i, n_outputs;
+ unsigned int i;
GHashTable *new_table;
+ MetaMonitorInfo *monitor_infos;
+ unsigned int n_monitor_infos;
- outputs = meta_monitor_manager_get_outputs (monitors, &n_outputs);
+ monitor_infos = meta_monitor_manager_get_monitor_infos (monitors, &n_monitor_infos);
new_table = g_hash_table_new_full (NULL, NULL, NULL, wayland_output_destroy_notify);
- for (i = 0; i < n_outputs; i++)
+ for (i = 0; i < n_monitor_infos; i++)
{
- MetaOutput *output = &outputs[i];
+ MetaMonitorInfo *info = &monitor_infos[i];
MetaWaylandOutput *wayland_output;
- /* wayland does not expose disabled outputs */
- if (output->crtc == NULL)
- {
- g_hash_table_remove (compositor->outputs, GSIZE_TO_POINTER (output->winsys_id));
- continue;
- }
-
- wayland_output = g_hash_table_lookup (compositor->outputs, GSIZE_TO_POINTER (output->winsys_id));
+ wayland_output = g_hash_table_lookup (compositor->outputs, GSIZE_TO_POINTER (info->winsys_id));
if (wayland_output)
{
- g_hash_table_steal (compositor->outputs, GSIZE_TO_POINTER (output->winsys_id));
+ g_hash_table_steal (compositor->outputs, GSIZE_TO_POINTER (info->winsys_id));
}
else
{
@@ -212,8 +206,8 @@ meta_wayland_compositor_update_outputs (MetaWaylandCompositor *compositor,
wayland_output, bind_output);
}
- wayland_output_update_for_output (wayland_output, output);
- g_hash_table_insert (new_table, GSIZE_TO_POINTER (output->winsys_id), wayland_output);
+ wayland_output_update_for_output (wayland_output, info);
+ g_hash_table_insert (new_table, GSIZE_TO_POINTER (info->winsys_id), wayland_output);
}
g_hash_table_destroy (compositor->outputs);