Commit 09cfec04 authored by Alberts Muktupāvels's avatar Alberts Muktupāvels

backends: take drm-connector panel-orientation property into account

Based on mutter commit:
mutter@7917b083
parent 9fb0bcaf
/*
* Copyright (C) 2016 Red Hat
* Copyright (C) 2017 Alberts Muktupāvels
* Copyright (C) 2017-2019 Alberts Muktupāvels
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -90,7 +90,7 @@ derive_monitor_transform (GfMonitor *monitor)
main_output = gf_monitor_get_main_output (monitor);
return main_output->crtc->transform;
return gf_monitor_crtc_to_logical_transform (monitor, main_output->crtc->transform);
}
static void
......
/*
* Copyright (C) 2016 Red Hat
* Copyright (C) 2017 Alberts Muktupāvels
* Copyright (C) 2017-2019 Alberts Muktupāvels
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -511,10 +511,9 @@ assign_monitor_crtc (GfMonitor *monitor,
}
transform = data->logical_monitor_config->transform;
if (gf_monitor_manager_is_transform_handled (data->monitor_manager,
crtc, transform))
crtc_transform = transform;
else
crtc_transform = gf_monitor_logical_to_crtc_transform (monitor, transform);
if (!gf_monitor_manager_is_transform_handled (data->monitor_manager,
crtc, crtc_transform))
crtc_transform = GF_MONITOR_TRANSFORM_NORMAL;
gf_monitor_calculate_crtc_pos (monitor, mode, output, crtc_transform,
......
......@@ -231,6 +231,12 @@ gf_monitor_transform_is_rotated (GfMonitorTransform transform)
return (transform % 2);
}
static inline gboolean
gf_monitor_transform_is_flipped (GfMonitorTransform transform)
{
return (transform >= GF_MONITOR_TRANSFORM_FLIPPED);
}
G_END_DECLS
#endif
/*
* Copyright (C) 2016 Red Hat
* Copyright (C) 2017 Alberts Muktupāvels
* Copyright (C) 2017-2019 Alberts Muktupāvels
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -52,10 +52,10 @@ generate_modes (GfMonitorNormal *normal)
crtc_mode = output->modes[i];
mode = g_new0 (GfMonitorMode, 1);
mode->spec.width = crtc_mode->width;
mode->spec.height = crtc_mode->height;
mode->spec.refresh_rate = crtc_mode->refresh_rate;
mode->spec.flags = crtc_mode->flags & HANDLED_CRTC_MODE_FLAGS;
mode->spec = gf_monitor_create_spec (monitor,
crtc_mode->width,
crtc_mode->height,
crtc_mode);
mode->id = gf_monitor_mode_spec_generate_id (&mode->spec);
......
/*
* Copyright (C) 2016 Red Hat
* Copyright (C) 2017 Alberts Muktupāvels
* Copyright (C) 2017-2019 Alberts Muktupāvels
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -88,134 +88,145 @@ struct _GfMonitorClass
gint *height);
};
GfGpu *gf_monitor_get_gpu (GfMonitor *monitor);
GfGpu *gf_monitor_get_gpu (GfMonitor *monitor);
gboolean gf_monitor_is_mode_assigned (GfMonitor *monitor,
GfMonitorMode *mode);
gboolean gf_monitor_is_mode_assigned (GfMonitor *monitor,
GfMonitorMode *mode);
void gf_monitor_append_output (GfMonitor *monitor,
GfOutput *output);
void gf_monitor_append_output (GfMonitor *monitor,
GfOutput *output);
void gf_monitor_set_winsys_id (GfMonitor *monitor,
glong winsys_id);
void gf_monitor_set_winsys_id (GfMonitor *monitor,
glong winsys_id);
void gf_monitor_set_preferred_mode (GfMonitor *monitor,
GfMonitorMode *mode);
void gf_monitor_set_preferred_mode (GfMonitor *monitor,
GfMonitorMode *mode);
void gf_monitor_generate_spec (GfMonitor *monitor);
GfMonitorModeSpec gf_monitor_create_spec (GfMonitor *monitor,
int width,
int height,
GfCrtcMode *crtc_mode);
gboolean gf_monitor_add_mode (GfMonitor *monitor,
GfMonitorMode *monitor_mode,
gboolean replace);
void gf_monitor_generate_spec (GfMonitor *monitor);
void gf_monitor_mode_free (GfMonitorMode *monitor_mode);
gboolean gf_monitor_add_mode (GfMonitor *monitor,
GfMonitorMode *monitor_mode,
gboolean replace);
gchar *gf_monitor_mode_spec_generate_id (GfMonitorModeSpec *spec);
void gf_monitor_mode_free (GfMonitorMode *monitor_mode);
GfMonitorSpec *gf_monitor_get_spec (GfMonitor *monitor);
gchar *gf_monitor_mode_spec_generate_id (GfMonitorModeSpec *spec);
gboolean gf_monitor_is_active (GfMonitor *monitor);
GfMonitorSpec *gf_monitor_get_spec (GfMonitor *monitor);
GfOutput *gf_monitor_get_main_output (GfMonitor *monitor);
gboolean gf_monitor_is_active (GfMonitor *monitor);
gboolean gf_monitor_is_primary (GfMonitor *monitor);
GfOutput *gf_monitor_get_main_output (GfMonitor *monitor);
gboolean gf_monitor_supports_underscanning (GfMonitor *monitor);
gboolean gf_monitor_is_primary (GfMonitor *monitor);
gboolean gf_monitor_is_underscanning (GfMonitor *monitor);
gboolean gf_monitor_supports_underscanning (GfMonitor *monitor);
gboolean gf_monitor_is_laptop_panel (GfMonitor *monitor);
gboolean gf_monitor_is_underscanning (GfMonitor *monitor);
gboolean gf_monitor_is_same_as (GfMonitor *monitor,
GfMonitor *other_monitor);
gboolean gf_monitor_is_laptop_panel (GfMonitor *monitor);
GList *gf_monitor_get_outputs (GfMonitor *monitor);
gboolean gf_monitor_is_same_as (GfMonitor *monitor,
GfMonitor *other_monitor);
void gf_monitor_get_current_resolution (GfMonitor *monitor,
int *width,
int *height);
GList *gf_monitor_get_outputs (GfMonitor *monitor);
void gf_monitor_derive_layout (GfMonitor *monitor,
GfRectangle *layout);
void gf_monitor_get_current_resolution (GfMonitor *monitor,
int *width,
int *height);
void gf_monitor_get_physical_dimensions (GfMonitor *monitor,
gint *width_mm,
gint *height_mm);
void gf_monitor_derive_layout (GfMonitor *monitor,
GfRectangle *layout);
const gchar *gf_monitor_get_connector (GfMonitor *monitor);
void gf_monitor_get_physical_dimensions (GfMonitor *monitor,
gint *width_mm,
gint *height_mm);
const gchar *gf_monitor_get_vendor (GfMonitor *monitor);
const gchar *gf_monitor_get_connector (GfMonitor *monitor);
const gchar *gf_monitor_get_product (GfMonitor *monitor);
const gchar *gf_monitor_get_vendor (GfMonitor *monitor);
const gchar *gf_monitor_get_serial (GfMonitor *monitor);
const gchar *gf_monitor_get_product (GfMonitor *monitor);
GfConnectorType gf_monitor_get_connector_type (GfMonitor *monitor);
const gchar *gf_monitor_get_serial (GfMonitor *monitor);
gboolean gf_monitor_get_suggested_position (GfMonitor *monitor,
gint *x,
gint *y);
GfConnectorType gf_monitor_get_connector_type (GfMonitor *monitor);
GfLogicalMonitor *gf_monitor_get_logical_monitor (GfMonitor *monitor);
GfMonitorTransform gf_monitor_logical_to_crtc_transform (GfMonitor *monitor,
GfMonitorTransform transform);
GfMonitorMode *gf_monitor_get_mode_from_id (GfMonitor *monitor,
const gchar *monitor_mode_id);
GfMonitorTransform gf_monitor_crtc_to_logical_transform (GfMonitor *monitor,
GfMonitorTransform transform);
GfMonitorMode *gf_monitor_get_mode_from_spec (GfMonitor *monitor,
GfMonitorModeSpec *monitor_mode_spec);
gboolean gf_monitor_get_suggested_position (GfMonitor *monitor,
gint *x,
gint *y);
GfMonitorMode *gf_monitor_get_preferred_mode (GfMonitor *monitor);
GfLogicalMonitor *gf_monitor_get_logical_monitor (GfMonitor *monitor);
GfMonitorMode *gf_monitor_get_current_mode (GfMonitor *monitor);
GfMonitorMode *gf_monitor_get_mode_from_id (GfMonitor *monitor,
const gchar *monitor_mode_id);
void gf_monitor_derive_current_mode (GfMonitor *monitor);
GfMonitorMode *gf_monitor_get_mode_from_spec (GfMonitor *monitor,
GfMonitorModeSpec *monitor_mode_spec);
void gf_monitor_set_current_mode (GfMonitor *monitor,
GfMonitorMode *mode);
GfMonitorMode *gf_monitor_get_preferred_mode (GfMonitor *monitor);
GList *gf_monitor_get_modes (GfMonitor *monitor);
GfMonitorMode *gf_monitor_get_current_mode (GfMonitor *monitor);
void gf_monitor_calculate_crtc_pos (GfMonitor *monitor,
GfMonitorMode *monitor_mode,
GfOutput *output,
GfMonitorTransform crtc_transform,
gint *out_x,
gint *out_y);
void gf_monitor_derive_current_mode (GfMonitor *monitor);
gfloat gf_monitor_calculate_mode_scale (GfMonitor *monitor,
GfMonitorMode *monitor_mode);
void gf_monitor_set_current_mode (GfMonitor *monitor,
GfMonitorMode *mode);
gfloat *gf_monitor_calculate_supported_scales (GfMonitor *monitor,
GfMonitorMode *monitor_mode,
GfMonitorScalesConstraint constraints,
gint *n_supported_scales);
GList *gf_monitor_get_modes (GfMonitor *monitor);
const gchar *gf_monitor_mode_get_id (GfMonitorMode *monitor_mode);
void gf_monitor_calculate_crtc_pos (GfMonitor *monitor,
GfMonitorMode *monitor_mode,
GfOutput *output,
GfMonitorTransform crtc_transform,
gint *out_x,
gint *out_y);
GfMonitorModeSpec *gf_monitor_mode_get_spec (GfMonitorMode *monitor_mode);
gfloat gf_monitor_calculate_mode_scale (GfMonitor *monitor,
GfMonitorMode *monitor_mode);
void gf_monitor_mode_get_resolution (GfMonitorMode *monitor_mode,
gint *width,
gint *height);
gfloat *gf_monitor_calculate_supported_scales (GfMonitor *monitor,
GfMonitorMode *monitor_mode,
GfMonitorScalesConstraint constraints,
gint *n_supported_scales);
gfloat gf_monitor_mode_get_refresh_rate (GfMonitorMode *monitor_mode);
const gchar *gf_monitor_mode_get_id (GfMonitorMode *monitor_mode);
GfCrtcModeFlag gf_monitor_mode_get_flags (GfMonitorMode *monitor_mode);
GfMonitorModeSpec *gf_monitor_mode_get_spec (GfMonitorMode *monitor_mode);
gboolean gf_monitor_mode_foreach_crtc (GfMonitor *monitor,
GfMonitorMode *mode,
GfMonitorModeFunc func,
gpointer user_data,
GError **error);
void gf_monitor_mode_get_resolution (GfMonitorMode *monitor_mode,
gint *width,
gint *height);
gboolean gf_monitor_mode_foreach_output (GfMonitor *monitor,
GfMonitorMode *mode,
GfMonitorModeFunc func,
gpointer user_data,
GError **error);
gfloat gf_monitor_mode_get_refresh_rate (GfMonitorMode *monitor_mode);
gboolean gf_verify_monitor_mode_spec (GfMonitorModeSpec *mode_spec,
GError **error);
GfCrtcModeFlag gf_monitor_mode_get_flags (GfMonitorMode *monitor_mode);
gboolean gf_monitor_mode_foreach_crtc (GfMonitor *monitor,
GfMonitorMode *mode,
GfMonitorModeFunc func,
gpointer user_data,
GError **error);
gboolean gf_monitor_mode_foreach_output (GfMonitor *monitor,
GfMonitorMode *mode,
GfMonitorModeFunc func,
gpointer user_data,
GError **error);
gboolean gf_verify_monitor_mode_spec (GfMonitorModeSpec *mode_spec,
GError **error);
G_END_DECLS
......
/*
* Copyright (C) 2016 Red Hat
* Copyright (C) 2017 Alberts Muktupāvels
* Copyright (C) 2017-2019 Alberts Muktupāvels
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -138,10 +138,10 @@ create_tiled_monitor_mode (GfMonitorTiled *tiled,
calculate_tiled_size (monitor, &width, &height);
mode->parent.spec.width = width;
mode->parent.spec.height = height;
mode->parent.spec.refresh_rate = reference_crtc_mode->refresh_rate;
mode->parent.spec.flags = reference_crtc_mode->flags & HANDLED_CRTC_MODE_FLAGS;
mode->parent.spec = gf_monitor_create_spec (monitor,
width,
height,
reference_crtc_mode);
mode->parent.id = gf_monitor_mode_spec_generate_id (&mode->parent.spec);
mode->parent.crtc_modes = g_new0 (GfMonitorCrtcMode, g_list_length (outputs));
......@@ -192,10 +192,10 @@ create_untiled_monitor_mode (GfMonitorTiled *tiled,
mode = g_new0 (GfMonitorModeTiled, 1);
mode->is_tiled = FALSE;
mode->parent.spec.width = crtc_mode->width;
mode->parent.spec.height = crtc_mode->height;
mode->parent.spec.refresh_rate = crtc_mode->refresh_rate;
mode->parent.spec.flags = crtc_mode->flags & HANDLED_CRTC_MODE_FLAGS;
mode->parent.spec = gf_monitor_create_spec (monitor,
crtc_mode->width,
crtc_mode->height,
crtc_mode);
mode->parent.id = gf_monitor_mode_spec_generate_id (&mode->parent.spec);
mode->parent.crtc_modes = g_new0 (GfMonitorCrtcMode, g_list_length (outputs));
......
/*
* Copyright (C) 2016 Red Hat
* Copyright (C) 2017 Alberts Muktupāvels
* Copyright (C) 2017-2019 Alberts Muktupāvels
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -422,6 +422,34 @@ gf_monitor_set_preferred_mode (GfMonitor *monitor,
priv->preferred_mode = mode;
}
GfMonitorModeSpec
gf_monitor_create_spec (GfMonitor *monitor,
int width,
int height,
GfCrtcMode *crtc_mode)
{
GfOutput *output;
GfMonitorModeSpec spec;
output = gf_monitor_get_main_output (monitor);
if (gf_monitor_transform_is_rotated (output->panel_orientation_transform))
{
int temp;
temp = width;
width = height;
height = temp;
}
spec.width = width;
spec.height = height;
spec.refresh_rate = crtc_mode->refresh_rate;
spec.flags = crtc_mode->flags & HANDLED_CRTC_MODE_FLAGS;
return spec;
}
void
gf_monitor_generate_spec (GfMonitor *monitor)
{
......@@ -678,6 +706,41 @@ gf_monitor_get_connector_type (GfMonitor *monitor)
return output->connector_type;
}
GfMonitorTransform
gf_monitor_logical_to_crtc_transform (GfMonitor *monitor,
GfMonitorTransform transform)
{
GfOutput *output;
GfMonitorTransform new_transform;
output = gf_monitor_get_main_output (monitor);
new_transform = (transform + output->panel_orientation_transform) %
GF_MONITOR_TRANSFORM_FLIPPED;
if (gf_monitor_transform_is_flipped (transform))
new_transform += GF_MONITOR_TRANSFORM_FLIPPED;
return new_transform;
}
GfMonitorTransform
gf_monitor_crtc_to_logical_transform (GfMonitor *monitor,
GfMonitorTransform transform)
{
GfOutput *output;
GfMonitorTransform new_transform;
output = gf_monitor_get_main_output (monitor);
new_transform = (transform + GF_MONITOR_TRANSFORM_FLIPPED -
output->panel_orientation_transform) %
GF_MONITOR_TRANSFORM_FLIPPED;
if (gf_monitor_transform_is_flipped (transform))
new_transform += GF_MONITOR_TRANSFORM_FLIPPED;
return new_transform;
}
gboolean
gf_monitor_get_suggested_position (GfMonitor *monitor,
gint *x,
......
......@@ -55,58 +55,59 @@ typedef struct
struct _GfOutput
{
GObject parent;
GObject parent;
GfGpu *gpu;
GfGpu *gpu;
/* The CRTC driving this output, NULL if the output is not enabled */
GfCrtc *crtc;
GfCrtc *crtc;
/* The low-level ID of this output, used to apply back configuration */
glong winsys_id;
gchar *name;
gchar *vendor;
gchar *product;
gchar *serial;
gint width_mm;
gint height_mm;
glong winsys_id;
gchar *name;
gchar *vendor;
gchar *product;
gchar *serial;
gint width_mm;
gint height_mm;
GfConnectorType connector_type;
GfConnectorType connector_type;
GfMonitorTransform panel_orientation_transform;
GfCrtcMode *preferred_mode;
GfCrtcMode **modes;
guint n_modes;
GfCrtcMode *preferred_mode;
GfCrtcMode **modes;
guint n_modes;
GfCrtc **possible_crtcs;
guint n_possible_crtcs;
GfCrtc **possible_crtcs;
guint n_possible_crtcs;
GfOutput **possible_clones;
guint n_possible_clones;
GfOutput **possible_clones;
guint n_possible_clones;
gint backlight;
gint backlight_min;
gint backlight_max;
gint backlight;
gint backlight_min;
gint backlight_max;
/* Used when changing configuration */
gboolean is_dirty;
gboolean is_dirty;
/* The low-level bits used to build the high-level info in GfLogicalMonitor */
gboolean is_primary;
gboolean is_presentation;
gboolean is_underscanning;
gboolean supports_underscanning;
gboolean is_primary;
gboolean is_presentation;
gboolean is_underscanning;
gboolean supports_underscanning;
gpointer driver_private;
GDestroyNotify driver_notify;
gpointer driver_private;
GDestroyNotify driver_notify;
/* Get a new preferred mode on hotplug events, to handle
* dynamic guest resizing
*/
gboolean hotplug_mode_update;
gint suggested_x;
gint suggested_y;
gboolean hotplug_mode_update;
gint suggested_x;
gint suggested_y;
GfTileInfo tile_info;
GfTileInfo tile_info;
};
#define GF_TYPE_OUTPUT (gf_output_get_type ())
......
......@@ -375,6 +375,52 @@ output_get_connector_type (GfOutput *output)
return GF_CONNECTOR_TYPE_Unknown;
}
static GfMonitorTransform
output_get_panel_orientation_transform (GfOutput *output)
{
Display *xdisplay;
unsigned long nitems;
unsigned long bytes_after;
Atom atom;
Atom actual_type;
int actual_format;
unsigned char *buffer;
char *str;
GfMonitorTransform transform;
xdisplay = xdisplay_from_output (output);
buffer = NULL;
str = NULL;
atom = XInternAtom (xdisplay, "panel orientation", False);
XRRGetOutputProperty (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)
{
g_free (buffer);
return GF_MONITOR_TRANSFORM_NORMAL;
}
str = XGetAtomName (xdisplay, *(Atom *) buffer);
g_free (buffer);
transform = GF_MONITOR_TRANSFORM_NORMAL;
if (strcmp (str, "Upside Down") == 0)
transform = GF_MONITOR_TRANSFORM_180;
else if (strcmp (str, "Left Side Up") == 0)
transform = GF_MONITOR_TRANSFORM_90;
else if (strcmp (str, "Right Side Up") == 0)
transform = GF_MONITOR_TRANSFORM_270;
g_free (str);
return transform;
}
static void
output_get_tile_info (GfOutput *output)
{
......@@ -727,6 +773,7 @@ gf_create_xrandr_output (GfGpuXrandr *gpu_xrandr,
output->suggested_x = output_get_suggested_x (output);
output->suggested_y = output_get_suggested_y (output);
output->connector_type = output_get_connector_type (output);
output->panel_orientation_transform = output_get_panel_orientation_transform (output);
output_get_tile_info (output);
output_get_modes (output, xrandr_output);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment