display: Adapt to new Mutter interface with scaling per mode
New Mutter GetCurrentState now provides a list of available scales, we need to use these values in order to define an UI that shows them all.
This commit is contained in:
parent
a23aa64ec7
commit
cca9663d87
5 changed files with 191 additions and 93 deletions
|
@ -21,17 +21,17 @@
|
||||||
|
|
||||||
#include "cc-display-config-dbus.h"
|
#include "cc-display-config-dbus.h"
|
||||||
|
|
||||||
#define MODE_FORMAT "(iiddu)"
|
#define MODE_FORMAT "(iiddadu)"
|
||||||
#define MODES_FORMAT "a" MODE_FORMAT
|
#define MODES_FORMAT "a" MODE_FORMAT
|
||||||
|
|
||||||
#define MONITOR_SPEC_FORMAT "(ssss)"
|
#define MONITOR_SPEC_FORMAT "(ssss)"
|
||||||
#define MONITOR_FORMAT "(" MONITOR_SPEC_FORMAT MODES_FORMAT "a{sv})"
|
#define MONITOR_FORMAT "(" MONITOR_SPEC_FORMAT MODES_FORMAT "a{sv})"
|
||||||
#define MONITORS_FORMAT "a" MONITOR_FORMAT
|
#define MONITORS_FORMAT "a" MONITOR_FORMAT
|
||||||
|
|
||||||
#define LOGICAL_MONITOR_FORMAT "(iiduba" MONITOR_SPEC_FORMAT "a{sv})"
|
#define LOGICAL_MONITOR_MONITORS_FORMAT "a" MONITOR_SPEC_FORMAT
|
||||||
|
#define LOGICAL_MONITOR_FORMAT "(iidub" LOGICAL_MONITOR_MONITORS_FORMAT "a{sv})"
|
||||||
#define LOGICAL_MONITORS_FORMAT "a" LOGICAL_MONITOR_FORMAT
|
#define LOGICAL_MONITORS_FORMAT "a" LOGICAL_MONITOR_FORMAT
|
||||||
|
|
||||||
#define CURRENT_STATE_FORMAT "(u" MONITORS_FORMAT LOGICAL_MONITORS_FORMAT "ad" "a{sv})"
|
#define CURRENT_STATE_FORMAT "(u" MONITORS_FORMAT LOGICAL_MONITORS_FORMAT "a{sv})"
|
||||||
|
|
||||||
typedef enum _CcDisplayModeFlags
|
typedef enum _CcDisplayModeFlags
|
||||||
{
|
{
|
||||||
|
@ -47,6 +47,7 @@ struct _CcDisplayModeDBus
|
||||||
int height;
|
int height;
|
||||||
double refresh_rate;
|
double refresh_rate;
|
||||||
double preferred_scale;
|
double preferred_scale;
|
||||||
|
GArray *supported_scales;
|
||||||
guint32 flags;
|
guint32 flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -80,6 +81,36 @@ cc_display_mode_dbus_get_resolution (CcDisplayMode *pself,
|
||||||
*h = self->height;
|
*h = self->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const double *
|
||||||
|
cc_display_mode_dbus_get_supported_scales (CcDisplayMode *pself)
|
||||||
|
{
|
||||||
|
CcDisplayModeDBus *self = CC_DISPLAY_MODE_DBUS (pself);
|
||||||
|
|
||||||
|
return (const double *) self->supported_scales->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static double
|
||||||
|
cc_display_mode_dbus_get_preferred_scale (CcDisplayMode *pself)
|
||||||
|
{
|
||||||
|
CcDisplayModeDBus *self = CC_DISPLAY_MODE_DBUS (pself);
|
||||||
|
|
||||||
|
return self->preferred_scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
cc_display_mode_dbus_is_supported_scale (CcDisplayMode *pself,
|
||||||
|
double scale)
|
||||||
|
{
|
||||||
|
CcDisplayModeDBus *self = CC_DISPLAY_MODE_DBUS (pself);
|
||||||
|
|
||||||
|
guint i;
|
||||||
|
for (i = 0; i < self->supported_scales->len; i++)
|
||||||
|
if (g_array_index (self->supported_scales, double, i) == scale)
|
||||||
|
return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
cc_display_mode_dbus_is_interlaced (CcDisplayMode *pself)
|
cc_display_mode_dbus_is_interlaced (CcDisplayMode *pself)
|
||||||
{
|
{
|
||||||
|
@ -106,11 +137,16 @@ cc_display_mode_dbus_get_freq_f (CcDisplayMode *pself)
|
||||||
static void
|
static void
|
||||||
cc_display_mode_dbus_init (CcDisplayModeDBus *self)
|
cc_display_mode_dbus_init (CcDisplayModeDBus *self)
|
||||||
{
|
{
|
||||||
|
self->supported_scales = g_array_new (TRUE, TRUE, sizeof (double));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cc_display_mode_dbus_finalize (GObject *object)
|
cc_display_mode_dbus_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
|
CcDisplayModeDBus *self = CC_DISPLAY_MODE_DBUS (object);
|
||||||
|
|
||||||
|
g_array_free (self->supported_scales, TRUE);
|
||||||
|
|
||||||
G_OBJECT_CLASS (cc_display_mode_dbus_parent_class)->finalize (object);
|
G_OBJECT_CLASS (cc_display_mode_dbus_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,6 +159,8 @@ cc_display_mode_dbus_class_init (CcDisplayModeDBusClass *klass)
|
||||||
gobject_class->finalize = cc_display_mode_dbus_finalize;
|
gobject_class->finalize = cc_display_mode_dbus_finalize;
|
||||||
|
|
||||||
parent_class->get_resolution = cc_display_mode_dbus_get_resolution;
|
parent_class->get_resolution = cc_display_mode_dbus_get_resolution;
|
||||||
|
parent_class->get_supported_scales = cc_display_mode_dbus_get_supported_scales;
|
||||||
|
parent_class->get_preferred_scale = cc_display_mode_dbus_get_preferred_scale;
|
||||||
parent_class->is_interlaced = cc_display_mode_dbus_is_interlaced;
|
parent_class->is_interlaced = cc_display_mode_dbus_is_interlaced;
|
||||||
parent_class->get_freq = cc_display_mode_dbus_get_freq;
|
parent_class->get_freq = cc_display_mode_dbus_get_freq;
|
||||||
parent_class->get_freq_f = cc_display_mode_dbus_get_freq_f;
|
parent_class->get_freq_f = cc_display_mode_dbus_get_freq_f;
|
||||||
|
@ -131,6 +169,8 @@ cc_display_mode_dbus_class_init (CcDisplayModeDBusClass *klass)
|
||||||
static CcDisplayModeDBus *
|
static CcDisplayModeDBus *
|
||||||
cc_display_mode_dbus_new (GVariant *variant)
|
cc_display_mode_dbus_new (GVariant *variant)
|
||||||
{
|
{
|
||||||
|
double d;
|
||||||
|
GVariantIter *scales_iter;
|
||||||
CcDisplayModeDBus *self = g_object_new (CC_TYPE_DISPLAY_MODE_DBUS, NULL);
|
CcDisplayModeDBus *self = g_object_new (CC_TYPE_DISPLAY_MODE_DBUS, NULL);
|
||||||
|
|
||||||
g_variant_get (variant, MODE_FORMAT,
|
g_variant_get (variant, MODE_FORMAT,
|
||||||
|
@ -138,8 +178,14 @@ cc_display_mode_dbus_new (GVariant *variant)
|
||||||
&self->height,
|
&self->height,
|
||||||
&self->refresh_rate,
|
&self->refresh_rate,
|
||||||
&self->preferred_scale,
|
&self->preferred_scale,
|
||||||
|
&scales_iter,
|
||||||
&self->flags);
|
&self->flags);
|
||||||
|
|
||||||
|
while (g_variant_iter_next (scales_iter, "d", &d))
|
||||||
|
g_array_append_val (self->supported_scales, d);
|
||||||
|
|
||||||
|
g_variant_iter_free (scales_iter);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,9 +308,6 @@ static void
|
||||||
cc_display_config_dbus_ensure_gapless (CcDisplayConfigDBus *self);
|
cc_display_config_dbus_ensure_gapless (CcDisplayConfigDBus *self);
|
||||||
static void
|
static void
|
||||||
cc_display_config_dbus_make_linear (CcDisplayConfigDBus *self);
|
cc_display_config_dbus_make_linear (CcDisplayConfigDBus *self);
|
||||||
static gboolean
|
|
||||||
cc_display_config_dbus_is_supported_scale (CcDisplayConfigDBus *self,
|
|
||||||
double scale);
|
|
||||||
|
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
|
@ -591,6 +634,9 @@ cc_display_monitor_dbus_set_mode (CcDisplayMonitor *pself,
|
||||||
existing layout here. */
|
existing layout here. */
|
||||||
if (w1 != w2 || h1 != h2)
|
if (w1 != w2 || h1 != h2)
|
||||||
cc_display_config_dbus_make_linear (self->config);
|
cc_display_config_dbus_make_linear (self->config);
|
||||||
|
|
||||||
|
if (!cc_display_mode_dbus_is_supported_scale (mode, cc_display_monitor_get_scale (pself)))
|
||||||
|
cc_display_monitor_set_scale (pself, cc_display_mode_get_preferred_scale (mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -623,7 +669,10 @@ cc_display_monitor_dbus_set_scale (CcDisplayMonitor *pself,
|
||||||
{
|
{
|
||||||
CcDisplayMonitorDBus *self = CC_DISPLAY_MONITOR_DBUS (pself);
|
CcDisplayMonitorDBus *self = CC_DISPLAY_MONITOR_DBUS (pself);
|
||||||
|
|
||||||
if (!cc_display_config_dbus_is_supported_scale (self->config, scale))
|
if (!self->current_mode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!cc_display_mode_dbus_is_supported_scale (self->current_mode, scale))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!self->logical_monitor)
|
if (!self->logical_monitor)
|
||||||
|
@ -812,8 +861,6 @@ struct _CcDisplayConfigDBus
|
||||||
gboolean supports_changing_layout_mode;
|
gboolean supports_changing_layout_mode;
|
||||||
CcDisplayLayoutMode layout_mode;
|
CcDisplayLayoutMode layout_mode;
|
||||||
|
|
||||||
GArray *supported_scales;
|
|
||||||
|
|
||||||
GList *monitors;
|
GList *monitors;
|
||||||
CcDisplayMonitorDBus *primary;
|
CcDisplayMonitorDBus *primary;
|
||||||
|
|
||||||
|
@ -1115,14 +1162,6 @@ cc_display_config_dbus_apply (CcDisplayConfig *pself,
|
||||||
return config_apply (self, CC_DISPLAY_CONFIG_METHOD_PERSISTENT, error);
|
return config_apply (self, CC_DISPLAY_CONFIG_METHOD_PERSISTENT, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const double *
|
|
||||||
cc_display_config_dbus_get_supported_scales (CcDisplayConfig *pself)
|
|
||||||
{
|
|
||||||
CcDisplayConfigDBus *self = CC_DISPLAY_CONFIG_DBUS (pself);
|
|
||||||
|
|
||||||
return (const double *) self->supported_scales->data;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
cc_display_config_dbus_is_layout_logical (CcDisplayConfig *pself)
|
cc_display_config_dbus_is_layout_logical (CcDisplayConfig *pself)
|
||||||
{
|
{
|
||||||
|
@ -1138,7 +1177,6 @@ cc_display_config_dbus_init (CcDisplayConfigDBus *self)
|
||||||
self->supports_mirroring = TRUE;
|
self->supports_mirroring = TRUE;
|
||||||
self->supports_changing_layout_mode = FALSE;
|
self->supports_changing_layout_mode = FALSE;
|
||||||
self->layout_mode = CC_DISPLAY_LAYOUT_MODE_LOGICAL;
|
self->layout_mode = CC_DISPLAY_LAYOUT_MODE_LOGICAL;
|
||||||
self->supported_scales = g_array_new (TRUE, TRUE, sizeof (double));
|
|
||||||
self->logical_monitors = g_hash_table_new (NULL, NULL);
|
self->logical_monitors = g_hash_table_new (NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1265,9 +1303,7 @@ cc_display_config_dbus_constructed (GObject *object)
|
||||||
CcDisplayConfigDBus *self = CC_DISPLAY_CONFIG_DBUS (object);
|
CcDisplayConfigDBus *self = CC_DISPLAY_CONFIG_DBUS (object);
|
||||||
GVariantIter *monitors;
|
GVariantIter *monitors;
|
||||||
GVariantIter *logical_monitors;
|
GVariantIter *logical_monitors;
|
||||||
GVariantIter *scales;
|
|
||||||
GVariantIter *props;
|
GVariantIter *props;
|
||||||
double d;
|
|
||||||
const char *s;
|
const char *s;
|
||||||
GVariant *v;
|
GVariant *v;
|
||||||
|
|
||||||
|
@ -1276,12 +1312,8 @@ cc_display_config_dbus_constructed (GObject *object)
|
||||||
&self->serial,
|
&self->serial,
|
||||||
&monitors,
|
&monitors,
|
||||||
&logical_monitors,
|
&logical_monitors,
|
||||||
&scales,
|
|
||||||
&props);
|
&props);
|
||||||
|
|
||||||
while (g_variant_iter_next (scales, "d", &d))
|
|
||||||
g_array_append_val (self->supported_scales, d);
|
|
||||||
|
|
||||||
while (g_variant_iter_next (props, "{&sv}", &s, &v))
|
while (g_variant_iter_next (props, "{&sv}", &s, &v))
|
||||||
{
|
{
|
||||||
if (g_str_equal (s, "supports-mirroring"))
|
if (g_str_equal (s, "supports-mirroring"))
|
||||||
|
@ -1308,7 +1340,6 @@ cc_display_config_dbus_constructed (GObject *object)
|
||||||
|
|
||||||
g_variant_iter_free (monitors);
|
g_variant_iter_free (monitors);
|
||||||
g_variant_iter_free (logical_monitors);
|
g_variant_iter_free (logical_monitors);
|
||||||
g_variant_iter_free (scales);
|
|
||||||
g_variant_iter_free (props);
|
g_variant_iter_free (props);
|
||||||
|
|
||||||
G_OBJECT_CLASS (cc_display_config_dbus_parent_class)->constructed (object);
|
G_OBJECT_CLASS (cc_display_config_dbus_parent_class)->constructed (object);
|
||||||
|
@ -1364,7 +1395,6 @@ cc_display_config_dbus_finalize (GObject *object)
|
||||||
g_clear_pointer (&self->state, g_variant_unref);
|
g_clear_pointer (&self->state, g_variant_unref);
|
||||||
g_clear_object (&self->connection);
|
g_clear_object (&self->connection);
|
||||||
|
|
||||||
g_array_free (self->supported_scales, TRUE);
|
|
||||||
g_list_foreach (self->monitors, (GFunc) g_object_unref, NULL);
|
g_list_foreach (self->monitors, (GFunc) g_object_unref, NULL);
|
||||||
g_clear_pointer (&self->monitors, g_list_free);
|
g_clear_pointer (&self->monitors, g_list_free);
|
||||||
g_clear_pointer (&self->logical_monitors, g_hash_table_destroy);
|
g_clear_pointer (&self->logical_monitors, g_hash_table_destroy);
|
||||||
|
@ -1392,7 +1422,6 @@ cc_display_config_dbus_class_init (CcDisplayConfigDBusClass *klass)
|
||||||
parent_class->is_cloning = cc_display_config_dbus_is_cloning;
|
parent_class->is_cloning = cc_display_config_dbus_is_cloning;
|
||||||
parent_class->set_cloning = cc_display_config_dbus_set_cloning;
|
parent_class->set_cloning = cc_display_config_dbus_set_cloning;
|
||||||
parent_class->get_cloning_modes = cc_display_config_dbus_get_cloning_modes;
|
parent_class->get_cloning_modes = cc_display_config_dbus_get_cloning_modes;
|
||||||
parent_class->get_supported_scales = cc_display_config_dbus_get_supported_scales;
|
|
||||||
parent_class->is_layout_logical = cc_display_config_dbus_is_layout_logical;
|
parent_class->is_layout_logical = cc_display_config_dbus_is_layout_logical;
|
||||||
|
|
||||||
pspec = g_param_spec_variant ("state",
|
pspec = g_param_spec_variant ("state",
|
||||||
|
@ -1632,14 +1661,3 @@ cc_display_config_dbus_make_linear (CcDisplayConfigDBus *self)
|
||||||
|
|
||||||
g_list_free (logical_monitors);
|
g_list_free (logical_monitors);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
cc_display_config_dbus_is_supported_scale (CcDisplayConfigDBus *self,
|
|
||||||
double scale)
|
|
||||||
{
|
|
||||||
guint i;
|
|
||||||
for (i = 0; i < self->supported_scales->len; i++)
|
|
||||||
if (g_array_index (self->supported_scales, double, i) == scale)
|
|
||||||
return TRUE;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
|
@ -46,6 +46,20 @@ cc_display_mode_rr_get_resolution (CcDisplayMode *pself,
|
||||||
*h = gnome_rr_mode_get_height (self->rr_mode);
|
*h = gnome_rr_mode_get_height (self->rr_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static double rr_supported_scales[] = { 1.0, 0.0 };
|
||||||
|
|
||||||
|
static const double *
|
||||||
|
cc_display_mode_rr_get_supported_scales (CcDisplayMode *pself)
|
||||||
|
{
|
||||||
|
return rr_supported_scales;
|
||||||
|
}
|
||||||
|
|
||||||
|
static double
|
||||||
|
cc_display_mode_rr_get_preferred_scale (CcDisplayMode *pself)
|
||||||
|
{
|
||||||
|
return rr_supported_scales[0];
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
cc_display_mode_rr_is_interlaced (CcDisplayMode *pself)
|
cc_display_mode_rr_is_interlaced (CcDisplayMode *pself)
|
||||||
{
|
{
|
||||||
|
@ -90,6 +104,8 @@ cc_display_mode_rr_class_init (CcDisplayModeRRClass *klass)
|
||||||
gobject_class->finalize = cc_display_mode_rr_finalize;
|
gobject_class->finalize = cc_display_mode_rr_finalize;
|
||||||
|
|
||||||
parent_class->get_resolution = cc_display_mode_rr_get_resolution;
|
parent_class->get_resolution = cc_display_mode_rr_get_resolution;
|
||||||
|
parent_class->get_supported_scales = cc_display_mode_rr_get_supported_scales;
|
||||||
|
parent_class->get_preferred_scale = cc_display_mode_rr_get_preferred_scale;
|
||||||
parent_class->is_interlaced = cc_display_mode_rr_is_interlaced;
|
parent_class->is_interlaced = cc_display_mode_rr_is_interlaced;
|
||||||
parent_class->get_freq = cc_display_mode_rr_get_freq;
|
parent_class->get_freq = cc_display_mode_rr_get_freq;
|
||||||
parent_class->get_freq_f = cc_display_mode_rr_get_freq_f;
|
parent_class->get_freq_f = cc_display_mode_rr_get_freq_f;
|
||||||
|
@ -339,7 +355,7 @@ cc_display_monitor_rr_set_position (CcDisplayMonitor *pself,
|
||||||
static double
|
static double
|
||||||
cc_display_monitor_rr_get_scale (CcDisplayMonitor *pself)
|
cc_display_monitor_rr_get_scale (CcDisplayMonitor *pself)
|
||||||
{
|
{
|
||||||
return 1.0;
|
return rr_supported_scales[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -429,9 +445,6 @@ cc_display_monitor_rr_new (GnomeRROutput *output,
|
||||||
return CC_DISPLAY_MONITOR (self);
|
return CC_DISPLAY_MONITOR (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static double rr_supported_scales[] = { 1.0, 0.0 };
|
|
||||||
|
|
||||||
struct _CcDisplayConfigRR
|
struct _CcDisplayConfigRR
|
||||||
{
|
{
|
||||||
CcDisplayConfig parent_instance;
|
CcDisplayConfig parent_instance;
|
||||||
|
@ -556,12 +569,6 @@ cc_display_config_rr_get_cloning_modes (CcDisplayConfig *pself)
|
||||||
return self->clone_modes;
|
return self->clone_modes;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const double *
|
|
||||||
cc_display_config_rr_get_supported_scales (CcDisplayConfig *pself)
|
|
||||||
{
|
|
||||||
return rr_supported_scales;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
cc_display_config_rr_is_layout_logical (CcDisplayConfig *pself)
|
cc_display_config_rr_is_layout_logical (CcDisplayConfig *pself)
|
||||||
{
|
{
|
||||||
|
@ -687,7 +694,6 @@ cc_display_config_rr_class_init (CcDisplayConfigRRClass *klass)
|
||||||
parent_class->is_cloning = cc_display_config_rr_is_cloning;
|
parent_class->is_cloning = cc_display_config_rr_is_cloning;
|
||||||
parent_class->set_cloning = cc_display_config_rr_set_cloning;
|
parent_class->set_cloning = cc_display_config_rr_set_cloning;
|
||||||
parent_class->get_cloning_modes = cc_display_config_rr_get_cloning_modes;
|
parent_class->get_cloning_modes = cc_display_config_rr_get_cloning_modes;
|
||||||
parent_class->get_supported_scales = cc_display_config_rr_get_supported_scales;
|
|
||||||
parent_class->is_layout_logical = cc_display_config_rr_is_layout_logical;
|
parent_class->is_layout_logical = cc_display_config_rr_is_layout_logical;
|
||||||
|
|
||||||
pspec = g_param_spec_object ("gnome-rr-screen",
|
pspec = g_param_spec_object ("gnome-rr-screen",
|
||||||
|
|
|
@ -39,6 +39,18 @@ cc_display_mode_get_resolution (CcDisplayMode *self, int *w, int *h)
|
||||||
return CC_DISPLAY_MODE_GET_CLASS (self)->get_resolution (self, w, h);
|
return CC_DISPLAY_MODE_GET_CLASS (self)->get_resolution (self, w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const double *
|
||||||
|
cc_display_mode_get_supported_scales (CcDisplayMode *self)
|
||||||
|
{
|
||||||
|
return CC_DISPLAY_MODE_GET_CLASS (self)->get_supported_scales (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
cc_display_mode_get_preferred_scale (CcDisplayMode *self)
|
||||||
|
{
|
||||||
|
return CC_DISPLAY_MODE_GET_CLASS (self)->get_preferred_scale (self);
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
cc_display_mode_is_interlaced (CcDisplayMode *self)
|
cc_display_mode_is_interlaced (CcDisplayMode *self)
|
||||||
{
|
{
|
||||||
|
@ -272,12 +284,6 @@ cc_display_config_get_cloning_modes (CcDisplayConfig *self)
|
||||||
return CC_DISPLAY_CONFIG_GET_CLASS (self)->get_cloning_modes (self);
|
return CC_DISPLAY_CONFIG_GET_CLASS (self)->get_cloning_modes (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
const double *
|
|
||||||
cc_display_config_get_supported_scales (CcDisplayConfig *self)
|
|
||||||
{
|
|
||||||
return CC_DISPLAY_CONFIG_GET_CLASS (self)->get_supported_scales (self);
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
cc_display_config_is_layout_logical (CcDisplayConfig *self)
|
cc_display_config_is_layout_logical (CcDisplayConfig *self)
|
||||||
{
|
{
|
||||||
|
|
|
@ -79,6 +79,8 @@ struct _CcDisplayModeClass
|
||||||
GObjectClass parent_class;
|
GObjectClass parent_class;
|
||||||
|
|
||||||
void (*get_resolution) (CcDisplayMode *self, int *w, int *h);
|
void (*get_resolution) (CcDisplayMode *self, int *w, int *h);
|
||||||
|
const double * (*get_supported_scales) (CcDisplayMode *self);
|
||||||
|
double (*get_preferred_scale) (CcDisplayMode *self);
|
||||||
gboolean (*is_interlaced) (CcDisplayMode *self);
|
gboolean (*is_interlaced) (CcDisplayMode *self);
|
||||||
int (*get_freq) (CcDisplayMode *self);
|
int (*get_freq) (CcDisplayMode *self);
|
||||||
double (*get_freq_f) (CcDisplayMode *self);
|
double (*get_freq_f) (CcDisplayMode *self);
|
||||||
|
@ -134,7 +136,6 @@ struct _CcDisplayConfigClass
|
||||||
gboolean (*is_cloning) (CcDisplayConfig *self);
|
gboolean (*is_cloning) (CcDisplayConfig *self);
|
||||||
void (*set_cloning) (CcDisplayConfig *self, gboolean clone);
|
void (*set_cloning) (CcDisplayConfig *self, gboolean clone);
|
||||||
GList * (*get_cloning_modes) (CcDisplayConfig *self);
|
GList * (*get_cloning_modes) (CcDisplayConfig *self);
|
||||||
const double * (*get_supported_scales) (CcDisplayConfig *self);
|
|
||||||
gboolean (*is_layout_logical) (CcDisplayConfig *self);
|
gboolean (*is_layout_logical) (CcDisplayConfig *self);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -147,7 +148,6 @@ gboolean cc_display_config_apply (CcDisplayConfig *config, GError **error);
|
||||||
gboolean cc_display_config_is_cloning (CcDisplayConfig *config);
|
gboolean cc_display_config_is_cloning (CcDisplayConfig *config);
|
||||||
void cc_display_config_set_cloning (CcDisplayConfig *config, gboolean clone);
|
void cc_display_config_set_cloning (CcDisplayConfig *config, gboolean clone);
|
||||||
GList *cc_display_config_get_cloning_modes (CcDisplayConfig *config);
|
GList *cc_display_config_get_cloning_modes (CcDisplayConfig *config);
|
||||||
const double *cc_display_config_get_supported_scales (CcDisplayConfig *self);
|
|
||||||
gboolean cc_display_config_is_layout_logical (CcDisplayConfig *self);
|
gboolean cc_display_config_is_layout_logical (CcDisplayConfig *self);
|
||||||
|
|
||||||
const char * cc_display_monitor_get_display_name (CcDisplayMonitor *monitor);
|
const char * cc_display_monitor_get_display_name (CcDisplayMonitor *monitor);
|
||||||
|
@ -188,9 +188,8 @@ void cc_display_monitor_set_position (CcDisplayMonitor *monitor,
|
||||||
void cc_display_mode_get_resolution (CcDisplayMode *mode,
|
void cc_display_mode_get_resolution (CcDisplayMode *mode,
|
||||||
int *width,
|
int *width,
|
||||||
int *height);
|
int *height);
|
||||||
void cc_display_mode_get_dimensions (CcDisplayMode *mode,
|
const double *cc_display_mode_get_supported_scales (CcDisplayMode *self);
|
||||||
int *width,
|
double cc_display_mode_get_preferred_scale (CcDisplayMode *self);
|
||||||
int *hegiht);
|
|
||||||
gboolean cc_display_mode_is_interlaced (CcDisplayMode *mode);
|
gboolean cc_display_mode_is_interlaced (CcDisplayMode *mode);
|
||||||
int cc_display_mode_get_freq (CcDisplayMode *mode);
|
int cc_display_mode_get_freq (CcDisplayMode *mode);
|
||||||
double cc_display_mode_get_freq_f (CcDisplayMode *mode);
|
double cc_display_mode_get_freq_f (CcDisplayMode *mode);
|
||||||
|
|
|
@ -82,6 +82,7 @@ struct _CcDisplayPanelPrivate
|
||||||
GtkWidget *arrange_button;
|
GtkWidget *arrange_button;
|
||||||
GtkWidget *res_combo;
|
GtkWidget *res_combo;
|
||||||
GtkWidget *freq_combo;
|
GtkWidget *freq_combo;
|
||||||
|
GtkWidget *scale_slider;
|
||||||
GHashTable *res_freqs;
|
GHashTable *res_freqs;
|
||||||
GtkWidget *scaling_switch;
|
GtkWidget *scaling_switch;
|
||||||
GtkWidget *rotate_left_button;
|
GtkWidget *rotate_left_button;
|
||||||
|
@ -1698,6 +1699,72 @@ setup_frequency_combo_box (CcDisplayPanel *panel,
|
||||||
gtk_combo_box_set_active (GTK_COMBO_BOX (priv->freq_combo), 0);
|
gtk_combo_box_set_active (GTK_COMBO_BOX (priv->freq_combo), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static guint
|
||||||
|
n_supported_scales (CcDisplayMode *mode)
|
||||||
|
{
|
||||||
|
const double *scales = cc_display_mode_get_supported_scales (mode);
|
||||||
|
guint n = 0;
|
||||||
|
|
||||||
|
while (scales[n] != 0.0)
|
||||||
|
n++;
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
setup_scaling_slider (CcDisplayPanel *panel,
|
||||||
|
CcDisplayMode *resolution_mode)
|
||||||
|
{
|
||||||
|
CcDisplayPanelPrivate *priv = panel->priv;
|
||||||
|
guint i;
|
||||||
|
guint n;
|
||||||
|
const double *scales;
|
||||||
|
|
||||||
|
scales = cc_display_mode_get_supported_scales (resolution_mode);
|
||||||
|
n = n_supported_scales (resolution_mode);
|
||||||
|
|
||||||
|
if (n > 0)
|
||||||
|
{
|
||||||
|
GtkAdjustment *adj;
|
||||||
|
double current_scale;
|
||||||
|
int current_index = -1;
|
||||||
|
|
||||||
|
current_scale = cc_display_monitor_get_scale (priv->current_output);
|
||||||
|
adj = gtk_range_get_adjustment (GTK_RANGE (priv->scale_slider));
|
||||||
|
|
||||||
|
gtk_scale_clear_marks (GTK_SCALE (priv->scale_slider));
|
||||||
|
|
||||||
|
gtk_adjustment_set_step_increment (adj, 1);
|
||||||
|
gtk_adjustment_set_lower (adj, 0);
|
||||||
|
gtk_adjustment_set_upper (adj, n-1);
|
||||||
|
gtk_scale_set_digits (GTK_SCALE (priv->scale_slider), 0);
|
||||||
|
|
||||||
|
for (i = 0; i < n; ++i)
|
||||||
|
{
|
||||||
|
double rounded_scale = round (scales[i] * 10) / 10;
|
||||||
|
double integral;
|
||||||
|
double fractional = modf (rounded_scale, &integral);
|
||||||
|
|
||||||
|
if (scales[i] == current_scale || (current_index < 0 && scales[i] == 1.0))
|
||||||
|
current_index = i;
|
||||||
|
|
||||||
|
if (fractional != 0 && (fractional != 0.5 || integral > 0))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
gchar *s = g_strdup_printf ("%.2lg×", scales[i]);
|
||||||
|
gtk_scale_add_mark (GTK_SCALE (priv->scale_slider), i, GTK_POS_TOP, s);
|
||||||
|
g_free (s);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_widget_show (priv->scale_slider);
|
||||||
|
gtk_range_set_value (GTK_RANGE (priv->scale_slider), current_index);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gtk_widget_hide (priv->scale_slider);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_mode_list (gpointer key,
|
free_mode_list (gpointer key,
|
||||||
gpointer value,
|
gpointer value,
|
||||||
|
@ -1782,6 +1849,7 @@ setup_resolution_combo_box (CcDisplayPanel *panel,
|
||||||
gtk_combo_box_set_active (GTK_COMBO_BOX (priv->res_combo), 0);
|
gtk_combo_box_set_active (GTK_COMBO_BOX (priv->res_combo), 0);
|
||||||
|
|
||||||
setup_frequency_combo_box (panel, current_mode);
|
setup_frequency_combo_box (panel, current_mode);
|
||||||
|
setup_scaling_slider (panel, current_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1988,6 +2056,7 @@ res_combo_changed (GtkComboBox *combo,
|
||||||
update_apply_button (panel);
|
update_apply_button (panel);
|
||||||
|
|
||||||
setup_frequency_combo_box (panel, mode);
|
setup_frequency_combo_box (panel, mode);
|
||||||
|
setup_scaling_slider (panel, mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2041,16 +2110,17 @@ underscan_switch_toggled (CcDisplayPanel *panel)
|
||||||
update_apply_button (panel);
|
update_apply_button (panel);
|
||||||
}
|
}
|
||||||
|
|
||||||
static guint
|
static double
|
||||||
n_supported_scales (CcDisplayConfig *config)
|
scale_slider_get_selected_scale (CcDisplayPanel *panel)
|
||||||
{
|
{
|
||||||
const double *scales = cc_display_config_get_supported_scales (config);
|
CcDisplayPanelPrivate *priv = panel->priv;
|
||||||
guint n = 0;
|
CcDisplayMode *mode = cc_display_monitor_get_mode (priv->current_output);
|
||||||
|
const double *scales = cc_display_mode_get_supported_scales (mode);
|
||||||
|
int selected = gtk_range_get_value (GTK_RANGE (priv->scale_slider));
|
||||||
|
|
||||||
while (scales[n] != 0.0)
|
g_return_val_if_fail (selected < n_supported_scales (mode), 1.0);
|
||||||
n++;
|
|
||||||
|
|
||||||
return n;
|
return scales[selected];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -2058,10 +2128,18 @@ scale_slider_changed (GtkRange *slider,
|
||||||
CcDisplayPanel *panel)
|
CcDisplayPanel *panel)
|
||||||
{
|
{
|
||||||
cc_display_monitor_set_scale (panel->priv->current_output,
|
cc_display_monitor_set_scale (panel->priv->current_output,
|
||||||
gtk_range_get_value (slider));
|
scale_slider_get_selected_scale (panel));
|
||||||
update_apply_button (panel);
|
update_apply_button (panel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
scale_slider_format_value (GtkScale *slider,
|
||||||
|
double value,
|
||||||
|
CcDisplayPanel *panel)
|
||||||
|
{
|
||||||
|
return g_strdup_printf ("%.3g", scale_slider_get_selected_scale (panel));
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
show_setup_dialog (CcDisplayPanel *panel)
|
show_setup_dialog (CcDisplayPanel *panel)
|
||||||
{
|
{
|
||||||
|
@ -2298,31 +2376,22 @@ show_setup_dialog (CcDisplayPanel *panel)
|
||||||
grid_pos++;
|
grid_pos++;
|
||||||
|
|
||||||
/* scale */
|
/* scale */
|
||||||
if (n_supported_scales (priv->current_config) > 1)
|
priv->scale_slider = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, NULL);
|
||||||
{
|
gtk_widget_set_no_show_all (priv->scale_slider, TRUE);
|
||||||
GtkWidget *slider;
|
|
||||||
const double *scales = cc_display_config_get_supported_scales (priv->current_config);
|
|
||||||
guint n = n_supported_scales (priv->current_config);
|
|
||||||
guint i = 0;
|
|
||||||
|
|
||||||
slider = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL,
|
g_signal_connect (priv->scale_slider, "format-value",
|
||||||
scales[0], scales[n - 1],
|
G_CALLBACK (scale_slider_format_value), panel);
|
||||||
scales[1] - scales[0]);
|
g_signal_connect (priv->scale_slider, "value-changed",
|
||||||
gtk_scale_set_draw_value (GTK_SCALE (slider), FALSE);
|
G_CALLBACK (scale_slider_changed), panel);
|
||||||
gtk_scale_set_has_origin (GTK_SCALE (slider), FALSE);
|
|
||||||
for (i = 0; i < n; i++)
|
|
||||||
{
|
|
||||||
gchar *s = g_strdup_printf ("%.1lg×", scales[i]);
|
|
||||||
gtk_scale_add_mark (GTK_SCALE (slider), scales[i], GTK_POS_TOP, s);
|
|
||||||
g_free (s);
|
|
||||||
}
|
|
||||||
gtk_range_set_value (GTK_RANGE (slider), cc_display_monitor_get_scale (priv->current_output));
|
|
||||||
g_signal_connect (slider, "value-changed", G_CALLBACK (scale_slider_changed), panel);
|
|
||||||
|
|
||||||
gtk_grid_attach (GTK_GRID (priv->config_grid), slider, 1, grid_pos, 1, 1);
|
gtk_scale_set_draw_value (GTK_SCALE (priv->scale_slider), TRUE);
|
||||||
|
gtk_range_set_round_digits (GTK_RANGE (priv->scale_slider), 2);
|
||||||
|
gtk_scale_set_value_pos (GTK_SCALE (priv->scale_slider), GTK_POS_BOTTOM);
|
||||||
|
gtk_scale_set_has_origin (GTK_SCALE (priv->scale_slider), FALSE);
|
||||||
|
gtk_grid_attach (GTK_GRID (priv->config_grid),
|
||||||
|
priv->scale_slider, 1, grid_pos, 1, 1);
|
||||||
gtk_widget_set_halign (priv->freq_combo, GTK_ALIGN_CENTER);
|
gtk_widget_set_halign (priv->freq_combo, GTK_ALIGN_CENTER);
|
||||||
grid_pos++;
|
grid_pos++;
|
||||||
}
|
|
||||||
|
|
||||||
was_clone = clone = cc_display_config_is_cloning (priv->current_config);
|
was_clone = clone = cc_display_config_is_cloning (priv->current_config);
|
||||||
primary = cc_display_monitor_is_primary (priv->current_output);
|
primary = cc_display_monitor_is_primary (priv->current_output);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue