int main(int argc, char** argv) { #if defined(SK_BUILD_FOR_MAC) CGColorSpaceRef cs = CGDisplayCopyColorSpace(CGMainDisplayID()); CFDataRef dataRef = CGColorSpaceCopyICCProfile(cs); const uint8_t* data = CFDataGetBytePtr(dataRef); size_t size = CFDataGetLength(dataRef); SkFILEWStream file("monitor_0.icc"); file.write(data, size); CFRelease(cs); CFRelease(dataRef); return 0; #elif defined(SK_BUILD_FOR_WIN) DISPLAY_DEVICE dd = { sizeof(DISPLAY_DEVICE) }; SkString outputFilename; // Chrome's code for this currently just gets the primary monitor's profile. This code iterates // over all attached monitors, so it's "better" in that sense. Making intelligent use of this // information (via things like MonitorFromWindow or MonitorFromRect to pick the correct // profile for a particular window or region of a window), is an exercise left to the reader. for (int i = 0; EnumDisplayDevices(NULL, i, &dd, 0); ++i) { if (dd.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) { // There are other helpful things in dd at this point: // dd.DeviceString has a longer name for the adapter // dd.StateFlags indicates primary display, mirroring, etc... HDC dc = CreateDC(NULL, dd.DeviceName, NULL, NULL); if (dc) { char icmPath[MAX_PATH + 1]; DWORD pathLength = MAX_PATH; if (GetICMProfile(dc, &pathLength, icmPath)) { // GetICMProfile just returns the path to the installed profile (not the data) outputFilename = SkStringPrintf("monitor_%d.icc", i); CopyFile(icmPath, outputFilename.c_str(), FALSE); } DeleteDC(dc); } } } return 0; #else SkDebugf("ERROR: Unsupported platform\n"); return 1; #endif }
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 { CGColorSpaceRef space = NULL; space = CGDisplayCopyColorSpace (monitor); if (space) { CFDataRef data; data = CGColorSpaceCopyICCProfile (space); 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 (buffer, CFDataGetLength (data), NULL); g_free (buffer); CFRelease (data); } CFRelease (space); } } #elif defined G_OS_WIN32 { HDC hdc = GetDC (NULL); if (hdc) { gchar *path; gint32 len = 0; GetICMProfile (hdc, (LPDWORD) &len, NULL); path = g_new (gchar, len); if (GetICMProfile (hdc, (LPDWORD) &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; }