[gnome-settings-daemon/f16] Backport several color plugin fixes from the gnome-3-2 branch.

Richard Hughes rhughes at fedoraproject.org
Thu Mar 15 16:51:53 UTC 2012


commit 821dbdc0645e1005a0521f3c37449fc96929d684
Author: Richard Hughes <richard at hughsie.com>
Date:   Thu Mar 15 16:50:54 2012 +0000

    Backport several color plugin fixes from the gnome-3-2 branch.
    
    - This fixes various problems people have reported when trying to
      assign color profiles to devices with invalid EDIDs.

 gnome-settings-daemon.spec |   11 ++-
 gsd-fix-color-plugin.patch |  288 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 298 insertions(+), 1 deletions(-)
---
diff --git a/gnome-settings-daemon.spec b/gnome-settings-daemon.spec
index 63d6fc6..a283185 100644
--- a/gnome-settings-daemon.spec
+++ b/gnome-settings-daemon.spec
@@ -1,6 +1,6 @@
 Name:           gnome-settings-daemon
 Version:        3.2.2
-Release:        1%{?dist}
+Release:        2%{?dist}
 Summary:        The daemon sharing settings from GNOME to GTK+/KDE applications
 
 Group:          System Environment/Daemons
@@ -12,6 +12,9 @@ Source:         http://download.gnome.org/sources/%{name}/3.2/%{name}-%{version}
 # Fedora specific patch
 Patch0: gsd-calculator.patch
 
+# Backported from gnome-3-2
+Patch1: gsd-fix-color-plugin.patch
+
 Requires(pre):    GConf2 >= 2.14
 Requires(preun):  GConf2 >= 2.14
 Requires(post):   GConf2 >= 2.14
@@ -65,6 +68,7 @@ developing applications that use %{name}.
 %prep
 %setup -q
 %patch0 -p1 -b .calc
+%patch1 -p1 -b .color-plugin
 
 # autoreconf -i -f
 
@@ -220,6 +224,11 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || :
 %{_datadir}/gnome-settings-daemon-3.0/input-device-example.sh
 
 %changelog
+* Thu Mar 15 2012 Richard Hughes <rhughes at redhat.com> 3.2.2-2
+- Backport several color plugin fixes from the gnome-3-2 branch.
+- This fixes various problems people have reported when trying to
+  assign color profiles to devices with invalid EDIDs.
+
 * Fri Nov 11 2011 Bastien Nocera <bnocera at redhat.com> 3.2.2-1
 - Update to 3.2.2
 
diff --git a/gsd-fix-color-plugin.patch b/gsd-fix-color-plugin.patch
new file mode 100644
index 0000000..00c1796
--- /dev/null
+++ b/gsd-fix-color-plugin.patch
@@ -0,0 +1,288 @@
+diff --git a/plugins/color/gcm-dmi.c b/plugins/color/gcm-dmi.c
+index f4be19a..b68cdf2 100644
+--- a/plugins/color/gcm-dmi.c
++++ b/plugins/color/gcm-dmi.c
+@@ -122,6 +122,7 @@ gcm_dmi_class_init (GcmDmiClass *klass)
+ static void
+ gcm_dmi_init (GcmDmi *dmi)
+ {
++#if defined(__linux__)
+         const gchar *sysfs_name[] = {
+                 "/sys/class/dmi/id/product_name",
+                 "/sys/class/dmi/id/board_name",
+@@ -136,6 +137,12 @@ gcm_dmi_init (GcmDmi *dmi)
+                 "/sys/class/dmi/id/chassis_vendor",
+                 "/sys/class/dmi/id/board_vendor",
+                 NULL};
++#else
++#warning Please add dmi support for your OS
++        const gchar *sysfs_name[] = { NULL };
++        const gchar *sysfs_version[] = { NULL };
++        const gchar *sysfs_vendor[] = { NULL };
++#endif
+ 
+         dmi->priv = GCM_DMI_GET_PRIVATE (dmi);
+ 
+diff --git a/plugins/color/gsd-color-manager.c b/plugins/color/gsd-color-manager.c
+index 01b20c0..d99e0b5 100644
+--- a/plugins/color/gsd-color-manager.c
++++ b/plugins/color/gsd-color-manager.c
+@@ -197,19 +197,29 @@ gcm_session_get_output_id (GsdColorManager *manager, GnomeRROutput *output)
+                          error->message);
+                 g_error_free (error);
+                 g_string_append_printf (device_id,
+-                                        "_%s",
++                                        "-%s",
+                                         gnome_rr_output_get_name (output));
+                 goto out;
+         }
+ 
+-        /* get EDID data */
++        /* check EDID data is okay to use */
+         vendor = gcm_edid_get_vendor_name (edid);
++        name = gcm_edid_get_monitor_name (edid);
++        serial = gcm_edid_get_serial_number (edid);
++        if (vendor == NULL && name == NULL && serial == NULL) {
++                g_debug ("edid invalid for %s, falling back to connection name",
++                         gnome_rr_output_get_name (output));
++                g_string_append_printf (device_id,
++                                        "-%s",
++                                        gnome_rr_output_get_name (output));
++                goto out;
++        }
++
++        /* use EDID data */
+         if (vendor != NULL)
+                 g_string_append_printf (device_id, "-%s", vendor);
+-        name = gcm_edid_get_monitor_name (edid);
+         if (name != NULL)
+                 g_string_append_printf (device_id, "-%s", name);
+-        serial = gcm_edid_get_serial_number (edid);
+         if (serial != NULL)
+                 g_string_append_printf (device_id, "-%s", serial);
+ out:
+@@ -356,8 +366,7 @@ gcm_session_profile_assign_find_device_cb (GObject *object,
+                                                res,
+                                                &error);
+         if (device == NULL) {
+-                g_warning ("not found device %s which should have been added: %s",
+-                           cd_device_get_id (device),
++                g_warning ("not found device which should have been added: %s",
+                            error->message);
+                 g_error_free (error);
+                 gcm_session_async_helper_free (helper);
+@@ -751,7 +760,7 @@ gcm_session_generate_vcgt (CdProfile *profile, guint size)
+                 goto out;
+ 
+         /* get tone curves from profile */
+-        vcgt = cmsReadTag (lcms_profile, cmsSigVcgtType);
++        vcgt = cmsReadTag (lcms_profile, cmsSigVcgtTag);
+         if (vcgt == NULL || vcgt[0] == NULL) {
+                 g_debug ("profile does not have any VCGT data");
+                 goto out;
+@@ -959,6 +968,51 @@ out:
+         return output;
+ }
+ 
++/* this function is more complicated than it should be, due to the
++ * fact that XOrg sometimes assigns no primary devices when using
++ * "xrandr --auto" or when the version of RANDR is < 1.3 */
++static gboolean
++gcm_session_use_output_profile_for_screen (GsdColorManager *manager,
++                                           GnomeRROutput *output)
++{
++        gboolean has_laptop = FALSE;
++        gboolean has_primary = FALSE;
++        GnomeRROutput **outputs;
++        GnomeRROutput *connected = NULL;
++        guint i;
++
++        /* do we have any screens marked as primary */
++        outputs = gnome_rr_screen_list_outputs (manager->priv->x11_screen);
++        if (outputs == NULL || outputs[0] == NULL) {
++                g_warning ("failed to get outputs");
++                return FALSE;
++        }
++        for (i = 0; outputs[i] != NULL; i++) {
++                if (!gnome_rr_output_is_connected (outputs[i]))
++                        continue;
++                if (connected == NULL)
++                        connected = outputs[i];
++                if (gnome_rr_output_get_is_primary (outputs[i]))
++                        has_primary = TRUE;
++                if (gnome_rr_output_is_laptop (outputs[i]))
++                        has_laptop = TRUE;
++        }
++
++        /* we have an assigned primary device, are we that? */
++        if (has_primary)
++                return gnome_rr_output_get_is_primary (output);
++
++        /* choosing the internal panel is probably sane */
++        if (has_laptop)
++                return gnome_rr_output_is_laptop (output);
++
++        /* we have to choose one, so go for the first connected device */
++        if (connected != NULL)
++                return gnome_rr_output_get_id (connected) == gnome_rr_output_get_id (output);
++
++        return FALSE;
++}
++
+ static void
+ gcm_session_device_assign_profile_connect_cb (GObject *object,
+                                               GAsyncResult *res,
+@@ -993,7 +1047,8 @@ gcm_session_device_assign_profile_connect_cb (GObject *object,
+                 goto out;
+ 
+         /* set the _ICC_PROFILE atom */
+-        if (gnome_rr_output_get_is_primary (output)) {
++        ret = gcm_session_use_output_profile_for_screen (manager, output);
++        if (ret) {
+                 ret = gcm_session_screen_set_icc_profile (manager,
+                                                           filename,
+                                                           &error);
+@@ -1085,35 +1140,33 @@ gcm_session_device_assign_connect_cb (GObject *object,
+                 goto out;
+         }
+ 
+-        /* get the output EDID */
++        /* create profile from device edid if it exists */
+         edid = gcm_session_get_output_edid (manager, output, &error);
+         if (edid == NULL) {
+                 g_warning ("unable to get EDID for %s: %s",
+                            cd_device_get_id (device),
+                            error->message);
+-                g_error_free (error);
+-                goto out;
+-        }
+-
+-        /* create profile from device edid if it does not exist */
+-        autogen_filename = g_strdup_printf ("edid-%s.icc",
+-                                            gcm_edid_get_checksum (edid));
+-        autogen_path = g_build_filename (g_get_user_data_dir (),
+-                                         "icc", autogen_filename, NULL);
++                g_clear_error (&error);
+ 
+-        if (g_file_test (autogen_path, G_FILE_TEST_EXISTS)) {
+-                g_debug ("auto-profile edid %s exists", autogen_path);
+         } else {
+-                g_debug ("auto-profile edid does not exist, creating as %s",
+-                         autogen_path);
+-                ret = gcm_apply_create_icc_profile_for_edid (manager,
+-                                                             edid,
+-                                                             autogen_path,
+-                                                             &error);
+-                if (!ret) {
+-                        g_warning ("failed to create profile from EDID data: %s",
+-                                     error->message);
+-                        g_clear_error (&error);
++                autogen_filename = g_strdup_printf ("edid-%s.icc",
++                                                    gcm_edid_get_checksum (edid));
++                autogen_path = g_build_filename (g_get_user_data_dir (),
++                                                 "icc", autogen_filename, NULL);
++                if (g_file_test (autogen_path, G_FILE_TEST_EXISTS)) {
++                        g_debug ("auto-profile edid %s exists", autogen_path);
++                } else {
++                        g_debug ("auto-profile edid does not exist, creating as %s",
++                                 autogen_path);
++                        ret = gcm_apply_create_icc_profile_for_edid (manager,
++                                                                     edid,
++                                                                     autogen_path,
++                                                                     &error);
++                        if (!ret) {
++                                g_warning ("failed to create profile from EDID data: %s",
++                                             error->message);
++                                g_clear_error (&error);
++                        }
+                 }
+         }
+ 
+@@ -1227,9 +1280,9 @@ gcm_session_create_device_cb (GObject *object,
+ static void
+ gcm_session_add_x11_output (GsdColorManager *manager, GnomeRROutput *output)
+ {
+-        const gchar *model;
+-        const gchar *serial;
+-        const gchar *vendor;
++        const gchar *model = NULL;
++        const gchar *serial = NULL;
++        const gchar *vendor = NULL;
+         gboolean ret;
+         gchar *device_id = NULL;
+         GcmEdid *edid;
+@@ -1237,32 +1290,45 @@ gcm_session_add_x11_output (GsdColorManager *manager, GnomeRROutput *output)
+         GHashTable *device_props = NULL;
+         GsdColorManagerPrivate *priv = manager->priv;
+ 
+-        /* get edid */
++        /* try to get edid */
+         edid = gcm_session_get_output_edid (manager, output, &error);
+         if (edid == NULL) {
+                 g_warning ("failed to get edid: %s",
+                            error->message);
+-                g_error_free (error);
+-                goto out;
++                g_clear_error (&error);
+         }
+ 
+-        /* is this an internal device? */
++        /* prefer DMI data for the internal output */
+         ret = gnome_rr_output_is_laptop (output);
+         if (ret) {
+                 model = gcm_dmi_get_name (priv->dmi);
+                 vendor = gcm_dmi_get_vendor (priv->dmi);
+-        } else {
+-                model = gcm_edid_get_monitor_name (edid);
+-                if (model == NULL)
+-                        model = gnome_rr_output_get_name (output);
+-                vendor = gcm_edid_get_vendor_name (edid);
+         }
+ 
+-        /* get a serial number if one exists */
+-        serial = gcm_edid_get_serial_number (edid);
++        /* use EDID data if we have it */
++        if (edid != NULL) {
++                if (model == NULL)
++                        model = gcm_edid_get_monitor_name (edid);
++                if (vendor == NULL)
++                        vendor = gcm_edid_get_vendor_name (edid);
++                if (serial == NULL)
++                        serial = gcm_edid_get_serial_number (edid);
++        }
++
++        /* ensure mandatory fields are set */
++        if (model == NULL)
++                model = gnome_rr_output_get_name (output);
++        if (vendor == NULL)
++                vendor = "unknown";
+         if (serial == NULL)
+                 serial = "unknown";
+ 
++        /* ensure mandatory fields are set */
++        if (model == NULL)
++                model = "unknown";
++        if (vendor == NULL)
++                vendor = "unknown";
++
+         device_id = gcm_session_get_output_id (manager, output);
+         g_debug ("output %s added", device_id);
+         device_props = g_hash_table_new_full (g_str_hash, g_str_equal,
+@@ -1295,7 +1361,6 @@ gcm_session_add_x11_output (GsdColorManager *manager, GnomeRROutput *output)
+                                  NULL,
+                                  gcm_session_create_device_cb,
+                                  manager);
+-out:
+         g_free (device_id);
+         if (device_props != NULL)
+                 g_hash_table_unref (device_props);
+@@ -1411,8 +1476,7 @@ gcm_session_profile_gamma_find_device_cb (GObject *object,
+                                                            res,
+                                                            &error);
+         if (device == NULL) {
+-                g_warning ("not found device %s: %s",
+-                           cd_device_get_id (device),
++                g_warning ("could not find device: %s",
+                            error->message);
+                 g_error_free (error);
+                 goto out;


More information about the scm-commits mailing list