[gnome-settings-daemon] color: Split out the X11 functionality into a new file



commit 09f2cf1b2c6dc0ba0172a1af0eaaa790ef6d8a2a
Author: Richard Hughes <richard hughsie com>
Date:   Wed Jul 17 11:43:49 2013 +0100

    color: Split out the X11 functionality into a new file
    
    Also, only run the X11 functionality when using the X11 backend. This prevents
    segfaults when using wayland.

 plugins/color/Makefile.am         |    2 +
 plugins/color/gsd-color-manager.c | 1356 +----------------------------------
 plugins/color/gsd-color-x11.c     | 1434 +++++++++++++++++++++++++++++++++++++
 plugins/color/gsd-color-x11.h     |   55 ++
 4 files changed, 1508 insertions(+), 1339 deletions(-)
---
diff --git a/plugins/color/Makefile.am b/plugins/color/Makefile.am
index bb02018..9af4592 100644
--- a/plugins/color/Makefile.am
+++ b/plugins/color/Makefile.am
@@ -12,6 +12,8 @@ libcolor_la_SOURCES =                         \
        gsd-color-manager.h             \
        gsd-color-profiles.c            \
        gsd-color-profiles.h            \
+       gsd-color-x11.c                 \
+       gsd-color-x11.h                 \
        gsd-color-plugin.c
 
 libcolor_la_CPPFLAGS = \
diff --git a/plugins/color/gsd-color-manager.c b/plugins/color/gsd-color-manager.c
index 173ca07..0b3de9a 100644
--- a/plugins/color/gsd-color-manager.c
+++ b/plugins/color/gsd-color-manager.c
@@ -1,7 +1,7 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
  *
  * Copyright (C) 2007 William Jon McCann <mccann jhu edu>
- * Copyright (C) 2011 Richard Hughes <richard hughsie com>
+ * Copyright (C) 2011-2013 Richard Hughes <richard hughsie com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,36 +22,26 @@
 #include "config.h"
 
 #include <glib/gi18n.h>
-#include <colord.h>
 #include <gdk/gdk.h>
-#include <stdlib.h>
-#include <lcms2.h>
-#include <canberra-gtk.h>
 
-#define GNOME_DESKTOP_USE_UNSTABLE_API
-#include <libgnome-desktop/gnome-rr.h>
+#ifdef GDK_WINDOWING_X11
+#include <gdk/gdkx.h>
+#endif
 
 #include "gnome-settings-plugin.h"
 #include "gnome-settings-profile.h"
-#include "gnome-settings-session.h"
 #include "gsd-color-calibrate.h"
 #include "gsd-color-manager.h"
 #include "gsd-color-profiles.h"
-#include "gcm-edid.h"
+#include "gsd-color-x11.h"
 
 #define GSD_COLOR_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_COLOR_MANAGER, 
GsdColorManagerPrivate))
 
 struct GsdColorManagerPrivate
 {
-        GDBusProxy      *session;
-        CdClient        *client;
-        GnomeRRScreen   *x11_screen;
-        GHashTable      *edid_cache;
-        GdkWindow       *gdk_window;
-        gboolean         session_is_active;
-        GHashTable      *device_assign_hash;
         GsdColorCalibrate *calibrate;
         GsdColorProfiles  *profiles;
+        GsdColorX11       *x11;
 };
 
 enum {
@@ -66,16 +56,6 @@ G_DEFINE_TYPE (GsdColorManager, gsd_color_manager, G_TYPE_OBJECT)
 
 static gpointer manager_object = NULL;
 
-/* see http://www.oyranos.org/wiki/index.php?title=ICC_Profiles_in_X_Specification_0.3 */
-#define GCM_ICC_PROFILE_IN_X_VERSION_MAJOR      0
-#define GCM_ICC_PROFILE_IN_X_VERSION_MINOR      3
-
-typedef struct {
-        guint32          red;
-        guint32          green;
-        guint32          blue;
-} GnomeRROutputClutItem;
-
 GQuark
 gsd_color_manager_error_quark (void)
 {
@@ -85,1250 +65,29 @@ gsd_color_manager_error_quark (void)
         return quark;
 }
 
-static GcmEdid *
-gcm_session_get_output_edid (GsdColorManager *manager, GnomeRROutput *output, GError **error)
-{
-        const guint8 *data;
-        gsize size;
-        GcmEdid *edid = NULL;
-        gboolean ret;
-
-        /* can we find it in the cache */
-        edid = g_hash_table_lookup (manager->priv->edid_cache,
-                                    gnome_rr_output_get_name (output));
-        if (edid != NULL) {
-                g_object_ref (edid);
-                goto out;
-        }
-
-        /* parse edid */
-        data = gnome_rr_output_get_edid_data (output, &size);
-        if (data == NULL || size == 0) {
-                g_set_error_literal (error,
-                                     GNOME_RR_ERROR,
-                                     GNOME_RR_ERROR_UNKNOWN,
-                                     "unable to get EDID for output");
-                goto out;
-        }
-        edid = gcm_edid_new ();
-        ret = gcm_edid_parse (edid, data, size, error);
-        if (!ret) {
-                g_object_unref (edid);
-                edid = NULL;
-                goto out;
-        }
-
-        /* add to cache */
-        g_hash_table_insert (manager->priv->edid_cache,
-                             g_strdup (gnome_rr_output_get_name (output)),
-                             g_object_ref (edid));
-out:
-        return edid;
-}
-
-static gboolean
-gcm_session_screen_set_icc_profile (GsdColorManager *manager,
-                                    const gchar *filename,
-                                    GError **error)
-{
-        gboolean ret;
-        gchar *data = NULL;
-        gsize length;
-        guint version_data;
-        GsdColorManagerPrivate *priv = manager->priv;
-
-        g_return_val_if_fail (filename != NULL, FALSE);
-
-        g_debug ("setting root window ICC profile atom from %s", filename);
-
-        /* get contents of file */
-        ret = g_file_get_contents (filename, &data, &length, error);
-        if (!ret)
-                goto out;
-
-        /* set profile property */
-        gdk_property_change (priv->gdk_window,
-                             gdk_atom_intern_static_string ("_ICC_PROFILE"),
-                             gdk_atom_intern_static_string ("CARDINAL"),
-                             8,
-                             GDK_PROP_MODE_REPLACE,
-                             (const guchar *) data, length);
-
-        /* set version property */
-        version_data = GCM_ICC_PROFILE_IN_X_VERSION_MAJOR * 100 +
-                        GCM_ICC_PROFILE_IN_X_VERSION_MINOR * 1;
-        gdk_property_change (priv->gdk_window,
-                             gdk_atom_intern_static_string ("_ICC_PROFILE_IN_X_VERSION"),
-                             gdk_atom_intern_static_string ("CARDINAL"),
-                             8,
-                             GDK_PROP_MODE_REPLACE,
-                             (const guchar *) &version_data, 1);
-out:
-        g_free (data);
-        return ret;
-}
-
-static gchar *
-gcm_session_get_output_id (GsdColorManager *manager, GnomeRROutput *output)
-{
-        const gchar *name;
-        const gchar *serial;
-        const gchar *vendor;
-        GcmEdid *edid = NULL;
-        GString *device_id;
-        GError *error = NULL;
-
-        /* all output devices are prefixed with this */
-        device_id = g_string_new ("xrandr");
-
-        /* get the output EDID if possible */
-        edid = gcm_session_get_output_edid (manager, output, &error);
-        if (edid == NULL) {
-                g_debug ("no edid for %s [%s], falling back to connection name",
-                         gnome_rr_output_get_name (output),
-                         error->message);
-                g_error_free (error);
-                g_string_append_printf (device_id,
-                                        "-%s",
-                                        gnome_rr_output_get_name (output));
-                goto out;
-        }
-
-        /* 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);
-        if (name != NULL)
-                g_string_append_printf (device_id, "-%s", name);
-        if (serial != NULL)
-                g_string_append_printf (device_id, "-%s", serial);
-out:
-        if (edid != NULL)
-                g_object_unref (edid);
-        return g_string_free (device_id, FALSE);
-}
-
-typedef struct {
-        GsdColorManager         *manager;
-        CdProfile               *profile;
-        CdDevice                *device;
-        guint32                  output_id;
-} GcmSessionAsyncHelper;
-
-static void
-gcm_session_async_helper_free (GcmSessionAsyncHelper *helper)
-{
-        if (helper->manager != NULL)
-                g_object_unref (helper->manager);
-        if (helper->profile != NULL)
-                g_object_unref (helper->profile);
-        if (helper->device != NULL)
-                g_object_unref (helper->device);
-        g_free (helper);
-}
-
-static gboolean
-gcm_utils_mkdir_for_filename (GFile *file, GError **error)
-{
-        gboolean ret = FALSE;
-        GFile *parent_dir = NULL;
-
-        /* get parent directory */
-        parent_dir = g_file_get_parent (file);
-        if (parent_dir == NULL) {
-                g_set_error_literal (error,
-                                     GSD_COLOR_MANAGER_ERROR,
-                                     GSD_COLOR_MANAGER_ERROR_FAILED,
-                                     "could not get parent dir");
-                goto out;
-        }
-
-        /* ensure desination does not already exist */
-        ret = g_file_query_exists (parent_dir, NULL);
-        if (ret)
-                goto out;
-        ret = g_file_make_directory_with_parents (parent_dir, NULL, error);
-        if (!ret)
-                goto out;
-out:
-        if (parent_dir != NULL)
-                g_object_unref (parent_dir);
-        return ret;
-}
-
-static gboolean
-gcm_apply_create_icc_profile_for_edid (GsdColorManager *manager,
-                                       CdDevice *device,
-                                       GcmEdid *edid,
-                                       GFile *file,
-                                       GError **error)
-{
-        CdIcc *icc = NULL;
-        const gchar *data;
-        gboolean ret = FALSE;
-        GsdColorManagerPrivate *priv = manager->priv;
-
-        /* ensure the per-user directory exists */
-        ret = gcm_utils_mkdir_for_filename (file, error);
-        if (!ret)
-                goto out;
-
-        /* create our generated profile */
-        icc = cd_icc_new ();
-        ret = cd_icc_create_from_edid (icc,
-                                       gcm_edid_get_gamma (edid),
-                                       gcm_edid_get_red (edid),
-                                       gcm_edid_get_green (edid),
-                                       gcm_edid_get_blue (edid),
-                                       gcm_edid_get_white (edid),
-                                       error);
-        if (!ret)
-                goto out;
-
-        /* set copyright */
-        cd_icc_set_copyright (icc, NULL,
-                              /* deliberately not translated */
-                              "This profile is free of known copyright restrictions.");
-
-        /* set model and title */
-        data = gcm_edid_get_monitor_name (edid);
-        if (data == NULL)
-                data = cd_client_get_system_model (priv->client);
-        if (data == NULL)
-                data = "Unknown monitor";
-        cd_icc_set_model (icc, NULL, data);
-        cd_icc_set_description (icc, NULL, data);
-
-        /* get manufacturer */
-        data = gcm_edid_get_vendor_name (edid);
-        if (data == NULL)
-                data = cd_client_get_system_vendor (priv->client);
-        if (data == NULL)
-                data = "Unknown vendor";
-        cd_icc_set_manufacturer (icc, NULL, data);
-
-        /* set the framework creator metadata */
-        cd_icc_add_metadata (icc,
-                             CD_PROFILE_METADATA_CMF_PRODUCT,
-                             PACKAGE_NAME);
-        cd_icc_add_metadata (icc,
-                             CD_PROFILE_METADATA_CMF_BINARY,
-                             PACKAGE_NAME);
-        cd_icc_add_metadata (icc,
-                             CD_PROFILE_METADATA_CMF_VERSION,
-                             PACKAGE_VERSION);
-        cd_icc_add_metadata (icc,
-                             CD_PROFILE_METADATA_MAPPING_DEVICE_ID,
-                             cd_device_get_id (device));
-
-        /* set 'ICC meta Tag for Monitor Profiles' data */
-        cd_icc_add_metadata (icc, CD_PROFILE_METADATA_EDID_MD5, gcm_edid_get_checksum (edid));
-        data = gcm_edid_get_monitor_name (edid);
-        if (data != NULL)
-                cd_icc_add_metadata (icc, CD_PROFILE_METADATA_EDID_MODEL, data);
-        data = gcm_edid_get_serial_number (edid);
-        if (data != NULL)
-                cd_icc_add_metadata (icc, CD_PROFILE_METADATA_EDID_SERIAL, data);
-        data = gcm_edid_get_pnp_id (edid);
-        if (data != NULL)
-                cd_icc_add_metadata (icc, CD_PROFILE_METADATA_EDID_MNFT, data);
-        data = gcm_edid_get_vendor_name (edid);
-        if (data != NULL)
-                cd_icc_add_metadata (icc, CD_PROFILE_METADATA_EDID_VENDOR, data);
-
-        /* save */
-        ret = cd_icc_save_file (icc, file, CD_ICC_SAVE_FLAGS_NONE, NULL, error);
-        if (!ret)
-                goto out;
-out:
-        if (icc != NULL)
-                g_object_unref (icc);
-        return ret;
-}
-
-static GPtrArray *
-gcm_session_generate_vcgt (CdProfile *profile, guint size)
-{
-        GnomeRROutputClutItem *tmp;
-        GPtrArray *array = NULL;
-        const cmsToneCurve **vcgt;
-        cmsFloat32Number in;
-        guint i;
-        cmsHPROFILE lcms_profile;
-        CdIcc *icc = NULL;
-
-        /* invalid size */
-        if (size == 0)
-                goto out;
-
-        /* open file */
-        icc = cd_profile_load_icc (profile, CD_ICC_LOAD_FLAGS_NONE, NULL, NULL);
-        if (icc == NULL)
-                goto out;
-
-        /* get tone curves from profile */
-        lcms_profile = cd_icc_get_handle (icc);
-        vcgt = cmsReadTag (lcms_profile, cmsSigVcgtTag);
-        if (vcgt == NULL || vcgt[0] == NULL) {
-                g_debug ("profile does not have any VCGT data");
-                goto out;
-        }
-
-        /* create array */
-        array = g_ptr_array_new_with_free_func (g_free);
-        for (i = 0; i < size; i++) {
-                in = (gdouble) i / (gdouble) (size - 1);
-                tmp = g_new0 (GnomeRROutputClutItem, 1);
-                tmp->red = cmsEvalToneCurveFloat(vcgt[0], in) * (gdouble) 0xffff;
-                tmp->green = cmsEvalToneCurveFloat(vcgt[1], in) * (gdouble) 0xffff;
-                tmp->blue = cmsEvalToneCurveFloat(vcgt[2], in) * (gdouble) 0xffff;
-                g_ptr_array_add (array, tmp);
-        }
-out:
-        if (icc != NULL)
-                g_object_unref (icc);
-        return array;
-}
-
-static guint
-gnome_rr_output_get_gamma_size (GnomeRROutput *output)
-{
-        GnomeRRCrtc *crtc;
-        gint len = 0;
-
-        crtc = gnome_rr_output_get_crtc (output);
-        if (crtc == NULL)
-                return 0;
-        gnome_rr_crtc_get_gamma (crtc,
-                                 &len,
-                                 NULL, NULL, NULL);
-        return (guint) len;
-}
-
-static gboolean
-gcm_session_output_set_gamma (GnomeRROutput *output,
-                              GPtrArray *array,
-                              GError **error)
-{
-        gboolean ret = TRUE;
-        guint16 *red = NULL;
-        guint16 *green = NULL;
-        guint16 *blue = NULL;
-        guint i;
-        GnomeRROutputClutItem *data;
-        GnomeRRCrtc *crtc;
-
-        /* no length? */
-        if (array->len == 0) {
-                ret = FALSE;
-                g_set_error_literal (error,
-                                     GSD_COLOR_MANAGER_ERROR,
-                                     GSD_COLOR_MANAGER_ERROR_FAILED,
-                                     "no data in the CLUT array");
-                goto out;
-        }
-
-        /* convert to a type X understands */
-        red = g_new (guint16, array->len);
-        green = g_new (guint16, array->len);
-        blue = g_new (guint16, array->len);
-        for (i = 0; i < array->len; i++) {
-                data = g_ptr_array_index (array, i);
-                red[i] = data->red;
-                green[i] = data->green;
-                blue[i] = data->blue;
-        }
-
-        /* send to LUT */
-        crtc = gnome_rr_output_get_crtc (output);
-        if (crtc == NULL) {
-                ret = FALSE;
-                g_set_error (error,
-                             GSD_COLOR_MANAGER_ERROR,
-                             GSD_COLOR_MANAGER_ERROR_FAILED,
-                             "failed to get ctrc for %s",
-                             gnome_rr_output_get_name (output));
-                goto out;
-        }
-        gnome_rr_crtc_set_gamma (crtc, array->len,
-                                 red, green, blue);
-out:
-        g_free (red);
-        g_free (green);
-        g_free (blue);
-        return ret;
-}
-
-static gboolean
-gcm_session_device_set_gamma (GnomeRROutput *output,
-                              CdProfile *profile,
-                              GError **error)
-{
-        gboolean ret = FALSE;
-        guint size;
-        GPtrArray *clut = NULL;
-
-        /* create a lookup table */
-        size = gnome_rr_output_get_gamma_size (output);
-        if (size == 0) {
-                ret = TRUE;
-                goto out;
-        }
-        clut = gcm_session_generate_vcgt (profile, size);
-        if (clut == NULL) {
-                g_set_error_literal (error,
-                                     GSD_COLOR_MANAGER_ERROR,
-                                     GSD_COLOR_MANAGER_ERROR_FAILED,
-                                     "failed to generate vcgt");
-                goto out;
-        }
-
-        /* apply the vcgt to this output */
-        ret = gcm_session_output_set_gamma (output, clut, error);
-        if (!ret)
-                goto out;
-out:
-        if (clut != NULL)
-                g_ptr_array_unref (clut);
-        return ret;
-}
-
-static gboolean
-gcm_session_device_reset_gamma (GnomeRROutput *output,
-                                GError **error)
-{
-        gboolean ret;
-        guint i;
-        guint size;
-        guint32 value;
-        GPtrArray *clut;
-        GnomeRROutputClutItem *data;
-
-        /* create a linear ramp */
-        g_debug ("falling back to dummy ramp");
-        clut = g_ptr_array_new_with_free_func (g_free);
-        size = gnome_rr_output_get_gamma_size (output);
-        if (size == 0) {
-                ret = TRUE;
-                goto out;
-        }
-        for (i = 0; i < size; i++) {
-                value = (i * 0xffff) / (size - 1);
-                data = g_new0 (GnomeRROutputClutItem, 1);
-                data->red = value;
-                data->green = value;
-                data->blue = value;
-                g_ptr_array_add (clut, data);
-        }
-
-        /* apply the vcgt to this output */
-        ret = gcm_session_output_set_gamma (output, clut, error);
-        if (!ret)
-                goto out;
-out:
-        g_ptr_array_unref (clut);
-        return ret;
-}
-
-static GnomeRROutput *
-gcm_session_get_x11_output_by_id (GsdColorManager *manager,
-                                  const gchar *device_id,
-                                  GError **error)
-{
-        gchar *output_id;
-        GnomeRROutput *output = NULL;
-        GnomeRROutput **outputs = NULL;
-        guint i;
-        GsdColorManagerPrivate *priv = manager->priv;
-
-        /* search all X11 outputs for the device id */
-        outputs = gnome_rr_screen_list_outputs (priv->x11_screen);
-        if (outputs == NULL) {
-                g_set_error_literal (error,
-                                     GSD_COLOR_MANAGER_ERROR,
-                                     GSD_COLOR_MANAGER_ERROR_FAILED,
-                                     "Failed to get outputs");
-                goto out;
-        }
-        for (i = 0; outputs[i] != NULL && output == NULL; i++) {
-                if (!gnome_rr_output_is_connected (outputs[i]))
-                        continue;
-                output_id = gcm_session_get_output_id (manager, outputs[i]);
-                if (g_strcmp0 (output_id, device_id) == 0)
-                        output = outputs[i];
-                g_free (output_id);
-        }
-        if (output == NULL) {
-                g_set_error (error,
-                             GSD_COLOR_MANAGER_ERROR,
-                             GSD_COLOR_MANAGER_ERROR_FAILED,
-                             "Failed to find output %s",
-                             device_id);
-        }
-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_builtin_display (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_builtin_display (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;
-}
-
-/* TODO: remove when we can dep on a released version of colord */
-#ifndef CD_PROFILE_METADATA_SCREEN_BRIGHTNESS
-#define CD_PROFILE_METADATA_SCREEN_BRIGHTNESS          "SCREEN_brightness"
-#endif
-
-#define GSD_DBUS_NAME_POWER            GSD_DBUS_NAME ".Power"
-#define GSD_DBUS_INTERFACE_POWER_SCREEN        GSD_DBUS_BASE_INTERFACE ".Power.Screen"
-#define GSD_DBUS_PATH_POWER            GSD_DBUS_PATH "/Power"
-
-static void
-gcm_session_set_output_percentage (guint percentage)
-{
-        GDBusConnection *connection;
-
-        /* get a ref to the existing bus connection */
-        connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
-        if (connection == NULL)
-                return;
-        g_dbus_connection_call (connection,
-                                GSD_DBUS_NAME_POWER,
-                                GSD_DBUS_PATH_POWER,
-                                "org.freedesktop.DBus.Properties",
-                                "Set",
-                                g_variant_new_parsed ("('" GSD_DBUS_INTERFACE_POWER_SCREEN "',"
-                                                      "'Brightness', %v)",
-                                                      g_variant_new_int32 (percentage)),
-                                NULL,
-                                G_DBUS_CALL_FLAGS_NONE,
-                                -1, NULL, NULL, NULL);
-        g_object_unref (connection);
-}
-
-static void
-gcm_session_device_assign_profile_connect_cb (GObject *object,
-                                              GAsyncResult *res,
-                                              gpointer user_data)
-{
-        CdProfile *profile = CD_PROFILE (object);
-        const gchar *brightness_profile;
-        const gchar *filename;
-        gboolean ret;
-        GError *error = NULL;
-        GnomeRROutput *output;
-        guint brightness_percentage;
-        GcmSessionAsyncHelper *helper = (GcmSessionAsyncHelper *) user_data;
-        GsdColorManager *manager = GSD_COLOR_MANAGER (helper->manager);
-
-        /* get properties */
-        ret = cd_profile_connect_finish (profile, res, &error);
-        if (!ret) {
-                g_warning ("failed to connect to profile: %s",
-                           error->message);
-                g_error_free (error);
-                goto out;
-        }
-
-        /* get the filename */
-        filename = cd_profile_get_filename (profile);
-        g_assert (filename != NULL);
-
-        /* get the output (can't save in helper as GnomeRROutput isn't
-         * a GObject, just a pointer */
-        output = gnome_rr_screen_get_output_by_id (manager->priv->x11_screen,
-                                                   helper->output_id);
-        if (output == NULL)
-                goto out;
-
-        /* if output is a laptop screen and the profile has a
-         * calibration brightness then set this new brightness */
-        brightness_profile = cd_profile_get_metadata_item (profile,
-                                                           CD_PROFILE_METADATA_SCREEN_BRIGHTNESS);
-        if (gnome_rr_output_is_builtin_display (output) &&
-            brightness_profile != NULL) {
-                /* the percentage is stored in the profile metadata as
-                 * a string, not ideal, but it's all we have... */
-                brightness_percentage = atoi (brightness_profile);
-                gcm_session_set_output_percentage (brightness_percentage);
-        }
-
-        /* set the _ICC_PROFILE atom */
-        ret = gcm_session_use_output_profile_for_screen (manager, output);
-        if (ret) {
-                ret = gcm_session_screen_set_icc_profile (manager,
-                                                          filename,
-                                                          &error);
-                if (!ret) {
-                        g_warning ("failed to set screen _ICC_PROFILE: %s",
-                                   error->message);
-                        g_clear_error (&error);
-                }
-        }
-
-        /* create a vcgt for this icc file */
-        ret = cd_profile_get_has_vcgt (profile);
-        if (ret) {
-                ret = gcm_session_device_set_gamma (output,
-                                                    profile,
-                                                    &error);
-                if (!ret) {
-                        g_warning ("failed to set %s gamma tables: %s",
-                                   cd_device_get_id (helper->device),
-                                   error->message);
-                        g_error_free (error);
-                        goto out;
-                }
-        } else {
-                ret = gcm_session_device_reset_gamma (output,
-                                                      &error);
-                if (!ret) {
-                        g_warning ("failed to reset %s gamma tables: %s",
-                                   cd_device_get_id (helper->device),
-                                   error->message);
-                        g_error_free (error);
-                        goto out;
-                }
-        }
-out:
-        gcm_session_async_helper_free (helper);
-}
-
-/*
- * Check to see if the on-disk profile has the MAPPING_device_id
- * metadata, and if not, we should delete the profile and re-create it
- * so that it gets mapped by the daemon.
- */
-static gboolean
-gcm_session_check_profile_device_md (GFile *file)
-{
-        const gchar *key_we_need = CD_PROFILE_METADATA_MAPPING_DEVICE_ID;
-        CdIcc *icc;
-        gboolean ret;
-
-        icc = cd_icc_new ();
-        ret = cd_icc_load_file (icc, file, CD_ICC_LOAD_FLAGS_METADATA, NULL, NULL);
-        if (!ret)
-                goto out;
-        ret = cd_icc_get_metadata_item (icc, key_we_need) != NULL;
-        if (!ret) {
-                g_debug ("auto-edid profile is old, and contains no %s data",
-                         key_we_need);
-        }
-out:
-        g_object_unref (icc);
-        return ret;
-}
-
-static void
-gcm_session_device_assign_connect_cb (GObject *object,
-                                      GAsyncResult *res,
-                                      gpointer user_data)
-{
-        CdDeviceKind kind;
-        CdProfile *profile = NULL;
-        gboolean ret;
-        gchar *autogen_filename = NULL;
-        gchar *autogen_path = NULL;
-        GcmEdid *edid = NULL;
-        GnomeRROutput *output = NULL;
-        GError *error = NULL;
-        GFile *file = NULL;
-        const gchar *xrandr_id;
-        GcmSessionAsyncHelper *helper;
-        CdDevice *device = CD_DEVICE (object);
-        GsdColorManager *manager = GSD_COLOR_MANAGER (user_data);
-        GsdColorManagerPrivate *priv = manager->priv;
-
-        /* remove from assign array */
-        g_hash_table_remove (manager->priv->device_assign_hash,
-                             cd_device_get_object_path (device));
-
-        /* get properties */
-        ret = cd_device_connect_finish (device, res, &error);
-        if (!ret) {
-                g_warning ("failed to connect to device: %s",
-                           error->message);
-                g_error_free (error);
-                goto out;
-        }
-
-        /* check we care */
-        kind = cd_device_get_kind (device);
-        if (kind != CD_DEVICE_KIND_DISPLAY)
-                goto out;
-
-        g_debug ("need to assign display device %s",
-                 cd_device_get_id (device));
-
-        /* get the GnomeRROutput for the device id */
-        xrandr_id = cd_device_get_id (device);
-        output = gcm_session_get_x11_output_by_id (manager,
-                                                   xrandr_id,
-                                                   &error);
-        if (output == NULL) {
-                g_warning ("no %s device found: %s",
-                           cd_device_get_id (device),
-                           error->message);
-                g_error_free (error);
-                goto out;
-        }
-
-        /* 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_clear_error (&error);
-
-        } else {
-                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);
-
-                /* check if auto-profile has up-to-date metadata */
-                file = g_file_new_for_path (autogen_path);
-                if (gcm_session_check_profile_device_md (file)) {
-                        g_debug ("auto-profile edid %s exists with md", 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,
-                                                                     device,
-                                                                     edid,
-                                                                     file,
-                                                                     &error);
-                        if (!ret) {
-                                g_warning ("failed to create profile from EDID data: %s",
-                                             error->message);
-                                g_clear_error (&error);
-                        }
-                }
-        }
-
-        /* get the default profile for the device */
-        profile = cd_device_get_default_profile (device);
-        if (profile == NULL) {
-                g_debug ("%s has no default profile to set",
-                         cd_device_get_id (device));
-
-                /* the default output? */
-                if (gnome_rr_output_get_is_primary (output)) {
-                        gdk_property_delete (priv->gdk_window,
-                                             gdk_atom_intern_static_string ("_ICC_PROFILE"));
-                        gdk_property_delete (priv->gdk_window,
-                                             gdk_atom_intern_static_string ("_ICC_PROFILE_IN_X_VERSION"));
-                }
-
-                /* reset, as we want linear profiles for profiling */
-                ret = gcm_session_device_reset_gamma (output,
-                                                      &error);
-                if (!ret) {
-                        g_warning ("failed to reset %s gamma tables: %s",
-                                   cd_device_get_id (device),
-                                   error->message);
-                        g_error_free (error);
-                        goto out;
-                }
-                goto out;
-        }
-
-        /* get properties */
-        helper = g_new0 (GcmSessionAsyncHelper, 1);
-        helper->output_id = gnome_rr_output_get_id (output);
-        helper->manager = g_object_ref (manager);
-        helper->device = g_object_ref (device);
-        cd_profile_connect (profile,
-                            NULL,
-                            gcm_session_device_assign_profile_connect_cb,
-                            helper);
-out:
-        g_free (autogen_filename);
-        g_free (autogen_path);
-        if (file != NULL)
-                g_object_unref (file);
-        if (edid != NULL)
-                g_object_unref (edid);
-        if (profile != NULL)
-                g_object_unref (profile);
-}
-
-static void
-gcm_session_device_assign (GsdColorManager *manager, CdDevice *device)
-{
-        const gchar *key;
-        gpointer found;
-
-        /* are we already assigning this device */
-        key = cd_device_get_object_path (device);
-        found = g_hash_table_lookup (manager->priv->device_assign_hash, key);
-        if (found != NULL) {
-                g_debug ("assign for %s already in progress", key);
-                return;
-        }
-        g_hash_table_insert (manager->priv->device_assign_hash,
-                             g_strdup (key),
-                             GINT_TO_POINTER (TRUE));
-        cd_device_connect (device,
-                           NULL,
-                           gcm_session_device_assign_connect_cb,
-                           manager);
-}
-
-static void
-gcm_session_device_added_assign_cb (CdClient *client,
-                                    CdDevice *device,
-                                    GsdColorManager *manager)
-{
-        gcm_session_device_assign (manager, device);
-}
-
-static void
-gcm_session_device_changed_assign_cb (CdClient *client,
-                                      CdDevice *device,
-                                      GsdColorManager *manager)
-{
-        g_debug ("%s changed", cd_device_get_object_path (device));
-        gcm_session_device_assign (manager, device);
-}
-
-static void
-gcm_session_create_device_cb (GObject *object,
-                              GAsyncResult *res,
-                              gpointer user_data)
-{
-        CdDevice *device;
-        GError *error = NULL;
-
-        device = cd_client_create_device_finish (CD_CLIENT (object),
-                                                 res,
-                                                 &error);
-        if (device == NULL) {
-                if (error->domain != CD_CLIENT_ERROR ||
-                    error->code != CD_CLIENT_ERROR_ALREADY_EXISTS) {
-                        g_warning ("failed to create device: %s",
-                                   error->message);
-                }
-                g_error_free (error);
-                return;
-        }
-        g_object_unref (device);
-}
-
-static void
-gcm_session_add_x11_output (GsdColorManager *manager, GnomeRROutput *output)
-{
-        const gchar *edid_checksum = NULL;
-        const gchar *model = NULL;
-        const gchar *serial = NULL;
-        const gchar *vendor = NULL;
-        gboolean ret;
-        gchar *device_id = NULL;
-        GcmEdid *edid;
-        GError *error = NULL;
-        GHashTable *device_props = NULL;
-        GsdColorManagerPrivate *priv = manager->priv;
-
-        /* 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_clear_error (&error);
-        }
-
-        /* prefer DMI data for the internal output */
-        ret = gnome_rr_output_is_builtin_display (output);
-        if (ret) {
-                model = cd_client_get_system_model (priv->client);
-                vendor = cd_client_get_system_vendor (priv->client);
-        }
-
-        /* use EDID data if we have it */
-        if (edid != NULL) {
-                edid_checksum = gcm_edid_get_checksum (edid);
-                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";
-
-        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,
-                                              NULL, NULL);
-        g_hash_table_insert (device_props,
-                             (gpointer) CD_DEVICE_PROPERTY_KIND,
-                             (gpointer) cd_device_kind_to_string (CD_DEVICE_KIND_DISPLAY));
-        g_hash_table_insert (device_props,
-                             (gpointer) CD_DEVICE_PROPERTY_MODE,
-                             (gpointer) cd_device_mode_to_string (CD_DEVICE_MODE_PHYSICAL));
-        g_hash_table_insert (device_props,
-                             (gpointer) CD_DEVICE_PROPERTY_COLORSPACE,
-                             (gpointer) cd_colorspace_to_string (CD_COLORSPACE_RGB));
-        g_hash_table_insert (device_props,
-                             (gpointer) CD_DEVICE_PROPERTY_VENDOR,
-                             (gpointer) vendor);
-        g_hash_table_insert (device_props,
-                             (gpointer) CD_DEVICE_PROPERTY_MODEL,
-                             (gpointer) model);
-        g_hash_table_insert (device_props,
-                             (gpointer) CD_DEVICE_PROPERTY_SERIAL,
-                             (gpointer) serial);
-        g_hash_table_insert (device_props,
-                             (gpointer) CD_DEVICE_METADATA_XRANDR_NAME,
-                             (gpointer) gnome_rr_output_get_name (output));
-        g_hash_table_insert (device_props,
-                             (gpointer) CD_DEVICE_METADATA_OUTPUT_PRIORITY,
-                             gnome_rr_output_get_is_primary (output) ?
-                             (gpointer) CD_DEVICE_METADATA_OUTPUT_PRIORITY_PRIMARY :
-                             (gpointer) CD_DEVICE_METADATA_OUTPUT_PRIORITY_SECONDARY);
-        if (edid_checksum != NULL) {
-                g_hash_table_insert (device_props,
-                                     (gpointer) CD_DEVICE_METADATA_OUTPUT_EDID_MD5,
-                                     (gpointer) edid_checksum);
-        }
-        /* set this so we can call the device a 'Laptop Screen' in the
-         * control center main panel */
-        if (gnome_rr_output_is_builtin_display (output)) {
-                g_hash_table_insert (device_props,
-                                     (gpointer) CD_DEVICE_PROPERTY_EMBEDDED,
-                                     NULL);
-        }
-        cd_client_create_device (priv->client,
-                                 device_id,
-                                 CD_OBJECT_SCOPE_TEMP,
-                                 device_props,
-                                 NULL,
-                                 gcm_session_create_device_cb,
-                                 manager);
-        g_free (device_id);
-        if (device_props != NULL)
-                g_hash_table_unref (device_props);
-        if (edid != NULL)
-                g_object_unref (edid);
-}
-
-
-static void
-gnome_rr_screen_output_added_cb (GnomeRRScreen *screen,
-                                GnomeRROutput *output,
-                                GsdColorManager *manager)
-{
-        gcm_session_add_x11_output (manager, output);
-}
-
-static void
-gcm_session_screen_removed_delete_device_cb (GObject *object, GAsyncResult *res, gpointer user_data)
-{
-        gboolean ret;
-        GError *error = NULL;
-
-        /* deleted device */
-        ret = cd_client_delete_device_finish (CD_CLIENT (object),
-                                              res,
-                                              &error);
-        if (!ret) {
-                g_warning ("failed to delete device: %s",
-                           error->message);
-                g_error_free (error);
-        }
-}
-
-static void
-gcm_session_screen_removed_find_device_cb (GObject *object, GAsyncResult *res, gpointer user_data)
-{
-        GError *error = NULL;
-        CdDevice *device;
-        GsdColorManager *manager = GSD_COLOR_MANAGER (user_data);
-
-        device = cd_client_find_device_finish (manager->priv->client,
-                                               res,
-                                               &error);
-        if (device == NULL) {
-                g_warning ("failed to find device: %s",
-                           error->message);
-                g_error_free (error);
-                return;
-        }
-        g_debug ("output %s found, and will be removed",
-                 cd_device_get_object_path (device));
-        cd_client_delete_device (manager->priv->client,
-                                 device,
-                                 NULL,
-                                 gcm_session_screen_removed_delete_device_cb,
-                                 manager);
-        g_object_unref (device);
-}
-
-static void
-gnome_rr_screen_output_removed_cb (GnomeRRScreen *screen,
-                                   GnomeRROutput *output,
-                                   GsdColorManager *manager)
-{
-        g_debug ("output %s removed",
-                 gnome_rr_output_get_name (output));
-        g_hash_table_remove (manager->priv->edid_cache,
-                             gnome_rr_output_get_name (output));
-        cd_client_find_device_by_property (manager->priv->client,
-                                           CD_DEVICE_METADATA_XRANDR_NAME,
-                                           gnome_rr_output_get_name (output),
-                                           NULL,
-                                           gcm_session_screen_removed_find_device_cb,
-                                           manager);
-}
-
-static void
-gcm_session_get_devices_cb (GObject *object, GAsyncResult *res, gpointer user_data)
-{
-        CdDevice *device;
-        GError *error = NULL;
-        GPtrArray *array;
-        guint i;
-        GsdColorManager *manager = GSD_COLOR_MANAGER (user_data);
-
-        array = cd_client_get_devices_finish (CD_CLIENT (object), res, &error);
-        if (array == NULL) {
-                g_warning ("failed to get devices: %s",
-                           error->message);
-                g_error_free (error);
-                goto out;
-        }
-        for (i = 0; i < array->len; i++) {
-                device = g_ptr_array_index (array, i);
-                gcm_session_device_assign (manager, device);
-        }
-out:
-        if (array != NULL)
-                g_ptr_array_unref (array);
-}
-
-static void
-gcm_session_profile_gamma_find_device_cb (GObject *object,
-                                          GAsyncResult *res,
-                                          gpointer user_data)
-{
-        CdClient *client = CD_CLIENT (object);
-        CdDevice *device = NULL;
-        GError *error = NULL;
-        GsdColorManager *manager = GSD_COLOR_MANAGER (user_data);
-
-        device = cd_client_find_device_by_property_finish (client,
-                                                           res,
-                                                           &error);
-        if (device == NULL) {
-                g_warning ("could not find device: %s",
-                           error->message);
-                g_error_free (error);
-                goto out;
-        }
-
-        /* get properties */
-        cd_device_connect (device,
-                           NULL,
-                           gcm_session_device_assign_connect_cb,
-                           manager);
-out:
-        if (device != NULL)
-                g_object_unref (device);
-}
-
-/* We have to reset the gamma tables each time as if the primary output
- * has changed then different crtcs are going to be used.
- * See https://bugzilla.gnome.org/show_bug.cgi?id=660164 for an example */
-static void
-gnome_rr_screen_output_changed_cb (GnomeRRScreen *screen,
-                                   GsdColorManager *manager)
-{
-        GnomeRROutput **outputs;
-        GsdColorManagerPrivate *priv = manager->priv;
-        guint i;
-
-        /* get X11 outputs */
-        outputs = gnome_rr_screen_list_outputs (priv->x11_screen);
-        if (outputs == NULL) {
-                g_warning ("failed to get outputs");
-                return;
-        }
-        for (i = 0; outputs[i] != NULL; i++) {
-                if (!gnome_rr_output_is_connected (outputs[i]))
-                        continue;
-
-                /* get CdDevice for this output */
-                cd_client_find_device_by_property (manager->priv->client,
-                                                   CD_DEVICE_METADATA_XRANDR_NAME,
-                                                   gnome_rr_output_get_name (outputs[i]),
-                                                   NULL,
-                                                   gcm_session_profile_gamma_find_device_cb,
-                                                   manager);
-        }
-
-}
-
-static void
-gcm_session_client_connect_cb (GObject *source_object,
-                               GAsyncResult *res,
-                               gpointer user_data)
-{
-        gboolean ret;
-        GError *error = NULL;
-        GnomeRROutput **outputs;
-        guint i;
-        GsdColorManager *manager = GSD_COLOR_MANAGER (user_data);
-        GsdColorManagerPrivate *priv = manager->priv;
-
-        /* connected */
-        g_debug ("connected to colord");
-        ret = cd_client_connect_finish (manager->priv->client, res, &error);
-        if (!ret) {
-                g_warning ("failed to connect to colord: %s", error->message);
-                g_error_free (error);
-                return;
-        }
-
-        /* is there an available colord instance? */
-        ret = cd_client_get_has_server (manager->priv->client);
-        if (!ret) {
-                g_warning ("There is no colord server available");
-                goto out;
-        }
-
-        /* add screens */
-        gnome_rr_screen_refresh (priv->x11_screen, &error);
-        if (error != NULL) {
-                g_warning ("failed to refresh: %s", error->message);
-                g_error_free (error);
-                goto out;
-        }
-
-        /* get X11 outputs */
-        outputs = gnome_rr_screen_list_outputs (priv->x11_screen);
-        if (outputs == NULL) {
-                g_warning ("failed to get outputs");
-                goto out;
-        }
-        for (i = 0; outputs[i] != NULL; i++) {
-                if (gnome_rr_output_is_connected (outputs[i]))
-                        gcm_session_add_x11_output (manager, outputs[i]);
-        }
-
-        /* only connect when colord is awake */
-        g_signal_connect (priv->x11_screen, "output-connected",
-                          G_CALLBACK (gnome_rr_screen_output_added_cb),
-                          manager);
-        g_signal_connect (priv->x11_screen, "output-disconnected",
-                          G_CALLBACK (gnome_rr_screen_output_removed_cb),
-                          manager);
-        g_signal_connect (priv->x11_screen, "changed",
-                          G_CALLBACK (gnome_rr_screen_output_changed_cb),
-                          manager);
-
-        g_signal_connect (priv->client, "device-added",
-                          G_CALLBACK (gcm_session_device_added_assign_cb),
-                          manager);
-        g_signal_connect (priv->client, "device-changed",
-                          G_CALLBACK (gcm_session_device_changed_assign_cb),
-                          manager);
-
-        /* set for each device that already exist */
-        cd_client_get_devices (priv->client, NULL,
-                               gcm_session_get_devices_cb,
-                               manager);
-out:
-        return;
-}
-
 gboolean
 gsd_color_manager_start (GsdColorManager *manager,
                          GError          **error)
 {
         GsdColorManagerPrivate *priv = manager->priv;
-        gboolean ret = FALSE;
+        gboolean ret;
 
         g_debug ("Starting color manager");
         gnome_settings_profile_start (NULL);
 
-        /* coldplug the list of screens */
-        priv->x11_screen = gnome_rr_screen_new (gdk_screen_get_default (), error);
-        if (priv->x11_screen == NULL)
-                goto out;
+#ifdef GDK_WINDOWING_X11
+        /* start the X11 device probing */
+        if (GDK_IS_X11_DISPLAY (gdk_display_get_default ())) {
+                ret = gsd_color_x11_start (priv->x11, error);
+                if (!ret)
+                        goto out;
+        }
+#endif
 
         /* start the profiles collection */
         ret = gsd_color_profiles_start (priv->profiles, error);
         if (!ret)
                 goto out;
-
-        cd_client_connect (priv->client,
-                           NULL,
-                           gcm_session_client_connect_cb,
-                           manager);
-
-        /* success */
-        ret = TRUE;
 out:
         gnome_settings_profile_end (NULL);
         return ret;
@@ -1338,62 +97,6 @@ void
 gsd_color_manager_stop (GsdColorManager *manager)
 {
         g_debug ("Stopping color manager");
-
-        g_clear_object (&manager->priv->client);
-        g_clear_object (&manager->priv->session);
-        g_clear_pointer (&manager->priv->edid_cache, g_hash_table_destroy);
-        g_clear_pointer (&manager->priv->device_assign_hash, g_hash_table_destroy);
-        g_clear_object (&manager->priv->x11_screen);
-}
-
-static gboolean
-has_changed (char       **strv,
-            const char  *str)
-{
-        guint i;
-        for (i = 0; strv[i] != NULL; i++) {
-                if (g_str_equal (str, strv[i]))
-                        return TRUE;
-        }
-        return FALSE;
-}
-
-static void
-gcm_session_active_changed_cb (GDBusProxy      *session,
-                               GVariant        *changed,
-                               char           **invalidated,
-                               GsdColorManager *manager)
-{
-        GsdColorManagerPrivate *priv = manager->priv;
-        GVariant *active_v = NULL;
-        gboolean is_active;
-
-        if (has_changed (invalidated, "SessionIsActive"))
-                return;
-
-        /* not yet connected to the daemon */
-        if (!cd_client_get_connected (priv->client))
-                return;
-
-        active_v = g_dbus_proxy_get_cached_property (session, "SessionIsActive");
-        g_return_if_fail (active_v != NULL);
-        is_active = g_variant_get_boolean (active_v);
-        g_variant_unref (active_v);
-
-        /* When doing the fast-user-switch into a new account, load the
-         * new users chosen profiles.
-         *
-         * If this is the first time the GnomeSettingsSession has been
-         * loaded, then we'll get a change from unknown to active
-         * and we want to avoid reprobing the devices for that.
-         */
-        if (is_active && !priv->session_is_active) {
-                g_debug ("Done switch to new account, reload devices");
-                cd_client_get_devices (manager->priv->client, NULL,
-                                       gcm_session_get_devices_cb,
-                                       manager);
-        }
-        priv->session_is_active = is_active;
 }
 
 static void
@@ -1412,31 +115,10 @@ gsd_color_manager_init (GsdColorManager *manager)
         GsdColorManagerPrivate *priv;
         priv = manager->priv = GSD_COLOR_MANAGER_GET_PRIVATE (manager);
 
-        /* track the active session */
-        priv->session = gnome_settings_session_get_session_proxy ();
-        g_signal_connect (priv->session, "g-properties-changed",
-                          G_CALLBACK (gcm_session_active_changed_cb), manager);
-
-        /* set the _ICC_PROFILE atoms on the root screen */
-        priv->gdk_window = gdk_screen_get_root_window (gdk_screen_get_default ());
-
-        /* parsing the EDID is expensive */
-        priv->edid_cache = g_hash_table_new_full (g_str_hash,
-                                                  g_str_equal,
-                                                  g_free,
-                                                  g_object_unref);
-
-        /* we don't want to assign devices multiple times at startup */
-        priv->device_assign_hash = g_hash_table_new_full (g_str_hash,
-                                                          g_str_equal,
-                                                          g_free,
-                                                          NULL);
-
-        priv->client = cd_client_new ();
-
         /* setup calibration features */
         priv->calibrate = gsd_color_calibrate_new ();
         priv->profiles = gsd_color_profiles_new ();
+        priv->x11 = gsd_color_x11_new ();
 }
 
 static void
@@ -1449,13 +131,9 @@ gsd_color_manager_finalize (GObject *object)
 
         manager = GSD_COLOR_MANAGER (object);
 
-        g_clear_object (&manager->priv->client);
         g_clear_object (&manager->priv->calibrate);
         g_clear_object (&manager->priv->profiles);
-        g_clear_object (&manager->priv->session);
-        g_clear_pointer (&manager->priv->edid_cache, g_hash_table_destroy);
-        g_clear_pointer (&manager->priv->device_assign_hash, g_hash_table_destroy);
-        g_clear_object (&manager->priv->x11_screen);
+        g_clear_object (&manager->priv->x11);
 
         G_OBJECT_CLASS (gsd_color_manager_parent_class)->finalize (object);
 }
diff --git a/plugins/color/gsd-color-x11.c b/plugins/color/gsd-color-x11.c
new file mode 100644
index 0000000..6e5fd79
--- /dev/null
+++ b/plugins/color/gsd-color-x11.c
@@ -0,0 +1,1434 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 William Jon McCann <mccann jhu edu>
+ * Copyright (C) 2011-2013 Richard Hughes <richard hughsie com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+#include <colord.h>
+#include <gdk/gdk.h>
+#include <stdlib.h>
+#include <lcms2.h>
+#include <canberra-gtk.h>
+
+#define GNOME_DESKTOP_USE_UNSTABLE_API
+#include <libgnome-desktop/gnome-rr.h>
+
+#include "gnome-settings-session.h"
+#include "gnome-settings-plugin.h"
+
+#include "gsd-color-manager.h"
+#include "gsd-color-x11.h"
+#include "gcm-edid.h"
+
+#define GSD_COLOR_X11_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_COLOR_X11, 
GsdColorX11Private))
+
+struct GsdColorX11Private
+{
+        GDBusProxy      *session;
+        CdClient        *client;
+        GnomeRRScreen   *x11_screen;
+        GHashTable      *edid_cache;
+        GdkWindow       *gdk_window;
+        gboolean         session_is_active;
+        GHashTable      *device_assign_hash;
+};
+
+static void     gsd_color_x11_class_init  (GsdColorX11Class *klass);
+static void     gsd_color_x11_init        (GsdColorX11      *color_x11);
+static void     gsd_color_x11_finalize    (GObject             *object);
+
+G_DEFINE_TYPE (GsdColorX11, gsd_color_x11, G_TYPE_OBJECT)
+
+/* see http://www.oyranos.org/wiki/index.php?title=ICC_Profiles_in_X_Specification_0.3 */
+#define GCM_ICC_PROFILE_IN_X_VERSION_MAJOR      0
+#define GCM_ICC_PROFILE_IN_X_VERSION_MINOR      3
+
+typedef struct {
+        guint32          red;
+        guint32          green;
+        guint32          blue;
+} GnomeRROutputClutItem;
+
+GQuark
+gsd_color_x11_error_quark (void)
+{
+        static GQuark quark = 0;
+        if (!quark)
+                quark = g_quark_from_static_string ("gsd_color_x11_error");
+        return quark;
+}
+
+static GcmEdid *
+gcm_session_get_output_edid (GsdColorX11 *x11, GnomeRROutput *output, GError **error)
+{
+        const guint8 *data;
+        gsize size;
+        GcmEdid *edid = NULL;
+        gboolean ret;
+
+        /* can we find it in the cache */
+        edid = g_hash_table_lookup (x11->priv->edid_cache,
+                                    gnome_rr_output_get_name (output));
+        if (edid != NULL) {
+                g_object_ref (edid);
+                goto out;
+        }
+
+        /* parse edid */
+        data = gnome_rr_output_get_edid_data (output, &size);
+        if (data == NULL || size == 0) {
+                g_set_error_literal (error,
+                                     GNOME_RR_ERROR,
+                                     GNOME_RR_ERROR_UNKNOWN,
+                                     "unable to get EDID for output");
+                goto out;
+        }
+        edid = gcm_edid_new ();
+        ret = gcm_edid_parse (edid, data, size, error);
+        if (!ret) {
+                g_object_unref (edid);
+                edid = NULL;
+                goto out;
+        }
+
+        /* add to cache */
+        g_hash_table_insert (x11->priv->edid_cache,
+                             g_strdup (gnome_rr_output_get_name (output)),
+                             g_object_ref (edid));
+out:
+        return edid;
+}
+
+static gboolean
+gcm_session_screen_set_icc_profile (GsdColorX11 *x11,
+                                    const gchar *filename,
+                                    GError **error)
+{
+        gboolean ret;
+        gchar *data = NULL;
+        gsize length;
+        guint version_data;
+        GsdColorX11Private *priv = x11->priv;
+
+        g_return_val_if_fail (filename != NULL, FALSE);
+
+        g_debug ("setting root window ICC profile atom from %s", filename);
+
+        /* get contents of file */
+        ret = g_file_get_contents (filename, &data, &length, error);
+        if (!ret)
+                goto out;
+
+        /* set profile property */
+        gdk_property_change (priv->gdk_window,
+                             gdk_atom_intern_static_string ("_ICC_PROFILE"),
+                             gdk_atom_intern_static_string ("CARDINAL"),
+                             8,
+                             GDK_PROP_MODE_REPLACE,
+                             (const guchar *) data, length);
+
+        /* set version property */
+        version_data = GCM_ICC_PROFILE_IN_X_VERSION_MAJOR * 100 +
+                        GCM_ICC_PROFILE_IN_X_VERSION_MINOR * 1;
+        gdk_property_change (priv->gdk_window,
+                             gdk_atom_intern_static_string ("_ICC_PROFILE_IN_X_VERSION"),
+                             gdk_atom_intern_static_string ("CARDINAL"),
+                             8,
+                             GDK_PROP_MODE_REPLACE,
+                             (const guchar *) &version_data, 1);
+out:
+        g_free (data);
+        return ret;
+}
+
+static gchar *
+gcm_session_get_output_id (GsdColorX11 *x11, GnomeRROutput *output)
+{
+        const gchar *name;
+        const gchar *serial;
+        const gchar *vendor;
+        GcmEdid *edid = NULL;
+        GString *device_id;
+        GError *error = NULL;
+
+        /* all output devices are prefixed with this */
+        device_id = g_string_new ("xrandr");
+
+        /* get the output EDID if possible */
+        edid = gcm_session_get_output_edid (x11, output, &error);
+        if (edid == NULL) {
+                g_debug ("no edid for %s [%s], falling back to connection name",
+                         gnome_rr_output_get_name (output),
+                         error->message);
+                g_error_free (error);
+                g_string_append_printf (device_id,
+                                        "-%s",
+                                        gnome_rr_output_get_name (output));
+                goto out;
+        }
+
+        /* 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);
+        if (name != NULL)
+                g_string_append_printf (device_id, "-%s", name);
+        if (serial != NULL)
+                g_string_append_printf (device_id, "-%s", serial);
+out:
+        if (edid != NULL)
+                g_object_unref (edid);
+        return g_string_free (device_id, FALSE);
+}
+
+typedef struct {
+        GsdColorX11         *x11;
+        CdProfile               *profile;
+        CdDevice                *device;
+        guint32                  output_id;
+} GcmSessionAsyncHelper;
+
+static void
+gcm_session_async_helper_free (GcmSessionAsyncHelper *helper)
+{
+        if (helper->x11 != NULL)
+                g_object_unref (helper->x11);
+        if (helper->profile != NULL)
+                g_object_unref (helper->profile);
+        if (helper->device != NULL)
+                g_object_unref (helper->device);
+        g_free (helper);
+}
+
+static gboolean
+gcm_utils_mkdir_for_filename (GFile *file, GError **error)
+{
+        gboolean ret = FALSE;
+        GFile *parent_dir = NULL;
+
+        /* get parent directory */
+        parent_dir = g_file_get_parent (file);
+        if (parent_dir == NULL) {
+                g_set_error_literal (error,
+                                     GSD_COLOR_MANAGER_ERROR,
+                                     GSD_COLOR_MANAGER_ERROR_FAILED,
+                                     "could not get parent dir");
+                goto out;
+        }
+
+        /* ensure desination does not already exist */
+        ret = g_file_query_exists (parent_dir, NULL);
+        if (ret)
+                goto out;
+        ret = g_file_make_directory_with_parents (parent_dir, NULL, error);
+        if (!ret)
+                goto out;
+out:
+        if (parent_dir != NULL)
+                g_object_unref (parent_dir);
+        return ret;
+}
+
+static gboolean
+gcm_apply_create_icc_profile_for_edid (GsdColorX11 *x11,
+                                       CdDevice *device,
+                                       GcmEdid *edid,
+                                       GFile *file,
+                                       GError **error)
+{
+        CdIcc *icc = NULL;
+        const gchar *data;
+        gboolean ret = FALSE;
+        GsdColorX11Private *priv = x11->priv;
+
+        /* ensure the per-user directory exists */
+        ret = gcm_utils_mkdir_for_filename (file, error);
+        if (!ret)
+                goto out;
+
+        /* create our generated profile */
+        icc = cd_icc_new ();
+        ret = cd_icc_create_from_edid (icc,
+                                       gcm_edid_get_gamma (edid),
+                                       gcm_edid_get_red (edid),
+                                       gcm_edid_get_green (edid),
+                                       gcm_edid_get_blue (edid),
+                                       gcm_edid_get_white (edid),
+                                       error);
+        if (!ret)
+                goto out;
+
+        /* set copyright */
+        cd_icc_set_copyright (icc, NULL,
+                              /* deliberately not translated */
+                              "This profile is free of known copyright restrictions.");
+
+        /* set model and title */
+        data = gcm_edid_get_monitor_name (edid);
+        if (data == NULL)
+                data = cd_client_get_system_model (priv->client);
+        if (data == NULL)
+                data = "Unknown monitor";
+        cd_icc_set_model (icc, NULL, data);
+        cd_icc_set_description (icc, NULL, data);
+
+        /* get manufacturer */
+        data = gcm_edid_get_vendor_name (edid);
+        if (data == NULL)
+                data = cd_client_get_system_vendor (priv->client);
+        if (data == NULL)
+                data = "Unknown vendor";
+        cd_icc_set_manufacturer (icc, NULL, data);
+
+        /* set the framework creator metadata */
+        cd_icc_add_metadata (icc,
+                             CD_PROFILE_METADATA_CMF_PRODUCT,
+                             PACKAGE_NAME);
+        cd_icc_add_metadata (icc,
+                             CD_PROFILE_METADATA_CMF_BINARY,
+                             PACKAGE_NAME);
+        cd_icc_add_metadata (icc,
+                             CD_PROFILE_METADATA_CMF_VERSION,
+                             PACKAGE_VERSION);
+        cd_icc_add_metadata (icc,
+                             CD_PROFILE_METADATA_MAPPING_DEVICE_ID,
+                             cd_device_get_id (device));
+
+        /* set 'ICC meta Tag for Monitor Profiles' data */
+        cd_icc_add_metadata (icc, CD_PROFILE_METADATA_EDID_MD5, gcm_edid_get_checksum (edid));
+        data = gcm_edid_get_monitor_name (edid);
+        if (data != NULL)
+                cd_icc_add_metadata (icc, CD_PROFILE_METADATA_EDID_MODEL, data);
+        data = gcm_edid_get_serial_number (edid);
+        if (data != NULL)
+                cd_icc_add_metadata (icc, CD_PROFILE_METADATA_EDID_SERIAL, data);
+        data = gcm_edid_get_pnp_id (edid);
+        if (data != NULL)
+                cd_icc_add_metadata (icc, CD_PROFILE_METADATA_EDID_MNFT, data);
+        data = gcm_edid_get_vendor_name (edid);
+        if (data != NULL)
+                cd_icc_add_metadata (icc, CD_PROFILE_METADATA_EDID_VENDOR, data);
+
+        /* save */
+        ret = cd_icc_save_file (icc, file, CD_ICC_SAVE_FLAGS_NONE, NULL, error);
+        if (!ret)
+                goto out;
+out:
+        if (icc != NULL)
+                g_object_unref (icc);
+        return ret;
+}
+
+static GPtrArray *
+gcm_session_generate_vcgt (CdProfile *profile, guint size)
+{
+        GnomeRROutputClutItem *tmp;
+        GPtrArray *array = NULL;
+        const cmsToneCurve **vcgt;
+        cmsFloat32Number in;
+        guint i;
+        cmsHPROFILE lcms_profile;
+        CdIcc *icc = NULL;
+
+        /* invalid size */
+        if (size == 0)
+                goto out;
+
+        /* open file */
+        icc = cd_profile_load_icc (profile, CD_ICC_LOAD_FLAGS_NONE, NULL, NULL);
+        if (icc == NULL)
+                goto out;
+
+        /* get tone curves from profile */
+        lcms_profile = cd_icc_get_handle (icc);
+        vcgt = cmsReadTag (lcms_profile, cmsSigVcgtTag);
+        if (vcgt == NULL || vcgt[0] == NULL) {
+                g_debug ("profile does not have any VCGT data");
+                goto out;
+        }
+
+        /* create array */
+        array = g_ptr_array_new_with_free_func (g_free);
+        for (i = 0; i < size; i++) {
+                in = (gdouble) i / (gdouble) (size - 1);
+                tmp = g_new0 (GnomeRROutputClutItem, 1);
+                tmp->red = cmsEvalToneCurveFloat(vcgt[0], in) * (gdouble) 0xffff;
+                tmp->green = cmsEvalToneCurveFloat(vcgt[1], in) * (gdouble) 0xffff;
+                tmp->blue = cmsEvalToneCurveFloat(vcgt[2], in) * (gdouble) 0xffff;
+                g_ptr_array_add (array, tmp);
+        }
+out:
+        if (icc != NULL)
+                g_object_unref (icc);
+        return array;
+}
+
+static guint
+gnome_rr_output_get_gamma_size (GnomeRROutput *output)
+{
+        GnomeRRCrtc *crtc;
+        gint len = 0;
+
+        crtc = gnome_rr_output_get_crtc (output);
+        if (crtc == NULL)
+                return 0;
+        gnome_rr_crtc_get_gamma (crtc,
+                                 &len,
+                                 NULL, NULL, NULL);
+        return (guint) len;
+}
+
+static gboolean
+gcm_session_output_set_gamma (GnomeRROutput *output,
+                              GPtrArray *array,
+                              GError **error)
+{
+        gboolean ret = TRUE;
+        guint16 *red = NULL;
+        guint16 *green = NULL;
+        guint16 *blue = NULL;
+        guint i;
+        GnomeRROutputClutItem *data;
+        GnomeRRCrtc *crtc;
+
+        /* no length? */
+        if (array->len == 0) {
+                ret = FALSE;
+                g_set_error_literal (error,
+                                     GSD_COLOR_MANAGER_ERROR,
+                                     GSD_COLOR_MANAGER_ERROR_FAILED,
+                                     "no data in the CLUT array");
+                goto out;
+        }
+
+        /* convert to a type X understands */
+        red = g_new (guint16, array->len);
+        green = g_new (guint16, array->len);
+        blue = g_new (guint16, array->len);
+        for (i = 0; i < array->len; i++) {
+                data = g_ptr_array_index (array, i);
+                red[i] = data->red;
+                green[i] = data->green;
+                blue[i] = data->blue;
+        }
+
+        /* send to LUT */
+        crtc = gnome_rr_output_get_crtc (output);
+        if (crtc == NULL) {
+                ret = FALSE;
+                g_set_error (error,
+                             GSD_COLOR_MANAGER_ERROR,
+                             GSD_COLOR_MANAGER_ERROR_FAILED,
+                             "failed to get ctrc for %s",
+                             gnome_rr_output_get_name (output));
+                goto out;
+        }
+        gnome_rr_crtc_set_gamma (crtc, array->len,
+                                 red, green, blue);
+out:
+        g_free (red);
+        g_free (green);
+        g_free (blue);
+        return ret;
+}
+
+static gboolean
+gcm_session_device_set_gamma (GnomeRROutput *output,
+                              CdProfile *profile,
+                              GError **error)
+{
+        gboolean ret = FALSE;
+        guint size;
+        GPtrArray *clut = NULL;
+
+        /* create a lookup table */
+        size = gnome_rr_output_get_gamma_size (output);
+        if (size == 0) {
+                ret = TRUE;
+                goto out;
+        }
+        clut = gcm_session_generate_vcgt (profile, size);
+        if (clut == NULL) {
+                g_set_error_literal (error,
+                                     GSD_COLOR_MANAGER_ERROR,
+                                     GSD_COLOR_MANAGER_ERROR_FAILED,
+                                     "failed to generate vcgt");
+                goto out;
+        }
+
+        /* apply the vcgt to this output */
+        ret = gcm_session_output_set_gamma (output, clut, error);
+        if (!ret)
+                goto out;
+out:
+        if (clut != NULL)
+                g_ptr_array_unref (clut);
+        return ret;
+}
+
+static gboolean
+gcm_session_device_reset_gamma (GnomeRROutput *output,
+                                GError **error)
+{
+        gboolean ret;
+        guint i;
+        guint size;
+        guint32 value;
+        GPtrArray *clut;
+        GnomeRROutputClutItem *data;
+
+        /* create a linear ramp */
+        g_debug ("falling back to dummy ramp");
+        clut = g_ptr_array_new_with_free_func (g_free);
+        size = gnome_rr_output_get_gamma_size (output);
+        if (size == 0) {
+                ret = TRUE;
+                goto out;
+        }
+        for (i = 0; i < size; i++) {
+                value = (i * 0xffff) / (size - 1);
+                data = g_new0 (GnomeRROutputClutItem, 1);
+                data->red = value;
+                data->green = value;
+                data->blue = value;
+                g_ptr_array_add (clut, data);
+        }
+
+        /* apply the vcgt to this output */
+        ret = gcm_session_output_set_gamma (output, clut, error);
+        if (!ret)
+                goto out;
+out:
+        g_ptr_array_unref (clut);
+        return ret;
+}
+
+static GnomeRROutput *
+gcm_session_get_x11_output_by_id (GsdColorX11 *x11,
+                                  const gchar *device_id,
+                                  GError **error)
+{
+        gchar *output_id;
+        GnomeRROutput *output = NULL;
+        GnomeRROutput **outputs = NULL;
+        guint i;
+        GsdColorX11Private *priv = x11->priv;
+
+        /* search all X11 outputs for the device id */
+        outputs = gnome_rr_screen_list_outputs (priv->x11_screen);
+        if (outputs == NULL) {
+                g_set_error_literal (error,
+                                     GSD_COLOR_MANAGER_ERROR,
+                                     GSD_COLOR_MANAGER_ERROR_FAILED,
+                                     "Failed to get outputs");
+                goto out;
+        }
+        for (i = 0; outputs[i] != NULL && output == NULL; i++) {
+                if (!gnome_rr_output_is_connected (outputs[i]))
+                        continue;
+                output_id = gcm_session_get_output_id (x11, outputs[i]);
+                if (g_strcmp0 (output_id, device_id) == 0)
+                        output = outputs[i];
+                g_free (output_id);
+        }
+        if (output == NULL) {
+                g_set_error (error,
+                             GSD_COLOR_MANAGER_ERROR,
+                             GSD_COLOR_MANAGER_ERROR_FAILED,
+                             "Failed to find output %s",
+                             device_id);
+        }
+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 (GsdColorX11 *x11,
+                                           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 (x11->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_builtin_display (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_builtin_display (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;
+}
+
+/* TODO: remove when we can dep on a released version of colord */
+#ifndef CD_PROFILE_METADATA_SCREEN_BRIGHTNESS
+#define CD_PROFILE_METADATA_SCREEN_BRIGHTNESS          "SCREEN_brightness"
+#endif
+
+#define GSD_DBUS_NAME_POWER            GSD_DBUS_NAME ".Power"
+#define GSD_DBUS_INTERFACE_POWER_SCREEN        GSD_DBUS_BASE_INTERFACE ".Power.Screen"
+#define GSD_DBUS_PATH_POWER            GSD_DBUS_PATH "/Power"
+
+static void
+gcm_session_set_output_percentage (guint percentage)
+{
+        GDBusConnection *connection;
+
+        /* get a ref to the existing bus connection */
+        connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
+        if (connection == NULL)
+                return;
+        g_dbus_connection_call (connection,
+                                GSD_DBUS_NAME_POWER,
+                                GSD_DBUS_PATH_POWER,
+                                "org.freedesktop.DBus.Properties",
+                                "Set",
+                                g_variant_new_parsed ("('" GSD_DBUS_INTERFACE_POWER_SCREEN "',"
+                                                      "'Brightness', %v)",
+                                                      g_variant_new_int32 (percentage)),
+                                NULL,
+                                G_DBUS_CALL_FLAGS_NONE,
+                                -1, NULL, NULL, NULL);
+        g_object_unref (connection);
+}
+
+static void
+gcm_session_device_assign_profile_connect_cb (GObject *object,
+                                              GAsyncResult *res,
+                                              gpointer user_data)
+{
+        CdProfile *profile = CD_PROFILE (object);
+        const gchar *brightness_profile;
+        const gchar *filename;
+        gboolean ret;
+        GError *error = NULL;
+        GnomeRROutput *output;
+        guint brightness_percentage;
+        GcmSessionAsyncHelper *helper = (GcmSessionAsyncHelper *) user_data;
+        GsdColorX11 *x11 = GSD_COLOR_X11 (helper->x11);
+
+        /* get properties */
+        ret = cd_profile_connect_finish (profile, res, &error);
+        if (!ret) {
+                g_warning ("failed to connect to profile: %s",
+                           error->message);
+                g_error_free (error);
+                goto out;
+        }
+
+        /* get the filename */
+        filename = cd_profile_get_filename (profile);
+        g_assert (filename != NULL);
+
+        /* get the output (can't save in helper as GnomeRROutput isn't
+         * a GObject, just a pointer */
+        output = gnome_rr_screen_get_output_by_id (x11->priv->x11_screen,
+                                                   helper->output_id);
+        if (output == NULL)
+                goto out;
+
+        /* if output is a laptop screen and the profile has a
+         * calibration brightness then set this new brightness */
+        brightness_profile = cd_profile_get_metadata_item (profile,
+                                                           CD_PROFILE_METADATA_SCREEN_BRIGHTNESS);
+        if (gnome_rr_output_is_builtin_display (output) &&
+            brightness_profile != NULL) {
+                /* the percentage is stored in the profile metadata as
+                 * a string, not ideal, but it's all we have... */
+                brightness_percentage = atoi (brightness_profile);
+                gcm_session_set_output_percentage (brightness_percentage);
+        }
+
+        /* set the _ICC_PROFILE atom */
+        ret = gcm_session_use_output_profile_for_screen (x11, output);
+        if (ret) {
+                ret = gcm_session_screen_set_icc_profile (x11,
+                                                          filename,
+                                                          &error);
+                if (!ret) {
+                        g_warning ("failed to set screen _ICC_PROFILE: %s",
+                                   error->message);
+                        g_clear_error (&error);
+                }
+        }
+
+        /* create a vcgt for this icc file */
+        ret = cd_profile_get_has_vcgt (profile);
+        if (ret) {
+                ret = gcm_session_device_set_gamma (output,
+                                                    profile,
+                                                    &error);
+                if (!ret) {
+                        g_warning ("failed to set %s gamma tables: %s",
+                                   cd_device_get_id (helper->device),
+                                   error->message);
+                        g_error_free (error);
+                        goto out;
+                }
+        } else {
+                ret = gcm_session_device_reset_gamma (output,
+                                                      &error);
+                if (!ret) {
+                        g_warning ("failed to reset %s gamma tables: %s",
+                                   cd_device_get_id (helper->device),
+                                   error->message);
+                        g_error_free (error);
+                        goto out;
+                }
+        }
+out:
+        gcm_session_async_helper_free (helper);
+}
+
+/*
+ * Check to see if the on-disk profile has the MAPPING_device_id
+ * metadata, and if not, we should delete the profile and re-create it
+ * so that it gets mapped by the daemon.
+ */
+static gboolean
+gcm_session_check_profile_device_md (GFile *file)
+{
+        const gchar *key_we_need = CD_PROFILE_METADATA_MAPPING_DEVICE_ID;
+        CdIcc *icc;
+        gboolean ret;
+
+        icc = cd_icc_new ();
+        ret = cd_icc_load_file (icc, file, CD_ICC_LOAD_FLAGS_METADATA, NULL, NULL);
+        if (!ret)
+                goto out;
+        ret = cd_icc_get_metadata_item (icc, key_we_need) != NULL;
+        if (!ret) {
+                g_debug ("auto-edid profile is old, and contains no %s data",
+                         key_we_need);
+        }
+out:
+        g_object_unref (icc);
+        return ret;
+}
+
+static void
+gcm_session_device_assign_connect_cb (GObject *object,
+                                      GAsyncResult *res,
+                                      gpointer user_data)
+{
+        CdDeviceKind kind;
+        CdProfile *profile = NULL;
+        gboolean ret;
+        gchar *autogen_filename = NULL;
+        gchar *autogen_path = NULL;
+        GcmEdid *edid = NULL;
+        GnomeRROutput *output = NULL;
+        GError *error = NULL;
+        GFile *file = NULL;
+        const gchar *xrandr_id;
+        GcmSessionAsyncHelper *helper;
+        CdDevice *device = CD_DEVICE (object);
+        GsdColorX11 *x11 = GSD_COLOR_X11 (user_data);
+        GsdColorX11Private *priv = x11->priv;
+
+        /* remove from assign array */
+        g_hash_table_remove (x11->priv->device_assign_hash,
+                             cd_device_get_object_path (device));
+
+        /* get properties */
+        ret = cd_device_connect_finish (device, res, &error);
+        if (!ret) {
+                g_warning ("failed to connect to device: %s",
+                           error->message);
+                g_error_free (error);
+                goto out;
+        }
+
+        /* check we care */
+        kind = cd_device_get_kind (device);
+        if (kind != CD_DEVICE_KIND_DISPLAY)
+                goto out;
+
+        g_debug ("need to assign display device %s",
+                 cd_device_get_id (device));
+
+        /* get the GnomeRROutput for the device id */
+        xrandr_id = cd_device_get_id (device);
+        output = gcm_session_get_x11_output_by_id (x11,
+                                                   xrandr_id,
+                                                   &error);
+        if (output == NULL) {
+                g_warning ("no %s device found: %s",
+                           cd_device_get_id (device),
+                           error->message);
+                g_error_free (error);
+                goto out;
+        }
+
+        /* create profile from device edid if it exists */
+        edid = gcm_session_get_output_edid (x11, output, &error);
+        if (edid == NULL) {
+                g_warning ("unable to get EDID for %s: %s",
+                           cd_device_get_id (device),
+                           error->message);
+                g_clear_error (&error);
+
+        } else {
+                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);
+
+                /* check if auto-profile has up-to-date metadata */
+                file = g_file_new_for_path (autogen_path);
+                if (gcm_session_check_profile_device_md (file)) {
+                        g_debug ("auto-profile edid %s exists with md", autogen_path);
+                } else {
+                        g_debug ("auto-profile edid does not exist, creating as %s",
+                                 autogen_path);
+                        ret = gcm_apply_create_icc_profile_for_edid (x11,
+                                                                     device,
+                                                                     edid,
+                                                                     file,
+                                                                     &error);
+                        if (!ret) {
+                                g_warning ("failed to create profile from EDID data: %s",
+                                             error->message);
+                                g_clear_error (&error);
+                        }
+                }
+        }
+
+        /* get the default profile for the device */
+        profile = cd_device_get_default_profile (device);
+        if (profile == NULL) {
+                g_debug ("%s has no default profile to set",
+                         cd_device_get_id (device));
+
+                /* the default output? */
+                if (gnome_rr_output_get_is_primary (output)) {
+                        gdk_property_delete (priv->gdk_window,
+                                             gdk_atom_intern_static_string ("_ICC_PROFILE"));
+                        gdk_property_delete (priv->gdk_window,
+                                             gdk_atom_intern_static_string ("_ICC_PROFILE_IN_X_VERSION"));
+                }
+
+                /* reset, as we want linear profiles for profiling */
+                ret = gcm_session_device_reset_gamma (output,
+                                                      &error);
+                if (!ret) {
+                        g_warning ("failed to reset %s gamma tables: %s",
+                                   cd_device_get_id (device),
+                                   error->message);
+                        g_error_free (error);
+                        goto out;
+                }
+                goto out;
+        }
+
+        /* get properties */
+        helper = g_new0 (GcmSessionAsyncHelper, 1);
+        helper->output_id = gnome_rr_output_get_id (output);
+        helper->x11 = g_object_ref (x11);
+        helper->device = g_object_ref (device);
+        cd_profile_connect (profile,
+                            NULL,
+                            gcm_session_device_assign_profile_connect_cb,
+                            helper);
+out:
+        g_free (autogen_filename);
+        g_free (autogen_path);
+        if (file != NULL)
+                g_object_unref (file);
+        if (edid != NULL)
+                g_object_unref (edid);
+        if (profile != NULL)
+                g_object_unref (profile);
+}
+
+static void
+gcm_session_device_assign (GsdColorX11 *x11, CdDevice *device)
+{
+        const gchar *key;
+        gpointer found;
+
+        /* are we already assigning this device */
+        key = cd_device_get_object_path (device);
+        found = g_hash_table_lookup (x11->priv->device_assign_hash, key);
+        if (found != NULL) {
+                g_debug ("assign for %s already in progress", key);
+                return;
+        }
+        g_hash_table_insert (x11->priv->device_assign_hash,
+                             g_strdup (key),
+                             GINT_TO_POINTER (TRUE));
+        cd_device_connect (device,
+                           NULL,
+                           gcm_session_device_assign_connect_cb,
+                           x11);
+}
+
+static void
+gcm_session_device_added_assign_cb (CdClient *client,
+                                    CdDevice *device,
+                                    GsdColorX11 *x11)
+{
+        gcm_session_device_assign (x11, device);
+}
+
+static void
+gcm_session_device_changed_assign_cb (CdClient *client,
+                                      CdDevice *device,
+                                      GsdColorX11 *x11)
+{
+        g_debug ("%s changed", cd_device_get_object_path (device));
+        gcm_session_device_assign (x11, device);
+}
+
+static void
+gcm_session_create_device_cb (GObject *object,
+                              GAsyncResult *res,
+                              gpointer user_data)
+{
+        CdDevice *device;
+        GError *error = NULL;
+
+        device = cd_client_create_device_finish (CD_CLIENT (object),
+                                                 res,
+                                                 &error);
+        if (device == NULL) {
+                if (error->domain != CD_CLIENT_ERROR ||
+                    error->code != CD_CLIENT_ERROR_ALREADY_EXISTS) {
+                        g_warning ("failed to create device: %s",
+                                   error->message);
+                }
+                g_error_free (error);
+                return;
+        }
+        g_object_unref (device);
+}
+
+static void
+gcm_session_add_x11_output (GsdColorX11 *x11, GnomeRROutput *output)
+{
+        const gchar *edid_checksum = NULL;
+        const gchar *model = NULL;
+        const gchar *serial = NULL;
+        const gchar *vendor = NULL;
+        gboolean ret;
+        gchar *device_id = NULL;
+        GcmEdid *edid;
+        GError *error = NULL;
+        GHashTable *device_props = NULL;
+        GsdColorX11Private *priv = x11->priv;
+
+        /* try to get edid */
+        edid = gcm_session_get_output_edid (x11, output, &error);
+        if (edid == NULL) {
+                g_warning ("failed to get edid: %s",
+                           error->message);
+                g_clear_error (&error);
+        }
+
+        /* prefer DMI data for the internal output */
+        ret = gnome_rr_output_is_builtin_display (output);
+        if (ret) {
+                model = cd_client_get_system_model (priv->client);
+                vendor = cd_client_get_system_vendor (priv->client);
+        }
+
+        /* use EDID data if we have it */
+        if (edid != NULL) {
+                edid_checksum = gcm_edid_get_checksum (edid);
+                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";
+
+        device_id = gcm_session_get_output_id (x11, output);
+        g_debug ("output %s added", device_id);
+        device_props = g_hash_table_new_full (g_str_hash, g_str_equal,
+                                              NULL, NULL);
+        g_hash_table_insert (device_props,
+                             (gpointer) CD_DEVICE_PROPERTY_KIND,
+                             (gpointer) cd_device_kind_to_string (CD_DEVICE_KIND_DISPLAY));
+        g_hash_table_insert (device_props,
+                             (gpointer) CD_DEVICE_PROPERTY_MODE,
+                             (gpointer) cd_device_mode_to_string (CD_DEVICE_MODE_PHYSICAL));
+        g_hash_table_insert (device_props,
+                             (gpointer) CD_DEVICE_PROPERTY_COLORSPACE,
+                             (gpointer) cd_colorspace_to_string (CD_COLORSPACE_RGB));
+        g_hash_table_insert (device_props,
+                             (gpointer) CD_DEVICE_PROPERTY_VENDOR,
+                             (gpointer) vendor);
+        g_hash_table_insert (device_props,
+                             (gpointer) CD_DEVICE_PROPERTY_MODEL,
+                             (gpointer) model);
+        g_hash_table_insert (device_props,
+                             (gpointer) CD_DEVICE_PROPERTY_SERIAL,
+                             (gpointer) serial);
+        g_hash_table_insert (device_props,
+                             (gpointer) CD_DEVICE_METADATA_XRANDR_NAME,
+                             (gpointer) gnome_rr_output_get_name (output));
+        g_hash_table_insert (device_props,
+                             (gpointer) CD_DEVICE_METADATA_OUTPUT_PRIORITY,
+                             gnome_rr_output_get_is_primary (output) ?
+                             (gpointer) CD_DEVICE_METADATA_OUTPUT_PRIORITY_PRIMARY :
+                             (gpointer) CD_DEVICE_METADATA_OUTPUT_PRIORITY_SECONDARY);
+        if (edid_checksum != NULL) {
+                g_hash_table_insert (device_props,
+                                     (gpointer) CD_DEVICE_METADATA_OUTPUT_EDID_MD5,
+                                     (gpointer) edid_checksum);
+        }
+        /* set this so we can call the device a 'Laptop Screen' in the
+         * control center main panel */
+        if (gnome_rr_output_is_builtin_display (output)) {
+                g_hash_table_insert (device_props,
+                                     (gpointer) CD_DEVICE_PROPERTY_EMBEDDED,
+                                     NULL);
+        }
+        cd_client_create_device (priv->client,
+                                 device_id,
+                                 CD_OBJECT_SCOPE_TEMP,
+                                 device_props,
+                                 NULL,
+                                 gcm_session_create_device_cb,
+                                 x11);
+        g_free (device_id);
+        if (device_props != NULL)
+                g_hash_table_unref (device_props);
+        if (edid != NULL)
+                g_object_unref (edid);
+}
+
+
+static void
+gnome_rr_screen_output_added_cb (GnomeRRScreen *screen,
+                                GnomeRROutput *output,
+                                GsdColorX11 *x11)
+{
+        gcm_session_add_x11_output (x11, output);
+}
+
+static void
+gcm_session_screen_removed_delete_device_cb (GObject *object, GAsyncResult *res, gpointer user_data)
+{
+        gboolean ret;
+        GError *error = NULL;
+
+        /* deleted device */
+        ret = cd_client_delete_device_finish (CD_CLIENT (object),
+                                              res,
+                                              &error);
+        if (!ret) {
+                g_warning ("failed to delete device: %s",
+                           error->message);
+                g_error_free (error);
+        }
+}
+
+static void
+gcm_session_screen_removed_find_device_cb (GObject *object, GAsyncResult *res, gpointer user_data)
+{
+        GError *error = NULL;
+        CdDevice *device;
+        GsdColorX11 *x11 = GSD_COLOR_X11 (user_data);
+
+        device = cd_client_find_device_finish (x11->priv->client,
+                                               res,
+                                               &error);
+        if (device == NULL) {
+                g_warning ("failed to find device: %s",
+                           error->message);
+                g_error_free (error);
+                return;
+        }
+        g_debug ("output %s found, and will be removed",
+                 cd_device_get_object_path (device));
+        cd_client_delete_device (x11->priv->client,
+                                 device,
+                                 NULL,
+                                 gcm_session_screen_removed_delete_device_cb,
+                                 x11);
+        g_object_unref (device);
+}
+
+static void
+gnome_rr_screen_output_removed_cb (GnomeRRScreen *screen,
+                                   GnomeRROutput *output,
+                                   GsdColorX11 *x11)
+{
+        g_debug ("output %s removed",
+                 gnome_rr_output_get_name (output));
+        g_hash_table_remove (x11->priv->edid_cache,
+                             gnome_rr_output_get_name (output));
+        cd_client_find_device_by_property (x11->priv->client,
+                                           CD_DEVICE_METADATA_XRANDR_NAME,
+                                           gnome_rr_output_get_name (output),
+                                           NULL,
+                                           gcm_session_screen_removed_find_device_cb,
+                                           x11);
+}
+
+static void
+gcm_session_get_devices_cb (GObject *object, GAsyncResult *res, gpointer user_data)
+{
+        CdDevice *device;
+        GError *error = NULL;
+        GPtrArray *array;
+        guint i;
+        GsdColorX11 *x11 = GSD_COLOR_X11 (user_data);
+
+        array = cd_client_get_devices_finish (CD_CLIENT (object), res, &error);
+        if (array == NULL) {
+                g_warning ("failed to get devices: %s",
+                           error->message);
+                g_error_free (error);
+                goto out;
+        }
+        for (i = 0; i < array->len; i++) {
+                device = g_ptr_array_index (array, i);
+                gcm_session_device_assign (x11, device);
+        }
+out:
+        if (array != NULL)
+                g_ptr_array_unref (array);
+}
+
+static void
+gcm_session_profile_gamma_find_device_cb (GObject *object,
+                                          GAsyncResult *res,
+                                          gpointer user_data)
+{
+        CdClient *client = CD_CLIENT (object);
+        CdDevice *device = NULL;
+        GError *error = NULL;
+        GsdColorX11 *x11 = GSD_COLOR_X11 (user_data);
+
+        device = cd_client_find_device_by_property_finish (client,
+                                                           res,
+                                                           &error);
+        if (device == NULL) {
+                g_warning ("could not find device: %s",
+                           error->message);
+                g_error_free (error);
+                goto out;
+        }
+
+        /* get properties */
+        cd_device_connect (device,
+                           NULL,
+                           gcm_session_device_assign_connect_cb,
+                           x11);
+out:
+        if (device != NULL)
+                g_object_unref (device);
+}
+
+/* We have to reset the gamma tables each time as if the primary output
+ * has changed then different crtcs are going to be used.
+ * See https://bugzilla.gnome.org/show_bug.cgi?id=660164 for an example */
+static void
+gnome_rr_screen_output_changed_cb (GnomeRRScreen *screen,
+                                   GsdColorX11 *x11)
+{
+        GnomeRROutput **outputs;
+        GsdColorX11Private *priv = x11->priv;
+        guint i;
+
+        /* get X11 outputs */
+        outputs = gnome_rr_screen_list_outputs (priv->x11_screen);
+        if (outputs == NULL) {
+                g_warning ("failed to get outputs");
+                return;
+        }
+        for (i = 0; outputs[i] != NULL; i++) {
+                if (!gnome_rr_output_is_connected (outputs[i]))
+                        continue;
+
+                /* get CdDevice for this output */
+                cd_client_find_device_by_property (x11->priv->client,
+                                                   CD_DEVICE_METADATA_XRANDR_NAME,
+                                                   gnome_rr_output_get_name (outputs[i]),
+                                                   NULL,
+                                                   gcm_session_profile_gamma_find_device_cb,
+                                                   x11);
+        }
+
+}
+
+static gboolean
+has_changed (char       **strv,
+            const char  *str)
+{
+        guint i;
+        for (i = 0; strv[i] != NULL; i++) {
+                if (g_str_equal (str, strv[i]))
+                        return TRUE;
+        }
+        return FALSE;
+}
+
+static void
+gcm_session_active_changed_cb (GDBusProxy      *session,
+                               GVariant        *changed,
+                               char           **invalidated,
+                               GsdColorX11 *x11)
+{
+        GsdColorX11Private *priv = x11->priv;
+        GVariant *active_v = NULL;
+        gboolean is_active;
+
+        if (has_changed (invalidated, "SessionIsActive"))
+                return;
+
+        /* not yet connected to the daemon */
+        if (!cd_client_get_connected (priv->client))
+                return;
+
+        active_v = g_dbus_proxy_get_cached_property (session, "SessionIsActive");
+        g_return_if_fail (active_v != NULL);
+        is_active = g_variant_get_boolean (active_v);
+        g_variant_unref (active_v);
+
+        /* When doing the fast-user-switch into a new account, load the
+         * new users chosen profiles.
+         *
+         * If this is the first time the GnomeSettingsSession has been
+         * loaded, then we'll get a change from unknown to active
+         * and we want to avoid reprobing the devices for that.
+         */
+        if (is_active && !priv->session_is_active) {
+                g_debug ("Done switch to new account, reload devices");
+                cd_client_get_devices (x11->priv->client, NULL,
+                                       gcm_session_get_devices_cb,
+                                       x11);
+        }
+        priv->session_is_active = is_active;
+}
+
+static void
+gcm_session_client_connect_cb (GObject *source_object,
+                               GAsyncResult *res,
+                               gpointer user_data)
+{
+        gboolean ret;
+        GError *error = NULL;
+        GnomeRROutput **outputs;
+        guint i;
+        GsdColorX11 *x11 = GSD_COLOR_X11 (user_data);
+        GsdColorX11Private *priv = x11->priv;
+
+        /* connected */
+        ret = cd_client_connect_finish (x11->priv->client, res, &error);
+        if (!ret) {
+                g_warning ("failed to connect to colord: %s", error->message);
+                g_error_free (error);
+                return;
+        }
+
+        /* is there an available colord instance? */
+        ret = cd_client_get_has_server (x11->priv->client);
+        if (!ret) {
+                g_warning ("There is no colord server available");
+                goto out;
+        }
+
+        /* watch if sessions change */
+        g_signal_connect (priv->session, "g-properties-changed",
+                          G_CALLBACK (gcm_session_active_changed_cb), x11);
+
+        /* add screens */
+        gnome_rr_screen_refresh (priv->x11_screen, &error);
+        if (error != NULL) {
+                g_warning ("failed to refresh: %s", error->message);
+                g_error_free (error);
+                goto out;
+        }
+
+        /* get X11 outputs */
+        outputs = gnome_rr_screen_list_outputs (priv->x11_screen);
+        if (outputs == NULL) {
+                g_warning ("failed to get outputs");
+                goto out;
+        }
+        for (i = 0; outputs[i] != NULL; i++) {
+                if (gnome_rr_output_is_connected (outputs[i]))
+                        gcm_session_add_x11_output (x11, outputs[i]);
+        }
+
+        /* only connect when colord is awake */
+        g_signal_connect (priv->x11_screen, "output-connected",
+                          G_CALLBACK (gnome_rr_screen_output_added_cb),
+                          x11);
+        g_signal_connect (priv->x11_screen, "output-disconnected",
+                          G_CALLBACK (gnome_rr_screen_output_removed_cb),
+                          x11);
+        g_signal_connect (priv->x11_screen, "changed",
+                          G_CALLBACK (gnome_rr_screen_output_changed_cb),
+                          x11);
+
+        g_signal_connect (priv->client, "device-added",
+                          G_CALLBACK (gcm_session_device_added_assign_cb),
+                          x11);
+        g_signal_connect (priv->client, "device-changed",
+                          G_CALLBACK (gcm_session_device_changed_assign_cb),
+                          x11);
+
+        /* set for each device that already exist */
+        cd_client_get_devices (priv->client, NULL,
+                               gcm_session_get_devices_cb,
+                               x11);
+out:
+        return;
+}
+
+gboolean
+gsd_color_x11_start (GsdColorX11 *x11,
+                     GError     **error)
+{
+        GsdColorX11Private *priv = x11->priv;
+        gboolean ret = FALSE;
+
+        /* coldplug the list of screens */
+        priv->x11_screen = gnome_rr_screen_new (gdk_screen_get_default (), error);
+        if (priv->x11_screen == NULL)
+                goto out;
+
+        cd_client_connect (priv->client,
+                           NULL,
+                           gcm_session_client_connect_cb,
+                           x11);
+
+        /* success */
+        ret = TRUE;
+out:
+        return ret;
+}
+
+static void
+gsd_color_x11_class_init (GsdColorX11Class *klass)
+{
+        GObjectClass   *object_class = G_OBJECT_CLASS (klass);
+
+        object_class->finalize = gsd_color_x11_finalize;
+
+        g_type_class_add_private (klass, sizeof (GsdColorX11Private));
+}
+
+static void
+gsd_color_x11_init (GsdColorX11 *x11)
+{
+        GsdColorX11Private *priv;
+        priv = x11->priv = GSD_COLOR_X11_GET_PRIVATE (x11);
+
+        /* track the active session */
+        priv->session = gnome_settings_session_get_session_proxy ();
+
+        /* set the _ICC_PROFILE atoms on the root screen */
+        priv->gdk_window = gdk_screen_get_root_window (gdk_screen_get_default ());
+
+        /* parsing the EDID is expensive */
+        priv->edid_cache = g_hash_table_new_full (g_str_hash,
+                                                  g_str_equal,
+                                                  g_free,
+                                                  g_object_unref);
+
+        /* we don't want to assign devices multiple times at startup */
+        priv->device_assign_hash = g_hash_table_new_full (g_str_hash,
+                                                          g_str_equal,
+                                                          g_free,
+                                                          NULL);
+
+        priv->client = cd_client_new ();
+}
+
+static void
+gsd_color_x11_finalize (GObject *object)
+{
+        GsdColorX11 *x11;
+
+        g_return_if_fail (object != NULL);
+        g_return_if_fail (GSD_IS_COLOR_X11 (object));
+
+        x11 = GSD_COLOR_X11 (object);
+
+        g_clear_object (&x11->priv->client);
+        g_clear_object (&x11->priv->session);
+        g_clear_pointer (&x11->priv->edid_cache, g_hash_table_destroy);
+        g_clear_pointer (&x11->priv->device_assign_hash, g_hash_table_destroy);
+        g_clear_object (&x11->priv->x11_screen);
+
+        G_OBJECT_CLASS (gsd_color_x11_parent_class)->finalize (object);
+}
+
+GsdColorX11 *
+gsd_color_x11_new (void)
+{
+        GsdColorX11 *x11;
+        x11 = g_object_new (GSD_TYPE_COLOR_X11, NULL);
+        return GSD_COLOR_X11 (x11);
+}
diff --git a/plugins/color/gsd-color-x11.h b/plugins/color/gsd-color-x11.h
new file mode 100644
index 0000000..6366c6d
--- /dev/null
+++ b/plugins/color/gsd-color-x11.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 William Jon McCann <mccann jhu edu>
+ * Copyright (C) 2011-2013 Richard Hughes <richard hughsie com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef __GSD_COLOR_X11_H
+#define __GSD_COLOR_X11_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GSD_TYPE_COLOR_X11         (gsd_color_x11_get_type ())
+#define GSD_COLOR_X11(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_COLOR_X11, GsdColorX11))
+#define GSD_IS_COLOR_X11(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_COLOR_X11))
+
+typedef struct GsdColorX11Private GsdColorX11Private;
+
+typedef struct
+{
+        GObject                     parent;
+        GsdColorX11Private *priv;
+} GsdColorX11;
+
+typedef struct
+{
+        GObjectClass   parent_class;
+} GsdColorX11Class;
+
+GType                   gsd_color_x11_get_type          (void);
+GQuark                  gsd_color_x11_error_quark       (void);
+
+GsdColorX11 *           gsd_color_x11_new               (void);
+gboolean                gsd_color_x11_start             (GsdColorX11 *x11,
+                                                         GError     **error);
+
+G_END_DECLS
+
+#endif /* __GSD_COLOR_X11_H */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]