[gnome-utils] screenshot: Save the screen ICC profile in the screenshot file if it has been set



commit 70c91e33d82bd2b1e8783e3b45f4f898bcf021f9
Author: Richard Hughes <richard hughsie com>
Date:   Thu Mar 17 10:02:00 2011 +0000

    screenshot: Save the screen ICC profile in the screenshot file if it has been set

 gnome-screenshot/gnome-screenshot.c                |  100 ++++++++++++++++++++
 .../org.gnome.gnome-screenshot.gschema.xml.in      |    5 +
 gnome-screenshot/screenshot-save.c                 |   31 +++++-
 gnome-screenshot/screenshot-save.h                 |    1 +
 4 files changed, 133 insertions(+), 4 deletions(-)
---
diff --git a/gnome-screenshot/gnome-screenshot.c b/gnome-screenshot/gnome-screenshot.c
index a3a6ecc..2ab66bd 100644
--- a/gnome-screenshot/gnome-screenshot.c
+++ b/gnome-screenshot/gnome-screenshot.c
@@ -52,6 +52,7 @@
 #define GNOME_SCREENSHOT_SCHEMA "org.gnome.gnome-screenshot"
 #define INCLUDE_BORDER_KEY      "include-border"
 #define INCLUDE_POINTER_KEY     "include-pointer"
+#define INCLUDE_ICC_PROFILE     "include-icc-profile"
 #define LAST_SAVE_DIRECTORY_KEY "last-save-directory"
 #define BORDER_EFFECT_KEY       "border-effect"
 #define DELAY_KEY               "delay"
@@ -102,6 +103,7 @@ static gboolean take_window_shot = FALSE;
 static gboolean take_area_shot = FALSE;
 static gboolean include_border = FALSE;
 static gboolean include_pointer = TRUE;
+static gboolean include_icc_profile = TRUE;
 static char *border_effect = NULL;
 static guint delay = 0;
 
@@ -803,9 +805,72 @@ play_sound_effect (GdkWindow *window)
 
 }
 
