mirror of
https://github.com/brl/mutter.git
synced 2024-11-24 17:10:40 -05:00
DisplayConfig: make the dummy backend writable
Add a number of dummy outputs and modes to the dummy backend, and implement the writing bits. The only visible effect is that you can change the screen size, which resizes the output window.
This commit is contained in:
parent
33c0c1dc18
commit
1e3aad2d8c
@ -73,6 +73,9 @@ struct _MetaOutput
|
||||
MetaOutput **possible_clones;
|
||||
unsigned int n_possible_clones;
|
||||
|
||||
/* Used when changing configuration */
|
||||
gboolean dirty;
|
||||
|
||||
/* The low-level bits used to build the high-level info
|
||||
in MetaMonitorInfo
|
||||
|
||||
|
@ -126,9 +126,22 @@ static int signals[SIGNALS_LAST];
|
||||
|
||||
G_DEFINE_TYPE (MetaMonitorManager, meta_monitor_manager, G_TYPE_OBJECT);
|
||||
|
||||
static void invalidate_logical_config (MetaMonitorManager *manager);
|
||||
|
||||
static void
|
||||
make_dummy_monitor_config (MetaMonitorManager *manager)
|
||||
{
|
||||
/* The dummy monitor config has:
|
||||
- one enabled output, LVDS, primary, at 0x0 and 1024x768
|
||||
- one free CRTC
|
||||
- two disabled outputs
|
||||
- three modes, 1024x768, 800x600 and 640x480
|
||||
- no clones are possible (use different CRTCs)
|
||||
|
||||
Low-level IDs should be assigned sequentially, to
|
||||
mimick what XRandR and KMS do
|
||||
*/
|
||||
|
||||
manager->backend = META_BACKEND_DUMMY;
|
||||
|
||||
manager->max_screen_width = 65535;
|
||||
@ -136,18 +149,28 @@ make_dummy_monitor_config (MetaMonitorManager *manager)
|
||||
manager->screen_width = 1024;
|
||||
manager->screen_height = 768;
|
||||
|
||||
manager->modes = g_new0 (MetaMonitorMode, 1);
|
||||
manager->n_modes = 1;
|
||||
manager->modes = g_new0 (MetaMonitorMode, 3);
|
||||
manager->n_modes = 3;
|
||||
|
||||
manager->modes[0].mode_id = 1;
|
||||
manager->modes[0].width = manager->screen_width;
|
||||
manager->modes[0].height = manager->screen_height;
|
||||
manager->modes[0].width = 1024;
|
||||
manager->modes[0].height = 768;
|
||||
manager->modes[0].refresh_rate = 60.0;
|
||||
|
||||
manager->crtcs = g_new0 (MetaCRTC, 1);
|
||||
manager->n_crtcs = 1;
|
||||
manager->modes[1].mode_id = 2;
|
||||
manager->modes[1].width = 800;
|
||||
manager->modes[1].height = 600;
|
||||
manager->modes[1].refresh_rate = 60.0;
|
||||
|
||||
manager->crtcs[0].crtc_id = 2;
|
||||
manager->modes[2].mode_id = 3;
|
||||
manager->modes[2].width = 640;
|
||||
manager->modes[2].height = 480;
|
||||
manager->modes[2].refresh_rate = 60.0;
|
||||
|
||||
manager->crtcs = g_new0 (MetaCRTC, 2);
|
||||
manager->n_crtcs = 2;
|
||||
|
||||
manager->crtcs[0].crtc_id = 4;
|
||||
manager->crtcs[0].rect.x = 0;
|
||||
manager->crtcs[0].rect.y = 0;
|
||||
manager->crtcs[0].rect.width = manager->modes[0].width;
|
||||
@ -156,11 +179,20 @@ make_dummy_monitor_config (MetaMonitorManager *manager)
|
||||
manager->crtcs[0].dirty = FALSE;
|
||||
manager->crtcs[0].logical_monitor = NULL;
|
||||
|
||||
manager->outputs = g_new0 (MetaOutput, 1);
|
||||
manager->n_outputs = 1;
|
||||
manager->crtcs[1].crtc_id = 5;
|
||||
manager->crtcs[1].rect.x = 0;
|
||||
manager->crtcs[1].rect.y = 0;
|
||||
manager->crtcs[1].rect.width = 0;
|
||||
manager->crtcs[1].rect.height = 0;
|
||||
manager->crtcs[1].current_mode = NULL;
|
||||
manager->crtcs[1].dirty = FALSE;
|
||||
manager->crtcs[1].logical_monitor = NULL;
|
||||
|
||||
manager->outputs = g_new0 (MetaOutput, 3);
|
||||
manager->n_outputs = 3;
|
||||
|
||||
manager->outputs[0].crtc = &manager->crtcs[0];
|
||||
manager->outputs[0].output_id = 3;
|
||||
manager->outputs[0].output_id = 6;
|
||||
manager->outputs[0].name = g_strdup ("LVDS");
|
||||
manager->outputs[0].vendor = g_strdup ("unknown");
|
||||
manager->outputs[0].product = g_strdup ("unknown");
|
||||
@ -169,14 +201,61 @@ make_dummy_monitor_config (MetaMonitorManager *manager)
|
||||
manager->outputs[0].height_mm = 125;
|
||||
manager->outputs[0].subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
|
||||
manager->outputs[0].preferred_mode = &manager->modes[0];
|
||||
manager->outputs[0].n_modes = 1;
|
||||
manager->outputs[0].modes = g_new0 (MetaMonitorMode *, 1);
|
||||
manager->outputs[0].n_modes = 3;
|
||||
manager->outputs[0].modes = g_new0 (MetaMonitorMode *, 3);
|
||||
manager->outputs[0].modes[0] = &manager->modes[0];
|
||||
manager->outputs[0].n_possible_crtcs = 1;
|
||||
manager->outputs[0].possible_crtcs = g_new0 (MetaCRTC *, 1);
|
||||
manager->outputs[0].modes[1] = &manager->modes[1];
|
||||
manager->outputs[0].modes[2] = &manager->modes[2];
|
||||
manager->outputs[0].n_possible_crtcs = 2;
|
||||
manager->outputs[0].possible_crtcs = g_new0 (MetaCRTC *, 2);
|
||||
manager->outputs[0].possible_crtcs[0] = &manager->crtcs[0];
|
||||
manager->outputs[0].possible_crtcs[1] = &manager->crtcs[1];
|
||||
manager->outputs[0].n_possible_clones = 0;
|
||||
manager->outputs[0].possible_clones = g_new0 (MetaOutput *, 0);
|
||||
|
||||
manager->outputs[1].crtc = NULL;
|
||||
manager->outputs[1].output_id = 7;
|
||||
manager->outputs[1].name = g_strdup ("HDMI");
|
||||
manager->outputs[1].vendor = g_strdup ("unknown");
|
||||
manager->outputs[1].product = g_strdup ("unknown");
|
||||
manager->outputs[1].serial = g_strdup ("");
|
||||
manager->outputs[1].width_mm = 510;
|
||||
manager->outputs[1].height_mm = 287;
|
||||
manager->outputs[1].subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
|
||||
manager->outputs[1].preferred_mode = &manager->modes[0];
|
||||
manager->outputs[1].n_modes = 3;
|
||||
manager->outputs[1].modes = g_new0 (MetaMonitorMode *, 3);
|
||||
manager->outputs[1].modes[0] = &manager->modes[0];
|
||||
manager->outputs[1].modes[1] = &manager->modes[1];
|
||||
manager->outputs[1].modes[2] = &manager->modes[2];
|
||||
manager->outputs[1].n_possible_crtcs = 2;
|
||||
manager->outputs[1].possible_crtcs = g_new0 (MetaCRTC *, 2);
|
||||
manager->outputs[1].possible_crtcs[0] = &manager->crtcs[0];
|
||||
manager->outputs[1].possible_crtcs[1] = &manager->crtcs[1];
|
||||
manager->outputs[1].n_possible_clones = 0;
|
||||
manager->outputs[1].possible_clones = g_new0 (MetaOutput *, 0);
|
||||
|
||||
manager->outputs[2].crtc = NULL;
|
||||
manager->outputs[2].output_id = 8;
|
||||
manager->outputs[2].name = g_strdup ("VGA");
|
||||
manager->outputs[2].vendor = g_strdup ("unknown");
|
||||
manager->outputs[2].product = g_strdup ("unknown");
|
||||
manager->outputs[2].serial = g_strdup ("");
|
||||
manager->outputs[2].width_mm = 309;
|
||||
manager->outputs[2].height_mm = 174;
|
||||
manager->outputs[2].subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
|
||||
manager->outputs[2].preferred_mode = &manager->modes[0];
|
||||
manager->outputs[2].n_modes = 3;
|
||||
manager->outputs[2].modes = g_new0 (MetaMonitorMode *, 3);
|
||||
manager->outputs[2].modes[0] = &manager->modes[0];
|
||||
manager->outputs[2].modes[1] = &manager->modes[1];
|
||||
manager->outputs[2].modes[2] = &manager->modes[2];
|
||||
manager->outputs[2].n_possible_crtcs = 2;
|
||||
manager->outputs[2].possible_crtcs = g_new0 (MetaCRTC *, 2);
|
||||
manager->outputs[2].possible_crtcs[0] = &manager->crtcs[0];
|
||||
manager->outputs[2].possible_crtcs[1] = &manager->crtcs[1];
|
||||
manager->outputs[2].n_possible_clones = 0;
|
||||
manager->outputs[2].possible_clones = g_new0 (MetaOutput *, 0);
|
||||
}
|
||||
|
||||
#ifdef HAVE_RANDR
|
||||
@ -1082,7 +1161,10 @@ apply_config_xrandr (MetaMonitorManager *manager,
|
||||
MetaCRTC *crtc = &manager->crtcs[i];
|
||||
|
||||
if (crtc->dirty)
|
||||
continue;
|
||||
{
|
||||
crtc->dirty = FALSE;
|
||||
continue;
|
||||
}
|
||||
if (crtc->current_mode == NULL)
|
||||
continue;
|
||||
|
||||
@ -1098,6 +1180,117 @@ apply_config_xrandr (MetaMonitorManager *manager,
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
apply_config_dummy (MetaMonitorManager *manager,
|
||||
GVariantIter *crtcs,
|
||||
GVariantIter *outputs)
|
||||
{
|
||||
GVariant *nested_outputs, *properties;
|
||||
guint crtc_id, output_id, transform;
|
||||
int new_mode, x, y;
|
||||
unsigned i;
|
||||
int screen_width = 0, screen_height = 0;
|
||||
|
||||
while (g_variant_iter_loop (crtcs, "(uiiiu@aua{sv})",
|
||||
&crtc_id, &new_mode, &x, &y,
|
||||
&transform, &nested_outputs, NULL))
|
||||
{
|
||||
MetaCRTC *crtc = &manager->crtcs[crtc_id];
|
||||
crtc->dirty = TRUE;
|
||||
|
||||
if (new_mode == -1)
|
||||
{
|
||||
crtc->rect.x = 0;
|
||||
crtc->rect.y = 0;
|
||||
crtc->rect.width = 0;
|
||||
crtc->rect.height = 0;
|
||||
crtc->current_mode = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
MetaMonitorMode *mode;
|
||||
MetaOutput *output;
|
||||
int i, n_outputs;
|
||||
guint output_id;
|
||||
|
||||
mode = &manager->modes[new_mode];
|
||||
|
||||
crtc->rect.x = x;
|
||||
crtc->rect.y = y;
|
||||
crtc->rect.width = mode->width;
|
||||
crtc->rect.height = mode->height;
|
||||
crtc->current_mode = mode;
|
||||
|
||||
screen_width = MAX (screen_width, x + mode->width);
|
||||
screen_height = MAX (screen_height, y + mode->height);
|
||||
|
||||
n_outputs = g_variant_n_children (nested_outputs);
|
||||
for (i = 0; i < n_outputs; i++)
|
||||
{
|
||||
g_variant_get_child (nested_outputs, i, "u", &output_id);
|
||||
|
||||
output = &manager->outputs[output_id];
|
||||
|
||||
output->dirty = TRUE;
|
||||
output->crtc = crtc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (g_variant_iter_loop (outputs, "(u@a{sv})",
|
||||
&output_id, &properties))
|
||||
{
|
||||
MetaOutput *output = &manager->outputs[output_id];
|
||||
gboolean primary, presentation;
|
||||
|
||||
if (g_variant_lookup (properties, "primary", "b", &primary))
|
||||
output->is_primary = primary;
|
||||
|
||||
if (g_variant_lookup (properties, "presentation", "b", &presentation))
|
||||
output->is_presentation = presentation;
|
||||
}
|
||||
|
||||
/* Disable CRTCs not mentioned in the list */
|
||||
for (i = 0; i < manager->n_crtcs; i++)
|
||||
{
|
||||
MetaCRTC *crtc = &manager->crtcs[i];
|
||||
|
||||
crtc->logical_monitor = NULL;
|
||||
|
||||
if (crtc->dirty)
|
||||
{
|
||||
crtc->dirty = FALSE;
|
||||
continue;
|
||||
}
|
||||
|
||||
crtc->rect.x = 0;
|
||||
crtc->rect.y = 0;
|
||||
crtc->rect.width = 0;
|
||||
crtc->rect.height = 0;
|
||||
crtc->current_mode = NULL;
|
||||
}
|
||||
|
||||
/* Disable outputs not mentioned in the list */
|
||||
for (i = 0; i < manager->n_outputs; i++)
|
||||
{
|
||||
MetaOutput *output = &manager->outputs[i];
|
||||
|
||||
if (output->dirty)
|
||||
{
|
||||
output->dirty = FALSE;
|
||||
continue;
|
||||
}
|
||||
|
||||
output->crtc = NULL;
|
||||
output->is_primary = FALSE;
|
||||
}
|
||||
|
||||
manager->screen_width = screen_width;
|
||||
manager->screen_height = screen_height;
|
||||
|
||||
invalidate_logical_config (manager);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_apply_configuration (MetaDBusDisplayConfig *skeleton,
|
||||
GDBusMethodInvocation *invocation,
|
||||
@ -1129,14 +1322,6 @@ handle_apply_configuration (MetaDBusDisplayConfig *skeleton,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (manager->backend != META_BACKEND_XRANDR)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_NOT_SUPPORTED,
|
||||
"Changing configuration is not supported by the backend");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Validate all arguments */
|
||||
g_variant_iter_init (&crtc_iter, crtcs);
|
||||
while (g_variant_iter_loop (&crtc_iter, "(uiiiuaua{sv})",
|
||||
@ -1246,7 +1431,19 @@ handle_apply_configuration (MetaDBusDisplayConfig *skeleton,
|
||||
|
||||
g_variant_iter_init (&crtc_iter, crtcs);
|
||||
g_variant_iter_init (&output_iter, outputs);
|
||||
apply_config_xrandr (manager, &crtc_iter, &output_iter);
|
||||
|
||||
if (manager->backend == META_BACKEND_COGL)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_NOT_SUPPORTED,
|
||||
"Changing configuration is not supported by the backend");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (manager->backend == META_BACKEND_XRANDR)
|
||||
apply_config_xrandr (manager, &crtc_iter, &output_iter);
|
||||
else
|
||||
apply_config_dummy (manager, &crtc_iter, &output_iter);
|
||||
|
||||
meta_dbus_display_config_complete_apply_configuration (skeleton, invocation);
|
||||
return TRUE;
|
||||
@ -1352,13 +1549,28 @@ meta_monitor_manager_get_screen_size (MetaMonitorManager *manager,
|
||||
*height = manager->screen_height;
|
||||
}
|
||||
|
||||
static void
|
||||
invalidate_logical_config (MetaMonitorManager *manager)
|
||||
{
|
||||
MetaMonitorInfo *old_monitor_infos;
|
||||
|
||||
old_monitor_infos = manager->monitor_infos;
|
||||
|
||||
manager->serial++;
|
||||
make_logical_config (manager);
|
||||
|
||||
g_signal_emit (manager, signals[MONITORS_CHANGED], 0);
|
||||
|
||||
g_free (old_monitor_infos);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_monitor_manager_handle_xevent (MetaMonitorManager *manager,
|
||||
XEvent *event)
|
||||
{
|
||||
MetaOutput *old_outputs;
|
||||
MetaCRTC *old_crtcs;
|
||||
MetaMonitorInfo *old_monitor_infos;
|
||||
|
||||
MetaMonitorMode *old_modes;
|
||||
int n_old_outputs;
|
||||
|
||||
@ -1374,17 +1586,12 @@ meta_monitor_manager_handle_xevent (MetaMonitorManager *manager,
|
||||
/* Save the old structures, so they stay valid during the update */
|
||||
old_outputs = manager->outputs;
|
||||
n_old_outputs = manager->n_outputs;
|
||||
old_monitor_infos = manager->monitor_infos;
|
||||
old_modes = manager->modes;
|
||||
old_crtcs = manager->crtcs;
|
||||
|
||||
manager->serial ++;
|
||||
read_current_config (manager);
|
||||
make_logical_config (manager);
|
||||
invalidate_logical_config (manager);
|
||||
|
||||
g_signal_emit (manager, signals[MONITORS_CHANGED], 0);
|
||||
|
||||
g_free (old_monitor_infos);
|
||||
free_output_array (old_outputs, n_old_outputs);
|
||||
g_free (old_modes);
|
||||
g_free (old_crtcs);
|
||||
|
Loading…
Reference in New Issue
Block a user