//----------------------------------------------------------------------------- static CGColorSpaceRef CreateMainDisplayColorSpace () { #if TARGET_OS_IPHONE return CGColorSpaceCreateDeviceRGB (); #elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7 ColorSyncProfileRef csProfileRef = ColorSyncProfileCreateWithDisplayID (0); if (csProfileRef) { CGColorSpaceRef colorSpace = CGColorSpaceCreateWithPlatformColorSpace (csProfileRef); CFRelease (csProfileRef); return colorSpace; } return 0; #else CMProfileRef sysprof = NULL; // Get the Systems Profile for the main display if (CMGetSystemProfile (&sysprof) == noErr) { // Create a colorspace with the systems profile CGColorSpaceRef colorSpace = CGColorSpaceCreateWithPlatformColorSpace (sysprof); // Close the profile CMCloseProfile (sysprof); return colorSpace; } return 0; #endif }
//----------------------------------------------------------------------------- static CGColorSpaceRef CreateGenericRGBColorSpace (void) { CGColorSpaceRef colorspace = 0; CMProfileRef genericRGBProfile = OpenGenericProfile (); if (genericRGBProfile) { colorspace = CGColorSpaceCreateWithPlatformColorSpace (genericRGBProfile); // we opened the profile so it is up to us to close it CMCloseProfile (genericRGBProfile); } if (colorspace == NULL) colorspace = CGColorSpaceCreateDeviceRGB (); return colorspace; }
CGColorRef createCGColor(const Color& c) { CGColorRef color = NULL; CMProfileRef prof = NULL; CMGetSystemProfile(&prof); RetainPtr<CGColorSpaceRef> rgbSpace(AdoptCF, CGColorSpaceCreateWithPlatformColorSpace(prof)); if (rgbSpace) { CGFloat components[4] = { static_cast<CGFloat>(c.red()) / 255, static_cast<CGFloat>(c.green()) / 255, static_cast<CGFloat>(c.blue()) / 255, static_cast<CGFloat>(c.alpha()) / 255 }; color = CGColorCreate(rgbSpace.get(), components); } CMCloseProfile(prof); return color; }
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; }
Boolean MCScreenDC::close(Boolean force) { if (m_dst_profile != nil) { CMCloseProfile(m_dst_profile); m_dst_profile = nil; } if (m_srgb_profile != nil) { CMCloseProfile(m_srgb_profile); m_srgb_profile = nil; } SetApplicationDockTileMenu(NULL); ReleaseMenu(f_icon_menu); DisposeEventHandlerUPP(s_icon_menu_event_handler_upp); f_icon_menu = NULL; s_icon_menu_event_handler_upp = NULL; showmenu(); //if the menu is hidden, show it. finalisebackdrop(); DisposeRgn(mouseMoveRgn); //dispose the region crated in open() uint2 i; if (ncolors != 0) { int2 i; for (i = 0 ; i < ncolors ; i++) { if (colornames[i] != NULL) MCValueRelease(colornames[i]); } delete colors; delete colornames; delete allocs; } DisposeWindow((WindowPtr)invisibleWin); delete vis; delete mousewindow; delete activewindow; delete lastactivewindow; //TSM - closes down TSM for this app and removes appleevents AERemoveEventHandler(kTextServiceClass, kPos2Offset, TSMPositionToOffsetUPP, False); AERemoveEventHandler(kTextServiceClass, kOffset2Pos, TSMOffsetToPositionUPP, False); AERemoveEventHandler(kTextServiceClass, kUpdateActiveInputArea, TSMUpdateHandlerUPP, False); AERemoveEventHandler(kTextServiceClass, kUnicodeNotFromInputMethod, TSMUnicodeNotFromInputUPP, False); DisposeAEEventHandlerUPP(TSMPositionToOffsetUPP); DisposeAEEventHandlerUPP(TSMOffsetToPositionUPP); DisposeAEEventHandlerUPP(TSMUpdateHandlerUPP); DisposeAEEventHandlerUPP(TSMUnicodeNotFromInputUPP); closeIME(); RemoveReceiveHandler(dragdropUPP, NULL); RemoveTrackingHandler(dragmoveUPP, NULL); DisposeDragTrackingHandlerUPP(dragmoveUPP); DisposeDragReceiveHandlerUPP(dragdropUPP); opened = False; return True; }
// 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); }
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; }
OSStatus DrawPage(PrintingLogicPtr printJob,CGContextRef printingContext) { OSStatus status = noErr; Rect dstRect = { 0, 0, 0, 0 }; Rect srcRect = { 0, 0, 0, 0 }; static CGColorSpaceRef colorspace = NULL; if (colorspace == NULL) { // Get the Systems Profile for the main display CMProfileRef sysprof = NULL; if (CMGetSystemProfile(&sysprof) == noErr) { // Create a colorspace with the systems profile colorspace = CGColorSpaceCreateWithPlatformColorSpace(sysprof); CMCloseProfile(sysprof); } else colorspace = CGColorSpaceCreateDeviceRGB(); } dstRect.top = printJob->offsetHeight; dstRect.left = printJob->offsetWidth; dstRect.right = printJob->width*printJob->scaleW + printJob->offsetWidth; dstRect.bottom = printJob->height*printJob->scaleH + printJob->offsetHeight; if (printJob->formBitMap != nil) { srcRect.right = printJob->width; srcRect.bottom = printJob->height; HLock((Handle)stPixMap); (*stPixMap)->baseAddr = (void *) printJob->formBitMap; (*stPixMap)->rowBytes = (((((printJob->width * printJob->depth) + 31) / 32) * 4) & 0x1FFF) | 0x8000; (*stPixMap)->bounds = srcRect; (*stPixMap)->pixelSize = printJob->depth; if (printJob->depth<=8) { (*stPixMap)->cmpSize = printJob->depth; (*stPixMap)->cmpCount = 1; } else if (printJob->depth==16) { (*stPixMap)->cmpSize = 5; (*stPixMap)->cmpCount = 3; } else if (printJob->depth==32) { (*stPixMap)->cmpSize = 8; (*stPixMap)->cmpCount = 3; } { PixMapHandle thePix; int pitch; CGDataProviderRef provider; CGImageRef image; CGRect clip; Ptr baseAddr; if (printJob->depth == 32) { pitch = (((((printJob->width * printJob->depth) + 31) / 32) * 4) & 0x1FFF); baseAddr = (void *) printJob->formBitMap; } else { if (printJob->aGWorld == NULL) NewGWorld(&printJob->aGWorld, 32, &srcRect, stColorTable, NULL, keepLocal+useTempMem+pixelsLocked); thePix = GetGWorldPixMap (printJob->aGWorld); CopyBits((BitMap *) *stPixMap, (BitMap *) *thePix, &srcRect, &srcRect, srcCopy, NULL); pitch = GetPixRowBytes(thePix); baseAddr = GetPixBaseAddr(thePix); } provider = CGDataProviderCreateDirectAccess((void*)baseAddr, pitch * (srcRect.bottom-srcRect.top), &gProviderCallbacks); image = CGImageCreate( srcRect.right-srcRect.left, srcRect.bottom-srcRect.top, 8 /* bitsPerComponent */, 32 /* bitsPerPixel */, pitch, colorspace, kCGImageAlphaNoneSkipFirst | (printJob->depth==32 ? kCGBitmapByteOrder32Host : 0), provider, NULL, 0, kCGRenderingIntentDefault); clip = CGRectMake(dstRect.left+(printJob->pageRect.left-printJob->paperRect.left), (printJob->paperRect.bottom-printJob->pageRect.bottom) + (printJob->pageRect.bottom - printJob->pageRect.top) - (dstRect.bottom-dstRect.top) - dstRect.top, dstRect.right-dstRect.left, dstRect.bottom-dstRect.top); CGContextDrawImage(printingContext, clip, image); CGContextFlush(printingContext); CGImageRelease(image); CGDataProviderRelease(provider); } HUnlock((Handle)stPixMap); } else { } #if TARGET_API_MAC_CARBON if (printJob->allowPostscript && printJob->postscriptLength > 0) { CGDataProviderRef provider,providerFakeImage; CGImageRef image,imageFake; CGRect clip; static long dirt=0xBBBBBBBB; //PMPrinter currentPrinter = NULL; //CFArrayRef mimeTypes; //status = PMSessionGetCurrentPrinter(printJob->printSession,¤tPrinter); //status = PMPrinterGetMimeTypes(currentPrinter,printJob->printSettings,&mimeTypes); provider = CGDataProviderCreateDirectAccess((void*)printJob->postscript,printJob->postscriptLength, &gProviderCallbacks); providerFakeImage = CGDataProviderCreateDirectAccess((void*)&dirt,4, &gProviderCallbacks); //OK make fake image using tiny bit of data imageFake = CGImageCreate(1, 1, 8 /* bitsPerComponent */, 32 /* bitsPerPixel */, 4, colorspace, kCGImageAlphaNoneSkipFirst , providerFakeImage, NULL, 0, kCGRenderingIntentDefault); image = PMCGImageCreateWithEPSDataProvider(provider,imageFake); dstRect.top = 0; dstRect.left = 0; dstRect.bottom = CGImageGetHeight(image); dstRect.right = CGImageGetWidth(image); clip = CGRectMake(dstRect.left+(printJob->pageRect.left-printJob->paperRect.left), (printJob->paperRect.bottom-printJob->pageRect.bottom) + (printJob->pageRect.bottom - printJob->pageRect.top) - (dstRect.bottom-dstRect.top) - dstRect.top, dstRect.right-dstRect.left, dstRect.bottom-dstRect.top); //PMPrinterPrintWithProvider CGContextDrawImage(printingContext, clip, image); CGContextFlush(printingContext); CGImageRelease(image); CGImageRelease(imageFake); CGDataProviderRelease(provider); CGDataProviderRelease(providerFakeImage); } #else return PrError(); #endif return status; } // DrawPage
qcms_profile * gfxPlatformMac::GetPlatformCMSOutputProfile() { qcms_profile *profile = nsnull; CMProfileRef cmProfile; CMProfileLocation *location; UInt32 locationSize; /* There a number of different ways that we could try to get a color profile to use. On 10.5 all of these methods seem to give the same results. On 10.6, the results are different and the following method, using CGMainDisplayID() seems to best match what we are looking for. Currently, both Google Chrome and Qt4 use a similar method. CMTypes.h describes CMDisplayIDType: "Data type for ColorSync DisplayID reference On 8 & 9 this is a AVIDType On X this is a CGSDisplayID" CGMainDisplayID gives us a CGDirectDisplayID which presumeably corresponds directly to a CGSDisplayID */ CGDirectDisplayID displayID = CGMainDisplayID(); CMError err = CMGetProfileByAVID(static_cast<CMDisplayIDType>(displayID), &cmProfile); if (err != noErr) return nsnull; // get the size of location err = NCMGetProfileLocation(cmProfile, NULL, &locationSize); if (err != noErr) return nsnull; // allocate enough room for location location = static_cast<CMProfileLocation*>(malloc(locationSize)); if (!location) goto fail_close; err = NCMGetProfileLocation(cmProfile, location, &locationSize); if (err != noErr) goto fail_location; switch (location->locType) { #ifndef __LP64__ case cmFileBasedProfile: { FSRef fsRef; if (!FSpMakeFSRef(&location->u.fileLoc.spec, &fsRef)) { char path[512]; if (!FSRefMakePath(&fsRef, reinterpret_cast<UInt8*>(path), sizeof(path))) { profile = qcms_profile_from_path(path); #ifdef DEBUG_tor if (profile) fprintf(stderr, "ICM profile read from %s fileLoc successfully\n", path); #endif } } break; } #endif case cmPathBasedProfile: profile = qcms_profile_from_path(location->u.pathLoc.path); #ifdef DEBUG_tor if (profile) fprintf(stderr, "ICM profile read from %s pathLoc successfully\n", device.u.pathLoc.path); #endif break; default: #ifdef DEBUG_tor fprintf(stderr, "Unhandled ColorSync profile location\n"); #endif break; } fail_location: free(location); fail_close: CMCloseProfile(cmProfile); return profile; }