+static gchar *
+get_profile_for_window (GdkWindow *window)
+{
+  gboolean ret = FALSE;
+  GDBusConnection *connection;
+  GError *error = NULL;
+  guint xid;
+  gchar *icc_profile = NULL;
+  GVariant *args = NULL;
+  GVariant *response = NULL;
+  GVariant *response_child = NULL;
+  GVariantIter *iter = NULL;
+
+  /* get a session bus connection */
+  connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
+  if (connection == NULL)
+    {
+      g_debug ("Failed to connect to session bus: %s", error->message);
+      g_error_free (error);
+      goto out;
+    }
+
+  /* get color profile */
+  xid = GDK_WINDOW_XID (window);
+  args = g_variant_new ("(u)", xid),
+  response = g_dbus_connection_call_sync (connection,
+                                          "org.gnome.ColorManager",
+                                          "/org/gnome/ColorManager",
+                                          "org.gnome.ColorManager",
+                                          "GetProfileForWindow",
+                                          args,
+                                          G_VARIANT_TYPE ("(s)"),
+                                          G_DBUS_CALL_FLAGS_NONE,
+                                          -1, NULL, &error);
+  if (response == NULL)
+    {
+      /* not a warning, as GCM might not be installed / running */
+      g_debug ("The GetProfileForWindow request failed: %s",
+               error->message);
+      g_error_free (error);
+      goto out;
+    }
+
+  /* get icc profile filename */
+  response_child = g_variant_get_child_value (response, 0);
+  icc_profile = g_variant_dup_string (response_child, NULL);
+out:
+  if (iter != NULL)
+    g_variant_iter_free (iter);
+  if (args != NULL)
+    g_variant_unref (args);
+  if (response != NULL)
+    g_variant_unref (response);
+  return icc_profile;
+}
+
 static void
 finish_prepare_screenshot (char *initial_uri, GdkWindow *window, GdkRectangle *rectangle)
 {  
+  char *icc_profile_filename;
+  guchar *icc_profile;
+  gsize icc_profile_size;
+  char *icc_profile_base64;
+  gboolean ret;
+  GError *error = NULL;
+
   ScreenshotDialog *dialog;
 
   /* always disable window border for full-desktop or selected-area screenshots */
@@ -845,6 +910,36 @@ finish_prepare_screenshot (char *initial_uri, GdkWindow *window, GdkRectangle *r
   dialog = screenshot_dialog_new (screenshot, initial_uri, take_window_shot);
   g_free (initial_uri);
 
+  /* load ICC profile */
+  if (include_icc_profile)
+    {
+      icc_profile_filename = get_profile_for_window (window);
+      if (icc_profile_filename != NULL)
+        {
+          ret = g_file_get_contents (icc_profile_filename,
+                                     (gchar **) &icc_profile,
+                                     &icc_profile_size,
+                                     &error);
+          if (ret)
+            {
+              icc_profile_base64 = g_base64_encode (icc_profile,
+                                                    icc_profile_size);
+
+              /* use this profile for saving the image */
+              screenshot_set_icc_profile (icc_profile_base64);
+              g_free (icc_profile);
+              g_free (icc_profile_base64);
+            }
+          else
+            {
+              g_warning ("could not open ICC file: %s",
+                         error->message);
+              g_error_free (error);
+            }
+          g_free (icc_profile_filename);
+        }
+    }
+
   screenshot_save_start (screenshot, save_done_notification, dialog);
 
   run_dialog (dialog);
@@ -1185,6 +1280,9 @@ load_options (void)
   include_border = g_settings_get_boolean (settings,
                                            INCLUDE_BORDER_KEY);
 
+  include_icc_profile = g_settings_get_boolean (settings,
+                                                INCLUDE_ICC_PROFILE);
+
   include_pointer = g_settings_get_boolean (settings,
                                             INCLUDE_POINTER_KEY);
 
@@ -1203,6 +1301,8 @@ save_options (void)
                           INCLUDE_BORDER_KEY, include_border);
   g_settings_set_boolean (settings,
                           INCLUDE_POINTER_KEY, include_pointer);
+  g_settings_set_boolean (settings,
+                          INCLUDE_ICC_PROFILE, include_icc_profile);
   g_settings_set_int (settings, DELAY_KEY, delay);
   g_settings_set_string (settings,
                          BORDER_EFFECT_KEY, border_effect);
diff --git a/gnome-screenshot/org.gnome.gnome-screenshot.gschema.xml.in b/gnome-screenshot/org.gnome.gnome-screenshot.gschema.xml.in
index 90311b1..ad844f9 100644
--- a/gnome-screenshot/org.gnome.gnome-screenshot.gschema.xml.in
+++ b/gnome-screenshot/org.gnome.gnome-screenshot.gschema.xml.in
@@ -25,6 +25,11 @@
       <_summary>Include Pointer</_summary>
       <_description>Include the pointer in the screenshot</_description>
     </key>
+    <key name="include-icc-profile" type="b">
+      <default>true</default>
+      <_summary>Include ICC Profile</_summary>
+      <_description>Include the ICC profile of the target in the screenshot file</_description>
+    </key>
     <key name="border-effect" type="s">
       <default>'none'</default>
       <_summary>Border Effect</_summary>
diff --git a/gnome-screenshot/screenshot-save.c b/gnome-screenshot/screenshot-save.c
index 513ce5f..fa0b016 100644
--- a/gnome-screenshot/screenshot-save.c
+++ b/gnome-screenshot/screenshot-save.c
@@ -29,10 +29,18 @@
 
 static char *parent_dir = NULL;
 static char *tmp_filename = NULL;
+static char *icc_profile_base64 = NULL;
 
 static SaveFunction save_callback = NULL;
 static gpointer save_user_data = NULL;
 
+void
+screenshot_set_icc_profile (const gchar *icc_profile)
+{
+  icc_profile_base64 = g_strdup (icc_profile);
+}
+
+
 /* Strategy for saving:
  *
  * We keep another process around to handle saving the image.  This is
@@ -74,6 +82,7 @@ clean_up_temporary_dir (gboolean gui_on_error)
       g_free (message);
     }
   g_free (tmp_filename);
+  g_free (icc_profile_base64);
   g_free (parent_dir);
 }
 
@@ -182,6 +191,7 @@ screenshot_save_start (GdkPixbuf    *pixbuf,
 		       gpointer      user_data)
 {
   GPid pid;
+  gboolean ret;
   int parent_exit_notification[2];
   int pipe_from_child[2];
 
@@ -210,10 +220,23 @@ screenshot_save_start (GdkPixbuf    *pixbuf,
       close (parent_exit_notification [1]);
       close (pipe_from_child [0]);
 
-      if (! gdk_pixbuf_save (pixbuf, tmp_filename,
-			     "png", &error,
-			     "tEXt::Software", "gnome-screenshot",
-			     NULL))
+      if (icc_profile_base64 != NULL)
+        {
+          ret = gdk_pixbuf_save (pixbuf, tmp_filename,
+                                 "png", &error,
+                                 "icc-profile", icc_profile_base64,
+                                 "tEXt::Software", "gnome-screenshot",
+                                 NULL);
+        }
+      else
+        {
+          ret = gdk_pixbuf_save (pixbuf, tmp_filename,
+                                 "png", &error,
+                                 "tEXt::Software", "gnome-screenshot",
+                                 NULL);
+        }
+
+      if (!ret)
 	{
 	  if (error && error->message)
 	    write (pipe_from_child[1],
diff --git a/gnome-screenshot/screenshot-save.h b/gnome-screenshot/screenshot-save.h
index 925c66f..efa53b4 100644
--- a/gnome-screenshot/screenshot-save.h
+++ b/gnome-screenshot/screenshot-save.h
@@ -28,6 +28,7 @@ void        screenshot_save_start        (GdkPixbuf    *pixbuf,
 					  SaveFunction  callback,
 					  gpointer      user_data);
 const char *screenshot_save_get_filename (void);
+void        screenshot_set_icc_profile   (const gchar  *icc_profile);
 gchar      *screenshot_sanitize_filename (const char   *filename);
 
 



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