[gnome-color-manager/colord] Assign devices as they appear from colord



commit a4bcef2da78c7dc1058de950ad02d1cbf2163250
Author: Richard Hughes <richard hughsie com>
Date:   Sat Jan 29 17:50:36 2011 +0000

    Assign devices as they appear from colord

 src/gcm-device-xrandr.c |   70 ---------
 src/gcm-session.c       |  383 +++++++++++++++++++++++++++++++++--------------
 src/gcm-x11-output.c    |   42 ++++--
 src/gcm-x11-output.h    |    5 +-
 4 files changed, 304 insertions(+), 196 deletions(-)
---
diff --git a/src/gcm-device-xrandr.c b/src/gcm-device-xrandr.c
index afbfe3b..b65c489 100644
--- a/src/gcm-device-xrandr.c
+++ b/src/gcm-device-xrandr.c
@@ -290,76 +290,6 @@ out:
 }
 
 /**
- * cd_device_xrandr_generate_profile:
- **/
-static GcmProfile *
-cd_device_xrandr_generate_profile (CdDevice *device, GError **error)
-{
-	gboolean ret;
-	const gchar *data;
-	gchar *title = NULL;
-	GcmProfile *profile;
-	CdDeviceXrandr *device_xrandr = CD_DEVICE_XRANDR (device);
-	CdDeviceXrandrPrivate *priv = device_xrandr->priv;
-
-	/* create new profile */
-	profile = gcm_profile_new ();
-	gcm_profile_set_colorspace (profile, 0);
-	gcm_profile_set_copyright (profile, "No copyright");
-	gcm_profile_set_kind (profile, CD_PROFILE_KIND_DISPLAY_DEVICE);
-
-	/* get manufacturer */
-	data = gcm_edid_get_vendor_name (priv->edid);
-	if (data == NULL)
-		data = "Unknown vendor";
-	gcm_profile_set_manufacturer (profile, data);
-
-	/* get model */
-	data = gcm_edid_get_monitor_name (priv->edid);
-	if (data == NULL)
-		data = "Unknown monitor";
-	gcm_profile_set_model (profile, data);
-
-	/* TRANSLATORS: this is prepended to the device title to let the use know it was generated by us automatically */
-	title = g_strdup_printf ("%s, %s", _("Automatic"), cd_device_get_title (device));
-	gcm_profile_set_description (profile, title);
-
-	/* generate a profile from the chroma data */
-	ret = gcm_profile_create_from_chroma (profile,
-					      gcm_edid_get_gamma (priv->edid),
-					      gcm_edid_get_red (priv->edid),
-					      gcm_edid_get_green (priv->edid),
-					      gcm_edid_get_blue (priv->edid),
-					      gcm_edid_get_white (priv->edid),
-					      error);
-	if (!ret) {
-		g_object_unref (profile);
-		profile = NULL;
-		goto out;
-	}
-
-	/* set 'ICC meta Tag for Monitor Profiles' data */
-	gcm_profile_set_data (profile,
-			      "EDID_md5",
-			      gcm_edid_get_checksum (priv->edid));
-	gcm_profile_set_data (profile,
-			      "EDID_model",
-			      gcm_edid_get_monitor_name (priv->edid));
-	gcm_profile_set_data (profile,
-			      "EDID_serial",
-			      gcm_edid_get_serial_number (priv->edid));
-	gcm_profile_set_data (profile,
-			      "EDID_mnft",
-			      gcm_edid_get_pnp_id (priv->edid));
-	gcm_profile_set_data (profile,
-			      "EDID_manufacturer",
-			      gcm_edid_get_vendor_name (priv->edid));
-out:
-	g_free (title);
-	return profile;
-}
-
-/**
  * cd_device_xrandr_reset:
  *
  * Clears any VCGT table, so we're ready for profiling
diff --git a/src/gcm-session.c b/src/gcm-session.c
index 32b80f1..8414952 100644
--- a/src/gcm-session.c
+++ b/src/gcm-session.c
@@ -218,6 +218,261 @@ out:
 }
 
 /**
+ * gcm_apply_create_icc_profile_for_edid:
+ **/
+static gboolean
+gcm_apply_create_icc_profile_for_edid (GcmEdid *edid,
+				       const gchar *filename,
+				       GError **error)
+{
+	const gchar *data;
+	gboolean ret;
+	gchar *title = NULL;
+	GcmProfile *profile = NULL;
+
+	/* ensure the per-user directory exists */
+	ret = gcm_utils_mkdir_for_filename (filename, error);
+	if (!ret)
+		goto out;
+
+	/* create new profile */
+	profile = gcm_profile_new ();
+	gcm_profile_set_colorspace (profile, 0);
+	gcm_profile_set_copyright (profile, "No copyright");
+	gcm_profile_set_kind (profile, CD_PROFILE_KIND_DISPLAY_DEVICE);
+
+	/* get manufacturer */
+	data = gcm_edid_get_vendor_name (edid);
+	if (data == NULL)
+		data = "Unknown vendor";
+	gcm_profile_set_manufacturer (profile, data);
+
+	/* get model */
+	data = gcm_edid_get_monitor_name (edid);
+	if (data == NULL)
+		data = "Unknown monitor";
+	gcm_profile_set_model (profile, data);
+
+	/* TRANSLATORS: this is prepended to the device title to let the use know it was generated by us automatically */
+	title = g_strdup_printf ("%s, %s",
+				 _("Automatic"),
+				 gcm_edid_get_monitor_name (edid));
+	gcm_profile_set_description (profile, title);
+
+	/* generate a profile from the chroma data */
+	ret = gcm_profile_create_from_chroma (profile,
+					      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 'ICC meta Tag for Monitor Profiles' data */
+	gcm_profile_set_data (profile,
+			      "EDID_md5",
+			      gcm_edid_get_checksum (edid));
+	gcm_profile_set_data (profile,
+			      "EDID_model",
+			      gcm_edid_get_monitor_name (edid));
+	gcm_profile_set_data (profile,
+			      "EDID_serial",
+			      gcm_edid_get_serial_number (edid));
+	gcm_profile_set_data (profile,
+			      "EDID_mnft",
+			      gcm_edid_get_pnp_id (edid));
+	gcm_profile_set_data (profile,
+			      "EDID_manufacturer",
+			      gcm_edid_get_vendor_name (edid));
+
+	/* save this */
+	ret = gcm_profile_save (profile, filename, error);
+	if (!ret)
+		goto out;
+out:
+	g_object_unref (profile);
+	g_free (title);
+	return ret;
+}
+
+/**
+ * gcm_session_device_assign:
+ **/
+static void
+gcm_session_device_assign (CdDevice *device)
+{
+	CdDeviceKind kind;
+	CdProfile *profile = NULL;
+	const gchar *filename;
+	gboolean ret;
+	gchar *autogen_filename = NULL;
+	gchar *autogen_path = NULL;
+	GcmClut *clut = NULL;
+	GcmEdid *edid = NULL;
+	GcmProfile *gcm_profile = NULL;
+	GcmX11Output *output = NULL;
+	GError *error = NULL;
+	GFile *file = NULL;
+
+	/* check we care */
+	kind = cd_device_get_kind (device);
+	if (kind != CD_DEVICE_KIND_DISPLAY)
+		return;
+
+	g_debug ("need to add display device %s",
+		 cd_device_get_id (device));
+
+	/* get the GcmX11Output for the device id */
+	output = gcm_x11_screen_get_output_by_name (x11_screen,
+						    cd_device_get_id (device),
+						    &error);
+	if (output == NULL) {
+		g_warning ("no %s device found: %s",
+			   cd_device_get_id (device),
+			   error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* get the output EDID */
+	edid = gcm_x11_output_get_edid (output, &error);
+	if (edid == NULL) {
+		g_warning ("unable to get EDID for %s: %s",
+			   cd_device_get_id (device),
+			   error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* create profile from device edid if it does not exist */
+	autogen_filename = g_strdup_printf ("edid-%s.icc",
+					    gcm_edid_get_checksum (edid));
+	autogen_path = g_build_filename (g_get_user_data_dir (),
+					 "icc", autogen_filename, NULL);
+
+	if (g_file_test (autogen_path, G_FILE_TEST_EXISTS)) {
+		g_debug ("auto-profile edid %s exists", autogen_path);
+	} else {
+		g_debug ("auto-profile edid does not exist, creating as %s",
+			 autogen_path);
+		ret = gcm_apply_create_icc_profile_for_edid (edid,
+							     autogen_path,
+							     &error);
+		if (!ret) {
+			g_warning ("failed to create profile from EDID data: %s",
+				     error->message);
+			g_clear_error (&error);
+		}
+
+		/* FIXME: assign profile to device */
+	}
+
+	/* get the default profile for the device */
+	profile = cd_device_get_default_profile (device);
+	if (profile == NULL) {
+		g_debug ("%s has no profile to set",
+			 cd_device_get_id (device));
+
+		/* clear the _ICC_PROFILE atom if not logging in */
+		ret = gcm_x11_output_remove_profile (output,
+						     &error);
+		if (!ret) {
+			g_warning ("failed to clear screen _ICC_PROFILE: %s",
+				   error->message);
+			g_clear_error (&error);
+		}
+
+		/* the default output? */
+		if (gcm_x11_output_get_primary (output)) {
+			ret = gcm_x11_screen_remove_profile (x11_screen,
+							     &error);
+			if (!ret) {
+				g_warning ("failed to clear output _ICC_PROFILE: %s",
+					   error->message);
+				g_clear_error (&error);
+			}
+		}
+		goto out;
+	}
+
+	/* get the filename */
+	filename = cd_profile_get_filename (profile);
+	g_assert (filename != NULL);
+
+	/* set the _ICC_PROFILE atom */
+	if (gcm_x11_output_get_primary (output)) {
+		ret = gcm_x11_screen_set_profile (x11_screen,
+						 filename,
+						 &error);
+		if (!ret) {
+			g_warning ("failed to set screen _ICC_PROFILE: %s",
+				   error->message);
+			g_clear_error (&error);
+		}
+	}
+	ret = gcm_x11_output_set_profile (output,
+					  filename,
+					  &error);
+	if (!ret) {
+		g_warning ("failed to clear output _ICC_PROFILE: %s",
+			   error->message);
+		g_clear_error (&error);
+	}
+
+	/* create a vcgt for this icc file */
+	gcm_profile = gcm_profile_new ();
+	file = g_file_new_for_path (filename);
+	ret = gcm_profile_parse (gcm_profile, file, &error);
+	if (!ret) {
+		g_warning ("failed to parse %s: %s",
+			   filename,
+			   error->message);
+		g_error_free (error);
+		goto out;
+	}
+	clut = gcm_profile_generate_vcgt (gcm_profile,
+					  gcm_x11_output_get_gamma_size (output));
+
+	/* apply the vcgt to this output */
+	ret = gcm_x11_output_set_gamma_from_clut (output, clut, &error);
+	if (!ret) {
+		g_warning ("failed to set %s gamma tables: %s",
+			   cd_device_get_id (device),
+			   error->message);
+		g_error_free (error);
+		goto out;
+	}
+out:
+	g_free (autogen_filename);
+	g_free (autogen_path);
+	if (file != NULL)
+		g_object_unref (file);
+	if (edid != NULL)
+		g_object_unref (edid);
+	if (clut != NULL)
+		g_object_unref (clut);
+	if (output != NULL)
+		g_object_unref (output);
+	if (profile != NULL)
+		g_object_unref (profile);
+	if (gcm_profile != NULL)
+		g_object_unref (gcm_profile);
+}
+
+/**
+ * gcm_session_device_added_assign_cb:
+ **/
+static void
+gcm_session_device_added_assign_cb (CdClient *client_,
+				    CdDevice *device,
+				    gpointer user_data)
+{
+	gcm_session_device_assign (device);
+}
+
+/**
  * gcm_session_get_profile_for_window:
  **/
 static const gchar *
@@ -589,67 +844,6 @@ gcm_session_key_changed_cb (GSettings *settings_, const gchar *key, gpointer use
 	gcm_session_emit_changed ();
 }
 
-#if 0
-/**
- * gcm_apply_create_icc_profile_for_edid:
- **/
-static gboolean
-gcm_apply_create_icc_profile_for_edid (CdDevice *device, const gchar *filename, GError **error)
-{
-	gboolean ret = FALSE;
-	GcmProfile *profile;
-
-	/* generate */
-	profile = cd_device_generate_profile (device, error);
-	if (profile == NULL)
-		goto out;
-
-	/* ensure the per-user directory exists */
-	ret = gcm_utils_mkdir_for_filename (filename, error);
-	if (!ret)
-		goto out;
-
-	/* save this */
-	ret = gcm_profile_save (profile, filename, error);
-	if (!ret)
-		goto out;
-
-	/*
-	 * When we get here there are 4 possible situations:
-	 *
-	 * 1. profiles assigned, use-edid-profile=TRUE		-> add to profiles if not already added, but not as default
-	 * 2. profiles assigned, use-edid-profile=FALSE		-> do nothing
-	 * 3. no profiles, use-edid-profile=TRUE		-> add to profiles as default
-	 * 4. no profiles, use-edid-profile=FALSE		-> do nothing
-	 */
-
-	/* do we set this by default? */
-	if (!cd_device_get_use_edid_profile (device)) {
-		g_debug ("not using auto-edid profile as device profile");
-		goto out;
-	}
-
-	/* add to the profiles list */
-	ret = cd_device_profile_add (device, profile, NULL);
-	if (ret) {
-		/* need to save new list */
-		ret = cd_device_save (device, error);
-		if (!ret)
-			goto out;
-	} else {
-		/* if this failed, it's because it's already associated
-		 * with the device which is okay with us */
-		g_debug ("already added auto-edid profile, not adding %s",
-			 gcm_profile_get_checksum (profile));
-		ret = TRUE;
-	}
-out:
-	if (profile != NULL)
-		g_object_unref (profile);
-	return ret;
-}
-#endif
-
 /**
  * gcm_session_profile_store_added_cb:
  **/
@@ -826,18 +1020,15 @@ out:
 int
 main (int argc, char *argv[])
 {
-//	const gchar *edid_md5;
+	CdDevice *device;
 	gboolean login = FALSE;
 	gboolean ret;
-//	gchar *filename;
 	gchar *introspection_data = NULL;
-//	gchar *path;
-//	CdDevice *device;
 	GError *error = NULL;
 	GFile *file = NULL;
 	GOptionContext *context;
 	GPtrArray *array = NULL;
-//	guint i;
+	guint i;
 	guint owner_id = 0;
 	guint poll_id = 0;
 	guint retval = 1;
@@ -882,7 +1073,9 @@ main (int argc, char *argv[])
 	g_signal_connect (client, "device-added",
 			  G_CALLBACK (gcm_session_device_added_notify_cb),
 			  NULL);
-
+	g_signal_connect (client, "device-added",
+			  G_CALLBACK (gcm_session_device_added_assign_cb),
+			  NULL);
 	ret = cd_client_connect_sync (client, NULL, &error);
 	if (!ret) {
 		g_warning ("failed to connect to colord: %s", error->message);
@@ -890,6 +1083,19 @@ main (int argc, char *argv[])
 		goto out;
 	}
 
+	/* set for each device that already exist */
+	array = cd_client_get_devices_sync (client, NULL, &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 (device);
+	}
+
 	/* monitor displays */
 	x11_screen = gcm_x11_screen_new ();
 	g_signal_connect (x11_screen, "added",
@@ -909,49 +1115,6 @@ main (int argc, char *argv[])
 		goto out;
 	}
 
-#if 0
-	/* set for each output */
-	array = cd_client_get_devices (client);
-	for (i=0; i<array->len; i++) {
-		device = g_ptr_array_index (array, i);
-
-		/* optimize for login to save a few hundred ms */
-		cd_device_xrandr_set_remove_atom (CD_DEVICE_XRANDR (device), !login);
-
-		/* do we have to generate a edid profile? */
-		edid_md5 = cd_device_xrandr_get_edid_md5 (CD_DEVICE_XRANDR (device));
-		if (edid_md5 == NULL) {
-			g_warning ("no EDID data for device");
-		} else {
-			filename = g_strdup_printf ("edid-%s.icc", edid_md5);
-			path = g_build_filename (g_get_user_data_dir (), "icc", filename, NULL);
-			if (g_file_test (path, G_FILE_TEST_EXISTS)) {
-				g_debug ("auto-profile edid %s exists", path);
-			} else {
-				g_debug ("auto-profile edid does not exist, creating as %s", path);
-				ret = gcm_apply_create_icc_profile_for_edid (device, path, &error);
-				if (!ret) {
-					g_warning ("failed to create profile from EDID data: %s",
-						     error->message);
-					g_clear_error (&error);
-				}
-			}
-			g_free (filename);
-			g_free (path);
-		}
-
-		/* set gamma for device */
-		g_debug ("applying default profile for device: %s", cd_device_get_id (device));
-		ret = cd_device_apply (device, &error);
-		if (!ret) {
-			retval = 1;
-			g_warning ("failed to set gamma: %s", error->message);
-			g_error_free (error);
-			break;
-		}
-	}
-#endif
-
 	/* have access to all profiles */
 	profile_store = gcm_profile_store_new ();
 	g_signal_connect (profile_store, "added",
diff --git a/src/gcm-x11-output.c b/src/gcm-x11-output.c
index 0b25b31..ccbf04d 100644
--- a/src/gcm-x11-output.c
+++ b/src/gcm-x11-output.c
@@ -60,6 +60,7 @@ struct _GcmX11OutputPrivate
 	guint				 y;
 	guint				 width;
 	guint				 height;
+	GcmEdid				*edid;
 };
 
 enum {
@@ -361,19 +362,24 @@ out:
  *
  * Return value: %TRUE for success.
  **/
-gboolean
-gcm_x11_output_get_edid_data (GcmX11Output *output,
-			      guint8 **data,
-			      gsize *length,
-			      GError **error)
+GcmEdid *
+gcm_x11_output_get_edid (GcmX11Output *output,
+			 GError **error)
 {
 	Atom edid_atom;
-	guint8 *result;
+	guint8 *result = NULL;
 	gint len;
+	GcmEdid *edid = NULL;
 	gboolean ret = FALSE;
 
-	g_return_val_if_fail (GCM_IS_X11_OUTPUT (output), FALSE);
-	g_return_val_if_fail (output->priv->display != NULL, FALSE);
+	g_return_val_if_fail (GCM_IS_X11_OUTPUT (output), NULL);
+	g_return_val_if_fail (output->priv->display != NULL, NULL);
+
+	/* already parsed */
+	if (output->priv->edid != NULL) {
+		edid = g_object_ref (output->priv->edid);
+		goto out;
+	}
 
 	/* get the new name */
 	edid_atom = XInternAtom (output->priv->display, "EDID", FALSE);
@@ -391,12 +397,20 @@ gcm_x11_output_get_edid_data (GcmX11Output *output,
 		goto out;
 	}
 
-	/* success */
-	if (data != NULL)
-		*data = result;
-	ret = TRUE;
+	/* parse edid */
+	edid = gcm_edid_new ();
+	ret = gcm_edid_parse (edid, result, len, error);
+	if (!ret) {
+		g_object_unref (edid);
+		edid = NULL;
+		goto out;
+	}
+
+	/* cache for later */
+	output->priv->edid = g_object_ref (edid);
 out:
-	return ret;
+	g_free (result);
+	return edid;
 }
 
 /**
@@ -846,6 +860,8 @@ gcm_x11_output_finalize (GObject *object)
 	GcmX11OutputPrivate *priv = output->priv;
 
 	g_free (priv->display_name);
+	if (priv->edid != NULL)
+		g_object_unref (priv->edid);
 
 	G_OBJECT_CLASS (gcm_x11_output_parent_class)->finalize (object);
 }
diff --git a/src/gcm-x11-output.h b/src/gcm-x11-output.h
index 7338c75..cae4b2d 100644
--- a/src/gcm-x11-output.h
+++ b/src/gcm-x11-output.h
@@ -25,6 +25,7 @@
 #include <glib-object.h>
 
 #include "gcm-clut.h"
+#include "gcm-edid.h"
 
 G_BEGIN_DECLS
 
@@ -99,9 +100,7 @@ gboolean	 gcm_x11_output_set_gamma		(GcmX11Output		*output,
 gboolean	 gcm_x11_output_set_gamma_from_clut	(GcmX11Output		*output,
 							 GcmClut		*clut,
 							 GError			**error);
-gboolean	 gcm_x11_output_get_edid_data		(GcmX11Output		*output,
-							 guint8			**data,
-							 gsize			*length,
+GcmEdid		*gcm_x11_output_get_edid		(GcmX11Output		*output,
 							 GError			**error);
 gboolean	 gcm_x11_output_get_profile_data	(GcmX11Output		*output,
 							 guint8			**data,



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