MonitorManager: ignore configuration changes that disable all outputs

If we compute a screen size of 0 in either direction, we crash
later on, as it is invalid for clutter, cogl and X.
This commit is contained in:
Giovanni Campagna 2013-07-26 15:31:17 +02:00
parent 8483dec921
commit c06762518e

View File

@ -1581,6 +1581,7 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
GVariant *properties; GVariant *properties;
guint crtc_id; guint crtc_id;
int new_mode, x, y; int new_mode, x, y;
int new_screen_width, new_screen_height;
guint transform; guint transform;
guint output_id; guint output_id;
GPtrArray *crtc_infos, *output_infos; GPtrArray *crtc_infos, *output_infos;
@ -1599,6 +1600,7 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
(GDestroyNotify) meta_output_info_free); (GDestroyNotify) meta_output_info_free);
/* Validate all arguments */ /* Validate all arguments */
new_screen_width = 0; new_screen_height = 0;
g_variant_iter_init (&crtc_iter, crtcs); g_variant_iter_init (&crtc_iter, crtcs);
while (g_variant_iter_loop (&crtc_iter, "(uiiiuaua{sv})", while (g_variant_iter_loop (&crtc_iter, "(uiiiuaua{sv})",
&crtc_id, &new_mode, &x, &y, &transform, &crtc_id, &new_mode, &x, &y, &transform,
@ -1633,19 +1635,29 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
mode = new_mode != -1 ? &manager->modes[new_mode] : NULL; mode = new_mode != -1 ? &manager->modes[new_mode] : NULL;
crtc_info->mode = mode; crtc_info->mode = mode;
if (mode && if (mode)
(x < 0 || {
if (x < 0 ||
x + mode->width > manager->max_screen_width || x + mode->width > manager->max_screen_width ||
y < 0 || y < 0 ||
y + mode->height > manager->max_screen_height)) y + mode->height > manager->max_screen_height)
{ {
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_INVALID_ARGS, G_DBUS_ERROR_INVALID_ARGS,
"Invalid CRTC geometry"); "Invalid CRTC geometry");
return TRUE; return TRUE;
} }
new_screen_width = MAX (new_screen_width, x + mode->width);
new_screen_height = MAX (new_screen_height, y + mode->height);
crtc_info->x = x; crtc_info->x = x;
crtc_info->y = y; crtc_info->y = y;
}
else
{
crtc_info->x = 0;
crtc_info->y = 0;
}
if (transform < WL_OUTPUT_TRANSFORM_NORMAL || if (transform < WL_OUTPUT_TRANSFORM_NORMAL ||
transform > WL_OUTPUT_TRANSFORM_FLIPPED_270) transform > WL_OUTPUT_TRANSFORM_FLIPPED_270)
@ -1705,6 +1717,14 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
g_ptr_array_add (crtc_infos, crtc_info); g_ptr_array_add (crtc_infos, crtc_info);
} }
if (new_screen_width == 0 || new_screen_height == 0)
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_INVALID_ARGS,
"Refusing to disable all outputs");
return TRUE;
}
g_variant_iter_init (&output_iter, outputs); g_variant_iter_init (&output_iter, outputs);
while (g_variant_iter_loop (&output_iter, "(u@a{sv})", &output_id, &properties)) while (g_variant_iter_loop (&output_iter, "(u@a{sv})", &output_id, &properties))
{ {