Пример #1
0
// Get the display ICC profile of the monitor associated with the widget.
// For X display, uses the ICC profile specifications version 0.2 from
// http://burtonini.com/blog/computers/xicc
// Based on code from Gimp's modules/cdisplay_lcms.c
void dt_ctl_set_display_profile()
{
  if(!dt_control_running()) return;
  // make sure that no one gets a broken profile
  // FIXME: benchmark if the try is really needed when moving/resizing the window. Maybe we can just lock it and block
  if(pthread_rwlock_trywrlock(&darktable.control->xprofile_lock))
    return; // we are already updating the profile. Or someone is reading right now. Too bad we can't distinguish that. Whatever ...

  GtkWidget *widget = dt_ui_center(darktable.gui->ui);
  guint8 *buffer = NULL;
  gint buffer_size = 0;
  gchar *profile_source = NULL;

#if defined GDK_WINDOWING_X11

  // we will use the xatom no matter what configured when compiled without colord
  gboolean use_xatom = TRUE;
#if defined USE_COLORDGTK
  gboolean use_colord = TRUE;
  gchar *display_profile_source = dt_conf_get_string("ui_last/display_profile_source");
  if(display_profile_source)
  {
    if(!strcmp(display_profile_source, "xatom"))
      use_colord = FALSE;
    else if(!strcmp(display_profile_source, "colord"))
      use_xatom = FALSE;
    g_free(display_profile_source);
  }
#endif

  /* let's have a look at the xatom, just in case ... */
  if(use_xatom)
  {
    GdkScreen *screen = gtk_widget_get_screen(widget);
    if ( screen==NULL )
      screen = gdk_screen_get_default();
    int monitor = gdk_screen_get_monitor_at_window (screen, gtk_widget_get_window(widget));
    char *atom_name;
    if (monitor > 0)
      atom_name = g_strdup_printf("_ICC_PROFILE_%d", monitor);
    else
      atom_name = g_strdup("_ICC_PROFILE");

    profile_source = g_strdup_printf("xatom %s", atom_name);

    GdkAtom type = GDK_NONE;
    gint format = 0;
    gdk_property_get(gdk_screen_get_root_window(screen),
                    gdk_atom_intern(atom_name, FALSE), GDK_NONE,
                    0, 64 * 1024 * 1024, FALSE,
                    &type, &format, &buffer_size, &buffer);
    g_free(atom_name);
  }

#ifdef USE_COLORDGTK
  /* also try to get the profile from colord. this will set the value asynchronously! */
  if(use_colord)
  {
    CdWindow *window = cd_window_new();
    GtkWidget *center_widget = dt_ui_center(darktable.gui->ui);
    cd_window_get_profile(window, center_widget, NULL, dt_ctl_get_display_profile_colord_callback, NULL);
  }
#endif

#elif defined GDK_WINDOWING_QUARTZ
  GdkScreen *screen = gtk_widget_get_screen(widget);
  if ( screen==NULL )
    screen = gdk_screen_get_default();
  int monitor = gdk_screen_get_monitor_at_window(screen, gtk_widget_get_window(widget));

  CGDirectDisplayID ids[monitor + 1];
  uint32_t total_ids;
  CMProfileRef prof = NULL;
  if(CGGetOnlineDisplayList(monitor + 1, &ids[0], &total_ids) == kCGErrorSuccess && total_ids == monitor + 1)
    CMGetProfileByAVID(ids[monitor], &prof);
  if ( prof!=NULL )
  {
    CFDataRef data;
    data = CMProfileCopyICCData(NULL, prof);
    CMCloseProfile(prof);

    UInt8 *tmp_buffer = (UInt8 *) g_malloc(CFDataGetLength(data));
    CFDataGetBytes(data, CFRangeMake(0, CFDataGetLength(data)), tmp_buffer);

    buffer = (guint8 *) tmp_buffer;
    buffer_size = CFDataGetLength(data);

    CFRelease(data);
  }
  profile_source = g_strdup("osx color profile api");
#elif defined G_OS_WIN32
  (void)widget;
  HDC hdc = GetDC (NULL);
  if ( hdc!=NULL )
  {
    DWORD len = 0;
    GetICMProfile (hdc, &len, NULL);
    gchar *path = g_new (gchar, len);

    if (GetICMProfile (hdc, &len, path))
    {
      gsize size;
      g_file_get_contents(path, (gchar**)&buffer, &size, NULL);
      buffer_size = size;
    }
    g_free (path);
    ReleaseDC (NULL, hdc);
  }
  profile_source = g_strdup("windows color profile api");
#endif

  int profile_changed = buffer_size > 0 &&
                        (darktable.control->xprofile_size != buffer_size || memcmp(darktable.control->xprofile_data, buffer, buffer_size) != 0);
  if(profile_changed)
  {
    cmsHPROFILE profile = NULL;
    char name[512];
    // thanks to ufraw for this!
    g_free(darktable.control->xprofile_data);
    darktable.control->xprofile_data = buffer;
    darktable.control->xprofile_size = buffer_size;
    profile = cmsOpenProfileFromMem(buffer, buffer_size);
    if(profile)
    {
      dt_colorspaces_get_profile_name(profile, "en", "US", name, sizeof(name));
      cmsCloseProfile(profile);
    }
    dt_print(DT_DEBUG_CONTROL, "[color profile] we got a new screen profile `%s' from the %s (size: %d)\n", *name?name:"(unknown)", profile_source, buffer_size);
  }
  pthread_rwlock_unlock(&darktable.control->xprofile_lock);
  if(profile_changed)
    dt_control_signal_raise(darktable.signals, DT_SIGNAL_CONTROL_PROFILE_CHANGED);
  g_free(profile_source);
}
Пример #2
0
GimpColorProfile *
gimp_widget_get_color_profile (GtkWidget *widget)
{
    GimpColorProfile *profile = NULL;
    GdkScreen        *screen;
    gint              monitor;

    g_return_val_if_fail (widget == NULL || GTK_IS_WIDGET (widget), NULL);

    if (widget)
    {
        screen  = gtk_widget_get_screen (widget);
        monitor = gimp_widget_get_monitor (widget);
    }
    else
    {
        screen  = gdk_screen_get_default ();
        monitor = 0;
    }

#if defined GDK_WINDOWING_X11
    {
        GdkAtom  type    = GDK_NONE;
        gint     format  = 0;
        gint     nitems  = 0;
        gchar   *atom_name;
        guchar  *data    = NULL;

        if (monitor > 0)
            atom_name = g_strdup_printf ("_ICC_PROFILE_%d", monitor);
        else
            atom_name = g_strdup ("_ICC_PROFILE");

        if (gdk_property_get (gdk_screen_get_root_window (screen),
                              gdk_atom_intern (atom_name, FALSE),
                              GDK_NONE,
                              0, 64 * 1024 * 1024, FALSE,
                              &type, &format, &nitems, &data) && nitems > 0)
        {
            profile = gimp_color_profile_new_from_icc_profile (data, nitems,
                      NULL);
            g_free (data);
        }

        g_free (atom_name);
    }
#elif defined GDK_WINDOWING_QUARTZ
    {
        CMProfileRef prof = NULL;

        CMGetProfileByAVID (monitor, &prof);

        if (prof)
        {
            CFDataRef data;

            data = CMProfileCopyICCData (NULL, prof);
            CMCloseProfile (prof);

            if (data)
            {
                UInt8 *buffer = g_malloc (CFDataGetLength (data));

                /* We cannot use CFDataGetBytesPtr(), because that returns
                 * a const pointer where cmsOpenProfileFromMem wants a
                 * non-const pointer.
                 */
                CFDataGetBytes (data, CFRangeMake (0, CFDataGetLength (data)),
                                buffer);

                profile = gimp_color_profile_new_from_icc_profile (data,
                          CFDataGetLength (data),
                          NULL);

                g_free (buffer);
                CFRelease (data);
            }
        }
    }
#elif defined G_OS_WIN32
    {
        HDC hdc = GetDC (NULL);

        if (hdc)
        {
            gchar  *path;
            gint32  len = 0;

            GetICMProfile (hdc, &len, NULL);
            path = g_new (gchar, len);

            if (GetICMProfile (hdc, &len, path))
            {
                GFile *file = g_file_new_for_path (path);

                profile = gimp_color_profile_new_from_file (file, NULL);
                g_object_unref (file);
            }

            g_free (path);
            ReleaseDC (NULL, hdc);
        }
    }
#endif

    return profile;
}
Пример #3
0
static cmsHPROFILE
cdisplay_lcms_get_display_profile (CdisplayLcms *lcms)
{
  GimpColorConfig *config;
  cmsHPROFILE      profile = NULL;

  config = gimp_color_display_get_config (GIMP_COLOR_DISPLAY (lcms));

#if defined GDK_WINDOWING_X11
  if (config->display_profile_from_gdk)
    {
      GdkScreen *screen;
      GdkAtom    type    = GDK_NONE;
      gint       format  = 0;
      gint       nitems  = 0;
      gint       monitor = 0;
      gchar     *atom_name;
      guchar    *data    = NULL;

      screen = cdisplay_lcms_get_screen (lcms, &monitor);

      if (monitor > 0)
        atom_name = g_strdup_printf ("_ICC_PROFILE_%d", monitor);
      else
        atom_name = g_strdup ("_ICC_PROFILE");

      if (gdk_property_get (gdk_screen_get_root_window (screen),
                            gdk_atom_intern (atom_name, FALSE),
                            GDK_NONE,
                            0, 64 * 1024 * 1024, FALSE,
                            &type, &format, &nitems, &data) && nitems > 0)
        {
          profile = cmsOpenProfileFromMem (data, nitems);
          g_free (data);
        }

      g_free (atom_name);
    }

#elif defined GDK_WINDOWING_QUARTZ
  if (config->display_profile_from_gdk)
    {
      CMProfileRef  prof    = NULL;
      gint          monitor = 0;

      cdisplay_lcms_get_screen (lcms, &monitor);

      CMGetProfileByAVID (monitor, &prof);

      if (prof)
        {
          CFDataRef data;

          data = CMProfileCopyICCData (NULL, prof);
          CMCloseProfile (prof);

          if (data)
            {
              UInt8 *buffer = g_malloc (CFDataGetLength (data));

              /* We cannot use CFDataGetBytesPtr(), because that returns
               * a const pointer where cmsOpenProfileFromMem wants a
               * non-const pointer.
               */
              CFDataGetBytes (data, CFRangeMake (0, CFDataGetLength (data)),
                              buffer);

              profile = cmsOpenProfileFromMem (buffer, CFDataGetLength (data));

              g_free (buffer);
              CFRelease (data);
            }
        }
    }

#elif defined G_OS_WIN32
  if (config->display_profile_from_gdk)
    {
      HDC hdc = GetDC (NULL);

      if (hdc)
        {
          gchar *path;
          gint32 len = 0;

          GetICMProfile (hdc, &len, NULL);
          path = g_new (gchar, len);

          if (GetICMProfile (hdc, &len, path))
            profile = cmsOpenProfileFromFile (path, "r");

          g_free (path);
          ReleaseDC (NULL, hdc);
        }
    }
#endif

  if (! profile && config->display_profile)
    profile = cmsOpenProfileFromFile (config->display_profile, "r");

  return profile;
}