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 <AppKit/AppKit.h> | |
37 #import <AvailabilityMacros.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(CGMainDisplayID()); | |
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 |