support X11 screen profile
authorVladimir Nadvornik <nadvornik@suse.cz>
Mon, 13 Apr 2009 10:55:49 +0000 (10:55 +0000)
committerVladimir Nadvornik <nadvornik@suse.cz>
Mon, 13 Apr 2009 10:55:49 +0000 (10:55 +0000)
http://freedesktop.org/wiki/ICC_Profiles_in_X_Specification_0.3

12 files changed:
src/color-man.c
src/color-man.h
src/image.c
src/image.h
src/layout_image.c
src/layout_image.h
src/layout_util.c
src/options.c
src/options.h
src/preferences.c
src/rcfile.c
src/typedefs.h

index 54ea188..9ca83e0 100644 (file)
@@ -136,6 +136,7 @@ static cmsHPROFILE color_man_cache_load_profile(ColorManProfileType type, const
 static ColorManCache *color_man_cache_new(ColorManProfileType in_type, const gchar *in_file,
                                          guchar *in_data, guint in_data_len,
                                          ColorManProfileType out_type, const gchar *out_file,
+                                         guchar *out_data, guint out_data_len,
                                          gboolean has_alpha)
 {
        ColorManCache *cc;
@@ -156,7 +157,7 @@ static ColorManCache *color_man_cache_new(ColorManProfileType in_type, const gch
        cc->profile_in = color_man_cache_load_profile(cc->profile_in_type, cc->profile_in_file,
                                                      in_data, in_data_len);
        cc->profile_out = color_man_cache_load_profile(cc->profile_out_type, cc->profile_out_file,
-                                                      NULL, 0);
+                                                      out_data, out_data_len);
 
        if (!cc->profile_in || !cc->profile_out)
                {
@@ -183,7 +184,7 @@ static ColorManCache *color_man_cache_new(ColorManProfileType in_type, const gch
                return NULL;
                }
 
-       if (cc->profile_in_type != COLOR_PROFILE_MEM)
+       if (cc->profile_in_type != COLOR_PROFILE_MEM && cc->profile_out_type != COLOR_PROFILE_MEM )
                {
                cm_cache_list = g_list_append(cm_cache_list, cc);
                color_man_cache_ref(cc);
@@ -253,6 +254,7 @@ static ColorManCache *color_man_cache_find(ColorManProfileType in_type, const gc
 static ColorManCache *color_man_cache_get(ColorManProfileType in_type, const gchar *in_file,
                                          guchar *in_data, guint in_data_len,
                                          ColorManProfileType out_type, const gchar *out_file,
+                                         guchar *out_data, guint out_data_len,
                                          gboolean has_alpha)
 {
        ColorManCache *cc;
@@ -265,7 +267,7 @@ static ColorManCache *color_man_cache_get(ColorManProfileType in_type, const gch
                }
 
        return color_man_cache_new(in_type, in_file, in_data, in_data_len,
-                                  out_type, out_file, has_alpha);
+                                  out_type, out_file, out_data, out_data_len, has_alpha);
 }
 
 
@@ -357,7 +359,8 @@ static gboolean color_man_idle_cb(gpointer data)
 static ColorMan *color_man_new_real(ImageWindow *imd, GdkPixbuf *pixbuf,
                                    ColorManProfileType input_type, const gchar *input_file,
                                    guchar *input_data, guint input_data_len,
-                                   ColorManProfileType screen_type, const gchar *screen_file)
+                                   ColorManProfileType screen_type, const gchar *screen_file,
+                                   guchar *screen_data, guint screen_data_len)
 {
        ColorMan *cm;
        gboolean has_alpha;
@@ -372,7 +375,7 @@ static ColorMan *color_man_new_real(ImageWindow *imd, GdkPixbuf *pixbuf,
        has_alpha = pixbuf ? gdk_pixbuf_get_has_alpha(pixbuf) : FALSE;
 
        cm->profile = color_man_cache_get(input_type, input_file, input_data, input_data_len,
-                                         screen_type, screen_file, has_alpha);
+                                         screen_type, screen_file, screen_data, screen_data_len, has_alpha);
        if (!cm->profile)
                {
                color_man_free(cm);
@@ -384,11 +387,12 @@ static ColorMan *color_man_new_real(ImageWindow *imd, GdkPixbuf *pixbuf,
 
 ColorMan *color_man_new(ImageWindow *imd, GdkPixbuf *pixbuf,
                        ColorManProfileType input_type, const gchar *input_file,
-                       ColorManProfileType screen_type, const gchar *screen_file)
+                       ColorManProfileType screen_type, const gchar *screen_file,
+                       guchar *screen_data, guint screen_data_len)
 {
        return color_man_new_real(imd, pixbuf,
                                  input_type, input_file, NULL, 0,
-                                 screen_type, screen_file);
+                                 screen_type, screen_file, screen_data, screen_data_len);
 }
 
 void color_man_start_bg(ColorMan *cm, ColorManDoneFunc done_func, gpointer done_data)
@@ -400,11 +404,12 @@ void color_man_start_bg(ColorMan *cm, ColorManDoneFunc done_func, gpointer done_
 
 ColorMan *color_man_new_embedded(ImageWindow *imd, GdkPixbuf *pixbuf,
                                 guchar *input_data, guint input_data_len,
-                                ColorManProfileType screen_type, const gchar *screen_file)
+                                ColorManProfileType screen_type, const gchar *screen_file,
+                                guchar *screen_data, guint screen_data_len)
 {
        return color_man_new_real(imd, pixbuf,
                                  COLOR_PROFILE_MEM, NULL, input_data, input_data_len,
-                                 screen_type, screen_file);
+                                 screen_type, screen_file, screen_data, screen_data_len);
 }
 
 void color_man_free(ColorMan *cm)
@@ -430,7 +435,8 @@ void color_man_update(void)
 
 ColorMan *color_man_new(ImageWindow *imd, GdkPixbuf *pixbuf,
                        ColorManProfileType input_type, const gchar *input_file,
-                       ColorManProfileType screen_type, const gchar *screen_file)
+                       ColorManProfileType screen_type, const gchar *screen_file,
+                       guchar *screen_data, guint screen_data_len)
 {
        /* no op */
        return NULL;
@@ -438,7 +444,8 @@ ColorMan *color_man_new(ImageWindow *imd, GdkPixbuf *pixbuf,
 
 ColorMan *color_man_new_embedded(ImageWindow *imd, GdkPixbuf *pixbuf,
                                 guchar *input_data, guint input_data_len,
-                                ColorManProfileType screen_type, const gchar *screen_file)
+                                ColorManProfileType screen_type, const gchar *screen_file,
+                                guchar *screen_data, guint screen_data_len)
 {
        /* no op */
        return NULL;
index 5ff4be7..7c8cb5a 100644 (file)
@@ -49,10 +49,12 @@ struct _ColorMan {
 
 ColorMan *color_man_new(ImageWindow *imd, GdkPixbuf *pixbuf,
                        ColorManProfileType input_type, const gchar *input_file,
-                       ColorManProfileType screen_type, const gchar *screen_file);
+                       ColorManProfileType screen_type, const gchar *screen_file,
+                       guchar *screen_data, guint screen_data_len);
 ColorMan *color_man_new_embedded(ImageWindow *imd, GdkPixbuf *pixbuf,
                                 guchar *input_data, guint input_data_len,
-                                ColorManProfileType screen_type, const gchar *screen_file);
+                                ColorManProfileType screen_type, const gchar *screen_file,
+                                guchar *screen_data, guint screen_data_len);
 void color_man_free(ColorMan *cm);
 
 void color_man_update(void);
index 3adb697..4b22831 100644 (file)
@@ -188,16 +188,30 @@ static void image_update_title(ImageWindow *imd)
  * rotation, flip, etc.
  *-------------------------------------------------------------------
  */
+static gboolean image_get_x11_screen_profile(ImageWindow *imd, guchar **screen_profile, gint *screen_profile_len)
+{
+       GdkScreen *screen = gtk_widget_get_screen(imd->widget);;
+       GdkAtom    type   = GDK_NONE;
+       gint       format = 0;
+
+       return (gdk_property_get(gdk_screen_get_root_window(screen),
+                                gdk_atom_intern ("_ICC_PROFILE", FALSE),
+                                GDK_NONE,
+                                0, 64 * 1024 * 1024, FALSE,
+                                &type, &format, screen_profile_len, screen_profile) && *screen_profile_len > 0);
+}
 
 static gboolean image_post_process_color(ImageWindow *imd, gint start_row, gboolean run_in_bg)
 {
        ColorMan *cm;
        ColorManProfileType input_type;
        ColorManProfileType screen_type;
-       const gchar *input_file;
-       const gchar *screen_file;
+       const gchar *input_file = NULL;
+       const gchar *screen_file = NULL;
        guchar *profile = NULL;
        guint profile_len;
+       guchar *screen_profile = NULL;
+       gint screen_profile_len;
        ExifData *exif;
 
        if (imd->cm) return FALSE;
@@ -223,21 +237,23 @@ static gboolean image_post_process_color(ImageWindow *imd, gint start_row, gbool
                return FALSE;
                }
 
-       if (imd->color_profile_screen == 1 &&
+       if (options->color_profile.use_x11_screen_profile &&
+           image_get_x11_screen_profile(imd, &screen_profile, &screen_profile_len))
+               {
+               screen_type = COLOR_PROFILE_MEM;
+               DEBUG_1("Using X11 screen profile, length: %d", screen_profile_len);
+               }
+       if (options->color_profile.screen_file &&
            is_readable_file(options->color_profile.screen_file))
                {
                screen_type = COLOR_PROFILE_FILE;
                screen_file = options->color_profile.screen_file;
                }
-       else if (imd->color_profile_screen == 0)
+       else
                {
                screen_type = COLOR_PROFILE_SRGB;
                screen_file = NULL;
                }
-       else
-               {
-               return FALSE;
-               }
 
 
        imd->color_profile_from_image = COLOR_PROFILE_NONE;
@@ -310,14 +326,14 @@ static gboolean image_post_process_color(ImageWindow *imd, gint start_row, gbool
                {
                cm = color_man_new_embedded(run_in_bg ? imd : NULL, NULL,
                                            profile, profile_len,
-                                           screen_type, screen_file);
+                                           screen_type, screen_file, screen_profile, screen_profile_len);
                g_free(profile);
                }
        else
                {
                cm = color_man_new(run_in_bg ? imd : NULL, NULL,
                                   input_type, input_file,
-                                  screen_type, screen_file);
+                                  screen_type, screen_file, screen_profile, screen_profile_len);
                }
 
        if (cm)
@@ -1170,7 +1186,6 @@ void image_change_from_image(ImageWindow *imd, ImageWindow *source)
 
        imd->color_profile_enable = source->color_profile_enable;
        imd->color_profile_input = source->color_profile_input;
-       imd->color_profile_screen = source->color_profile_screen;
        imd->color_profile_use_image = source->color_profile_use_image;
        color_man_free((ColorMan *)imd->cm);
        imd->cm = NULL;
@@ -1423,30 +1438,27 @@ void image_background_set_color(ImageWindow *imd, GdkColor *color)
 }
 
 void image_color_profile_set(ImageWindow *imd,
-                            gint input_type, gint screen_type,
+                            gint input_type,
                             gboolean use_image)
 {
        if (!imd) return;
 
-       if (input_type < 0 || input_type >= COLOR_PROFILE_FILE + COLOR_PROFILE_INPUTS ||
-           screen_type < 0 || screen_type > 1)
+       if (input_type < 0 || input_type >= COLOR_PROFILE_FILE + COLOR_PROFILE_INPUTS)
                {
                return;
                }
 
        imd->color_profile_input = input_type;
-       imd->color_profile_screen = screen_type;
        imd->color_profile_use_image = use_image;
 }
 
 gboolean image_color_profile_get(ImageWindow *imd,
-                                gint *input_type, gint *screen_type,
+                                gint *input_type,
                                 gboolean *use_image)
 {
        if (!imd) return FALSE;
 
        if (input_type) *input_type = imd->color_profile_input;
-       if (screen_type) *screen_type = imd->color_profile_screen;
        if (use_image) *use_image = imd->color_profile_use_image;
 
        return TRUE;
index 7542dfc..bae7255 100644 (file)
@@ -103,10 +103,10 @@ void image_background_set_color(ImageWindow *imd, GdkColor *color);
 
 /* color profiles */
 void image_color_profile_set(ImageWindow *imd,
-                            gint input_type, gint screen_type,
+                            gint input_type,
                             gboolean use_image);
 gboolean image_color_profile_get(ImageWindow *imd,
-                            gint *input_type, gint *screen_type,
+                            gint *input_type,
                             gboolean *use_image);
 void image_color_profile_set_use(ImageWindow *imd, gboolean enable);
 gboolean image_color_profile_get_use(ImageWindow *imd);
index 23f1be4..769cc1d 100644 (file)
@@ -1059,21 +1059,21 @@ void layout_image_refresh(LayoutWindow *lw)
 }
 
 void layout_image_color_profile_set(LayoutWindow *lw,
-                                   gint input_type, gint screen_type,
+                                   gint input_type,
                                    gboolean use_image)
 {
        if (!layout_valid(&lw)) return;
 
-       image_color_profile_set(lw->image, input_type, screen_type, use_image);
+       image_color_profile_set(lw->image, input_type, use_image);
 }
 
 gboolean layout_image_color_profile_get(LayoutWindow *lw,
-                                       gint *input_type, gint *screen_type,
+                                       gint *input_type,
                                        gboolean *use_image)
 {
        if (!layout_valid(&lw)) return FALSE;
 
-       return image_color_profile_get(lw->image, input_type, screen_type, use_image);
+       return image_color_profile_get(lw->image, input_type, use_image);
 }
 
 void layout_image_color_profile_set_use(LayoutWindow *lw, gboolean enable)
@@ -1607,7 +1607,6 @@ GtkWidget *layout_image_new(LayoutWindow *lw, gint i)
                layout_image_dnd_init(lw, i);
                image_color_profile_set(lw->split_images[i],
                                        options->color_profile.input_type,
-                                       options->color_profile.screen_type,
                                        options->color_profile.use_image);
                image_color_profile_set_use(lw->split_images[i], options->color_profile.enabled);
 
index 0589871..06f0221 100644 (file)
@@ -29,10 +29,10 @@ void layout_image_set_collection(LayoutWindow *lw, CollectionData *cd, CollectIn
 void layout_image_refresh(LayoutWindow *lw);
 
 void layout_image_color_profile_set(LayoutWindow *lw,
-                                   gint input_type, gint screen_type,
+                                   gint input_type,
                                    gboolean use_image);
 gboolean layout_image_color_profile_get(LayoutWindow *lw,
-                                   gint *input_type, gint *screen_type,
+                                   gint *input_type,
                                    gboolean *use_image);
 void layout_image_color_profile_set_use(LayoutWindow *lw, gint enable);
 gboolean layout_image_color_profile_get_use(LayoutWindow *lw);
index 0e3f34d..ff592c0 100644 (file)
@@ -1059,11 +1059,11 @@ static void layout_color_menu_use_image_cb(GtkToggleAction *action, gpointer dat
 {
 #ifdef HAVE_LCMS
        LayoutWindow *lw = data;
-       gint input, screen;
+       gint input;
        gboolean use_image;
 
-       if (!layout_image_color_profile_get(lw, &input, &screen, &use_image)) return;
-       layout_image_color_profile_set(lw, input, screen, gtk_toggle_action_get_active(action));
+       if (!layout_image_color_profile_get(lw, &input, &use_image)) return;
+       layout_image_color_profile_set(lw, input, gtk_toggle_action_get_active(action));
        layout_util_sync_color(lw);
        layout_image_refresh(lw);
 #endif
@@ -1074,16 +1074,16 @@ static void layout_color_menu_input_cb(GtkRadioAction *action, GtkRadioAction *c
 #ifdef HAVE_LCMS
        LayoutWindow *lw = data;
        gint type;
-       gint input, screen;
+       gint input;
        gboolean use_image;
 
        type = gtk_radio_action_get_current_value(action);
        if (type < 0 || type >= COLOR_PROFILE_FILE + COLOR_PROFILE_INPUTS) return;
 
-       if (!layout_image_color_profile_get(lw, &input, &screen, &use_image)) return;
+       if (!layout_image_color_profile_get(lw, &input, &use_image)) return;
        if (type == input) return;
 
-       layout_image_color_profile_set(lw, type, screen, use_image);
+       layout_image_color_profile_set(lw, type, use_image);
        layout_image_refresh(lw);
 #endif
 }
@@ -2071,14 +2071,13 @@ static void layout_util_sync_color(LayoutWindow *lw)
 {
        GtkAction *action;
        gint input = 0;
-       gint screen = 0;
        gboolean use_color;
        gboolean use_image = FALSE;
        gint i;
        gchar action_name[15];
 
        if (!lw->action_group) return;
-       if (!layout_image_color_profile_get(lw, &input, &screen, &use_image)) return;
+       if (!layout_image_color_profile_get(lw, &input, &use_image)) return;
        
        use_color = layout_image_color_profile_get_use(lw);
 
index 9705e5c..bbdd033 100644 (file)
@@ -33,8 +33,8 @@ ConfOptions *init_options(ConfOptions *options)
        options->color_profile.enabled = TRUE;
        options->color_profile.input_type = 0;
        options->color_profile.screen_file = NULL;
-       options->color_profile.screen_type = 0;
        options->color_profile.use_image = TRUE;
+       options->color_profile.use_x11_screen_profile = TRUE;
 
        options->dnd_icon_size = 48;
        options->duplicates_similarity_threshold = 99;
@@ -223,7 +223,6 @@ static void sync_options_with_current_state(ConfOptions *options)
                options->color_profile.enabled = layout_image_color_profile_get_use(lw);
                layout_image_color_profile_get(lw,
                                               &options->color_profile.input_type,
-                                              &options->color_profile.screen_type,
                                               &options->color_profile.use_image);
                }
 
index 2fceb1e..54a54a7 100644 (file)
@@ -146,9 +146,9 @@ struct _ConfOptions
                gint input_type;
                gchar *input_file[COLOR_PROFILE_INPUTS];
                gchar *input_name[COLOR_PROFILE_INPUTS];
-               gint screen_type;
                gchar *screen_file;
                gboolean use_image;
+               gboolean use_x11_screen_profile;
 
        } color_profile;
 
index f7c738d..02045a0 100644 (file)
@@ -337,6 +337,7 @@ static void config_window_apply(void)
                config_entry_to_option(color_profile_input_file_entry[i], &options->color_profile.input_file[i], NULL);
                }
        config_entry_to_option(color_profile_screen_file_entry, &options->color_profile.screen_file, NULL);
+       options->color_profile.use_x11_screen_profile = c_options->color_profile.use_x11_screen_profile;
 #endif
 
 #if 0
@@ -1382,12 +1383,12 @@ static void config_tab_color(GtkWidget *notebook)
 
        vbox = scrolled_notebook_page(notebook, _("Color management"));
 
-       group =  pref_group_new(vbox, FALSE, _("Color profiles"), GTK_ORIENTATION_VERTICAL);
+       group =  pref_group_new(vbox, FALSE, _("Input profiles"), GTK_ORIENTATION_VERTICAL);
 #ifndef HAVE_LCMS
        gtk_widget_set_sensitive(pref_group_parent(group), FALSE);
 #endif
 
-       table = pref_table_new(group, 3, COLOR_PROFILE_INPUTS + 2, FALSE, FALSE);
+       table = pref_table_new(group, 3, COLOR_PROFILE_INPUTS + 1, FALSE, FALSE);
        gtk_table_set_col_spacings(GTK_TABLE(table), PREF_PAD_GAP);
 
        label = pref_table_label(table, 0, 0, _("Type"), 0.0);
@@ -1429,13 +1430,22 @@ static void config_tab_color(GtkWidget *notebook)
                color_profile_input_file_entry[i] = entry;
                }
 
-       pref_table_label(table, 0, COLOR_PROFILE_INPUTS + 1, _("Screen:"), 1.0);
+       group =  pref_group_new(vbox, FALSE, _("Screen profile"), GTK_ORIENTATION_VERTICAL);
+#ifndef HAVE_LCMS
+       gtk_widget_set_sensitive(pref_group_parent(group), FALSE);
+#endif
+       pref_checkbox_new_int(group, _("Use system screen profile if available"),
+                             options->color_profile.use_x11_screen_profile, &c_options->color_profile.use_x11_screen_profile);
+
+       table = pref_table_new(group, 2, 1, FALSE, FALSE);
+
+       pref_table_label(table, 0, 0, _("Screen:"), 1.0);
        tabcomp = tab_completion_new(&color_profile_screen_file_entry,
                                     options->color_profile.screen_file, NULL, NULL);
        tab_completion_add_select_button(color_profile_screen_file_entry, _("Select color profile"), FALSE);
        gtk_widget_set_size_request(color_profile_screen_file_entry, 160, -1);
-       gtk_table_attach(GTK_TABLE(table), tabcomp, 2, 3,
-                        COLOR_PROFILE_INPUTS + 1, COLOR_PROFILE_INPUTS + 2,
+       gtk_table_attach(GTK_TABLE(table), tabcomp, 1, 2,
+                        0, 1,
                         GTK_FILL | GTK_EXPAND, 0, 0, 0);
        gtk_widget_show(tabcomp);
 }
index c7f6d68..b8b3593 100644 (file)
@@ -450,11 +450,11 @@ static void write_color_profile(GString *outstr, gint indent)
 #endif
 
        WRITE_NL(); WRITE_STRING("<color_profiles ");
-       WRITE_INT(options->color_profile, screen_type);
        WRITE_CHAR(options->color_profile, screen_file);
        WRITE_BOOL(options->color_profile, enabled);
        WRITE_BOOL(options->color_profile, use_image);
        WRITE_INT(options->color_profile, input_type);
+       WRITE_BOOL(options->color_profile, use_x11_screen_profile);
        WRITE_STRING(">");
 
        indent++;
@@ -714,8 +714,8 @@ static void options_load_color_profiles(GQParserData *parser_data, GMarkupParseC
                if (READ_BOOL(options->color_profile, enabled)) continue;
                if (READ_BOOL(options->color_profile, use_image)) continue;
                if (READ_INT(options->color_profile, input_type)) continue;
-               if (READ_INT(options->color_profile, screen_type)) continue;
                if (READ_CHAR(options->color_profile, screen_file)) continue;
+               if (READ_BOOL(options->color_profile, use_x11_screen_profile)) continue;
 
                log_printf("unknown attribute %s = %s\n", option, value);
                }
index f1cf613..110198a 100644 (file)
@@ -418,7 +418,6 @@ struct _ImageWindow
        /* color profiles */
        gboolean color_profile_enable;
        gint color_profile_input;
-       gint color_profile_screen;
        gboolean color_profile_use_image;
        gint color_profile_from_image;
        gpointer cm;