mirror of
https://github.com/brl/mutter.git
synced 2025-02-23 08:24:09 +00:00
MonitorManager: Add support for overscan compensation
Some DRM drivers have added a consistent set of properties that allow compensating for the overscan that some TVs do, without the user being able to disable.
This commit is contained in:
parent
ca6e799b97
commit
cc53d48fa8
@ -65,6 +65,7 @@ typedef struct {
|
|||||||
|
|
||||||
gboolean is_primary;
|
gboolean is_primary;
|
||||||
gboolean is_presentation;
|
gboolean is_presentation;
|
||||||
|
gboolean is_underscanning;
|
||||||
} MetaOutputConfig;
|
} MetaOutputConfig;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -403,7 +404,8 @@ handle_start_element (GMarkupParseContext *context,
|
|||||||
strcmp (element_name, "reflect_x") == 0 ||
|
strcmp (element_name, "reflect_x") == 0 ||
|
||||||
strcmp (element_name, "reflect_y") == 0 ||
|
strcmp (element_name, "reflect_y") == 0 ||
|
||||||
strcmp (element_name, "primary") == 0 ||
|
strcmp (element_name, "primary") == 0 ||
|
||||||
strcmp (element_name, "presentation") == 0) && parser->unknown_count == 0)
|
strcmp (element_name, "presentation") == 0 ||
|
||||||
|
strcmp (element_name, "underscanning") == 0) && parser->unknown_count == 0)
|
||||||
{
|
{
|
||||||
parser->state = STATE_OUTPUT_FIELD;
|
parser->state = STATE_OUTPUT_FIELD;
|
||||||
|
|
||||||
@ -710,6 +712,8 @@ handle_text (GMarkupParseContext *context,
|
|||||||
parser->output.is_primary = read_bool (text, text_len, error);
|
parser->output.is_primary = read_bool (text, text_len, error);
|
||||||
else if (strcmp (parser->output_field, "presentation") == 0)
|
else if (strcmp (parser->output_field, "presentation") == 0)
|
||||||
parser->output.is_presentation = read_bool (text, text_len, error);
|
parser->output.is_presentation = read_bool (text, text_len, error);
|
||||||
|
else if (strcmp (parser->output_field, "underscanning") == 0)
|
||||||
|
parser->output.is_underscanning = read_bool (text, text_len, error);
|
||||||
else
|
else
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
return;
|
return;
|
||||||
@ -1427,6 +1431,7 @@ init_config_from_output (MetaOutputConfig *config,
|
|||||||
config->transform = output->crtc->transform;
|
config->transform = output->crtc->transform;
|
||||||
config->is_primary = output->is_primary;
|
config->is_primary = output->is_primary;
|
||||||
config->is_presentation = output->is_presentation;
|
config->is_presentation = output->is_presentation;
|
||||||
|
config->is_underscanning = output->is_underscanning;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1617,7 +1622,8 @@ meta_monitor_config_save (MetaMonitorConfig *self)
|
|||||||
" <reflect_x>%s</reflect_x>\n"
|
" <reflect_x>%s</reflect_x>\n"
|
||||||
" <reflect_y>no</reflect_y>\n"
|
" <reflect_y>no</reflect_y>\n"
|
||||||
" <primary>%s</primary>\n"
|
" <primary>%s</primary>\n"
|
||||||
" <presentation>%s</presentation>\n",
|
" <presentation>%s</presentation>\n"
|
||||||
|
" <underscanning>%s</underscanning>\n",
|
||||||
output->rect.width,
|
output->rect.width,
|
||||||
output->rect.height,
|
output->rect.height,
|
||||||
refresh_rate,
|
refresh_rate,
|
||||||
@ -1626,7 +1632,8 @@ meta_monitor_config_save (MetaMonitorConfig *self)
|
|||||||
rotation_map[output->transform & 0x3],
|
rotation_map[output->transform & 0x3],
|
||||||
output->transform >= META_MONITOR_TRANSFORM_FLIPPED ? "yes" : "no",
|
output->transform >= META_MONITOR_TRANSFORM_FLIPPED ? "yes" : "no",
|
||||||
output->is_primary ? "yes" : "no",
|
output->is_primary ? "yes" : "no",
|
||||||
output->is_presentation ? "yes" : "no");
|
output->is_presentation ? "yes" : "no",
|
||||||
|
output->is_underscanning ? "yes" : "no");
|
||||||
}
|
}
|
||||||
|
|
||||||
g_string_append (buffer, " </output>\n");
|
g_string_append (buffer, " </output>\n");
|
||||||
@ -1960,6 +1967,7 @@ meta_monitor_config_assign_crtcs (MetaConfiguration *config,
|
|||||||
&config->keys[i]);
|
&config->keys[i]);
|
||||||
output_info->is_primary = output_config->is_primary;
|
output_info->is_primary = output_config->is_primary;
|
||||||
output_info->is_presentation = output_config->is_presentation;
|
output_info->is_presentation = output_config->is_presentation;
|
||||||
|
output_info->is_underscanning = output_config->is_underscanning;
|
||||||
|
|
||||||
g_ptr_array_add (outputs, output_info);
|
g_ptr_array_add (outputs, output_info);
|
||||||
}
|
}
|
||||||
|
@ -132,6 +132,7 @@ struct _MetaOutput
|
|||||||
*/
|
*/
|
||||||
gboolean is_primary;
|
gboolean is_primary;
|
||||||
gboolean is_presentation;
|
gboolean is_presentation;
|
||||||
|
gboolean is_underscanning;
|
||||||
|
|
||||||
gpointer driver_private;
|
gpointer driver_private;
|
||||||
GDestroyNotify driver_notify;
|
GDestroyNotify driver_notify;
|
||||||
@ -230,6 +231,7 @@ struct _MetaOutputInfo {
|
|||||||
MetaOutput *output;
|
MetaOutput *output;
|
||||||
gboolean is_primary;
|
gboolean is_primary;
|
||||||
gboolean is_presentation;
|
gboolean is_presentation;
|
||||||
|
gboolean is_underscanning;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define META_TYPE_MONITOR_MANAGER (meta_monitor_manager_get_type ())
|
#define META_TYPE_MONITOR_MANAGER (meta_monitor_manager_get_type ())
|
||||||
|
@ -520,6 +520,8 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
|
|||||||
g_variant_new_boolean (output->is_presentation));
|
g_variant_new_boolean (output->is_presentation));
|
||||||
g_variant_builder_add (&properties, "{sv}", "connector-type",
|
g_variant_builder_add (&properties, "{sv}", "connector-type",
|
||||||
g_variant_new_string (get_connector_type_name (output->connector_type)));
|
g_variant_new_string (get_connector_type_name (output->connector_type)));
|
||||||
|
g_variant_builder_add (&properties, "{sv}", "underscanning",
|
||||||
|
g_variant_new_boolean (output->is_underscanning));
|
||||||
|
|
||||||
edid_file = manager_class->get_edid_file (manager, output);
|
edid_file = manager_class->get_edid_file (manager, output);
|
||||||
if (edid_file)
|
if (edid_file)
|
||||||
@ -808,7 +810,7 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
|
|||||||
while (g_variant_iter_loop (&output_iter, "(u@a{sv})", &output_index, &properties))
|
while (g_variant_iter_loop (&output_iter, "(u@a{sv})", &output_index, &properties))
|
||||||
{
|
{
|
||||||
MetaOutputInfo *output_info;
|
MetaOutputInfo *output_info;
|
||||||
gboolean primary, presentation;
|
gboolean primary, presentation, underscanning;
|
||||||
|
|
||||||
if (output_index >= manager->n_outputs)
|
if (output_index >= manager->n_outputs)
|
||||||
{
|
{
|
||||||
@ -827,6 +829,9 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
|
|||||||
if (g_variant_lookup (properties, "presentation", "b", &presentation))
|
if (g_variant_lookup (properties, "presentation", "b", &presentation))
|
||||||
output_info->is_presentation = presentation;
|
output_info->is_presentation = presentation;
|
||||||
|
|
||||||
|
if (g_variant_lookup (properties, "underscanning", "b", &underscanning))
|
||||||
|
output_info->is_underscanning = underscanning;
|
||||||
|
|
||||||
g_ptr_array_add (output_infos, output_info);
|
g_ptr_array_add (output_infos, output_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,6 +225,38 @@ output_get_presentation_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
|||||||
return output_get_boolean_property (manager_xrandr, output, "_MUTTER_PRESENTATION_OUTPUT");
|
return output_get_boolean_property (manager_xrandr, output, "_MUTTER_PRESENTATION_OUTPUT");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
output_get_underscanning_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
||||||
|
MetaOutput *output)
|
||||||
|
{
|
||||||
|
gboolean value = FALSE;
|
||||||
|
Atom atom, actual_type;
|
||||||
|
int actual_format;
|
||||||
|
unsigned long nitems, bytes_after;
|
||||||
|
unsigned char *buffer;
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
atom = XInternAtom (manager_xrandr->xdisplay, "underscan", False);
|
||||||
|
XRRGetOutputProperty (manager_xrandr->xdisplay,
|
||||||
|
(XID)output->winsys_id,
|
||||||
|
atom,
|
||||||
|
0, G_MAXLONG, False, False, XA_ATOM,
|
||||||
|
&actual_type, &actual_format,
|
||||||
|
&nitems, &bytes_after, &buffer);
|
||||||
|
|
||||||
|
if (actual_type != XA_ATOM || actual_format != 32 ||
|
||||||
|
nitems < 1)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
str = XGetAtomName (manager_xrandr->xdisplay, *(Atom *)buffer);
|
||||||
|
value = !strcmp(str, "on");
|
||||||
|
XFree (str);
|
||||||
|
|
||||||
|
out:
|
||||||
|
XFree (buffer);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
normalize_backlight (MetaOutput *output,
|
normalize_backlight (MetaOutput *output,
|
||||||
int hw_value)
|
int hw_value)
|
||||||
@ -756,6 +788,7 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
|
|||||||
|
|
||||||
meta_output->is_primary = ((XID)meta_output->winsys_id == primary_output);
|
meta_output->is_primary = ((XID)meta_output->winsys_id == primary_output);
|
||||||
meta_output->is_presentation = output_get_presentation_xrandr (manager_xrandr, meta_output);
|
meta_output->is_presentation = output_get_presentation_xrandr (manager_xrandr, meta_output);
|
||||||
|
meta_output->is_underscanning = output_get_underscanning_xrandr (manager_xrandr, meta_output);
|
||||||
output_get_backlight_limits_xrandr (manager_xrandr, meta_output);
|
output_get_backlight_limits_xrandr (manager_xrandr, meta_output);
|
||||||
|
|
||||||
if (!(meta_output->backlight_min == 0 && meta_output->backlight_max == 0))
|
if (!(meta_output->backlight_min == 0 && meta_output->backlight_max == 0))
|
||||||
@ -876,6 +909,27 @@ output_set_presentation_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
|||||||
(unsigned char*) &value, 1);
|
(unsigned char*) &value, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
output_set_underscanning_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
||||||
|
MetaOutput *output,
|
||||||
|
gboolean underscanning)
|
||||||
|
{
|
||||||
|
Atom prop, valueatom;
|
||||||
|
const char *value;
|
||||||
|
|
||||||
|
prop = XInternAtom (manager_xrandr->xdisplay, "underscan", False);
|
||||||
|
|
||||||
|
/* XXX: Also implement underscan border */
|
||||||
|
value = underscanning ? "on" : "off";
|
||||||
|
valueatom = XInternAtom (manager_xrandr->xdisplay, value, False);
|
||||||
|
|
||||||
|
XRRChangeOutputProperty (manager_xrandr->xdisplay,
|
||||||
|
(XID)output->winsys_id,
|
||||||
|
prop,
|
||||||
|
XA_ATOM, 32, PropModeReplace,
|
||||||
|
(unsigned char*) &valueatom, 1);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
||||||
MetaCRTCInfo **crtcs,
|
MetaCRTCInfo **crtcs,
|
||||||
@ -1071,8 +1125,13 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
|||||||
output_info->output,
|
output_info->output,
|
||||||
output_info->is_presentation);
|
output_info->is_presentation);
|
||||||
|
|
||||||
|
output_set_underscanning_xrandr (manager_xrandr,
|
||||||
|
output_info->output,
|
||||||
|
output_info->is_underscanning);
|
||||||
|
|
||||||
output->is_primary = output_info->is_primary;
|
output->is_primary = output_info->is_primary;
|
||||||
output->is_presentation = output_info->is_presentation;
|
output->is_presentation = output_info->is_presentation;
|
||||||
|
output->is_underscanning = output_info->is_underscanning;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable outputs not mentioned in the list */
|
/* Disable outputs not mentioned in the list */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user