[gnome-color-manager] Add some initial code to support calibration of devices. It's pretty raw at the moment
- From: Richard Hughes <rhughes src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-color-manager] Add some initial code to support calibration of devices. It's pretty raw at the moment
- Date: Thu, 29 Oct 2009 22:41:05 +0000 (UTC)
commit aa4f26f96d0fcb47f2647c7a3bee00cfad48de53
Author: Richard Hughes <richard hughsie com>
Date: Thu Oct 29 22:39:16 2009 +0000
Add some initial code to support calibration of devices. It's pretty raw at the moment
data/Makefile.am | 1 +
data/gcm-import.ui | 181 ++++++++++++++++++++++
data/gcm-prefs.ui | 1 -
src/gcm-calibrate.c | 419 ++++++++++++++++++++++++++++++++++++++++++++++++++-
src/gcm-calibrate.h | 5 +-
src/gcm-prefs.c | 67 ++++++++-
6 files changed, 667 insertions(+), 7 deletions(-)
---
diff --git a/data/Makefile.am b/data/Makefile.am
index deaa1bc..2719f88 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -15,6 +15,7 @@ desktop_in_files = \
desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
pkgdata_DATA = \
+ gcm-import.ui \
gcm-prefs.ui
EXTRA_DIST = \
diff --git a/data/gcm-import.ui b/data/gcm-import.ui
new file mode 100644
index 0000000..38dcef8
--- /dev/null
+++ b/data/gcm-import.ui
@@ -0,0 +1,181 @@
+<?xml version="1.0"?>
+<interface>
+ <requires lib="gtk+" version="2.16"/>
+ <!-- interface-naming-policy project-wide -->
+ <object class="GtkDialog" id="dialog_calibrate">
+ <property name="border_width">5</property>
+ <property name="type_hint">normal</property>
+ <property name="has_separator">False</property>
+ <child internal-child="vbox">
+ <object class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child>
+ <object class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkVBox" id="vbox2">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="stock">gtk-dialog-info</property>
+ <property name="icon-size">6</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">9</property>
+ <child>
+ <object class="GtkHBox" id="hbox2">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkLabel" id="label_title">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"><big><b>Title</b></big></property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox_contents">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkHBox" id="hbox3">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkLabel" id="label_message">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Message</property>
+ <property name="wrap">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkExpander" id="expander_details">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <child>
+ <object class="GtkVBox" id="vbox_details">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"><b>Details</b></property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="action_area">
+ <object class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="button_cancel">
+ <property name="label">gtk-cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button_ok">
+ <property name="label">gtk-ok</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="0">button_cancel</action-widget>
+ <action-widget response="0">button_ok</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/data/gcm-prefs.ui b/data/gcm-prefs.ui
index 2f07161..234f1c8 100644
--- a/data/gcm-prefs.ui
+++ b/data/gcm-prefs.ui
@@ -295,7 +295,6 @@
<object class="GtkButton" id="button_calibrate">
<property name="label" translatable="yes">_Calibrate</property>
<property name="visible">True</property>
- <property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_underline">True</property>
diff --git a/src/gcm-calibrate.c b/src/gcm-calibrate.c
index 7dd5cf5..d0aedb0 100644
--- a/src/gcm-calibrate.c
+++ b/src/gcm-calibrate.c
@@ -28,9 +28,13 @@
#include "config.h"
-#include <glib-object.h>
+#include <glib/gi18n.h>
#include <math.h>
+#include <string.h>
#include <gio/gio.h>
+#include <stdlib.h>
+#include <gtk/gtk.h>
+#include <vte/vte.h>
#include "gcm-calibrate.h"
@@ -49,7 +53,14 @@ struct _GcmCalibratePrivate
{
gboolean is_lcd;
gboolean is_crt;
+ guint display;
gchar *output_name;
+ gchar *basename;
+ GMainLoop *loop;
+ GtkWidget *terminal;
+ GtkBuilder *builder;
+ pid_t child_pid;
+ GtkResponseType response;
};
enum {
@@ -63,19 +74,367 @@ enum {
G_DEFINE_TYPE (GcmCalibrate, gcm_calibrate, G_TYPE_OBJECT)
/**
- * gcm_calibrate_run_task:
+ * gcm_calibrate_get_display:
+ **/
+static guint
+gcm_calibrate_get_display (const gchar *output_name, GError **error)
+{
+ gboolean ret;
+ gchar *data = NULL;
+ gchar **split = NULL;
+ gint exit_status;
+ guint display = G_MAXUINT;
+ guint i;
+ gchar *name;
+
+ /* execute it and capture stderr */
+ ret = g_spawn_command_line_sync ("dispcal", NULL, &data, &exit_status, error);
+ if (!ret)
+ goto out;
+
+ /* split it into lines */
+ split = g_strsplit (data, "\n", -1);
+ for (i=0; split[i] != NULL; i++) {
+ name = g_strdup (split[i]);
+ g_strdelimit (name, " ", '\0');
+ if (g_strcmp0 (output_name, &name[26]) == 0) {
+ display = atoi (&name[4]);
+ egg_debug ("found %s mapped to %i", output_name, display);
+ }
+ g_free (name);
+ }
+
+ /* nothing found */
+ if (display == G_MAXUINT) {
+ if (error != NULL)
+ *error = g_error_new (1, 0, "failed to match display");
+ }
+out:
+ g_free (data);
+ g_strfreev (split);
+ return display;
+}
+
+/**
+ * gcm_calibrate_get_display_type:
+ **/
+static gchar
+gcm_calibrate_get_display_type (GcmCalibrate *calibrate)
+{
+ GcmCalibratePrivate *priv = calibrate->priv;
+ if (priv->is_lcd)
+ return 'l';
+ if (priv->is_crt)
+ return 'c';
+ return '\0';
+}
+
+/**
+ * gcm_calibrate_set_title:
+ **/
+static void
+gcm_calibrate_set_title (GcmCalibrate *calibrate, const gchar *title)
+{
+ GcmCalibratePrivate *priv = calibrate->priv;
+ GtkWidget *widget;
+ gchar *text;
+
+ /* set the text */
+ text = g_strdup_printf ("<big><b>%s</b></big>", title);
+ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_title"));
+ gtk_label_set_markup (GTK_LABEL(widget), text);
+ g_free (text);
+}
+
+/**
+ * gcm_calibrate_set_message:
+ **/
+static void
+gcm_calibrate_set_message (GcmCalibrate *calibrate, const gchar *title)
+{
+ GcmCalibratePrivate *priv = calibrate->priv;
+ GtkWidget *widget;
+ gchar *text;
+
+ /* set the text */
+ text = g_strdup_printf ("%s", title);
+ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_message"));
+ gtk_label_set_markup (GTK_LABEL(widget), text);
+ g_free (text);
+}
+
+/**
+ * gcm_calibrate_setup:
**/
gboolean
-gcm_calibrate_run_task (GcmCalibrate *calibrate, GcmCalibrateTask task, GError **error)
+gcm_calibrate_setup (GcmCalibrate *calibrate, GtkWindow *window, GError **error)
+{
+ GtkWidget *widget;
+ GcmCalibratePrivate *priv = calibrate->priv;
+ GtkWidget *dialog;
+ GtkResponseType response;
+ gboolean ret = TRUE;
+
+ /* show main UI */
+ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "dialog_calibrate"));
+ gtk_widget_show_all (widget);
+ if (window != NULL)
+ gdk_window_set_transient_for (gtk_widget_get_window (widget), gtk_widget_get_window (GTK_WIDGET(window)));
+
+ /* setup GUI */
+ gcm_calibrate_set_title (calibrate, _("Setup hardware"));
+ gcm_calibrate_set_message (calibrate, _("Setting up hardware device for use..."));
+
+ /* this wasn't previously set */
+ if (!priv->is_lcd && !priv->is_crt) {
+ dialog = gtk_message_dialog_new (GTK_WINDOW(widget), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_CANCEL,
+ _("Could not auto-detect CRT or LCD"));
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), _("Please indicate if the screen you are trying to profile is a CRT (old type) or a LCD (digital flat panel)."));
+ gtk_dialog_add_button (GTK_DIALOG (dialog), _("LCD"), GTK_RESPONSE_YES);
+ gtk_dialog_add_button (GTK_DIALOG (dialog), _("CRT"), GTK_RESPONSE_NO);
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ if (response == GTK_RESPONSE_YES) {
+ g_object_set (calibrate,
+ "is-lcd", TRUE,
+ NULL);
+ } else if (response == GTK_RESPONSE_NO) {
+ g_object_set (calibrate,
+ "is-crt", TRUE,
+ NULL);
+ } else {
+ if (error != NULL)
+ *error = g_error_new (1, 0, "user did not choose crt or lcd");
+ ret = FALSE;
+ goto out;
+ }
+ }
+out:
+ return ret;
+}
+
+/**
+ * gcm_calibrate_task_neutralise:
+ **/
+static gboolean
+gcm_calibrate_task_neutralise (GcmCalibrate *calibrate, GError **error)
+{
+ gboolean ret = TRUE;
+ GcmCalibratePrivate *priv = calibrate->priv;
+ gchar type;
+ gchar *cmd = NULL;
+ gchar **argc = NULL;
+ GtkWidget *widget;
+ GtkWidget *dialog;
+ GtkResponseType response;
+
+ /* match up the output name with the device number defined by dispcal */
+ priv->display = gcm_calibrate_get_display (priv->output_name, error);
+ if (priv->display == G_MAXUINT)
+ goto out;
+
+ /* get l-cd or c-rt */
+ type = gcm_calibrate_get_display_type (calibrate);
+
+ /* TODO: choose a better filename, maybe based on the monitor serial number */
+ priv->basename = g_strdup ("basename");
+
+ /* setup the command */
+ cmd = g_strdup_printf ("dispcal -v -ql -m -d%i -y%c %s", priv->display, type, priv->basename);
+ argc = g_strsplit (cmd, " ", -1);
+ egg_debug ("running %s", cmd);
+
+ /* start up the command */
+ priv->child_pid = vte_terminal_fork_command (VTE_TERMINAL(priv->terminal), argc[0], &argc[1], NULL, "/tmp", FALSE, FALSE, FALSE);
+
+ /* ask user to attach device */
+ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "dialog_calibrate"));
+ dialog = gtk_message_dialog_new (GTK_WINDOW(widget), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_OK_CANCEL,
+ _("Please attach device"));
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), _("Please attach the hardware device to the center of the screen on the grey square."));
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ if (response != GTK_RESPONSE_OK) {
+ vte_terminal_feed_child (VTE_TERMINAL(priv->terminal), "Q", 1);
+ if (error != NULL)
+ *error = g_error_new (1, 0, "user did not attach hardware device");
+ ret = FALSE;
+ goto out;
+ }
+
+ /* send the terminal an okay */
+ vte_terminal_feed_child (VTE_TERMINAL(priv->terminal), " ", 1);
+
+ /* setup GUI */
+ gcm_calibrate_set_title (calibrate, _("Resetting screen to neutral state"));
+ gcm_calibrate_set_message (calibrate, _("This brings the screen to a neutral state by sending colored and gray patches to your screen and measuring them with the hardware device."));
+
+ /* wait until finished */
+ g_main_loop_run (priv->loop);
+out:
+ g_strfreev (argc);
+ g_free (cmd);
+ return ret;
+}
+
+/**
+ * gcm_calibrate_timeout_cb:
+ **/
+static gboolean
+gcm_calibrate_timeout_cb (GcmCalibrate *calibrate)
+{
+ vte_terminal_feed_child (VTE_TERMINAL(calibrate->priv->terminal), " ", 1);
+ return FALSE;
+}
+
+/**
+ * gcm_calibrate_task_generate_patches:
+ **/
+static gboolean
+gcm_calibrate_task_generate_patches (GcmCalibrate *calibrate, GError **error)
{
gboolean ret = TRUE;
+ GcmCalibratePrivate *priv = calibrate->priv;
+ gchar type;
+ gchar *cmd = NULL;
+ gchar **argc = NULL;
+
+ /* get l-cd or c-rt */
+ type = gcm_calibrate_get_display_type (calibrate);
+
+ /* setup the command */
+ cmd = g_strdup_printf ("targen -v -d3 -f250 %s", priv->basename);
+ argc = g_strsplit (cmd, " ", -1);
+ egg_debug ("running %s", cmd);
+
+ /* start up the command */
+ priv->child_pid = vte_terminal_fork_command (VTE_TERMINAL(priv->terminal), argc[0], &argc[1], NULL, "/tmp", FALSE, FALSE, FALSE);
+ g_timeout_add_seconds (3, (GSourceFunc) gcm_calibrate_timeout_cb, calibrate);
+
+ /* setup GUI */
+ gcm_calibrate_set_title (calibrate, _("Generating the patches"));
+ gcm_calibrate_set_message (calibrate, _("Generating the patches that will be measured with the hardware device."));
+
+ /* wait until finished */
+ g_main_loop_run (priv->loop);
+
+ g_strfreev (argc);
+ g_free (cmd);
+ return ret;
+}
+
+/**
+ * gcm_calibrate_task_draw_and_measure:
+ **/
+static gboolean
+gcm_calibrate_task_draw_and_measure (GcmCalibrate *calibrate, GError **error)
+{
+ gboolean ret = TRUE;
+ GcmCalibratePrivate *priv = calibrate->priv;
+ gchar type;
+ gchar *cmd = NULL;
+ gchar **argc = NULL;
+
+ /* get l-cd or c-rt */
+ type = gcm_calibrate_get_display_type (calibrate);
+
+ /* setup the command */
+ cmd = g_strdup_printf ("dispread -v -d%i -y%c -k %s.cal %s", priv->display, type, priv->basename, priv->basename);
+ argc = g_strsplit (cmd, " ", -1);
+ egg_debug ("running %s", cmd);
+
+ /* start up the command */
+ priv->child_pid = vte_terminal_fork_command (VTE_TERMINAL(priv->terminal), argc[0], &argc[1], NULL, "/tmp", FALSE, FALSE, FALSE);
+
+ /* setup GUI */
+ gcm_calibrate_set_title (calibrate, _("Drawing the patches"));
+ gcm_calibrate_set_message (calibrate, _("Drawing the generated patches to the screen, which will then be measured by the hardware device."));
+
+ /* wait until finished */
+ g_main_loop_run (priv->loop);
+
+ g_strfreev (argc);
+ g_free (cmd);
+ return ret;
+}
+
+/**
+ * gcm_calibrate_task_generate_profile:
+ **/
+static gboolean
+gcm_calibrate_task_generate_profile (GcmCalibrate *calibrate, GError **error)
+{
+ gboolean ret = TRUE;
+ GcmCalibratePrivate *priv = calibrate->priv;
+ gchar type;
+ gchar *cmd = NULL;
+ gchar **argc = NULL;
+
+ /* get l-cd or c-rt */
+ type = gcm_calibrate_get_display_type (calibrate);
+
+ /* setup the command */
+ cmd = g_strdup_printf ("colprof -A \"LG\" -M \"LG Flatpanel\" -D \"October 29 2009\" -q m -as %s", priv->basename);
+
+ argc = g_strsplit (cmd, " ", -1);
+ egg_debug ("running %s", cmd);
+
+ /* start up the command */
+ priv->child_pid = vte_terminal_fork_command (VTE_TERMINAL(priv->terminal), argc[0], &argc[1], NULL, "/tmp", FALSE, FALSE, FALSE);
+
+ /* setup GUI */
+ gcm_calibrate_set_title (calibrate, _("Generating the profile"));
+ gcm_calibrate_set_message (calibrate, _("Generating the ICC color profile that can be used with this screen."));
+
+ /* wait until finished */
+ g_main_loop_run (priv->loop);
+
+ g_strfreev (argc);
+ g_free (cmd);
+ return ret;
+}
+
+/**
+ * gcm_calibrate_task:
+ **/
+gboolean
+gcm_calibrate_task (GcmCalibrate *calibrate, GcmCalibrateTask task, GError **error)
+{
+ gboolean ret = FALSE;
g_return_val_if_fail (GCM_IS_CALIBRATE (calibrate), FALSE);
+ /* each option */
+ if (task == GCM_CALIBRATE_TASK_NEUTRALISE) {
+ ret = gcm_calibrate_task_neutralise (calibrate, error);
+ goto out;
+ }
+ if (task == GCM_CALIBRATE_TASK_GENERATE_PATCHES) {
+ ret = gcm_calibrate_task_generate_patches (calibrate, error);
+ goto out;
+ }
+ if (task == GCM_CALIBRATE_TASK_DRAW_AND_MEASURE) {
+ ret = gcm_calibrate_task_draw_and_measure (calibrate, error);
+ goto out;
+ }
+ if (task == GCM_CALIBRATE_TASK_GENERATE_PROFILE) {
+ ret = gcm_calibrate_task_generate_profile (calibrate, error);
+ goto out;
+ }
+out:
return ret;
}
/**
+ * gcm_calibrate_exit_cb:
+ **/
+static void
+gcm_calibrate_exit_cb (VteTerminal *terminal, GcmCalibrate *calibrate)
+{
+ g_main_loop_quit (calibrate->priv->loop);
+}
+
+/**
* gcm_calibrate_get_property:
**/
static void
@@ -101,6 +460,25 @@ gcm_calibrate_get_property (GObject *object, guint prop_id, GValue *value, GPara
}
/**
+ * gcm_calibrate_guess_type:
+ **/
+static void
+gcm_calibrate_guess_type (GcmCalibrate *calibrate)
+{
+ GcmCalibratePrivate *priv = calibrate->priv;
+
+ /* guess based on the output name */
+ if (strstr (priv->output_name, "DVI") != NULL ||
+ strstr (priv->output_name, "LVDS") != NULL) {
+ priv->is_lcd = TRUE;
+ priv->is_crt = FALSE;
+ } else {
+ priv->is_lcd = FALSE;
+ priv->is_crt = FALSE;
+ }
+}
+
+/**
* gcm_calibrate_set_property:
**/
static void
@@ -119,6 +497,7 @@ gcm_calibrate_set_property (GObject *object, guint prop_id, const GValue *value,
case PROP_OUTPUT_NAME:
g_free (priv->output_name);
priv->output_name = g_strdup (g_value_get_string (value));
+ gcm_calibrate_guess_type (calibrate);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -171,8 +550,30 @@ gcm_calibrate_class_init (GcmCalibrateClass *klass)
static void
gcm_calibrate_init (GcmCalibrate *calibrate)
{
+ gint retval;
+ GError *error = NULL;
+ GtkWidget *widget;
+
calibrate->priv = GCM_CALIBRATE_GET_PRIVATE (calibrate);
calibrate->priv->output_name = NULL;
+ calibrate->priv->basename = NULL;
+ calibrate->priv->loop = g_main_loop_new (NULL, FALSE);
+
+ /* get UI */
+ calibrate->priv->builder = gtk_builder_new ();
+ retval = gtk_builder_add_from_file (calibrate->priv->builder, GCM_DATA "/gcm-import.ui", &error);
+ if (retval == 0) {
+ egg_warning ("failed to load ui: %s", error->message);
+ g_error_free (error);
+ }
+
+ /* add vte widget */
+ calibrate->priv->terminal = vte_terminal_new ();
+ vte_terminal_set_size (VTE_TERMINAL(calibrate->priv->terminal), 40, 10);
+ g_signal_connect (calibrate->priv->terminal, "child-exited",
+ G_CALLBACK (gcm_calibrate_exit_cb), calibrate);
+ widget = GTK_WIDGET (gtk_builder_get_object (calibrate->priv->builder, "vbox_details"));
+ gtk_box_pack_end (GTK_BOX(widget), calibrate->priv->terminal, TRUE, TRUE, 6);
}
/**
@@ -181,10 +582,22 @@ gcm_calibrate_init (GcmCalibrate *calibrate)
static void
gcm_calibrate_finalize (GObject *object)
{
+ GtkWidget *widget;
GcmCalibrate *calibrate = GCM_CALIBRATE (object);
GcmCalibratePrivate *priv = calibrate->priv;
+ /* wait until finished */
+ if (g_main_loop_is_running (priv->loop))
+ g_main_loop_quit (priv->loop);
+
+ /* hide window */
+ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "dialog_calibrate"));
+ gtk_widget_hide (widget);
+
g_free (priv->output_name);
+ g_free (priv->basename);
+ g_main_loop_unref (priv->loop);
+ g_object_unref (priv->builder);
G_OBJECT_CLASS (gcm_calibrate_parent_class)->finalize (object);
}
diff --git a/src/gcm-calibrate.h b/src/gcm-calibrate.h
index 091d4a1..1b8f6d4 100644
--- a/src/gcm-calibrate.h
+++ b/src/gcm-calibrate.h
@@ -64,7 +64,10 @@ typedef enum {
GType gcm_calibrate_get_type (void);
GcmCalibrate *gcm_calibrate_new (void);
-gboolean gcm_calibrate_run_task (GcmCalibrate *calibrate,
+gboolean gcm_calibrate_setup (GcmCalibrate *calibrate,
+ GtkWindow *window,
+ GError **error);
+gboolean gcm_calibrate_task (GcmCalibrate *calibrate,
GcmCalibrateTask task,
GError **error);
diff --git a/src/gcm-prefs.c b/src/gcm-prefs.c
index a83f28a..4ff52b3 100644
--- a/src/gcm-prefs.c
+++ b/src/gcm-prefs.c
@@ -28,6 +28,7 @@
#include "gcm-utils.h"
#include "gcm-profile.h"
+#include "gcm-calibrate.h"
static GtkBuilder *builder = NULL;
static GtkListStore *list_store_devices = NULL;
@@ -74,6 +75,67 @@ gcm_prefs_help_cb (GtkWidget *widget, gpointer data)
}
/**
+ * gcm_prefs_calibrate_cb:
+ **/
+static void
+gcm_prefs_calibrate_cb (GtkWidget *widget, gpointer data)
+{
+ GcmCalibrate *calib;
+ gboolean ret;
+ GError *error = NULL;
+ GtkWindow *window;
+
+ calib = gcm_calibrate_new ();
+ g_object_set (calib,
+ "output-name", "LVDS1",
+ // "output-name", "DVI1",
+ NULL);
+
+ /* run each task in order */
+ window = GTK_WINDOW(gtk_builder_get_object (builder, "dialog_prefs"));
+ ret = gcm_calibrate_setup (calib, window, &error);
+ if (!ret) {
+ egg_warning ("failed to setup: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ /* step 1 */
+ ret = gcm_calibrate_task (calib, GCM_CALIBRATE_TASK_NEUTRALISE, &error);
+ if (!ret) {
+ egg_warning ("failed to calibrate: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ /* step 2 */
+ ret = gcm_calibrate_task (calib, GCM_CALIBRATE_TASK_GENERATE_PATCHES, &error);
+ if (!ret) {
+ egg_warning ("failed to calibrate: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ /* step 3 */
+ ret = gcm_calibrate_task (calib, GCM_CALIBRATE_TASK_DRAW_AND_MEASURE, &error);
+ if (!ret) {
+ egg_warning ("failed to calibrate: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ /* step 4 */
+ ret = gcm_calibrate_task (calib, GCM_CALIBRATE_TASK_GENERATE_PROFILE, &error);
+ if (!ret) {
+ egg_warning ("failed to calibrate: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+out:
+ g_object_unref (calib);
+}
+
+/**
* gcm_prefs_reset_cb:
**/
static void
@@ -461,10 +523,8 @@ out:
int
main (int argc, char **argv)
{
-// gboolean ret;
gboolean verbose = FALSE;
guint retval = 0;
-// GError *error = NULL;
GOptionContext *context;
GtkWidget *main_window;
GtkWidget *widget;
@@ -550,6 +610,9 @@ main (int argc, char **argv)
widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_reset"));
g_signal_connect (widget, "clicked",
G_CALLBACK (gcm_prefs_reset_cb), NULL);
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_calibrate"));
+ g_signal_connect (widget, "clicked",
+ G_CALLBACK (gcm_prefs_calibrate_cb), NULL);
/* setup icc profiles list */
widget = GTK_WIDGET (gtk_builder_get_object (builder, "combobox_profile"));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]