diff options
Diffstat (limited to 'libmate-desktop')
-rw-r--r-- | libmate-desktop/Makefile.am | 1 | ||||
-rw-r--r-- | libmate-desktop/mate-rr-config.c | 837 | ||||
-rw-r--r-- | libmate-desktop/mate-rr-config.h | 190 | ||||
-rw-r--r-- | libmate-desktop/mate-rr-labeler.c | 212 | ||||
-rw-r--r-- | libmate-desktop/mate-rr-labeler.h | 16 | ||||
-rw-r--r-- | libmate-desktop/mate-rr-output-info.c | 246 | ||||
-rw-r--r-- | libmate-desktop/mate-rr-private.h | 30 | ||||
-rw-r--r-- | libmate-desktop/mate-rr.c | 221 | ||||
-rw-r--r-- | libmate-desktop/mate-rr.h | 34 |
9 files changed, 1077 insertions, 710 deletions
diff --git a/libmate-desktop/Makefile.am b/libmate-desktop/Makefile.am index 3f8a6e5..8459d5f 100644 --- a/libmate-desktop/Makefile.am +++ b/libmate-desktop/Makefile.am @@ -45,6 +45,7 @@ introspection_sources = \ display-name.c \ mate-rr.c \ mate-rr-config.c \ + mate-rr-output-info.c \ mate-rr-labeler.c \ mate-colorbutton.c \ mate-colorsel.c \ diff --git a/libmate-desktop/mate-rr-config.c b/libmate-desktop/mate-rr-config.c index 9f83c0c..1c13630 100644 --- a/libmate-desktop/mate-rr-config.c +++ b/libmate-desktop/mate-rr-config.c @@ -1,6 +1,8 @@ /* mate-rr-config.c + * -*- c-basic-offset: 4 -*- * * Copyright 2007, 2008, Red Hat, Inc. + * Copyright 2010 Giovanni Campagna * * This file is part of the Mate Library. * @@ -34,7 +36,6 @@ #include <X11/Xlib.h> #include <gdk/gdkx.h> -#undef MATE_DISABLE_DEPRECATED #include "mate-rr-config.h" #include "edid.h" @@ -79,16 +80,18 @@ typedef struct CrtcAssignment CrtcAssignment; static gboolean crtc_assignment_apply (CrtcAssignment *assign, guint32 timestamp, GError **error); -static CrtcAssignment *crtc_assignment_new (MateRRScreen *screen, - MateOutputInfo **outputs, - GError **error); +static CrtcAssignment *crtc_assignment_new (MateRRScreen *screen, + MateRROutputInfo **outputs, + GError **error); static void crtc_assignment_free (CrtcAssignment *assign); -static void output_free (MateOutputInfo *output); -static MateOutputInfo *output_copy (const MateOutputInfo *output); -static MateRRConfig * mate_rr_config_copy (const MateRRConfig *config); -G_DEFINE_BOXED_TYPE (MateOutputInfo, mate_rr_output_info, output_copy, output_free) -G_DEFINE_BOXED_TYPE (MateRRConfig, mate_rr_config, mate_rr_config_copy, mate_rr_config_free) +enum { + PROP_0, + PROP_SCREEN, + PROP_LAST +}; + +G_DEFINE_TYPE (MateRRConfig, mate_rr_config, G_TYPE_OBJECT) typedef struct Parser Parser; @@ -96,7 +99,7 @@ typedef struct Parser Parser; struct Parser { int config_file_version; - MateOutputInfo * output; + MateRROutputInfo * output; MateRRConfig * configuration; GPtrArray * outputs; GPtrArray * configurations; @@ -173,38 +176,38 @@ handle_start_element (GMarkupParseContext *context, int i; g_assert (parser->output == NULL); - parser->output = g_new0 (MateOutputInfo, 1); - parser->output->rotation = 0; + parser->output = g_object_new (MATE_TYPE_RR_OUTPUT_INFO, NULL); + parser->output->priv->rotation = 0; for (i = 0; attr_names[i] != NULL; ++i) { if (strcmp (attr_names[i], "name") == 0) { - parser->output->name = g_strdup (attr_values[i]); + parser->output->priv->name = g_strdup (attr_values[i]); break; } } - if (!parser->output->name) + if (!parser->output->priv->name) { /* This really shouldn't happen, but it's better to make * something up than to crash later. */ g_warning ("Malformed monitor configuration file"); - parser->output->name = g_strdup ("default"); + parser->output->priv->name = g_strdup ("default"); } - parser->output->connected = FALSE; - parser->output->on = FALSE; - parser->output->primary = FALSE; + parser->output->priv->connected = FALSE; + parser->output->priv->on = FALSE; + parser->output->priv->primary = FALSE; } else if (strcmp (name, "configuration") == 0) { g_assert (parser->configuration == NULL); - parser->configuration = g_new0 (MateRRConfig, 1); - parser->configuration->clone = FALSE; - parser->configuration->outputs = NULL; + parser->configuration = g_object_new (MATE_TYPE_RR_CONFIG, NULL); + parser->configuration->priv->clone = FALSE; + parser->configuration->priv->outputs = NULL; } else if (strcmp (name, "monitors") == 0) { @@ -234,8 +237,8 @@ handle_end_element (GMarkupParseContext *context, if (strcmp (name, "output") == 0) { /* If no rotation properties were set, just use MATE_RR_ROTATION_0 */ - if (parser->output->rotation == 0) - parser->output->rotation = MATE_RR_ROTATION_0; + if (parser->output->priv->rotation == 0) + parser->output->priv->rotation = MATE_RR_ROTATION_0; g_ptr_array_add (parser->outputs, parser->output); @@ -244,8 +247,8 @@ handle_end_element (GMarkupParseContext *context, else if (strcmp (name, "configuration") == 0) { g_ptr_array_add (parser->outputs, NULL); - parser->configuration->outputs = - (MateOutputInfo **)g_ptr_array_free (parser->outputs, FALSE); + parser->configuration->priv->outputs = + (MateRROutputInfo **)g_ptr_array_free (parser->outputs, FALSE); parser->outputs = g_ptr_array_new (); g_ptr_array_add (parser->configurations, parser->configuration); parser->configuration = NULL; @@ -267,96 +270,96 @@ handle_text (GMarkupParseContext *context, if (stack_is (parser, "vendor", "output", "configuration", TOPLEVEL_ELEMENT, NULL)) { - parser->output->connected = TRUE; + parser->output->priv->connected = TRUE; - strncpy (parser->output->vendor, text, 3); - parser->output->vendor[3] = 0; + strncpy ((gchar*) parser->output->priv->vendor, text, 3); + parser->output->priv->vendor[3] = 0; } else if (stack_is (parser, "clone", "configuration", TOPLEVEL_ELEMENT, NULL)) { if (strcmp (text, "yes") == 0) - parser->configuration->clone = TRUE; + parser->configuration->priv->clone = TRUE; } else if (stack_is (parser, "product", "output", "configuration", TOPLEVEL_ELEMENT, NULL)) { - parser->output->connected = TRUE; + parser->output->priv->connected = TRUE; - parser->output->product = parse_int (text); + parser->output->priv->product = parse_int (text); } else if (stack_is (parser, "serial", "output", "configuration", TOPLEVEL_ELEMENT, NULL)) { - parser->output->connected = TRUE; + parser->output->priv->connected = TRUE; - parser->output->serial = parse_uint (text); + parser->output->priv->serial = parse_uint (text); } else if (stack_is (parser, "width", "output", "configuration", TOPLEVEL_ELEMENT, NULL)) { - parser->output->on = TRUE; + parser->output->priv->on = TRUE; - parser->output->width = parse_int (text); + parser->output->priv->width = parse_int (text); } else if (stack_is (parser, "x", "output", "configuration", TOPLEVEL_ELEMENT, NULL)) { - parser->output->on = TRUE; + parser->output->priv->on = TRUE; - parser->output->x = parse_int (text); + parser->output->priv->x = parse_int (text); } else if (stack_is (parser, "y", "output", "configuration", TOPLEVEL_ELEMENT, NULL)) { - parser->output->on = TRUE; + parser->output->priv->on = TRUE; - parser->output->y = parse_int (text); + parser->output->priv->y = parse_int (text); } else if (stack_is (parser, "height", "output", "configuration", TOPLEVEL_ELEMENT, NULL)) { - parser->output->on = TRUE; + parser->output->priv->on = TRUE; - parser->output->height = parse_int (text); + parser->output->priv->height = parse_int (text); } else if (stack_is (parser, "rate", "output", "configuration", TOPLEVEL_ELEMENT, NULL)) { - parser->output->on = TRUE; + parser->output->priv->on = TRUE; - parser->output->rate = parse_int (text); + parser->output->priv->rate = parse_int (text); } else if (stack_is (parser, "rotation", "output", "configuration", TOPLEVEL_ELEMENT, NULL)) { if (strcmp (text, "normal") == 0) { - parser->output->rotation |= MATE_RR_ROTATION_0; + parser->output->priv->rotation |= MATE_RR_ROTATION_0; } else if (strcmp (text, "left") == 0) { - parser->output->rotation |= MATE_RR_ROTATION_90; + parser->output->priv->rotation |= MATE_RR_ROTATION_90; } else if (strcmp (text, "upside_down") == 0) { - parser->output->rotation |= MATE_RR_ROTATION_180; + parser->output->priv->rotation |= MATE_RR_ROTATION_180; } else if (strcmp (text, "right") == 0) { - parser->output->rotation |= MATE_RR_ROTATION_270; + parser->output->priv->rotation |= MATE_RR_ROTATION_270; } } else if (stack_is (parser, "reflect_x", "output", "configuration", TOPLEVEL_ELEMENT, NULL)) { if (strcmp (text, "yes") == 0) { - parser->output->rotation |= MATE_RR_REFLECT_X; + parser->output->priv->rotation |= MATE_RR_REFLECT_X; } } else if (stack_is (parser, "reflect_y", "output", "configuration", TOPLEVEL_ELEMENT, NULL)) { if (strcmp (text, "yes") == 0) { - parser->output->rotation |= MATE_RR_REFLECT_Y; + parser->output->priv->rotation |= MATE_RR_REFLECT_Y; } } else if (stack_is (parser, "primary", "output", "configuration", TOPLEVEL_ELEMENT, NULL)) { if (strcmp (text, "yes") == 0) { - parser->output->primary = TRUE; + parser->output->priv->primary = TRUE; } } else @@ -374,16 +377,16 @@ parser_free (Parser *parser) g_assert (parser != NULL); if (parser->output) - output_free (parser->output); + g_object_unref (parser->output); if (parser->configuration) - mate_rr_config_free (parser->configuration); + g_object_unref (parser->configuration); for (i = 0; i < parser->outputs->len; ++i) { - MateOutputInfo *output = parser->outputs->pdata[i]; + MateRROutputInfo *output = parser->outputs->pdata[i]; - output_free (output); + g_object_unref (output); } g_ptr_array_free (parser->outputs, TRUE); @@ -392,7 +395,7 @@ parser_free (Parser *parser) { MateRRConfig *config = parser->configurations->pdata[i]; - mate_rr_config_free (config); + g_object_unref (config); } g_ptr_array_free (parser->configurations, TRUE); @@ -443,10 +446,54 @@ out: return result; } -MateRRConfig * -mate_rr_config_new_current (MateRRScreen *screen) +static void +mate_rr_config_init (MateRRConfig *self) +{ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, MATE_TYPE_RR_CONFIG, MateRRConfigPrivate); + + self->priv->clone = FALSE; + self->priv->screen = NULL; + self->priv->outputs = NULL; +} + +static void +mate_rr_config_set_property (GObject *gobject, guint property_id, const GValue *value, GParamSpec *property) +{ + MateRRConfig *self = MATE_RR_CONFIG (gobject); + + switch (property_id) { + case PROP_SCREEN: + self->priv->screen = g_value_dup_object (value); + return; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, property); + } +} + +static void +mate_rr_config_finalize (GObject *gobject) +{ + MateRRConfig *self = MATE_RR_CONFIG (gobject); + + if (self->priv->screen) + g_object_unref (self->priv->screen); + + if (self->priv->outputs) { + int i; + + for (i = 0; self->priv->outputs[i] != NULL; i++) { + MateRROutputInfo *output = self->priv->outputs[i]; + g_object_unref (output); + } + g_free (self->priv->outputs); + } + + G_OBJECT_CLASS (mate_rr_config_parent_class)->finalize (gobject); +} + +gboolean +mate_rr_config_load_current (MateRRConfig *config, GError **error) { - MateRRConfig *config; GPtrArray *a; MateRROutput **rr_outputs; int i; @@ -454,34 +501,32 @@ mate_rr_config_new_current (MateRRScreen *screen) int clone_height = -1; int last_x; - g_return_val_if_fail (screen != NULL, NULL); + g_return_val_if_fail (MATE_IS_RR_CONFIG (config), FALSE); - config = g_new0 (MateRRConfig, 1); a = g_ptr_array_new (); + rr_outputs = mate_rr_screen_list_outputs (config->priv->screen); - rr_outputs = mate_rr_screen_list_outputs (screen); - - config->clone = FALSE; + config->priv->clone = FALSE; for (i = 0; rr_outputs[i] != NULL; ++i) { MateRROutput *rr_output = rr_outputs[i]; - MateOutputInfo *output = g_new0 (MateOutputInfo, 1); + MateRROutputInfo *output = g_object_new (MATE_TYPE_RR_OUTPUT_INFO, NULL); MateRRMode *mode = NULL; const guint8 *edid_data = mate_rr_output_get_edid_data (rr_output); MateRRCrtc *crtc; - output->name = g_strdup (mate_rr_output_get_name (rr_output)); - output->connected = mate_rr_output_is_connected (rr_output); + output->priv->name = g_strdup (mate_rr_output_get_name (rr_output)); + output->priv->connected = mate_rr_output_is_connected (rr_output); - if (!output->connected) + if (!output->priv->connected) { - output->x = -1; - output->y = -1; - output->width = -1; - output->height = -1; - output->rate = -1; - output->rotation = MATE_RR_ROTATION_0; + output->priv->x = -1; + output->priv->y = -1; + output->priv->width = -1; + output->priv->height = -1; + output->priv->rate = -1; + output->priv->rotation = MATE_RR_ROTATION_0; } else { @@ -492,24 +537,24 @@ mate_rr_config_new_current (MateRRScreen *screen) if (info) { - memcpy (output->vendor, info->manufacturer_code, - sizeof (output->vendor)); + memcpy (output->priv->vendor, info->manufacturer_code, + sizeof (output->priv->vendor)); - output->product = info->product_code; - output->serial = info->serial_number; - output->aspect = info->aspect_ratio; + output->priv->product = info->product_code; + output->priv->serial = info->serial_number; + output->priv->aspect = info->aspect_ratio; } else { - strcpy (output->vendor, "???"); - output->product = 0; - output->serial = 0; + strcpy (output->priv->vendor, "???"); + output->priv->product = 0; + output->priv->serial = 0; } if (mate_rr_output_is_laptop (rr_output)) - output->display_name = g_strdup (_("Laptop")); + output->priv->display_name = g_strdup (_("Laptop")); else - output->display_name = make_display_name (info); + output->priv->display_name = make_display_name (info); g_free (info); @@ -518,28 +563,28 @@ mate_rr_config_new_current (MateRRScreen *screen) if (crtc && mode) { - output->on = TRUE; + output->priv->on = TRUE; - mate_rr_crtc_get_position (crtc, &output->x, &output->y); - output->width = mate_rr_mode_get_width (mode); - output->height = mate_rr_mode_get_height (mode); - output->rate = mate_rr_mode_get_freq (mode); - output->rotation = mate_rr_crtc_get_current_rotation (crtc); + mate_rr_crtc_get_position (crtc, &output->priv->x, &output->priv->y); + output->priv->width = mate_rr_mode_get_width (mode); + output->priv->height = mate_rr_mode_get_height (mode); + output->priv->rate = mate_rr_mode_get_freq (mode); + output->priv->rotation = mate_rr_crtc_get_current_rotation (crtc); - if (output->x == 0 && output->y == 0) { + if (output->priv->x == 0 && output->priv->y == 0) { if (clone_width == -1) { - clone_width = output->width; - clone_height = output->height; - } else if (clone_width == output->width && - clone_height == output->height) { - config->clone = TRUE; + clone_width = output->priv->width; + clone_height = output->priv->height; + } else if (clone_width == output->priv->width && + clone_height == output->priv->height) { + config->priv->clone = TRUE; } } } else { - output->on = FALSE; - config->clone = FALSE; + output->priv->on = FALSE; + config->priv->clone = FALSE; } /* Get preferred size for the monitor */ @@ -565,117 +610,152 @@ mate_rr_config_new_current (MateRRScreen *screen) if (mode) { - output->pref_width = mate_rr_mode_get_width (mode); - output->pref_height = mate_rr_mode_get_height (mode); + output->priv->pref_width = mate_rr_mode_get_width (mode); + output->priv->pref_height = mate_rr_mode_get_height (mode); } else { /* Pick some random numbers. This should basically never happen */ - output->pref_width = 1024; - output->pref_height = 768; + output->priv->pref_width = 1024; + output->priv->pref_height = 768; } } - output->primary = mate_rr_output_get_is_primary (rr_output); + output->priv->primary = mate_rr_output_get_is_primary (rr_output); g_ptr_array_add (a, output); } g_ptr_array_add (a, NULL); - config->outputs = (MateOutputInfo **)g_ptr_array_free (a, FALSE); + config->priv->outputs = (MateRROutputInfo **)g_ptr_array_free (a, FALSE); /* Walk the outputs computing the right-most edge of all * lit-up displays */ last_x = 0; - for (i = 0; config->outputs[i] != NULL; ++i) + for (i = 0; config->priv->outputs[i] != NULL; ++i) { - MateOutputInfo *output = config->outputs[i]; + MateRROutputInfo *output = config->priv->outputs[i]; - if (output->on) + if (output->priv->on) { - last_x = MAX (last_x, output->x + output->width); + last_x = MAX (last_x, output->priv->x + output->priv->width); } } /* Now position all off displays to the right of the * on displays */ - for (i = 0; config->outputs[i] != NULL; ++i) + for (i = 0; config->priv->outputs[i] != NULL; ++i) { - MateOutputInfo *output = config->outputs[i]; + MateRROutputInfo *output = config->priv->outputs[i]; - if (output->connected && !output->on) + if (output->priv->connected && !output->priv->on) { - output->x = last_x; - last_x = output->x + output->width; + output->priv->x = last_x; + last_x = output->priv->x + output->priv->width; } } g_assert (mate_rr_config_match (config, config)); - - return config; + + return TRUE; } -static void -output_free (MateOutputInfo *output) +gboolean +mate_rr_config_load_filename (MateRRConfig *result, const char *filename, GError **error) { - if (output->display_name) - g_free (output->display_name); + MateRRConfig *current; + MateRRConfig **configs; + gboolean found = FALSE; - if (output->name) - g_free (output->name); - - g_free (output); -} + g_return_val_if_fail (MATE_IS_RR_CONFIG (result), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); -static MateOutputInfo * -output_copy (const MateOutputInfo *output) -{ - MateOutputInfo *copy = g_new0 (MateOutputInfo, 1); + if (filename == NULL) + filename = mate_rr_config_get_intended_filename (); - *copy = *output; + current = mate_rr_config_new_current (result->priv->screen, error); - copy->name = g_strdup (output->name); - copy->display_name = g_strdup (output->display_name); + configs = configurations_read_from_file (filename, error); - return copy; + if (configs) + { + int i; + + for (i = 0; configs[i] != NULL; ++i) + { + if (mate_rr_config_match (configs[i], current)) + { + int j; + GPtrArray *array; + result->priv->clone = configs[i]->priv->clone; + + array = g_ptr_array_new (); + for (j = 0; configs[i]->priv->outputs[j] != NULL; j++) { + g_ptr_array_add (array, configs[i]->priv->outputs[i]); + } + g_ptr_array_add (array, NULL); + result->priv->outputs = (MateRROutputInfo **) g_ptr_array_free (array, FALSE); + + found = TRUE; + break; + } + g_object_unref (configs[i]); + } + g_free (configs); + + if (!found) + g_set_error (error, MATE_RR_ERROR, MATE_RR_ERROR_NO_MATCHING_CONFIG, + _("none of the saved display configurations matched the active configuration")); + } + + g_object_unref (current); + return found; } static void -outputs_free (MateOutputInfo **outputs) +mate_rr_config_class_init (MateRRConfigClass *klass) { - int i; + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - g_assert (outputs != NULL); + g_type_class_add_private (klass, sizeof (MateRROutputInfoPrivate)); - for (i = 0; outputs[i] != NULL; ++i) - output_free (outputs[i]); + gobject_class->set_property = mate_rr_config_set_property; + gobject_class->finalize = mate_rr_config_finalize; - g_free (outputs); + g_object_class_install_property (gobject_class, PROP_SCREEN, + g_param_spec_object ("screen", "Screen", "The MateRRScreen this config applies to", MATE_TYPE_RR_SCREEN, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); } -void -mate_rr_config_free (MateRRConfig *config) +MateRRConfig * +mate_rr_config_new_current (MateRRScreen *screen, GError **error) { - g_return_if_fail (config != NULL); - outputs_free (config->outputs); - - g_free (config); + MateRRConfig *self = g_object_new (MATE_TYPE_RR_CONFIG, "screen", screen, NULL); + + if (mate_rr_config_load_current (self, error)) + return self; + else + { + g_object_unref (self); + return NULL; + } } -static void -configurations_free (MateRRConfig **configurations) +MateRRConfig * +mate_rr_config_new_stored (MateRRScreen *screen, GError **error) { - int i; - - g_assert (configurations != NULL); + MateRRConfig *self = g_object_new (MATE_TYPE_RR_CONFIG, "screen", screen, NULL); - for (i = 0; configurations[i] != NULL; ++i) - mate_rr_config_free (configurations[i]); - - g_free (configurations); + if (mate_rr_config_load_filename (self, NULL, error)) + return self; + else + { + g_object_unref (self); + return NULL; + } } static gboolean @@ -720,75 +800,75 @@ out: } static gboolean -output_match (MateOutputInfo *output1, MateOutputInfo *output2) +output_match (MateRROutputInfo *output1, MateRROutputInfo *output2) { - g_assert (output1 != NULL); - g_assert (output2 != NULL); + g_assert (MATE_IS_RR_OUTPUT_INFO (output1)); + g_assert (MATE_IS_RR_OUTPUT_INFO (output2)); - if (strcmp (output1->name, output2->name) != 0) + if (strcmp (output1->priv->name, output2->priv->name) != 0) return FALSE; - if (strcmp (output1->vendor, output2->vendor) != 0) + if (strcmp (output1->priv->vendor, output2->priv->vendor) != 0) return FALSE; - if (output1->product != output2->product) + if (output1->priv->product != output2->priv->product) return FALSE; - if (output1->serial != output2->serial) + if (output1->priv->serial != output2->priv->serial) return FALSE; - if (output1->connected != output2->connected) + if (output1->priv->connected != output2->priv->connected) return FALSE; return TRUE; } static gboolean -output_equal (MateOutputInfo *output1, MateOutputInfo *output2) +output_equal (MateRROutputInfo *output1, MateRROutputInfo *output2) { - g_assert (output1 != NULL); - g_assert (output2 != NULL); + g_assert (MATE_IS_RR_OUTPUT_INFO (output1)); + g_assert (MATE_IS_RR_OUTPUT_INFO (output2)); if (!output_match (output1, output2)) return FALSE; - if (output1->on != output2->on) + if (output1->priv->on != output2->priv->on) return FALSE; - if (output1->on) + if (output1->priv->on) { - if (output1->width != output2->width) + if (output1->priv->width != output2->priv->width) return FALSE; - if (output1->height != output2->height) + if (output1->priv->height != output2->priv->height) return FALSE; - if (output1->rate != output2->rate) + if (output1->priv->rate != output2->priv->rate) return FALSE; - if (output1->x != output2->x) + if (output1->priv->x != output2->priv->x) return FALSE; - if (output1->y != output2->y) + if (output1->priv->y != output2->priv->y) return FALSE; - if (output1->rotation != output2->rotation) + if (output1->priv->rotation != output2->priv->rotation) return FALSE; } return TRUE; } -static MateOutputInfo * +static MateRROutputInfo * find_output (MateRRConfig *config, const char *name) { int i; - for (i = 0; config->outputs[i] != NULL; ++i) + for (i = 0; config->priv->outputs[i] != NULL; ++i) { - MateOutputInfo *output = config->outputs[i]; + MateRROutputInfo *output = config->priv->outputs[i]; - if (strcmp (name, output->name) == 0) + if (strcmp (name, output->priv->name) == 0) return output; } @@ -802,13 +882,15 @@ gboolean mate_rr_config_match (MateRRConfig *c1, MateRRConfig *c2) { int i; + g_return_val_if_fail (MATE_IS_RR_CONFIG (c1), FALSE); + g_return_val_if_fail (MATE_IS_RR_CONFIG (c2), FALSE); - for (i = 0; c1->outputs[i] != NULL; ++i) + for (i = 0; c1->priv->outputs[i] != NULL; ++i) { - MateOutputInfo *output1 = c1->outputs[i]; - MateOutputInfo *output2; + MateRROutputInfo *output1 = c1->priv->outputs[i]; + MateRROutputInfo *output2; - output2 = find_output (c2, output1->name); + output2 = find_output (c2, output1->priv->name); if (!output2 || !output_match (output1, output2)) return FALSE; } @@ -824,13 +906,15 @@ mate_rr_config_equal (MateRRConfig *c1, MateRRConfig *c2) { int i; + g_return_val_if_fail (MATE_IS_RR_CONFIG (c1), FALSE); + g_return_val_if_fail (MATE_IS_RR_CONFIG (c2), FALSE); - for (i = 0; c1->outputs[i] != NULL; ++i) + for (i = 0; c1->priv->outputs[i] != NULL; ++i) { - MateOutputInfo *output1 = c1->outputs[i]; - MateOutputInfo *output2; + MateRROutputInfo *output1 = c1->priv->outputs[i]; + MateRROutputInfo *output2; - output2 = find_output (c2, output1->name); + output2 = find_output (c2, output1->priv->name); if (!output2 || !output_equal (output1, output2)) return FALSE; } @@ -838,34 +922,39 @@ mate_rr_config_equal (MateRRConfig *c1, return TRUE; } -static MateOutputInfo ** +static MateRROutputInfo ** make_outputs (MateRRConfig *config) { GPtrArray *outputs; - MateOutputInfo *first_on; + MateRROutputInfo *first_on; int i; outputs = g_ptr_array_new (); first_on = NULL; - for (i = 0; config->outputs[i] != NULL; ++i) + for (i = 0; config->priv->outputs[i] != NULL; ++i) { - MateOutputInfo *old = config->outputs[i]; - MateOutputInfo *new = output_copy (old); - - if (old->on && !first_on) + MateRROutputInfo *old = config->priv->outputs[i]; + MateRROutputInfo *new = g_object_new (MATE_TYPE_RR_OUTPUT_INFO, NULL); + *(new->priv) = *(old->priv); + if (old->priv->name) + new->priv->name = g_strdup (old->priv->name); + if (old->priv->display_name) + new->priv->display_name = g_strdup (old->priv->display_name); + + if (old->priv->on && !first_on) first_on = old; - if (config->clone && new->on) + if (config->priv->clone && new->priv->on) { g_assert (first_on); - new->width = first_on->width; - new->height = first_on->height; - new->rotation = first_on->rotation; - new->x = 0; - new->y = 0; + new->priv->width = first_on->priv->width; + new->priv->height = first_on->priv->height; + new->priv->rotation = first_on->priv->rotation; + new->priv->x = 0; + new->priv->y = 0; } g_ptr_array_add (outputs, new); @@ -873,7 +962,7 @@ make_outputs (MateRRConfig *config) g_ptr_array_add (outputs, NULL); - return (MateOutputInfo **)g_ptr_array_free (outputs, FALSE); + return (MateRROutputInfo **)g_ptr_array_free (outputs, FALSE); } gboolean @@ -881,11 +970,13 @@ mate_rr_config_applicable (MateRRConfig *configuration, MateRRScreen *screen, GError **error) { - MateOutputInfo **outputs; + MateRROutputInfo **outputs; CrtcAssignment *assign; gboolean result; + int i; - g_return_val_if_fail (configuration != NULL, FALSE); + g_return_val_if_fail (MATE_IS_RR_CONFIG (configuration), FALSE); + g_return_val_if_fail (MATE_IS_RR_SCREEN (screen), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); outputs = make_outputs (configuration); @@ -901,7 +992,9 @@ mate_rr_config_applicable (MateRRConfig *configuration, result = FALSE; } - outputs_free (outputs); + for (i = 0; outputs[i] != NULL; i++) { + g_object_unref (outputs[i]); + } return result; } @@ -969,46 +1062,46 @@ emit_configuration (MateRRConfig *config, g_string_append_printf (string, " <configuration>\n"); - g_string_append_printf (string, " <clone>%s</clone>\n", yes_no (config->clone)); + g_string_append_printf (string, " <clone>%s</clone>\n", yes_no (config->priv->clone)); - for (j = 0; config->outputs[j] != NULL; ++j) + for (j = 0; config->priv->outputs[j] != NULL; ++j) { - MateOutputInfo *output = config->outputs[j]; + MateRROutputInfo *output = config->priv->outputs[j]; g_string_append_printf ( - string, " <output name=\"%s\">\n", output->name); + string, " <output name=\"%s\">\n", output->priv->name); - if (output->connected && *output->vendor != '\0') + if (output->priv->connected && *output->priv->vendor != '\0') { g_string_append_printf ( - string, " <vendor>%s</vendor>\n", output->vendor); + string, " <vendor>%s</vendor>\n", output->priv->vendor); g_string_append_printf ( - string, " <product>0x%04x</product>\n", output->product); + string, " <product>0x%04x</product>\n", output->priv->product); g_string_append_printf ( - string, " <serial>0x%08x</serial>\n", output->serial); + string, " <serial>0x%08x</serial>\n", output->priv->serial); } /* An unconnected output which is on does not make sense */ - if (output->connected && output->on) + if (output->priv->connected && output->priv->on) { g_string_append_printf ( - string, " <width>%d</width>\n", output->width); + string, " <width>%d</width>\n", output->priv->width); g_string_append_printf ( - string, " <height>%d</height>\n", output->height); + string, " <height>%d</height>\n", output->priv->height); g_string_append_printf ( - string, " <rate>%d</rate>\n", output->rate); + string, " <rate>%d</rate>\n", output->priv->rate); g_string_append_printf ( - string, " <x>%d</x>\n", output->x); + string, " <x>%d</x>\n", output->priv->x); g_string_append_printf ( - string, " <y>%d</y>\n", output->y); + string, " <y>%d</y>\n", output->priv->y); g_string_append_printf ( - string, " <rotation>%s</rotation>\n", get_rotation_name (output->rotation)); + string, " <rotation>%s</rotation>\n", get_rotation_name (output->priv->rotation)); g_string_append_printf ( - string, " <reflect_x>%s</reflect_x>\n", get_reflect_x (output->rotation)); + string, " <reflect_x>%s</reflect_x>\n", get_reflect_x (output->priv->rotation)); g_string_append_printf ( - string, " <reflect_y>%s</reflect_y>\n", get_reflect_y (output->rotation)); + string, " <reflect_y>%s</reflect_y>\n", get_reflect_y (output->priv->rotation)); g_string_append_printf ( - string, " <primary>%s</primary>\n", yes_no (output->primary)); + string, " <primary>%s</primary>\n", yes_no (output->priv->primary)); } g_string_append_printf (string, " </output>\n"); @@ -1028,37 +1121,37 @@ mate_rr_config_sanitize (MateRRConfig *config) * make sure the configuration starts at (0, 0) */ x_offset = y_offset = G_MAXINT; - for (i = 0; config->outputs[i]; ++i) + for (i = 0; config->priv->outputs[i]; ++i) { - MateOutputInfo *output = config->outputs[i]; + MateRROutputInfo *output = config->priv->outputs[i]; - if (output->on) + if (output->priv->on) { - x_offset = MIN (x_offset, output->x); - y_offset = MIN (y_offset, output->y); + x_offset = MIN (x_offset, output->priv->x); + y_offset = MIN (y_offset, output->priv->y); } } - for (i = 0; config->outputs[i]; ++i) + for (i = 0; config->priv->outputs[i]; ++i) { - MateOutputInfo *output = config->outputs[i]; + MateRROutputInfo *output = config->priv->outputs[i]; - if (output->on) + if (output->priv->on) { - output->x -= x_offset; - output->y -= y_offset; + output->priv->x -= x_offset; + output->priv->y -= y_offset; } } /* Only one primary, please */ found = FALSE; - for (i = 0; config->outputs[i]; ++i) + for (i = 0; config->priv->outputs[i]; ++i) { - if (config->outputs[i]->primary) + if (config->priv->outputs[i]->priv->primary) { if (found) { - config->outputs[i]->primary = FALSE; + config->priv->outputs[i]->priv->primary = FALSE; } else { @@ -1069,13 +1162,13 @@ mate_rr_config_sanitize (MateRRConfig *config) } static gboolean -output_info_is_laptop (MateOutputInfo *info) +output_info_is_laptop (MateRROutputInfo *info) { - if (info->name - && (strstr (info->name, "lvds") || /* Most drivers use an "LVDS" prefix... */ - strstr (info->name, "LVDS") || - strstr (info->name, "Lvds") || - strstr (info->name, "LCD"))) /* ... but fglrx uses "LCD" in some versions. Shoot me now, kthxbye. */ + if (info->priv->name + && (strstr (info->priv->name, "lvds") || /* Most drivers use an "LVDS" prefix... */ + strstr (info->priv->name, "LVDS") || + strstr (info->priv->name, "Lvds") || + strstr (info->priv->name, "LCD"))) /* ... but fglrx uses "LCD" in some versions. Shoot me now, kthxbye. */ return TRUE; return FALSE; @@ -1084,35 +1177,39 @@ output_info_is_laptop (MateOutputInfo *info) gboolean mate_rr_config_ensure_primary (MateRRConfig *configuration) { - int i; - MateOutputInfo *laptop; - MateOutputInfo *top_left; - gboolean found; + int i; + MateRROutputInfo *laptop; + MateRROutputInfo *top_left; + gboolean found; + MateRRConfigPrivate *priv; + + g_return_val_if_fail (MATE_IS_RR_CONFIG (configuration), FALSE); laptop = NULL; top_left = NULL; found = FALSE; + priv = configuration->priv; - for (i = 0; configuration->outputs[i] != NULL; ++i) { - MateOutputInfo *info = configuration->outputs[i]; + for (i = 0; priv->outputs[i] != NULL; ++i) { + MateRROutputInfo *info = priv->outputs[i]; - if (! info->on) { - info->primary = FALSE; + if (! info->priv->on) { + info->priv->primary = FALSE; continue; } /* ensure only one */ - if (info->primary) { + if (info->priv->primary) { if (found) { - info->primary = FALSE; + info->priv->primary = FALSE; } else { found = TRUE; } } if (top_left == NULL - || (info->x < top_left->x - && info->y < top_left->y)) { + || (info->priv->x < top_left->priv->x + && info->priv->y < top_left->priv->y)) { top_left = info; } if (laptop == NULL @@ -1123,11 +1220,11 @@ mate_rr_config_ensure_primary (MateRRConfig *configuration) } } - if (! found) { + if (!found) { if (laptop != NULL) { - laptop->primary = TRUE; + laptop->priv->primary = TRUE; } else { - top_left->primary = TRUE; + top_left->priv->primary = TRUE; } } @@ -1144,7 +1241,7 @@ mate_rr_config_save (MateRRConfig *configuration, GError **error) gchar *backup_filename; gboolean result; - g_return_val_if_fail (configuration != NULL, FALSE); + g_return_val_if_fail (MATE_IS_RR_CONFIG (configuration), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); output = g_string_new (""); @@ -1162,9 +1259,10 @@ mate_rr_config_save (MateRRConfig *configuration, GError **error) { if (!mate_rr_config_match (configurations[i], configuration)) emit_configuration (configurations[i], output); + g_object_unref (configurations[i]); } - configurations_free (configurations); + g_free (configurations); } emit_configuration (configuration, output); @@ -1186,89 +1284,6 @@ mate_rr_config_save (MateRRConfig *configuration, GError **error) return result; } -static MateRRConfig * -mate_rr_config_copy (const MateRRConfig *config) -{ - MateRRConfig *copy = g_new0 (MateRRConfig, 1); - int i; - GPtrArray *array = g_ptr_array_new (); - - copy->clone = config->clone; - - for (i = 0; config->outputs[i] != NULL; ++i) - g_ptr_array_add (array, output_copy (config->outputs[i])); - - g_ptr_array_add (array, NULL); - copy->outputs = (MateOutputInfo **)g_ptr_array_free (array, FALSE); - - return copy; -} - -static MateRRConfig * -config_new_stored (MateRRScreen *screen, const char *filename, GError **error) -{ - MateRRConfig *current; - MateRRConfig **configs; - MateRRConfig *result; - - g_return_val_if_fail (screen != NULL, NULL); - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - current = mate_rr_config_new_current (screen); - - configs = configurations_read_from_file (filename, error); - - result = NULL; - if (configs) - { - int i; - - for (i = 0; configs[i] != NULL; ++i) - { - if (mate_rr_config_match (configs[i], current)) - { - result = mate_rr_config_copy (configs[i]); - break; - } - } - - if (result == NULL) - g_set_error (error, MATE_RR_ERROR, MATE_RR_ERROR_NO_MATCHING_CONFIG, - _("none of the saved display configurations matched the active configuration")); - - configurations_free (configs); - } - - mate_rr_config_free (current); - - return result; -} - -MateRRConfig * -mate_rr_config_new_stored (MateRRScreen *screen, GError **error) -{ - char *intended_filename; - MateRRConfig *config; - - intended_filename = mate_rr_config_get_intended_filename (); - - config = config_new_stored (screen, intended_filename, error); - - g_free (intended_filename); - - return config; -} - -#ifndef MATE_DISABLE_DEPRECATED_SOURCE -gboolean -mate_rr_config_apply (MateRRConfig *config, - MateRRScreen *screen, - GError **error) -{ - return mate_rr_config_apply_with_time (config, screen, GDK_CURRENT_TIME, error); -} -#endif - gboolean mate_rr_config_apply_with_time (MateRRConfig *config, MateRRScreen *screen, @@ -1276,14 +1291,20 @@ mate_rr_config_apply_with_time (MateRRConfig *config, GError **error) { CrtcAssignment *assignment; - MateOutputInfo **outputs; + MateRROutputInfo **outputs; gboolean result = FALSE; + int i; + + g_return_val_if_fail (MATE_IS_RR_CONFIG (config), FALSE); + g_return_val_if_fail (MATE_IS_RR_SCREEN (screen), FALSE); outputs = make_outputs (config); assignment = crtc_assignment_new (screen, outputs, error); - outputs_free (outputs); + for (i = 0; outputs[i] != NULL; i++) + g_object_unref (outputs[i]); + g_free (outputs); if (assignment) { @@ -1298,74 +1319,6 @@ mate_rr_config_apply_with_time (MateRRConfig *config, return result; } -#ifndef MATE_DISABLE_DEPRECATED_SOURCE -/** - * mate_rr_config_apply_stored: - * @screen: A #MateRRScreen - * @error: Location to store error, or %NULL - * - * See the documentation for mate_rr_config_apply_from_filename(). This - * function simply calls that other function with a filename of - * mate_rr_config_get_intended_filename(). - * - * Deprecated: 2.26: Use mate_rr_config_apply_from_filename() instead and pass it - * the filename from mate_rr_config_get_intended_filename(). - */ -gboolean -mate_rr_config_apply_stored (MateRRScreen *screen, GError **error) -{ - char *filename; - gboolean result; - - filename = mate_rr_config_get_intended_filename (); - result = mate_rr_config_apply_from_filename_with_time (screen, filename, GDK_CURRENT_TIME, error); - g_free (filename); - - return result; -} -#endif - -#ifndef MATE_DISABLE_DEPRECATED_SOURCE -/* mate_rr_config_apply_from_filename: - * @screen: A #MateRRScreen - * @filename: Path of the file to look in for stored RANDR configurations. - * @error: Location to store error, or %NULL - * - * First, this function refreshes the @screen to match the current RANDR - * configuration from the X server. Then, it tries to load the file in - * @filename and looks for suitable matching RANDR configurations in the file; - * if one is found, that configuration will be applied to the current set of - * RANDR outputs. - * - * Typically, @filename is the result of mate_rr_config_get_intended_filename() or - * mate_rr_config_get_backup_filename(). - * - * Returns: TRUE if the RANDR configuration was loaded and applied from - * $(XDG_CONFIG_HOME)/monitors.xml, or FALSE otherwise: - * - * If the current RANDR configuration could not be refreshed, the @error will - * have a domain of #MATE_RR_ERROR and a corresponding error code. - * - * If the file in question is loaded successfully but the configuration cannot - * be applied, the @error will have a domain of #MATE_RR_ERROR. Note that an - * error code of #MATE_RR_ERROR_NO_MATCHING_CONFIG is not a real error; it - * simply means that there were no stored configurations that match the current - * set of RANDR outputs. - * - * If the file in question cannot be loaded, the @error will have a domain of - * #G_FILE_ERROR. Note that an error code of G_FILE_ERROR_NOENT is not really - * an error, either; it means that there was no stored configuration file and so - * nothing is changed. - * - * @Deprecated: 2.28: use mate_rr_config_apply_from_filename_with_time() instead. - */ -gboolean -mate_rr_config_apply_from_filename (MateRRScreen *screen, const char *filename, GError **error) -{ - return mate_rr_config_apply_from_filename_with_time (screen, filename, GDK_CURRENT_TIME, error); -} -#endif - /* mate_rr_config_apply_from_filename_with_time: * @screen: A #MateRRScreen * @filename: Path of the file to look in for stored RANDR configurations. @@ -1404,7 +1357,7 @@ mate_rr_config_apply_from_filename_with_time (MateRRScreen *screen, const char * MateRRConfig *stored; GError *my_error; - g_return_val_if_fail (screen != NULL, FALSE); + g_return_val_if_fail (MATE_IS_RR_SCREEN (screen), FALSE); g_return_val_if_fail (filename != NULL, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); @@ -1418,25 +1371,63 @@ mate_rr_config_apply_from_filename_with_time (MateRRScreen *screen, const char * /* This means the screen didn't change, so just proceed */ } - stored = config_new_stored (screen, filename, error); + stored = g_object_new (MATE_TYPE_RR_CONFIG, "screen", screen, NULL); - if (stored) + if (mate_rr_config_load_filename (stored, filename, error)) { gboolean result; mate_rr_config_ensure_primary (stored); result = mate_rr_config_apply_with_time (stored, screen, timestamp, error); - mate_rr_config_free (stored); + g_object_unref (stored); return result; } else { + g_object_unref (stored); return FALSE; } } +/** + * mate_rr_config_get_outputs: + * + * Returns: (array zero-terminated=1) (element-type MateDesktop.RROutputInfo) (transfer none): the output configuration for this #MateRRConfig + */ +MateRROutputInfo ** +mate_rr_config_get_outputs (MateRRConfig *self) +{ + g_return_val_if_fail (MATE_IS_RR_CONFIG (self), NULL); + + return self->priv->outputs; +} + +/** + * mate_rr_config_get_clone: + * + * Returns: whether at least two outputs are at (0, 0) offset and they + * have the same width/height. Those outputs are of course connected and on + * (i.e. they have a CRTC assigned). + */ +gboolean +mate_rr_config_get_clone (MateRRConfig *self) +{ + g_return_val_if_fail (MATE_IS_RR_CONFIG (self), FALSE); + + return self->priv->clone; +} + +void +mate_rr_config_set_clone (MateRRConfig *self, gboolean clone) +{ + g_return_if_fail (MATE_IS_RR_CONFIG (self)); + + self->priv->clone = clone; +} + + /* * CRTC assignment */ @@ -1679,12 +1670,12 @@ accumulate_error (GString *accumulated_error, GError *error) */ static gboolean real_assign_crtcs (MateRRScreen *screen, - MateOutputInfo **outputs, + MateRROutputInfo **outputs, CrtcAssignment *assignment, GError **error) { MateRRCrtc **crtcs = mate_rr_screen_list_crtcs (screen); - MateOutputInfo *output; + MateRROutputInfo *output; int i; gboolean tried_mode; GError *my_error; @@ -1696,7 +1687,7 @@ real_assign_crtcs (MateRRScreen *screen, return TRUE; /* It is always allowed for an output to be turned off */ - if (!output->on) + if (!output->priv->on) { return real_assign_crtcs (screen, outputs + 1, assignment, error); } @@ -1720,7 +1711,7 @@ real_assign_crtcs (MateRRScreen *screen, */ for (pass = 0; pass < 2; ++pass) { - MateRROutput *mate_rr_output = mate_rr_screen_get_output_by_name (screen, output->name); + MateRROutput *mate_rr_output = mate_rr_screen_get_output_by_name (screen, output->priv->name); MateRRMode **modes = mate_rr_output_list_modes (mate_rr_output); int j; @@ -1739,21 +1730,21 @@ real_assign_crtcs (MateRRScreen *screen, _("CRTC %d: trying mode %dx%d@%dHz with output at %dx%d@%dHz (pass %d)\n"), crtc_id, mode_width, mode_height, mode_freq, - output->width, output->height, output->rate, + output->priv->width, output->priv->height, output->priv->rate, pass); - if (mode_width == output->width && - mode_height == output->height && - (pass == 1 || mode_freq == output->rate)) + if (mode_width == output->priv->width && + mode_height == output->priv->height && + (pass == 1 || mode_freq == output->priv->rate)) { tried_mode = TRUE; my_error = NULL; if (crtc_assignment_assign ( assignment, crtc, modes[j], - output->x, output->y, - output->rotation, - output->primary, + output->priv->x, output->priv->y, + output->priv->rotation, + output->priv->primary, mate_rr_output, &my_error)) { @@ -1841,7 +1832,7 @@ get_required_virtual_size (CrtcAssignment *assign, int *width, int *height) } static CrtcAssignment * -crtc_assignment_new (MateRRScreen *screen, MateOutputInfo **outputs, GError **error) +crtc_assignment_new (MateRRScreen *screen, MateRROutputInfo **outputs, GError **error) { CrtcAssignment *assignment = g_new0 (CrtcAssignment, 1); diff --git a/libmate-desktop/mate-rr-config.h b/libmate-desktop/mate-rr-config.h index 2216eda..cd343ab 100644 --- a/libmate-desktop/mate-rr-config.h +++ b/libmate-desktop/mate-rr-config.h @@ -1,6 +1,8 @@ /* mate-rr-config.h + * -*- c-basic-offset: 4 -*- * * Copyright 2007, 2008, Red Hat, Inc. + * Copyright 2010 Giovanni Campagna * * This file is part of the Mate Library. * @@ -30,108 +32,120 @@ #include "mate-rr.h" #include <glib.h> +#include <glib-object.h> -typedef struct MateOutputInfo MateOutputInfo; -typedef struct MateRRConfig MateRRConfig; +typedef struct MateRROutputInfoPrivate MateRROutputInfoPrivate; +typedef struct MateRRConfigPrivate MateRRConfigPrivate; -/* FIXME: - * - * This structure is a Frankenstein monster where all of the fields - * are generated by the system, but some of them can be changed by - * the client. - */ +typedef struct +{ + GObject parent; -struct MateOutputInfo + /*< private >*/ + MateRROutputInfoPrivate *priv; +} MateRROutputInfo; + +typedef struct { - char * name; - - gboolean on; /* whether there is a CRTC assigned to this output (i.e. a signal is being sent to it) */ - int width; - int height; - int rate; - int x; - int y; - MateRRRotation rotation; - - gboolean connected; /* whether the output is physically connected to a monitor */ - char vendor[4]; - guint product; - guint serial; - double aspect; - int pref_width; - int pref_height; - char * display_name; - gboolean primary; - - gpointer user_data; -}; - -#define MATE_RR_TYPE_OUTPUT_INFO (mate_rr_output_info_get_type()) -#define MATE_RR_TYPE_CONFIG (mate_rr_config_get_type()) + GObjectClass parent_class; +} MateRROutputInfoClass; + +#define MATE_TYPE_RR_OUTPUT_INFO (mate_rr_output_info_get_type()) +#define MATE_RR_OUTPUT_INFO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MATE_TYPE_RR_OUTPUT_INFO, MateRROutputInfo)) +#define MATE_IS_RR_OUTPUT_INFO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MATE_TYPE_RR_OUTPUT_INFO)) +#define MATE_RR_OUTPUT_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MATE_TYPE_RR_OUTPUT_INFO, MateRROutputInfoClass)) +#define MATE_IS_RR_OUTPUT_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MATE_TYPE_RR_OUTPUT_INFO)) +#define MATE_RR_OUTPUT_INFO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MATE_TYPE_RR_OUTPUT_INFO, MateRROutputInfoClass)) + GType mate_rr_output_info_get_type (void); -GType mate_rr_config_get_type (void); -struct MateRRConfig -{ - /* "clone" means that at least two outputs are at (0, 0) offset and they - * have the same width/height. Those outputs are of course connected and on - * (i.e. they have a CRTC assigned). - */ - gboolean clone; - - MateOutputInfo ** outputs; -}; - -MateRRConfig *mate_rr_config_new_current (MateRRScreen *screen); -MateRRConfig *mate_rr_config_new_stored (MateRRScreen *screen, - GError **error); -void mate_rr_config_free (MateRRConfig *configuration); -gboolean mate_rr_config_match (MateRRConfig *config1, - MateRRConfig *config2); -gboolean mate_rr_config_equal (MateRRConfig *config1, - MateRRConfig *config2); -gboolean mate_rr_config_save (MateRRConfig *configuration, - GError **error); -void mate_rr_config_sanitize (MateRRConfig *configuration); -gboolean mate_rr_config_ensure_primary (MateRRConfig *configuration); - -#ifndef MATE_DISABLE_DEPRECATED -gboolean mate_rr_config_apply (MateRRConfig *configuration, - MateRRScreen *screen, - GError **error); -#endif +char *mate_rr_output_info_get_name (MateRROutputInfo *self); -gboolean mate_rr_config_apply_with_time (MateRRConfig *configuration, - MateRRScreen *screen, - guint32 timestamp, - GError **error); +gboolean mate_rr_output_info_get_active (MateRROutputInfo *self); +void mate_rr_output_info_set_active (MateRROutputInfo *self, gboolean active); -#ifndef MATE_DISABLE_DEPRECATED -gboolean mate_rr_config_apply_stored (MateRRScreen *screen, - GError **error); -#endif -#ifndef MATE_DISABLE_DEPRECATED -gboolean mate_rr_config_apply_from_filename (MateRRScreen *screen, - const char *filename, +void mate_rr_output_info_get_geometry (MateRROutputInfo *self, int *x, int *y, int *width, int *height); +void mate_rr_output_info_set_geometry (MateRROutputInfo *self, int x, int y, int width, int height); + +int mate_rr_output_info_get_refresh_rate (MateRROutputInfo *self); +void mate_rr_output_info_set_refresh_rate (MateRROutputInfo *self, int rate); + +MateRRRotation mate_rr_output_info_get_rotation (MateRROutputInfo *self); +void mate_rr_output_info_set_rotation (MateRROutputInfo *self, MateRRRotation rotation); + +gboolean mate_rr_output_info_get_connected (MateRROutputInfo *self); +void mate_rr_output_info_get_vendor (MateRROutputInfo *self, gchar* vendor); +guint mate_rr_output_info_get_product (MateRROutputInfo *self); +guint mate_rr_output_info_get_serial (MateRROutputInfo *self); +double mate_rr_output_info_get_aspect_ratio (MateRROutputInfo *self); +char *mate_rr_output_info_get_display_name (MateRROutputInfo *self); + +gboolean mate_rr_output_info_get_primary (MateRROutputInfo *self); +void mate_rr_output_info_set_primary (MateRROutputInfo *self, gboolean primary); + +int mate_rr_output_info_get_preferred_width (MateRROutputInfo *self); +int mate_rr_output_info_get_preferred_height (MateRROutputInfo *self); + +typedef struct +{ + GObject parent; + + /*< private >*/ + MateRRConfigPrivate *priv; +} MateRRConfig; + +typedef struct +{ + GObjectClass parent_class; +} MateRRConfigClass; + +#define MATE_TYPE_RR_CONFIG (mate_rr_config_get_type()) +#define MATE_RR_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MATE_TYPE_RR_CONFIG, MateRRConfig)) +#define MATE_IS_RR_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MATE_TYPE_RR_CONFIG)) +#define MATE_RR_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MATE_TYPE_RR_CONFIG, MateRRConfigClass)) +#define MATE_IS_RR_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MATE_TYPE_RR_CONFIG)) +#define MATE_RR_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MATE_TYPE_RR_CONFIG, MateRRConfigClass)) + +GType mate_rr_config_get_type (void); + +MateRRConfig *mate_rr_config_new_current (MateRRScreen *screen, + GError **error); +MateRRConfig *mate_rr_config_new_stored (MateRRScreen *screen, + GError **error); +gboolean mate_rr_config_load_current (MateRRConfig *self, + GError **error); +gboolean mate_rr_config_load_filename (MateRRConfig *self, + const gchar *filename, + GError **error); +gboolean mate_rr_config_match (MateRRConfig *config1, + MateRRConfig *config2); +gboolean mate_rr_config_equal (MateRRConfig *config1, + MateRRConfig *config2); +gboolean mate_rr_config_save (MateRRConfig *configuration, + GError **error); +void mate_rr_config_sanitize (MateRRConfig *configuration); +gboolean mate_rr_config_ensure_primary (MateRRConfig *configuration); + +gboolean mate_rr_config_apply_with_time (MateRRConfig *configuration, + MateRRScreen *screen, + guint32 timestamp, GError **error); -#endif -gboolean mate_rr_config_apply_from_filename_with_time (MateRRScreen *screen, - const char *filename, - guint32 timestamp, - GError **error); +gboolean mate_rr_config_apply_from_filename_with_time (MateRRScreen *screen, + const char *filename, + guint32 timestamp, + GError **error); + +gboolean mate_rr_config_applicable (MateRRConfig *configuration, + MateRRScreen *screen, + GError **error); -gboolean mate_rr_config_applicable (MateRRConfig *configuration, - MateRRScreen *screen, - GError **error); +gboolean mate_rr_config_get_clone (MateRRConfig *configuration); +void mate_rr_config_set_clone (MateRRConfig *configuration, gboolean clone); +MateRROutputInfo **mate_rr_config_get_outputs (MateRRConfig *configuration); char *mate_rr_config_get_backup_filename (void); char *mate_rr_config_get_intended_filename (void); -/* A utility function that isn't really in the spirit of this file, but I don't - * don't know a better place for it. - */ -MateRRMode **mate_rr_create_clone_modes (MateRRScreen *screen); - #endif diff --git a/libmate-desktop/mate-rr-labeler.c b/libmate-desktop/mate-rr-labeler.c index e515b51..e4aaa3e 100644 --- a/libmate-desktop/mate-rr-labeler.c +++ b/libmate-desktop/mate-rr-labeler.c @@ -29,7 +29,6 @@ #include <config.h> #include <glib/gi18n-lib.h> -#include "mate-rr-labeler.h" #include <gtk/gtk.h> #include <X11/Xproto.h> @@ -38,9 +37,9 @@ #include <X11/Xatom.h> #include <gdk/gdkx.h> -struct _MateRRLabeler { - GObject parent; +#include "mate-rr-labeler.h" +struct _MateRRLabelerPrivate { MateRRConfig *config; int num_outputs; @@ -56,14 +55,17 @@ struct _MateRRLabeler { Atom workarea_atom; }; -struct _MateRRLabelerClass { - GObjectClass parent_class; +enum { + PROP_0, + PROP_CONFIG, + PROP_LAST }; G_DEFINE_TYPE (MateRRLabeler, mate_rr_labeler, G_TYPE_OBJECT); static void mate_rr_labeler_finalize (GObject *object); static void create_label_windows (MateRRLabeler *labeler); +static void setup_from_config (MateRRLabeler *labeler); static gboolean get_work_area (MateRRLabeler *labeler, @@ -82,16 +84,16 @@ get_work_area (MateRRLabeler *labeler, int disp_screen; Display *display; - display = GDK_DISPLAY_XDISPLAY (gdk_screen_get_display (labeler->screen)); + display = GDK_DISPLAY_XDISPLAY (gdk_screen_get_display (labeler->priv->screen)); workarea = XInternAtom (display, "_NET_WORKAREA", True); - disp_screen = GDK_SCREEN_XNUMBER (labeler->screen); + disp_screen = GDK_SCREEN_XNUMBER (labeler->priv->screen); /* Defaults in case of error */ rect->x = 0; rect->y = 0; - rect->width = gdk_screen_get_width (labeler->screen); - rect->height = gdk_screen_get_height (labeler->screen); + rect->width = gdk_screen_get_width (labeler->priv->screen); + rect->height = gdk_screen_get_height (labeler->priv->screen); if (workarea == None) return FALSE; @@ -139,7 +141,7 @@ screen_xevent_filter (GdkXEvent *xevent, xev = (XEvent *) xevent; if (xev->type == PropertyNotify && - xev->xproperty.atom == labeler->workarea_atom) { + xev->xproperty.atom == labeler->priv->workarea_atom) { /* update label positions */ mate_rr_labeler_hide (labeler); create_label_windows (labeler); @@ -153,25 +155,62 @@ mate_rr_labeler_init (MateRRLabeler *labeler) { GdkWindow *gdkwindow; - labeler->workarea_atom = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), - "_NET_WORKAREA", - True); + labeler->priv = G_TYPE_INSTANCE_GET_PRIVATE (labeler, MATE_TYPE_RR_LABELER, MateRRLabelerPrivate); - labeler->screen = gdk_screen_get_default (); + labeler->priv->workarea_atom = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), + "_NET_WORKAREA", + True); + + labeler->priv->screen = gdk_screen_get_default (); /* code is not really designed to handle multiple screens so *shrug* */ - gdkwindow = gdk_screen_get_root_window (labeler->screen); + gdkwindow = gdk_screen_get_root_window (labeler->priv->screen); gdk_window_add_filter (gdkwindow, (GdkFilterFunc) screen_xevent_filter, labeler); gdk_window_set_events (gdkwindow, gdk_window_get_events (gdkwindow) | GDK_PROPERTY_CHANGE_MASK); } static void -mate_rr_labeler_class_init (MateRRLabelerClass *class) +mate_rr_labeler_set_property (GObject *gobject, guint property_id, const GValue *value, GParamSpec *param_spec) +{ + MateRRLabeler *self = MATE_RR_LABELER (gobject); + + switch (property_id) { + case PROP_CONFIG: + self->priv->config = MATE_RR_CONFIG (g_value_get_object (value)); + return; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, param_spec); + } +} + +static GObject * +mate_rr_labeler_constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties) +{ + MateRRLabeler *self = (MateRRLabeler*) G_OBJECT_CLASS (mate_rr_labeler_parent_class)->constructor (type, n_construct_properties, construct_properties); + + setup_from_config (self); + + return (GObject*) self; +} + +static void +mate_rr_labeler_class_init (MateRRLabelerClass *klass) { GObjectClass *object_class; - object_class = (GObjectClass *) class; + g_type_class_add_private (klass, sizeof (MateRRLabelerPrivate)); + object_class = (GObjectClass *) klass; + + object_class->set_property = mate_rr_labeler_set_property; object_class->finalize = mate_rr_labeler_finalize; + object_class->constructor = mate_rr_labeler_constructor; + + g_object_class_install_property (object_class, PROP_CONFIG, g_param_spec_object ("config", + "Configuration", + "RandR configuration to label", + MATE_TYPE_RR_CONFIG, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); } static void @@ -182,21 +221,19 @@ mate_rr_labeler_finalize (GObject *object) labeler = MATE_RR_LABELER (object); - gdkwindow = gdk_screen_get_root_window (labeler->screen); + gdkwindow = gdk_screen_get_root_window (labeler->priv->screen); gdk_window_remove_filter (gdkwindow, (GdkFilterFunc) screen_xevent_filter, labeler); - /* We don't destroy the labeler->config (a MateRRConfig*) here; let our - * caller do that instead. - */ + if (labeler->priv->config != NULL) { + g_object_unref (labeler->priv->config); + } - if (labeler->windows != NULL) { + if (labeler->priv->windows != NULL) { mate_rr_labeler_hide (labeler); - g_free (labeler->windows); - labeler->windows = NULL; + g_free (labeler->priv->windows); } - g_free (labeler->palette); - labeler->palette = NULL; + g_free (labeler->priv->palette); G_OBJECT_CLASS (mate_rr_labeler_parent_class)->finalize (object); } @@ -205,8 +242,9 @@ static int count_outputs (MateRRConfig *config) { int i; + MateRROutputInfo **outputs = mate_rr_config_get_outputs (config); - for (i = 0; config->outputs[i] != NULL; i++) + for (i = 0; outputs[i] != NULL; i++) ; return i; @@ -227,36 +265,36 @@ make_palette (MateRRLabeler *labeler) double end_hue; int i; - g_assert (labeler->num_outputs > 0); + g_assert (labeler->priv->num_outputs > 0); #if GTK_CHECK_VERSION (3, 0, 0) - labeler->palette = g_new (GdkRGBA, labeler->num_outputs); + labeler->priv->palette = g_new (GdkRGBA, labeler->priv->num_outputs); #else - labeler->palette = g_new (GdkColor, labeler->num_outputs); + labeler->priv->palette = g_new (GdkColor, labeler->priv->num_outputs); #endif start_hue = 0.0; /* red */ end_hue = 2.0/3; /* blue */ - for (i = 0; i < labeler->num_outputs; i++) { + for (i = 0; i < labeler->priv->num_outputs; i++) { double h, s, v; double r, g, b; - h = start_hue + (end_hue - start_hue) / labeler->num_outputs * i; + h = start_hue + (end_hue - start_hue) / labeler->priv->num_outputs * i; s = 1.0 / 3; v = 1.0; gtk_hsv_to_rgb (h, s, v, &r, &g, &b); #if GTK_CHECK_VERSION (3, 0, 0) - labeler->palette[i].red = r; - labeler->palette[i].green = g; - labeler->palette[i].blue = b; - labeler->palette[i].alpha = 1.0; + labeler->priv->palette[i].red = r; + labeler->priv->palette[i].green = g; + labeler->priv->palette[i].blue = b; + labeler->priv->palette[i].alpha = 1.0; #else - labeler->palette[i].red = (int) (65535 * r + 0.5); - labeler->palette[i].green = (int) (65535 * g + 0.5); - labeler->palette[i].blue = (int) (65535 * b + 0.5); + labeler->priv->palette[i].red = (int) (65535 * r + 0.5); + labeler->priv->palette[i].green = (int) (65535 * g + 0.5); + labeler->priv->palette[i].blue = (int) (65535 * b + 0.5); #endif } } @@ -327,8 +365,8 @@ position_window (MateRRLabeler *labeler, int monitor_num; get_work_area (labeler, &workarea); - monitor_num = gdk_screen_get_monitor_at_point (labeler->screen, x, y); - gdk_screen_get_monitor_geometry (labeler->screen, + monitor_num = gdk_screen_get_monitor_at_point (labeler->priv->screen, x, y); + gdk_screen_get_monitor_geometry (labeler->priv->screen, monitor_num, &monitor); gdk_rectangle_intersect (&monitor, &workarea, &workarea); @@ -338,10 +376,10 @@ position_window (MateRRLabeler *labeler, #if GTK_CHECK_VERSION (3, 0, 0) static GtkWidget * -create_label_window (MateRRLabeler *labeler, MateOutputInfo *output, GdkRGBA *color) +create_label_window (MateRRLabeler *labeler, MateRROutputInfo *output, GdkRGBA *color) #else static GtkWidget * -create_label_window (MateRRLabeler *labeler, MateOutputInfo *output, GdkColor *color) +create_label_window (MateRRLabeler *labeler, MateRROutputInfo *output, GdkColor *color) #endif { GtkWidget *window; @@ -349,6 +387,7 @@ create_label_window (MateRRLabeler *labeler, MateOutputInfo *output, GdkColor *c char *str; const char *display_name; GdkColor black = { 0, 0, 0, 0 }; + int x,y; window = gtk_window_new (GTK_WINDOW_POPUP); gtk_widget_set_app_paintable (window, TRUE); @@ -369,7 +408,7 @@ create_label_window (MateRRLabeler *labeler, MateOutputInfo *output, GdkColor *c G_CALLBACK (label_window_expose_event_cb), labeler); #endif - if (labeler->config->clone) { + if (mate_rr_config_get_clone (labeler->priv->config)) { /* Keep this string in sync with mate-control-center/capplets/display/xrandr-capplet.c:get_display_name() */ /* Translators: this is the feature where what you see on your laptop's @@ -379,7 +418,7 @@ create_label_window (MateRRLabeler *labeler, MateOutputInfo *output, GdkColor *c */ display_name = _("Mirror Screens"); } else - display_name = output->display_name; + display_name = mate_rr_output_info_get_display_name (output); str = g_strdup_printf ("<b>%s</b>", display_name); widget = gtk_label_new (NULL); @@ -395,7 +434,8 @@ create_label_window (MateRRLabeler *labeler, MateOutputInfo *output, GdkColor *c gtk_container_add (GTK_CONTAINER (window), widget); /* Should we center this at the top edge of the monitor, instead of using the upper-left corner? */ - position_window (labeler, window, output->x, output->y); + mate_rr_output_info_get_geometry (output, &x, &y, NULL, NULL); + position_window (labeler, window, x, y); gtk_widget_show_all (window); @@ -407,26 +447,29 @@ create_label_windows (MateRRLabeler *labeler) { int i; gboolean created_window_for_clone; + MateRROutputInfo **outputs; - labeler->windows = g_new (GtkWidget *, labeler->num_outputs); + labeler->priv->windows = g_new (GtkWidget *, labeler->priv->num_outputs); created_window_for_clone = FALSE; - for (i = 0; i < labeler->num_outputs; i++) { - if (!created_window_for_clone && labeler->config->outputs[i]->on) { - labeler->windows[i] = create_label_window (labeler, labeler->config->outputs[i], labeler->palette + i); + outputs = mate_rr_config_get_outputs (labeler->priv->config); + + for (i = 0; i < labeler->priv->num_outputs; i++) { + if (!created_window_for_clone && mate_rr_output_info_get_active (outputs[i])) { + labeler->priv->windows[i] = create_label_window (labeler, outputs[i], labeler->priv->palette + i); - if (labeler->config->clone) + if (mate_rr_config_get_clone (labeler->priv->config)) created_window_for_clone = TRUE; } else - labeler->windows[i] = NULL; + labeler->priv->windows[i] = NULL; } } static void setup_from_config (MateRRLabeler *labeler) { - labeler->num_outputs = count_outputs (labeler->config); + labeler->priv->num_outputs = count_outputs (labeler->priv->config); make_palette (labeler); @@ -436,51 +479,49 @@ setup_from_config (MateRRLabeler *labeler) MateRRLabeler * mate_rr_labeler_new (MateRRConfig *config) { - MateRRLabeler *labeler; - - g_return_val_if_fail (config != NULL, NULL); - - labeler = g_object_new (MATE_TYPE_RR_LABELER, NULL); - labeler->config = config; + g_return_val_if_fail (MATE_IS_RR_CONFIG (config), NULL); - setup_from_config (labeler); - - return labeler; + return g_object_new (MATE_TYPE_RR_LABELER, "config", config, NULL); } void mate_rr_labeler_hide (MateRRLabeler *labeler) { int i; + MateRRLabelerPrivate *priv; g_return_if_fail (MATE_IS_RR_LABELER (labeler)); - if (labeler->windows == NULL) - return; + priv = labeler->priv; - for (i = 0; i < labeler->num_outputs; i++) - if (labeler->windows[i] != NULL) { - gtk_widget_destroy (labeler->windows[i]); - labeler->windows[i] = NULL; - } - g_free (labeler->windows); - labeler->windows = NULL; + if (priv->windows == NULL) + return; + for (i = 0; i < priv->num_outputs; i++) + if (priv->windows[i] != NULL) { + gtk_widget_destroy (priv->windows[i]); + priv->windows[i] = NULL; + } + g_free (priv->windows); + priv->windows = NULL; } #if GTK_CHECK_VERSION (3, 0, 0) void -mate_rr_labeler_get_rgba_for_output (MateRRLabeler *labeler, MateOutputInfo *output, GdkRGBA *color_out) +mate_rr_labeler_get_rgba_for_output (MateRRLabeler *labeler, MateRROutputInfo *output, GdkRGBA *color_out) { int i; + MateRROutputInfo **outputs; g_return_if_fail (MATE_IS_RR_LABELER (labeler)); - g_return_if_fail (output != NULL); + g_return_if_fail (MATE_IS_RR_OUTPUT_INFO (output)) g_return_if_fail (color_out != NULL); - for (i = 0; i < labeler->num_outputs; i++) - if (labeler->config->outputs[i] == output) { - *color_out = labeler->palette[i]; + outputs = mate_rr_config_get_outputs (labeler->priv->config); + + for (i = 0; i < labeler->priv->num_outputs; i++) + if (outputs[i] == output) { + *color_out = labeler->priv->palette[i]; return; } @@ -494,22 +535,25 @@ mate_rr_labeler_get_rgba_for_output (MateRRLabeler *labeler, MateOutputInfo *out #endif void -mate_rr_labeler_get_color_for_output (MateRRLabeler *labeler, MateOutputInfo *output, GdkColor *color_out) +mate_rr_labeler_get_color_for_output (MateRRLabeler *labeler, MateRROutputInfo *output, GdkColor *color_out) { int i; + MateRROutputInfo **outputs; g_return_if_fail (MATE_IS_RR_LABELER (labeler)); - g_return_if_fail (output != NULL); + g_return_if_fail (MATE_IS_RR_OUTPUT_INFO (output)); g_return_if_fail (color_out != NULL); - for (i = 0; i < labeler->num_outputs; i++) - if (labeler->config->outputs[i] == output) { + outputs = mate_rr_config_get_outputs (labeler->priv->config); + + for (i = 0; i < labeler->priv->num_outputs; i++) + if (outputs[i] == output) { #if GTK_CHECK_VERSION (3, 0, 0) - color_out->red = labeler->palette[i].red * 0xffff; - color_out->green = labeler->palette[i].green * 0xffff; - color_out->blue = labeler->palette[i].blue * 0xffff; + color_out->red = labeler->priv->palette[i].red * 0xffff; + color_out->green = labeler->priv->palette[i].green * 0xffff; + color_out->blue = labeler->priv->palette[i].blue * 0xffff; #else - *color_out = labeler->palette[i]; + *color_out = labeler->priv->palette[i]; #endif return; } diff --git a/libmate-desktop/mate-rr-labeler.h b/libmate-desktop/mate-rr-labeler.h index 1be5f98..f5e98f7 100644 --- a/libmate-desktop/mate-rr-labeler.h +++ b/libmate-desktop/mate-rr-labeler.h @@ -41,6 +41,18 @@ typedef struct _MateRRLabeler MateRRLabeler; typedef struct _MateRRLabelerClass MateRRLabelerClass; +typedef struct _MateRRLabelerPrivate MateRRLabelerPrivate; + +struct _MateRRLabeler { + GObject parent; + + /*< private >*/ + MateRRLabelerPrivate *priv; +}; + +struct _MateRRLabelerClass { + GObjectClass parent_class; +}; GType mate_rr_labeler_get_type (void); @@ -49,8 +61,8 @@ MateRRLabeler *mate_rr_labeler_new (MateRRConfig *config); void mate_rr_labeler_hide (MateRRLabeler *labeler); #ifdef GDK_VERSION_3_0 -void mate_rr_labeler_get_rgba_for_output (MateRRLabeler *labeler, MateOutputInfo *output, GdkRGBA *color_out); +void mate_rr_labeler_get_rgba_for_output (MateRRLabeler *labeler, MateRROutputInfo *output, GdkRGBA *color_out); #endif -void mate_rr_labeler_get_color_for_output (MateRRLabeler *labeler, MateOutputInfo *output, GdkColor *color_out); +void mate_rr_labeler_get_color_for_output (MateRRLabeler *labeler, MateRROutputInfo *output, GdkColor *color_out); #endif diff --git a/libmate-desktop/mate-rr-output-info.c b/libmate-desktop/mate-rr-output-info.c new file mode 100644 index 0000000..0020541 --- /dev/null +++ b/libmate-desktop/mate-rr-output-info.c @@ -0,0 +1,246 @@ +/* mate-rr-output-info.c + * -*- c-basic-offset: 4 -*- + * + * Copyright 2010 Giovanni Campagna + * + * This file is part of the Mate Desktop Library. + * + * The Mate Desktop Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Mate Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Mate Desktop Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#define MATE_DESKTOP_USE_UNSTABLE_API + +#include <config.h> + +#include "mate-rr-config.h" + +#include "edid.h" +#include "mate-rr-private.h" + +G_DEFINE_TYPE (MateRROutputInfo, mate_rr_output_info, G_TYPE_OBJECT) + +static void +mate_rr_output_info_init (MateRROutputInfo *self) +{ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, MATE_TYPE_RR_OUTPUT_INFO, MateRROutputInfoPrivate); + + self->priv->name = NULL; + self->priv->on = FALSE; + self->priv->display_name = NULL; +} + +static void +mate_rr_output_info_finalize (GObject *gobject) +{ + MateRROutputInfo *self = MATE_RR_OUTPUT_INFO (gobject); + + g_free (self->priv->name); + g_free (self->priv->display_name); + + G_OBJECT_CLASS (mate_rr_output_info_parent_class)->finalize (gobject); +} + +static void +mate_rr_output_info_class_init (MateRROutputInfoClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (MateRROutputInfoPrivate)); + + gobject_class->finalize = mate_rr_output_info_finalize; +} + +/** + * mate_rr_output_info_get_name: + * + * Returns: (transfer none): the output name + */ +char *mate_rr_output_info_get_name (MateRROutputInfo *self) +{ + g_return_val_if_fail (MATE_IS_RR_OUTPUT_INFO (self), NULL); + + return self->priv->name; +} + +/** + * mate_rr_output_info_get_active: + * + * Returns: whether there is a CRTC assigned to this output (i.e. a signal is being sent to it) + */ +gboolean mate_rr_output_info_get_active (MateRROutputInfo *self) +{ + g_return_val_if_fail (MATE_IS_RR_OUTPUT_INFO (self), FALSE); + + return self->priv->on; +} + +void mate_rr_output_info_set_active (MateRROutputInfo *self, gboolean active) +{ + g_return_if_fail (MATE_IS_RR_OUTPUT_INFO (self)); + + self->priv->on = active; +} + +/** + * mate_rr_output_info_get_geometry: + * + * @self: a #MateRROutputInfo + * @x: (out) (allow-none): + * @y: (out) (allow-none): + * @width: (out) (allow-none): + * @height: (out) (allow-none): + */ +void mate_rr_output_info_get_geometry (MateRROutputInfo *self, int *x, int *y, int *width, int *height) +{ + g_return_if_fail (MATE_IS_RR_OUTPUT_INFO (self)); + + if (x) + *x = self->priv->x; + if (y) + *y = self->priv->y; + if (width) + *width = self->priv->width; + if (height) + *height = self->priv->height; +} + +void mate_rr_output_info_set_geometry (MateRROutputInfo *self, int x, int y, int width, int height) +{ + g_return_if_fail (MATE_IS_RR_OUTPUT_INFO (self)); + + self->priv->x = x; + self->priv->y = y; + self->priv->width = width; + self->priv->height = height; +} + +int mate_rr_output_info_get_refresh_rate (MateRROutputInfo *self) +{ + g_return_val_if_fail (MATE_IS_RR_OUTPUT_INFO (self), 0); + + return self->priv->rate; +} + +void mate_rr_output_info_set_refresh_rate (MateRROutputInfo *self, int rate) +{ + g_return_if_fail (MATE_IS_RR_OUTPUT_INFO (self)); + + self->priv->rate = rate; +} + +MateRRRotation mate_rr_output_info_get_rotation (MateRROutputInfo *self) +{ + g_return_val_if_fail (MATE_IS_RR_OUTPUT_INFO (self), MATE_RR_ROTATION_0); + + return self->priv->rotation; +} + +void mate_rr_output_info_set_rotation (MateRROutputInfo *self, MateRRRotation rotation) +{ + g_return_if_fail (MATE_IS_RR_OUTPUT_INFO (self)); + + self->priv->rotation = rotation; +} + +/** + * mate_rr_output_info_get_connected: + * + * Returns: whether the output is physically connected to a monitor + */ +gboolean mate_rr_output_info_get_connected (MateRROutputInfo *self) +{ + g_return_val_if_fail (MATE_IS_RR_OUTPUT_INFO (self), FALSE); + + return self->priv->connected; +} + +/** + * mate_rr_output_info_get_vendor: + * + * @self: a #MateRROutputInfo + * @vendor: (out caller-allocates) (array fixed-size=4): + */ +void mate_rr_output_info_get_vendor (MateRROutputInfo *self, gchar* vendor) +{ + g_return_if_fail (MATE_IS_RR_OUTPUT_INFO (self)); + g_return_if_fail (vendor != NULL); + + vendor[0] = self->priv->vendor[0]; + vendor[1] = self->priv->vendor[1]; + vendor[2] = self->priv->vendor[2]; + vendor[3] = self->priv->vendor[3]; +} + +guint mate_rr_output_info_get_product (MateRROutputInfo *self) +{ + g_return_val_if_fail (MATE_IS_RR_OUTPUT_INFO (self), 0); + + return self->priv->product; +} + +guint mate_rr_output_info_get_serial (MateRROutputInfo *self) +{ + g_return_val_if_fail (MATE_IS_RR_OUTPUT_INFO (self), 0); + + return self->priv->serial; +} + +double mate_rr_output_info_get_aspect_ratio (MateRROutputInfo *self) +{ + g_return_val_if_fail (MATE_IS_RR_OUTPUT_INFO (self), 0); + + return self->priv->aspect; +} + +/** + * mate_rr_output_info_get_display_name: + * + * Returns: (transfer none): the display name of this output + */ +char *mate_rr_output_info_get_display_name (MateRROutputInfo *self) +{ + g_return_val_if_fail (MATE_IS_RR_OUTPUT_INFO (self), NULL); + + return self->priv->display_name; +} + +gboolean mate_rr_output_info_get_primary (MateRROutputInfo *self) +{ + g_return_val_if_fail (MATE_IS_RR_OUTPUT_INFO (self), FALSE); + + return self->priv->primary; +} + +void mate_rr_output_info_set_primary (MateRROutputInfo *self, gboolean primary) +{ + g_return_if_fail (MATE_IS_RR_OUTPUT_INFO (self)); + + self->priv->primary = primary; +} + +int mate_rr_output_info_get_preferred_width (MateRROutputInfo *self) +{ + g_return_val_if_fail (MATE_IS_RR_OUTPUT_INFO (self), 0); + + return self->priv->pref_width; +} + +int mate_rr_output_info_get_preferred_height (MateRROutputInfo *self) +{ + g_return_val_if_fail (MATE_IS_RR_OUTPUT_INFO (self), 0); + + return self->priv->pref_height; +} diff --git a/libmate-desktop/mate-rr-private.h b/libmate-desktop/mate-rr-private.h index ebb6417..74bb9c4 100644 --- a/libmate-desktop/mate-rr-private.h +++ b/libmate-desktop/mate-rr-private.h @@ -47,4 +47,34 @@ struct MateRRScreenPrivate Atom connector_type_atom; }; +struct MateRROutputInfoPrivate +{ + char * name; + + gboolean on; + int width; + int height; + int rate; + int x; + int y; + MateRRRotation rotation; + + gboolean connected; + gchar vendor[4]; + guint product; + guint serial; + double aspect; + int pref_width; + int pref_height; + char * display_name; + gboolean primary; +}; + +struct MateRRConfigPrivate +{ + gboolean clone; + MateRRScreen *screen; + MateRROutputInfo **outputs; +}; + #endif diff --git a/libmate-desktop/mate-rr.c b/libmate-desktop/mate-rr.c index e5a242a..e49707b 100644 --- a/libmate-desktop/mate-rr.c +++ b/libmate-desktop/mate-rr.c @@ -39,6 +39,7 @@ #undef MATE_DISABLE_DEPRECATED #include "mate-rr.h" +#include "mate-rr-config.h" #include "private.h" #include "mate-rr-private.h" @@ -162,6 +163,7 @@ static void mode_free (MateRRMode *mode); static void mate_rr_screen_finalize (GObject*); static void mate_rr_screen_set_property (GObject*, guint, const GValue*, GParamSpec*); +static void mate_rr_screen_get_property (GObject*, guint, GValue*, GParamSpec*); static gboolean mate_rr_screen_initable_init (GInitable*, GCancellable*, GError**); static void mate_rr_screen_initable_iface_init (GInitableIface *iface); G_DEFINE_TYPE_WITH_CODE (MateRRScreen, mate_rr_screen, G_TYPE_OBJECT, @@ -435,9 +437,12 @@ fill_out_screen_info (Display *xdisplay, { #ifdef HAVE_RANDR XRRScreenResources *resources; + MateRRScreenPrivate *priv; - g_return_val_if_fail (xdisplay != NULL, FALSE); - g_return_val_if_fail (info != NULL, FALSE); + g_assert (xdisplay != NULL); + g_assert (info != NULL); + + priv = info->screen->priv; /* First update the screen resources */ @@ -451,7 +456,7 @@ fill_out_screen_info (Display *xdisplay, */ #if (RANDR_MAJOR > 1 || (RANDR_MAJOR == 1 && RANDR_MINOR >= 3)) /* Runtime check for RandR 1.3 or higher */ - if (info->screen->priv->rr_major_version == 1 && info->screen->priv->rr_minor_version >= 3) + if (priv->rr_major_version == 1 && priv->rr_minor_version >= 3) resources = XRRGetScreenResourcesCurrent (xdisplay, xroot); else resources = XRRGetScreenResources (xdisplay, xroot); @@ -511,7 +516,7 @@ fill_out_screen_info (Display *xdisplay, info->primary = None; #if (RANDR_MAJOR > 1 || (RANDR_MAJOR == 1 && RANDR_MINOR >= 3)) /* Runtime check for RandR 1.3 or higher */ - if (info->screen->priv->rr_major_version == 1 && info->screen->priv->rr_minor_version >= 3) { + if (priv->rr_major_version == 1 && priv->rr_minor_version >= 3) { gdk_error_trap_push (); info->primary = XRRGetOutputPrimary (xdisplay, xroot); #if GTK_CHECK_VERSION (3, 0, 0) @@ -533,15 +538,18 @@ static ScreenInfo * screen_info_new (MateRRScreen *screen, gboolean needs_reprobe, GError **error) { ScreenInfo *info = g_new0 (ScreenInfo, 1); - + MateRRScreenPrivate *priv; + g_assert (screen != NULL); - + + priv = screen->priv; + info->outputs = NULL; info->crtcs = NULL; info->modes = NULL; info->screen = screen; - if (fill_out_screen_info (screen->priv->xdisplay, screen->priv->xroot, info, needs_reprobe, error)) + if (fill_out_screen_info (priv->xdisplay, priv->xroot, info, needs_reprobe, error)) { return info; } @@ -586,13 +594,14 @@ screen_on_event (GdkXEvent *xevent, { #ifdef HAVE_RANDR MateRRScreen *screen = data; + MateRRScreenPrivate *priv = screen->priv; XEvent *e = xevent; int event_num; if (!e) return GDK_FILTER_CONTINUE; - event_num = e->type - screen->priv->randr_event_base; + event_num = e->type - priv->randr_event_base; if (event_num == RRScreenChangeNotify) { /* We don't reprobe the hardware; we just fetch the X server's latest @@ -624,8 +633,8 @@ screen_on_event (GdkXEvent *xevent, (guint32) rr_event->timestamp, (guint32) rr_event->config_timestamp, rr_event->serial, - (guint32) screen->priv->info->resources->timestamp, - (guint32) screen->priv->info->resources->configTimestamp); + (guint32) priv->info->resources->timestamp, + (guint32) priv->info->resources->configTimestamp); g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL); gtk_widget_show (dialog); @@ -680,37 +689,38 @@ mate_rr_screen_initable_init (GInitable *initable, GCancellable *canc, GError ** { MateRRScreen *self = MATE_RR_SCREEN (initable); + MateRRScreenPrivate *priv = self->priv; Display *dpy = GDK_SCREEN_XDISPLAY (self->priv->gdk_screen); int event_base; int ignore; - self->priv->connector_type_atom = XInternAtom (dpy, "ConnectorType", FALSE); + priv->connector_type_atom = XInternAtom (dpy, "ConnectorType", FALSE); #ifdef HAVE_RANDR if (XRRQueryExtension (dpy, &event_base, &ignore)) { - self->priv->randr_event_base = event_base; + priv->randr_event_base = event_base; - XRRQueryVersion (dpy, &self->priv->rr_major_version, &self->priv->rr_minor_version); - if (self->priv->rr_major_version > 1 || (self->priv->rr_major_version == 1 && self->priv->rr_minor_version < 2)) { + XRRQueryVersion (dpy, &priv->rr_major_version, &priv->rr_minor_version); + if (priv->rr_major_version > 1 || (priv->rr_major_version == 1 && priv->rr_minor_version < 2)) { g_set_error (error, MATE_RR_ERROR, MATE_RR_ERROR_NO_RANDR_EXTENSION, "RANDR extension is too old (must be at least 1.2)"); return FALSE; } - self->priv->info = screen_info_new (self, TRUE, error); + priv->info = screen_info_new (self, TRUE, error); - if (!self->priv->info) { + if (!priv->info) { return FALSE; } - XRRSelectInput (self->priv->xdisplay, - self->priv->xroot, + XRRSelectInput (priv->xdisplay, + priv->xroot, RRScreenChangeNotifyMask); - gdk_x11_register_standard_event_type (gdk_screen_get_display (self->priv->gdk_screen), + gdk_x11_register_standard_event_type (gdk_screen_get_display (priv->gdk_screen), event_base, RRNotify + 1); - gdk_window_add_filter (self->priv->gdk_root, screen_on_event, self); + gdk_window_add_filter (priv->gdk_root, screen_on_event, self); return TRUE; } @@ -741,21 +751,24 @@ void gdk_window_remove_filter (screen->priv->gdk_root, screen_on_event, screen); screen_info_free (screen->priv->info); + + G_OBJECT_CLASS (mate_rr_screen_parent_class)->finalize (gobject); } void - mate_rr_screen_set_property (GObject *gobject, guint property_id, const GValue *value, GParamSpec *property) +mate_rr_screen_set_property (GObject *gobject, guint property_id, const GValue *value, GParamSpec *property) { MateRRScreen *self = MATE_RR_SCREEN (gobject); + MateRRScreenPrivate *priv = self->priv; switch (property_id) { case SCREEN_PROP_GDK_SCREEN: - self->priv->gdk_screen = g_value_get_object (value); - self->priv->gdk_root = gdk_screen_get_root_window (self->priv->gdk_screen); - self->priv->xroot = gdk_x11_drawable_get_xid (self->priv->gdk_root); - self->priv->xdisplay = GDK_SCREEN_XDISPLAY (self->priv->gdk_screen); - self->priv->xscreen = gdk_x11_screen_get_xscreen (self->priv->gdk_screen); + priv->gdk_screen = g_value_get_object (value); + priv->gdk_root = gdk_screen_get_root_window (priv->gdk_screen); + priv->xroot = gdk_x11_drawable_get_xid (priv->gdk_root); + priv->xdisplay = GDK_SCREEN_XDISPLAY (priv->gdk_screen); + priv->xscreen = gdk_x11_screen_get_xscreen (priv->gdk_screen); return; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, property); @@ -764,13 +777,30 @@ void } void +mate_rr_screen_get_property (GObject *gobject, guint property_id, GValue *value, GParamSpec *property) +{ + MateRRScreen *self = MATE_RR_SCREEN (gobject); + MateRRScreenPrivate *priv = self->priv; + + switch (property_id) + { + case SCREEN_PROP_GDK_SCREEN: + g_value_set_object (value, priv->gdk_screen); + return; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, property); + return; + } +} + +void mate_rr_screen_class_init (MateRRScreenClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); g_type_class_add_private (klass, sizeof (MateRRScreenPrivate)); gobject_class->set_property = mate_rr_screen_set_property; - gobject_class->get_property = NULL; + gobject_class->get_property = mate_rr_screen_get_property; gobject_class->finalize = mate_rr_screen_finalize; g_object_class_install_property( @@ -781,44 +811,41 @@ mate_rr_screen_class_init (MateRRScreenClass *klass) "GDK Screen", "The GDK Screen represented by this MateRRScreen", GDK_TYPE_SCREEN, - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB - ) + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS) ); - screen_signals[SCREEN_CHANGED] = g_signal_newv("screen-changed", + screen_signals[SCREEN_CHANGED] = g_signal_new("screen-changed", G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, - NULL, + G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, + G_STRUCT_OFFSET (MateRRScreenClass, changed), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, - 0, - NULL); + 0); } void mate_rr_screen_init (MateRRScreen *self) { - self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, MATE_RR_TYPE_SCREEN, MateRRScreenPrivate); + MateRRScreenPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self, MATE_TYPE_RR_SCREEN, MateRRScreenPrivate); + self->priv = priv; - self->priv->gdk_screen = NULL; - self->priv->gdk_root = NULL; - self->priv->xdisplay = NULL; - self->priv->xroot = None; - self->priv->xscreen = NULL; - self->priv->info = NULL; - self->priv->rr_major_version = 0; - self->priv->rr_minor_version = 0; + priv->gdk_screen = NULL; + priv->gdk_root = NULL; + priv->xdisplay = NULL; + priv->xroot = None; + priv->xscreen = NULL; + priv->info = NULL; + priv->rr_major_version = 0; + priv->rr_minor_version = 0; } /** - * mate_rr_screen_new: (skip) + * mate_rr_screen_new: * Creates a new #MateRRScreen instance * * @screen: the #GdkScreen on which to operate - * @callback: an optional callback for screen-changed signal - * @data: * @error: will be set if XRandR is not supported * * Returns: a new #MateRRScreen instance or NULL if screen could not be created, @@ -826,27 +853,10 @@ mate_rr_screen_init (MateRRScreen *self) */ MateRRScreen * mate_rr_screen_new (GdkScreen *screen, - MateRRScreenChanged callback, - gpointer data, GError **error) { _mate_desktop_init_i18n (); - MateRRScreen *self = g_initable_new (MATE_RR_TYPE_SCREEN, NULL, error, "gdk-screen", screen, NULL); - if (self && callback) { - g_signal_connect (self, "screen-changed", G_CALLBACK (callback), data); - } - return self; -} -/** - * mate_rr_screen_destroy: - * - * Destroy the screen and all associated resources - * Deprecated: 3.0 - */ -void -mate_rr_screen_destroy (MateRRScreen *self) -{ - g_object_run_dispose (G_OBJECT (self)); + return g_initable_new (MATE_TYPE_RR_SCREEN, NULL, error, "gdk-screen", screen, NULL); } void @@ -856,7 +866,7 @@ mate_rr_screen_set_size (MateRRScreen *screen, int mm_width, int mm_height) { - g_return_if_fail (MATE_RR_IS_SCREEN (screen)); + g_return_if_fail (MATE_IS_RR_SCREEN (screen)); #ifdef HAVE_RANDR gdk_error_trap_push (); @@ -888,19 +898,23 @@ mate_rr_screen_get_ranges (MateRRScreen *screen, int *min_height, int *max_height) { - g_return_if_fail (MATE_RR_IS_SCREEN (screen)); + MateRRScreenPrivate *priv; + + g_return_if_fail (MATE_IS_RR_SCREEN (screen)); + + priv = screen->priv; if (min_width) - *min_width = screen->priv->info->min_width; + *min_width = priv->info->min_width; if (max_width) - *max_width = screen->priv->info->max_width; + *max_width = priv->info->max_width; if (min_height) - *min_height = screen->priv->info->min_height; + *min_height = priv->info->min_height; if (max_height) - *max_height = screen->priv->info->max_height; + *max_height = priv->info->max_height; } /** @@ -920,20 +934,25 @@ mate_rr_screen_get_timestamps (MateRRScreen *screen, guint32 *change_timestamp_ret, guint32 *config_timestamp_ret) { - g_return_if_fail (MATE_RR_IS_SCREEN (screen)); + MateRRScreenPrivate *priv; + + g_return_if_fail (MATE_IS_RR_SCREEN (screen)); + + priv = screen->priv; #ifdef HAVE_RANDR if (change_timestamp_ret) - *change_timestamp_ret = screen->priv->info->resources->timestamp; + *change_timestamp_ret = priv->info->resources->timestamp; if (config_timestamp_ret) - *config_timestamp_ret = screen->priv->info->resources->configTimestamp; + *config_timestamp_ret = priv->info->resources->configTimestamp; #endif } static gboolean force_timestamp_update (MateRRScreen *screen) { + MateRRScreenPrivate *priv = screen->priv; MateRRCrtc *crtc; XRRCrtcInfo *current_info; Status status; @@ -941,21 +960,21 @@ force_timestamp_update (MateRRScreen *screen) timestamp_updated = FALSE; - crtc = screen->priv->info->crtcs[0]; + crtc = priv->info->crtcs[0]; if (crtc == NULL) goto out; - current_info = XRRGetCrtcInfo (screen->priv->xdisplay, - screen->priv->info->resources, + current_info = XRRGetCrtcInfo (priv->xdisplay, + priv->info->resources, crtc->id); if (current_info == NULL) goto out; gdk_error_trap_push (); - status = XRRSetCrtcConfig (screen->priv->xdisplay, - screen->priv->info->resources, + status = XRRSetCrtcConfig (priv->xdisplay, + priv->info->resources, crtc->id, current_info->timestamp, current_info->x, @@ -1018,7 +1037,7 @@ mate_rr_screen_refresh (MateRRScreen *screen, MateRRMode ** mate_rr_screen_list_modes (MateRRScreen *screen) { - g_return_val_if_fail (MATE_RR_IS_SCREEN (screen), NULL); + g_return_val_if_fail (MATE_IS_RR_SCREEN (screen), NULL); g_return_val_if_fail (screen->priv->info != NULL, NULL); return screen->priv->info->modes; @@ -1034,7 +1053,7 @@ mate_rr_screen_list_modes (MateRRScreen *screen) MateRRMode ** mate_rr_screen_list_clone_modes (MateRRScreen *screen) { - g_return_val_if_fail (MATE_RR_IS_SCREEN (screen), NULL); + g_return_val_if_fail (MATE_IS_RR_SCREEN (screen), NULL); g_return_val_if_fail (screen->priv->info != NULL, NULL); return screen->priv->info->clone_modes; @@ -1050,7 +1069,7 @@ mate_rr_screen_list_clone_modes (MateRRScreen *screen) MateRRCrtc ** mate_rr_screen_list_crtcs (MateRRScreen *screen) { - g_return_val_if_fail (MATE_RR_IS_SCREEN (screen), NULL); + g_return_val_if_fail (MATE_IS_RR_SCREEN (screen), NULL); g_return_val_if_fail (screen->priv->info != NULL, NULL); return screen->priv->info->crtcs; @@ -1066,7 +1085,7 @@ mate_rr_screen_list_crtcs (MateRRScreen *screen) MateRROutput ** mate_rr_screen_list_outputs (MateRRScreen *screen) { - g_return_val_if_fail (MATE_RR_IS_SCREEN (screen), NULL); + g_return_val_if_fail (MATE_IS_RR_SCREEN (screen), NULL); g_return_val_if_fail (screen->priv->info != NULL, NULL); return screen->priv->info->outputs; @@ -1081,15 +1100,18 @@ MateRRCrtc * mate_rr_screen_get_crtc_by_id (MateRRScreen *screen, guint32 id) { + MateRRCrtc **crtcs; int i; - g_return_val_if_fail (MATE_RR_IS_SCREEN (screen), NULL); + g_return_val_if_fail (MATE_IS_RR_SCREEN (screen), NULL); g_return_val_if_fail (screen->priv->info != NULL, NULL); + + crtcs = screen->priv->info->crtcs; - for (i = 0; screen->priv->info->crtcs[i] != NULL; ++i) + for (i = 0; crtcs[i] != NULL; ++i) { - if (screen->priv->info->crtcs[i]->id == id) - return screen->priv->info->crtcs[i]; + if (crtcs[i]->id == id) + return crtcs[i]; } return NULL; @@ -1104,15 +1126,18 @@ MateRROutput * mate_rr_screen_get_output_by_id (MateRRScreen *screen, guint32 id) { + MateRROutput **outputs; int i; - g_return_val_if_fail (MATE_RR_IS_SCREEN (screen), NULL); + g_return_val_if_fail (MATE_IS_RR_SCREEN (screen), NULL); g_return_val_if_fail (screen->priv->info != NULL, NULL); - - for (i = 0; screen->priv->info->outputs[i] != NULL; ++i) + + outputs = screen->priv->info->outputs; + + for (i = 0; outputs[i] != NULL; ++i) { - if (screen->priv->info->outputs[i]->id == id) - return screen->priv->info->outputs[i]; + if (outputs[i]->id == id) + return outputs[i]; } return NULL; @@ -1401,7 +1426,7 @@ mate_rr_screen_get_output_by_name (MateRRScreen *screen, { int i; - g_return_val_if_fail (MATE_RR_IS_SCREEN (screen), NULL); + g_return_val_if_fail (MATE_IS_RR_SCREEN (screen), NULL); g_return_val_if_fail (screen->priv->info != NULL, NULL); for (i = 0; screen->priv->info->outputs[i] != NULL; ++i) @@ -1583,6 +1608,12 @@ void mate_rr_screen_set_primary_output (MateRRScreen *screen, MateRROutput *output) { + MateRRScreenPrivate *priv; + + g_return_if_fail (MATE_IS_RR_SCREEN (screen)); + + priv = screen->priv; + #ifdef HAVE_RANDR #if (RANDR_MAJOR > 1 || (RANDR_MAJOR == 1 && RANDR_MINOR >= 3)) RROutput id; @@ -1592,9 +1623,9 @@ mate_rr_screen_set_primary_output (MateRRScreen *screen, else id = None; - /* Runtime check for RandR 1.3 or higher */ - if (screen->priv->rr_major_version == 1 && screen->priv->rr_minor_version >= 3) - XRRSetOutputPrimary (screen->priv->xdisplay, screen->priv->xroot, id); + /* Runtime check for RandR 1.3 or higher */ + if (priv->rr_major_version > 1 || (priv->rr_major_version == 1 && priv->rr_minor_version >= 3)) + XRRSetOutputPrimary (priv->xdisplay, priv->xroot, id); #endif #endif /* HAVE_RANDR */ } diff --git a/libmate-desktop/mate-rr.h b/libmate-desktop/mate-rr.h index 5b55224..124979b 100644 --- a/libmate-desktop/mate-rr.h +++ b/libmate-desktop/mate-rr.h @@ -1,4 +1,4 @@ -/* randrwrap.h +/* mate-rr.h * * Copyright 2007, 2008, Red Hat, Inc. * @@ -21,8 +21,8 @@ * * Author: Soren Sandmann <[email protected]> */ -#ifndef RANDR_WRAP_H -#define RANDR_WRAP_H +#ifndef MATE_RR_H +#define MATE_RR_H #ifndef MATE_DESKTOP_USE_UNSTABLE_API #error MateRR is unstable API. You must define MATE_DESKTOP_USE_UNSTABLE_API before including materr.h @@ -45,10 +45,9 @@ typedef struct { typedef struct { GObjectClass parent_class; + void (* changed) (void); } MateRRScreenClass; -typedef void (* MateRRScreenChanged) (MateRRScreen *screen, gpointer data); - typedef enum { MATE_RR_ROTATION_0 = (1 << 0), @@ -76,16 +75,16 @@ typedef enum { #define MATE_RR_CONNECTOR_TYPE_PANEL "Panel" /* This is a laptop's built-in LCD */ -#define MATE_RR_TYPE_SCREEN (mate_rr_screen_get_type()) -#define MATE_RR_SCREEN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MATE_RR_TYPE_SCREEN, MateRRScreen)) -#define MATE_RR_IS_SCREEN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MATE_RR_TYPE_SCREEN)) -#define MATE_RR_SCREEN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MATE_RR_TYPE_SCREEN, MateRRScreenClass)) -#define MATE_RR_IS_SCREEN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MATE_RR_TYPE_SCREEN)) -#define MATE_RR_SCREEN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MATE_RR_TYPE_SCREEN, MateRRScreenClass)) +#define MATE_TYPE_RR_SCREEN (mate_rr_screen_get_type()) +#define MATE_RR_SCREEN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MATE_TYPE_RR_SCREEN, MateRRScreen)) +#define MATE_IS_RR_SCREEN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MATE_TYPE_RR_SCREEN)) +#define MATE_RR_SCREEN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MATE_TYPE_RR_SCREEN, MateRRScreenClass)) +#define MATE_IS_RR_SCREEN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MATE_TYPE_RR_SCREEN)) +#define MATE_RR_SCREEN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MATE_TYPE_RR_SCREEN, MateRRScreenClass)) -#define MATE_RR_TYPE_OUTPUT (mate_rr_output_get_type()) -#define MATE_RR_TYPE_CRTC (mate_rr_crtc_get_type()) -#define MATE_RR_TYPE_MODE (mate_rr_mode_get_type()) +#define MATE_TYPE_RR_OUTPUT (mate_rr_output_get_type()) +#define MATE_TYPE_RR_CRTC (mate_rr_crtc_get_type()) +#define MATE_TYPE_RR_MODE (mate_rr_mode_get_type()) GType mate_rr_screen_get_type (void); GType mate_rr_output_get_type (void); @@ -94,10 +93,7 @@ GType mate_rr_mode_get_type (void); /* MateRRScreen */ MateRRScreen * mate_rr_screen_new (GdkScreen *screen, - MateRRScreenChanged callback, - gpointer data, GError **error); -void mate_rr_screen_destroy (MateRRScreen *screen); MateRROutput **mate_rr_screen_list_outputs (MateRRScreen *screen); MateRRCrtc ** mate_rr_screen_list_crtcs (MateRRScreen *screen); MateRRMode ** mate_rr_screen_list_modes (MateRRScreen *screen); @@ -127,6 +123,8 @@ void mate_rr_screen_get_timestamps (MateRRScreen *screen, void mate_rr_screen_set_primary_output (MateRRScreen *screen, MateRROutput *output); +MateRRMode **mate_rr_screen_create_clone_modes (MateRRScreen *screen); + /* MateRROutput */ guint32 mate_rr_output_get_id (MateRROutput *output); const char * mate_rr_output_get_name (MateRROutput *output); @@ -201,4 +199,4 @@ void mate_rr_crtc_set_gamma (MateRRCrtc *crtc, unsigned short *red, unsigned short *green, unsigned short *blue); -#endif +#endif /* MATE_RR_H */ |