[gnome-color-manager] Add printer profiling support using argyllcms and GtkPrint
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-color-manager] Add printer profiling support using argyllcms and GtkPrint
- Date: Tue, 23 Feb 2010 11:39:00 +0000 (UTC)
commit b24a922960df55ad024011856e805a11ff31ab98
Author: Richard Hughes <richard hughsie com>
Date: Tue Feb 23 11:38:00 2010 +0000
Add printer profiling support using argyllcms and GtkPrint
src/gcm-calibrate-argyll.c | 370 +++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 366 insertions(+), 4 deletions(-)
---
diff --git a/src/gcm-calibrate-argyll.c b/src/gcm-calibrate-argyll.c
index 0a29370..6c60618 100644
--- a/src/gcm-calibrate-argyll.c
+++ b/src/gcm-calibrate-argyll.c
@@ -87,6 +87,7 @@ struct _GcmCalibrateArgyllPrivate
glong vte_previous_col;
gboolean already_on_window;
GcmCalibrateArgyllState state;
+ GcmPrint *print;
};
enum {
@@ -441,6 +442,90 @@ out:
return ret;
}
+
+/**
+ * gcm_calibrate_argyll_display_read_chart:
+ **/
+static gboolean
+gcm_calibrate_argyll_display_read_chart (GcmCalibrateArgyll *calibrate_argyll, GError **error)
+{
+ gboolean ret = TRUE;
+ GcmCalibrateArgyllPrivate *priv = calibrate_argyll->priv;
+ gchar *command = NULL;
+ gchar **argv = NULL;
+ GPtrArray *array = NULL;
+ gchar *basename = NULL;
+ const gchar *title;
+ const gchar *message;
+
+ /* get shared data */
+ g_object_get (calibrate_argyll,
+ "basename", &basename,
+ NULL);
+
+ /* get correct name of the command */
+ command = gcm_calibrate_argyll_get_tool_filename ("chartread", error);
+ if (command == NULL) {
+ ret = FALSE;
+ goto out;
+ }
+
+ /* TRANSLATORS: title, patches are specific colours used in calibration */
+ title = _("Reading the patches");
+ /* TRANSLATORS: dialog message */
+ message = _("Reading the patches using the hardware device.");
+
+ /* push new messages into the UI */
+ gcm_calibrate_dialog_show (priv->calibrate_dialog, GCM_CALIBRATE_DIALOG_TAB_GENERIC, title, message);
+ gcm_calibrate_dialog_set_show_button_ok (priv->calibrate_dialog, FALSE);
+ gcm_calibrate_dialog_set_show_expander (priv->calibrate_dialog, TRUE);
+
+ /* argument array */
+ array = g_ptr_array_new_with_free_func (g_free);
+
+ /* setup the command */
+ g_ptr_array_add (array, g_strdup ("-v9"));
+ g_ptr_array_add (array, g_strdup (basename));
+ argv = gcm_utils_ptr_array_to_strv (array);
+ gcm_calibrate_argyll_debug_argv (command, argv);
+
+ /* start up the command */
+ priv->state = GCM_CALIBRATE_ARGYLL_STATE_RUNNING;
+ vte_terminal_reset (VTE_TERMINAL(priv->terminal), TRUE, FALSE);
+ priv->child_pid = vte_terminal_fork_command (VTE_TERMINAL(priv->terminal), command, argv, NULL, GCM_CALIBRATE_ARGYLL_TEMP_DIR, FALSE, FALSE, FALSE);
+
+ /* wait until finished */
+ g_main_loop_run (priv->loop);
+
+ /* get result */
+ if (priv->response == GTK_RESPONSE_CANCEL) {
+ g_set_error_literal (error,
+ GCM_CALIBRATE_ERROR,
+ GCM_CALIBRATE_ERROR_USER_ABORT,
+ "calibration was cancelled");
+ ret = FALSE;
+ goto out;
+ }
+ if (priv->response == GTK_RESPONSE_REJECT) {
+ gchar *vte_text;
+ vte_text = vte_terminal_get_text (VTE_TERMINAL(priv->terminal), NULL, NULL, NULL);
+ g_set_error (error,
+ GCM_CALIBRATE_ERROR,
+ GCM_CALIBRATE_ERROR_INTERNAL,
+ "command failed to run successfully: %s", vte_text);
+ g_free (vte_text);
+ ret = FALSE;
+ goto out;
+ }
+out:
+ if (array != NULL)
+ g_ptr_array_unref (array);
+ g_free (basename);
+ g_free (command);
+ g_strfreev (argv);
+ return ret;
+}
+
/**
* gcm_calibrate_argyll_display_generate_patches:
**/
@@ -1210,25 +1295,246 @@ out:
}
/**
+ * gcm_calibrate_argyll_get_colorimeter_target:
+ **/
+static const gchar *
+gcm_calibrate_argyll_get_colorimeter_target (GcmCalibrateArgyll *calibrate_argyll)
+{
+ GcmColorimeterKind colorimeter_kind;
+
+ g_object_get (calibrate_argyll,
+ "colorimeter-kind", &colorimeter_kind,
+ NULL);
+
+ if (colorimeter_kind == GCM_COLORIMETER_KIND_DTP20)
+ return "20";
+ if (colorimeter_kind == GCM_COLORIMETER_KIND_DTP22)
+ return "22";
+ if (colorimeter_kind == GCM_COLORIMETER_KIND_DTP41)
+ return "41";
+ if (colorimeter_kind == GCM_COLORIMETER_KIND_DTP51)
+ return "51";
+ if (colorimeter_kind == GCM_COLORIMETER_KIND_SPECTRO_SCAN)
+ return "SS";
+ if (colorimeter_kind == GCM_COLORIMETER_KIND_I1_PRO)
+ return "i1";
+ if (colorimeter_kind == GCM_COLORIMETER_KIND_COLOR_MUNKI)
+ return "CM";
+ return NULL;
+}
+
+/**
+ * gcm_calibrate_argyll_display_generate_targets:
+ **/
+static gboolean
+gcm_calibrate_argyll_display_generate_targets (GcmCalibrateArgyll *calibrate_argyll, gdouble width, gdouble height, GError **error)
+{
+ gboolean ret = TRUE;
+ GcmCalibrateArgyllPrivate *priv = calibrate_argyll->priv;
+ gchar *command = NULL;
+ gchar **argv = NULL;
+ GPtrArray *array = NULL;
+ gchar *basename = NULL;
+ const gchar *title;
+ const gchar *message;
+ GcmColorimeterKind colorimeter_kind;
+
+ /* get shared data */
+ g_object_get (calibrate_argyll,
+ "basename", &basename,
+ "colorimeter-kind", &colorimeter_kind,
+ NULL);
+
+ /* get correct name of the command */
+ command = gcm_calibrate_argyll_get_tool_filename ("printtarg", error);
+ if (command == NULL) {
+ ret = FALSE;
+ goto out;
+ }
+
+ /* TRANSLATORS: title, patches are specific colors used in calibration */
+ title = _("Printing patches");
+
+ /* TRANSLATORS: dialog message */
+ message = _("Rendering the patches for the selected paper and ink.");
+
+ /* push new messages into the UI */
+ gcm_calibrate_dialog_show (priv->calibrate_dialog, GCM_CALIBRATE_DIALOG_TAB_GENERIC, title, message);
+ gcm_calibrate_dialog_set_show_button_ok (priv->calibrate_dialog, FALSE);
+ gcm_calibrate_dialog_set_show_expander (priv->calibrate_dialog, TRUE);
+
+ /* argument array */
+ array = g_ptr_array_new_with_free_func (g_free);
+
+ /* setup the command */
+ g_ptr_array_add (array, g_strdup ("-v"));
+
+ /* target instrument */
+ g_ptr_array_add (array, g_strdup_printf ("-i%s", gcm_calibrate_argyll_get_colorimeter_target (calibrate_argyll)));
+
+ /* use double density */
+ if (colorimeter_kind == GCM_COLORIMETER_KIND_COLOR_MUNKI ||
+ colorimeter_kind == GCM_COLORIMETER_KIND_SPECTRO_SCAN) {
+ g_ptr_array_add (array, g_strdup ("-h"));
+ }
+
+ /* 8 bit TIFF 300 dpi */
+ g_ptr_array_add (array, g_strdup ("-t300"));
+
+ /* paper size */
+ g_ptr_array_add (array, g_strdup_printf ("-p%ix%i", (gint) width, (gint) height));
+
+ g_ptr_array_add (array, g_strdup (basename));
+ argv = gcm_utils_ptr_array_to_strv (array);
+ gcm_calibrate_argyll_debug_argv (command, argv);
+
+ /* start up the command */
+ priv->state = GCM_CALIBRATE_ARGYLL_STATE_RUNNING;
+ vte_terminal_reset (VTE_TERMINAL(priv->terminal), TRUE, FALSE);
+ priv->child_pid = vte_terminal_fork_command (VTE_TERMINAL(priv->terminal), command, argv, NULL, GCM_CALIBRATE_ARGYLL_TEMP_DIR, FALSE, FALSE, FALSE);
+
+ /* wait until finished */
+ g_main_loop_run (priv->loop);
+
+ /* get result */
+ if (priv->response == GTK_RESPONSE_CANCEL) {
+ g_set_error_literal (error,
+ GCM_CALIBRATE_ERROR,
+ GCM_CALIBRATE_ERROR_USER_ABORT,
+ "target generation was cancelled");
+ ret = FALSE;
+ goto out;
+ }
+ if (priv->response == GTK_RESPONSE_REJECT) {
+ gchar *vte_text;
+ vte_text = vte_terminal_get_text (VTE_TERMINAL(priv->terminal), NULL, NULL, NULL);
+ g_set_error (error,
+ GCM_CALIBRATE_ERROR,
+ GCM_CALIBRATE_ERROR_INTERNAL,
+ "command failed to run successfully: %s", vte_text);
+ g_free (vte_text);
+ ret = FALSE;
+ goto out;
+ }
+out:
+ if (array != NULL)
+ g_ptr_array_unref (array);
+ g_free (basename);
+ g_free (command);
+ g_strfreev (argv);
+ return ret;
+}
+
+/**
+ * gcm_calibrate_argyll_render_cb:
+ **/
+static GPtrArray *
+gcm_calibrate_argyll_render_cb (GcmPrint *print, GtkPageSetup *page_setup, GcmCalibrate *calibrate, GError **error)
+{
+ gboolean ret = TRUE;
+ GPtrArray *array = NULL;
+ gdouble width, height;
+ GtkPaperSize *paper_size;
+ GDir *dir = NULL;
+ const gchar *filename;
+ gchar *basename = NULL;
+ gchar *filename_tmp;
+
+ /* get shared data */
+ g_object_get (calibrate,
+ "basename", &basename,
+ NULL);
+
+ paper_size = gtk_page_setup_get_paper_size (page_setup);
+ width = gtk_paper_size_get_width (paper_size, GTK_UNIT_MM);
+ height = gtk_paper_size_get_height (paper_size, GTK_UNIT_MM);
+
+ /* generate the tiff files */
+ ret = gcm_calibrate_argyll_display_generate_targets (GCM_CALIBRATE_ARGYLL (calibrate), width, height, error);
+ if (!ret)
+ goto out;
+
+ //FIXME: we need a temp directory, not just the root of tmp
+
+ /* list files */
+ dir = g_dir_open (GCM_CALIBRATE_ARGYLL_TEMP_DIR, 0, error);
+ if (dir == NULL)
+ goto out;
+
+ /* read in each file */
+ array = g_ptr_array_new_with_free_func (g_free);
+ filename = g_dir_read_name (dir);
+ while (filename != NULL) {
+ if (g_str_has_prefix (filename, basename) &&
+ g_str_has_suffix (filename, ".tif")) {
+ filename_tmp = g_build_filename (GCM_CALIBRATE_ARGYLL_TEMP_DIR, filename, NULL);
+ egg_debug ("add print page %s", filename_tmp);
+ g_ptr_array_add (array, filename_tmp);
+ }
+ filename = g_dir_read_name (dir);
+ }
+out:
+ g_free (basename);
+ if (dir != NULL)
+ g_dir_close (dir);
+ return array;
+}
+
+/**
* gcm_calibrate_argyll_printer:
**/
static gboolean
gcm_calibrate_argyll_printer (GcmCalibrate *calibrate, GtkWindow *window, GError **error)
{
gboolean ret;
+ const gchar *title;
+ const gchar *message;
+ GtkResponseType response;
GcmCalibrateArgyll *calibrate_argyll = GCM_CALIBRATE_ARGYLL(calibrate);
-// GcmCalibrateArgyllPrivate *priv = calibrate_argyll->priv;
+ GcmCalibrateArgyllPrivate *priv = calibrate_argyll->priv;
/* need to ask if we are printing now, or using old data */
+ /* set modal windows up correctly */
+ gcm_calibrate_dialog_set_window (priv->calibrate_dialog, window);
+
/* step 1 */
ret = gcm_calibrate_argyll_display_generate_patches (calibrate_argyll, error);
if (!ret)
goto out;
-// printtarg -v -i CM -h -t 300 -p A4 test
-// chartread -v test
-// colprof -v -A "bla" -M "bla" -D "bla" -C "bla" -a l -q m test
+ /* print */
+ window = gcm_calibrate_dialog_get_window (priv->calibrate_dialog);
+ ret = gcm_print_with_render_callback (priv->print, window, (GcmPrintRenderCb) gcm_calibrate_argyll_render_cb, calibrate, error);
+ if (!ret)
+ goto out;
+
+ /* TRANSLATORS: title, patches are specific colours used in calibration */
+ title = _("Wait for the ink to dry");
+
+ /* TRANSLATORS: dialog message */
+ message = _("Please wait a few minutes for the ink to dry. Profiling damp ink will produce a poor profile and may damage your calibration device.");
+
+ /* push new messages into the UI */
+ gcm_calibrate_dialog_show (priv->calibrate_dialog, GCM_CALIBRATE_DIALOG_TAB_GENERIC, title, message);
+ gcm_calibrate_dialog_set_show_button_ok (priv->calibrate_dialog, TRUE);
+ gcm_calibrate_dialog_set_show_expander (priv->calibrate_dialog, FALSE);
+ gcm_calibrate_dialog_set_image_filename (priv->calibrate_dialog, "clock.svg");
+ response = gcm_calibrate_dialog_run (priv->calibrate_dialog);
+ if (response != GTK_RESPONSE_OK) {
+ gcm_calibrate_dialog_hide (priv->calibrate_dialog);
+ g_set_error_literal (error,
+ GCM_CALIBRATE_ERROR,
+ GCM_CALIBRATE_ERROR_USER_ABORT,
+ "user did not wait for ink to dry");
+ ret = FALSE;
+ goto out;
+ }
+
+ /* step 3 */
+ ret = gcm_calibrate_argyll_display_read_chart (calibrate_argyll, error);
+ if (!ret)
+ goto out;
/* step 4 */
ret = gcm_calibrate_argyll_device_generate_profile (calibrate_argyll, error);
@@ -1625,6 +1931,58 @@ out:
}
/**
+ * gcm_calibrate_argyll_status_changed_cb:
+ **/
+static void
+gcm_calibrate_argyll_status_changed_cb (GcmPrint *print, GtkPrintStatus status, GcmCalibrateArgyll *calibrate_argyll)
+{
+ const gchar *title;
+ const gchar *message = NULL;
+ GcmCalibrateArgyllPrivate *priv = calibrate_argyll->priv;
+
+ /* TRANSLATORS: title, printing reference files to media */
+ title = _("Printing");
+
+ switch (status) {
+ case GTK_PRINT_STATUS_INITIAL:
+ case GTK_PRINT_STATUS_PREPARING:
+ case GTK_PRINT_STATUS_GENERATING_DATA:
+ /* TRANSLATORS: dialog message */
+ message = _("Preparing the data for the printer.");
+ break;
+ case GTK_PRINT_STATUS_SENDING_DATA:
+ case GTK_PRINT_STATUS_PENDING:
+ case GTK_PRINT_STATUS_PENDING_ISSUE:
+ /* TRANSLATORS: dialog message */
+ message = _("Sending the targets to the printer.");
+ break;
+ case GTK_PRINT_STATUS_PRINTING:
+ /* TRANSLATORS: dialog message */
+ message = _("Printing the targets...");
+ break;
+ case GTK_PRINT_STATUS_FINISHED:
+ /* TRANSLATORS: dialog message */
+ message = _("The printing has finished.");
+ break;
+ case GTK_PRINT_STATUS_FINISHED_ABORTED:
+ /* TRANSLATORS: dialog message */
+ message = _("The print was aborted.");
+ break;
+ default:
+ break;
+ }
+
+ /* not a translated message */
+ if (message == NULL)
+ return;
+
+ /* push new messages into the UI */
+ gcm_calibrate_dialog_show (priv->calibrate_dialog, GCM_CALIBRATE_DIALOG_TAB_GENERIC, title, message);
+ gcm_calibrate_dialog_set_show_button_ok (priv->calibrate_dialog, FALSE);
+ gcm_calibrate_dialog_set_show_expander (priv->calibrate_dialog, FALSE);
+}
+
+/**
* gcm_calibrate_argyll_get_property:
**/
static void
@@ -1685,6 +2043,9 @@ gcm_calibrate_argyll_init (GcmCalibrateArgyll *calibrate_argyll)
calibrate_argyll->priv->vte_previous_col = 0;
calibrate_argyll->priv->already_on_window = FALSE;
calibrate_argyll->priv->state = GCM_CALIBRATE_ARGYLL_STATE_IDLE;
+ calibrate_argyll->priv->print = gcm_print_new ();
+ g_signal_connect (calibrate_argyll->priv->print, "status-changed",
+ G_CALLBACK (gcm_calibrate_argyll_status_changed_cb), calibrate_argyll);
calibrate_argyll->priv->calibrate_dialog = gcm_calibrate_dialog_new ();
g_signal_connect (calibrate_argyll->priv->calibrate_dialog, "response",
G_CALLBACK (gcm_calibrate_argyll_response_cb), calibrate_argyll);
@@ -1736,6 +2097,7 @@ gcm_calibrate_argyll_finalize (GObject *object)
g_object_unref (priv->screen);
g_object_unref (priv->gconf_client);
g_object_unref (priv->calibrate_dialog);
+ g_object_unref (priv->print);
G_OBJECT_CLASS (gcm_calibrate_argyll_parent_class)->finalize (object);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]