OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 /* |
| 6 * Copyright (C) 2010 Google Inc. All rights reserved. |
| 7 * Copyright (C) 2012 Apple Inc. |
| 8 * |
| 9 * Redistribution and use in source and binary forms, with or without |
| 10 * modification, are permitted provided that the following conditions are |
| 11 * met: |
| 12 * |
| 13 * * Redistributions of source code must retain the above copyright |
| 14 * notice, this list of conditions and the following disclaimer. |
| 15 * * Redistributions in binary form must reproduce the above |
| 16 * copyright notice, this list of conditions and the following disclaimer |
| 17 * in the documentation and/or other materials provided with the |
| 18 * distribution. |
| 19 * * Neither the name of Google Inc. nor the names of its |
| 20 * contributors may be used to endorse or promote products derived from |
| 21 * this software without specific prior written permission. |
| 22 * |
| 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 27 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 29 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 33 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 34 */ |
| 35 |
| 36 #import <AvailabilityMacros.h> |
| 37 #import <AppKit/AppKit.h> |
| 38 #include <signal.h> |
| 39 #include <stdio.h> |
| 40 #include <stdlib.h> |
| 41 |
| 42 // This is a simple helper app that changes the color sync profile to the |
| 43 // generic profile and back when done. This program is managed by the layout |
| 44 // test script, so it can do the job for multiple DumpRenderTree while they are |
| 45 // running layout tests. |
| 46 |
| 47 namespace { |
| 48 |
| 49 #if defined(MAC_OS_X_VERSION_10_7) && \ |
| 50 MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 |
| 51 |
| 52 CFURLRef user_color_profile_url; |
| 53 |
| 54 void InstallLayoutTestColorProfile() { |
| 55 // To make sure we get consistent colors (not dependent on the chosen color |
| 56 // space of the main display), we force the generic RGB color profile. |
| 57 // This causes a change the user can see. |
| 58 |
| 59 CFUUIDRef main_display_id = |
| 60 CGDisplayCreateUUIDFromDisplayID(CGmain_display_id()); |
| 61 |
| 62 if (!user_color_profile_url) { |
| 63 CFDictionaryRef device_info = ColorSyncDeviceCopyDeviceInfo( |
| 64 kColorSyncDisplayDeviceClass, main_display_id); |
| 65 |
| 66 if (!device_info) { |
| 67 NSLog(@"No display attached to system; not setting main display's color " |
| 68 "profile."); |
| 69 CFRelease(main_display_id); |
| 70 return; |
| 71 } |
| 72 |
| 73 CFDictionaryRef profile_info = (CFDictionaryRef)CFDictionaryGetValue( |
| 74 device_info, kColorSyncCustomProfiles); |
| 75 if (profile_info) { |
| 76 user_color_profile_url = |
| 77 (CFURLRef)CFDictionaryGetValue(profile_info, CFSTR("1")); |
| 78 CFRetain(user_color_profile_url); |
| 79 } else { |
| 80 profile_info = (CFDictionaryRef)CFDictionaryGetValue( |
| 81 device_info, kColorSyncFactoryProfiles); |
| 82 CFDictionaryRef factory_profile = |
| 83 (CFDictionaryRef)CFDictionaryGetValue(profile_info, CFSTR("1")); |
| 84 user_color_profile_url = (CFURLRef)CFDictionaryGetValue( |
| 85 factory_profile, kColorSyncDeviceProfileURL); |
| 86 CFRetain(user_color_profile_url); |
| 87 } |
| 88 |
| 89 CFRelease(device_info); |
| 90 } |
| 91 |
| 92 ColorSyncProfileRef generic_rgb_profile = |
| 93 ColorSyncProfileCreateWithName(kColorSyncGenericRGBProfile); |
| 94 CFErrorRef error; |
| 95 CFURLRef profile_url = ColorSyncProfileGetURL(generic_rgb_profile, &error); |
| 96 if (!profile_url) { |
| 97 NSLog(@"Failed to get URL of Generic RGB color profile! Many pixel tests " |
| 98 "may fail as a result. Error: %@", |
| 99 error); |
| 100 |
| 101 if (user_color_profile_url) { |
| 102 CFRelease(user_color_profile_url); |
| 103 user_color_profile_url = 0; |
| 104 } |
| 105 |
| 106 CFRelease(generic_rgb_profile); |
| 107 CFRelease(main_display_id); |
| 108 return; |
| 109 } |
| 110 |
| 111 CFMutableDictionaryRef profile_info = |
| 112 CFDictionaryCreateMutable(kCFAllocatorDefault, |
| 113 0, |
| 114 &kCFTypeDictionaryKeyCallBacks, |
| 115 &kCFTypeDictionaryValueCallBacks); |
| 116 CFDictionarySetValue( |
| 117 profile_info, kColorSyncDeviceDefaultProfileID, profile_url); |
| 118 |
| 119 if (!ColorSyncDeviceSetCustomProfiles( |
| 120 kColorSyncDisplayDeviceClass, main_display_id, profile_info)) { |
| 121 NSLog(@"Failed to set color profile for main display! Many pixel tests may " |
| 122 "fail as a result."); |
| 123 |
| 124 if (user_color_profile_url) { |
| 125 CFRelease(user_color_profile_url); |
| 126 user_color_profile_url = 0; |
| 127 } |
| 128 } |
| 129 |
| 130 CFRelease(profile_info); |
| 131 CFRelease(generic_rgb_profile); |
| 132 CFRelease(main_display_id); |
| 133 } |
| 134 |
| 135 void RestoreUserColorProfile() { |
| 136 // This is used as a signal handler, and thus the calls into ColorSync are |
| 137 // unsafe. |
| 138 // But we might as well try to restore the user's color profile, we're going |
| 139 // down anyway... |
| 140 |
| 141 if (!user_color_profile_url) |
| 142 return; |
| 143 |
| 144 CFUUIDRef main_display_id = |
| 145 CGDisplayCreateUUIDFromDisplayID(CGMainDisplayID()); |
| 146 CFMutableDictionaryRef profile_info = |
| 147 CFDictionaryCreateMutable(kCFAllocatorDefault, |
| 148 0, |
| 149 &kCFTypeDictionaryKeyCallBacks, |
| 150 &kCFTypeDictionaryValueCallBacks); |
| 151 CFDictionarySetValue( |
| 152 profile_info, kColorSyncDeviceDefaultProfileID, user_color_profile_url); |
| 153 ColorSyncDeviceSetCustomProfiles( |
| 154 kColorSyncDisplayDeviceClass, main_display_id, profile_info); |
| 155 CFRelease(main_display_id); |
| 156 CFRelease(profile_info); |
| 157 } |
| 158 |
| 159 #else // For Snow Leopard and before, use older CM* API. |
| 160 |
| 161 const char color_profile_path[] = |
| 162 "/System/Library/ColorSync/Profiles/Generic RGB Profile.icc"; |
| 163 |
| 164 // The locType field is initialized to 0 which is the same as cmNoProfileBase. |
| 165 CMProfileLocation initial_color_profile_location; |
| 166 |
| 167 void InstallLayoutTestColorProfile() { |
| 168 // To make sure we get consistent colors (not dependent on the Main display), |
| 169 // we force the generic rgb color profile. This cases a change the user can |
| 170 // see. |
| 171 const CMDeviceScope scope = {kCFPreferencesCurrentUser, |
| 172 kCFPreferencesCurrentHost}; |
| 173 |
| 174 CMProfileRef profile = 0; |
| 175 int error = |
| 176 CMGetProfileByAVID((CMDisplayIDType)kCGDirectMainDisplay, &profile); |
| 177 if (!error) { |
| 178 UInt32 size = sizeof(initial_color_profile_location); |
| 179 error = NCMGetProfileLocation(profile, &initial_color_profile_location, &siz
e); |
| 180 CMCloseProfile(profile); |
| 181 } |
| 182 if (error) { |
| 183 NSLog(@"failed to get the current color profile, pixmaps won't match. " |
| 184 "Error: %d", |
| 185 (int)error); |
| 186 initial_color_profile_location.locType = cmNoProfileBase; |
| 187 return; |
| 188 } |
| 189 |
| 190 CMProfileLocation location; |
| 191 location.locType = cmPathBasedProfile; |
| 192 strncpy(location.u.pathLoc.path, |
| 193 color_profile_path, |
| 194 sizeof(location.u.pathLoc.path)); |
| 195 error = CMSetDeviceProfile(cmDisplayDeviceClass, |
| 196 (CMDeviceID)kCGDirectMainDisplay, |
| 197 &scope, |
| 198 cmDefaultProfileID, |
| 199 &location); |
| 200 if (error) { |
| 201 NSLog(@"failed install the generic color profile, pixmaps won't match. " |
| 202 "Error: %d", |
| 203 (int)error); |
| 204 initial_color_profile_location.locType = cmNoProfileBase; |
| 205 } |
| 206 } |
| 207 |
| 208 void RestoreUserColorProfile() { |
| 209 // This is used as a signal handler, and thus the calls into ColorSync are |
| 210 // unsafe. |
| 211 // But we might as well try to restore the user's color profile, we're going |
| 212 // down anyway... |
| 213 if (initial_color_profile_location.locType != cmNoProfileBase) { |
| 214 const CMDeviceScope scope = {kCFPreferencesCurrentUser, |
| 215 kCFPreferencesCurrentHost}; |
| 216 int error = CMSetDeviceProfile(cmDisplayDeviceClass, |
| 217 (CMDeviceID)kCGDirectMainDisplay, |
| 218 &scope, |
| 219 cmDefaultProfileID, |
| 220 &initial_color_profile_location); |
| 221 if (error) { |
| 222 NSLog(@"Failed to restore color profile, use System Preferences -> " |
| 223 "Displays -> Color to reset. Error: %d", |
| 224 (int)error); |
| 225 } |
| 226 initial_color_profile_location.locType = cmNoProfileBase; |
| 227 } |
| 228 } |
| 229 |
| 230 #endif |
| 231 |
| 232 void SimpleSignalHandler(int sig) { |
| 233 // Try to restore the color profile and try to go down cleanly. |
| 234 RestoreUserColorProfile(); |
| 235 exit(128 + sig); |
| 236 } |
| 237 |
| 238 } // namespace |
| 239 |
| 240 int main(int argc, char* argv[]) { |
| 241 NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; |
| 242 |
| 243 // Hooks the ways we might get told to clean up... |
| 244 signal(SIGINT, SimpleSignalHandler); |
| 245 signal(SIGHUP, SimpleSignalHandler); |
| 246 signal(SIGTERM, SimpleSignalHandler); |
| 247 |
| 248 // Save off the current profile, and then install the layout test profile. |
| 249 InstallLayoutTestColorProfile(); |
| 250 |
| 251 // Let the script know we're ready. |
| 252 printf("ready\n"); |
| 253 fflush(stdout); |
| 254 |
| 255 // Wait for any key (or signal). |
| 256 getchar(); |
| 257 |
| 258 // Restore the profile. |
| 259 RestoreUserColorProfile(); |
| 260 |
| 261 [pool release]; |
| 262 return 0; |
| 263 } |
OLD | NEW |