Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
1 /* -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "mozilla/ArrayUtils.h"
8 #include "nscore.h"
10 #include "nsXPLookAndFeel.h"
11 #include "nsLookAndFeel.h"
12 #include "nsCRT.h"
13 #include "nsFont.h"
14 #include "nsThemeConstants.h"
15 #include "mozilla/Preferences.h"
16 #include "mozilla/gfx/2D.h"
18 #include "gfxPlatform.h"
19 #include "qcms.h"
21 #ifdef DEBUG
22 #include "nsSize.h"
23 #endif
25 using namespace mozilla;
27 nsLookAndFeelIntPref nsXPLookAndFeel::sIntPrefs[] =
28 {
29 { "ui.caretBlinkTime",
30 eIntID_CaretBlinkTime,
31 false, 0 },
32 { "ui.caretWidth",
33 eIntID_CaretWidth,
34 false, 0 },
35 { "ui.caretVisibleWithSelection",
36 eIntID_ShowCaretDuringSelection,
37 false, 0 },
38 { "ui.submenuDelay",
39 eIntID_SubmenuDelay,
40 false, 0 },
41 { "ui.dragThresholdX",
42 eIntID_DragThresholdX,
43 false, 0 },
44 { "ui.dragThresholdY",
45 eIntID_DragThresholdY,
46 false, 0 },
47 { "ui.useAccessibilityTheme",
48 eIntID_UseAccessibilityTheme,
49 false, 0 },
50 { "ui.menusCanOverlapOSBar",
51 eIntID_MenusCanOverlapOSBar,
52 false, 0 },
53 { "ui.useOverlayScrollbars",
54 eIntID_UseOverlayScrollbars,
55 false, 0 },
56 { "ui.scrollbarDisplayOnMouseMove",
57 eIntID_ScrollbarDisplayOnMouseMove,
58 false, 0 },
59 { "ui.scrollbarFadeBeginDelay",
60 eIntID_ScrollbarFadeBeginDelay,
61 false, 0 },
62 { "ui.scrollbarFadeDuration",
63 eIntID_ScrollbarFadeDuration,
64 false, 0 },
65 { "ui.showHideScrollbars",
66 eIntID_ShowHideScrollbars,
67 false, 0 },
68 { "ui.skipNavigatingDisabledMenuItem",
69 eIntID_SkipNavigatingDisabledMenuItem,
70 false, 0 },
71 { "ui.treeOpenDelay",
72 eIntID_TreeOpenDelay,
73 false, 0 },
74 { "ui.treeCloseDelay",
75 eIntID_TreeCloseDelay,
76 false, 0 },
77 { "ui.treeLazyScrollDelay",
78 eIntID_TreeLazyScrollDelay,
79 false, 0 },
80 { "ui.treeScrollDelay",
81 eIntID_TreeScrollDelay,
82 false, 0 },
83 { "ui.treeScrollLinesMax",
84 eIntID_TreeScrollLinesMax,
85 false, 0 },
86 { "accessibility.tabfocus",
87 eIntID_TabFocusModel,
88 false, 0 },
89 { "ui.alertNotificationOrigin",
90 eIntID_AlertNotificationOrigin,
91 false, 0 },
92 { "ui.scrollToClick",
93 eIntID_ScrollToClick,
94 false, 0 },
95 { "ui.IMERawInputUnderlineStyle",
96 eIntID_IMERawInputUnderlineStyle,
97 false, 0 },
98 { "ui.IMESelectedRawTextUnderlineStyle",
99 eIntID_IMESelectedRawTextUnderlineStyle,
100 false, 0 },
101 { "ui.IMEConvertedTextUnderlineStyle",
102 eIntID_IMEConvertedTextUnderlineStyle,
103 false, 0 },
104 { "ui.IMESelectedConvertedTextUnderlineStyle",
105 eIntID_IMESelectedConvertedTextUnderline,
106 false, 0 },
107 { "ui.SpellCheckerUnderlineStyle",
108 eIntID_SpellCheckerUnderlineStyle,
109 false, 0 },
110 { "ui.scrollbarButtonAutoRepeatBehavior",
111 eIntID_ScrollbarButtonAutoRepeatBehavior,
112 false, 0 },
113 { "ui.tooltipDelay",
114 eIntID_TooltipDelay,
115 false, 0 },
116 { "ui.physicalHomeButton",
117 eIntID_PhysicalHomeButton,
118 false, 0 },
119 };
121 nsLookAndFeelFloatPref nsXPLookAndFeel::sFloatPrefs[] =
122 {
123 { "ui.IMEUnderlineRelativeSize",
124 eFloatID_IMEUnderlineRelativeSize,
125 false, 0 },
126 { "ui.SpellCheckerUnderlineRelativeSize",
127 eFloatID_SpellCheckerUnderlineRelativeSize,
128 false, 0 },
129 { "ui.caretAspectRatio",
130 eFloatID_CaretAspectRatio,
131 false, 0 },
132 };
135 // This array MUST be kept in the same order as the color list in LookAndFeel.h.
136 /* XXX If you add any strings longer than
137 * "ui.IMESelectedConvertedTextBackground"
138 * to the following array then you MUST update the
139 * sizes of the sColorPrefs array in nsXPLookAndFeel.h
140 */
141 const char nsXPLookAndFeel::sColorPrefs[][38] =
142 {
143 "ui.windowBackground",
144 "ui.windowForeground",
145 "ui.widgetBackground",
146 "ui.widgetForeground",
147 "ui.widgetSelectBackground",
148 "ui.widgetSelectForeground",
149 "ui.widget3DHighlight",
150 "ui.widget3DShadow",
151 "ui.textBackground",
152 "ui.textForeground",
153 "ui.textSelectBackground",
154 "ui.textSelectForeground",
155 "ui.textSelectBackgroundDisabled",
156 "ui.textSelectBackgroundAttention",
157 "ui.textHighlightBackground",
158 "ui.textHighlightForeground",
159 "ui.IMERawInputBackground",
160 "ui.IMERawInputForeground",
161 "ui.IMERawInputUnderline",
162 "ui.IMESelectedRawTextBackground",
163 "ui.IMESelectedRawTextForeground",
164 "ui.IMESelectedRawTextUnderline",
165 "ui.IMEConvertedTextBackground",
166 "ui.IMEConvertedTextForeground",
167 "ui.IMEConvertedTextUnderline",
168 "ui.IMESelectedConvertedTextBackground",
169 "ui.IMESelectedConvertedTextForeground",
170 "ui.IMESelectedConvertedTextUnderline",
171 "ui.SpellCheckerUnderline",
172 "ui.activeborder",
173 "ui.activecaption",
174 "ui.appworkspace",
175 "ui.background",
176 "ui.buttonface",
177 "ui.buttonhighlight",
178 "ui.buttonshadow",
179 "ui.buttontext",
180 "ui.captiontext",
181 "ui.graytext",
182 "ui.highlight",
183 "ui.highlighttext",
184 "ui.inactiveborder",
185 "ui.inactivecaption",
186 "ui.inactivecaptiontext",
187 "ui.infobackground",
188 "ui.infotext",
189 "ui.menu",
190 "ui.menutext",
191 "ui.scrollbar",
192 "ui.threeddarkshadow",
193 "ui.threedface",
194 "ui.threedhighlight",
195 "ui.threedlightshadow",
196 "ui.threedshadow",
197 "ui.window",
198 "ui.windowframe",
199 "ui.windowtext",
200 "ui.-moz-buttondefault",
201 "ui.-moz-field",
202 "ui.-moz-fieldtext",
203 "ui.-moz-dialog",
204 "ui.-moz-dialogtext",
205 "ui.-moz-dragtargetzone",
206 "ui.-moz-cellhighlight",
207 "ui.-moz_cellhighlighttext",
208 "ui.-moz-html-cellhighlight",
209 "ui.-moz-html-cellhighlighttext",
210 "ui.-moz-buttonhoverface",
211 "ui.-moz_buttonhovertext",
212 "ui.-moz_menuhover",
213 "ui.-moz_menuhovertext",
214 "ui.-moz_menubartext",
215 "ui.-moz_menubarhovertext",
216 "ui.-moz_eventreerow",
217 "ui.-moz_oddtreerow",
218 "ui.-moz_mac_chrome_active",
219 "ui.-moz_mac_chrome_inactive",
220 "ui.-moz-mac-focusring",
221 "ui.-moz-mac-menuselect",
222 "ui.-moz-mac-menushadow",
223 "ui.-moz-mac-menutextdisable",
224 "ui.-moz-mac-menutextselect",
225 "ui.-moz_mac_disabledtoolbartext",
226 "ui.-moz-mac-secondaryhighlight",
227 "ui.-moz-win-mediatext",
228 "ui.-moz-win-communicationstext",
229 "ui.-moz-nativehyperlinktext",
230 "ui.-moz-comboboxtext",
231 "ui.-moz-combobox"
232 };
234 int32_t nsXPLookAndFeel::sCachedColors[LookAndFeel::eColorID_LAST_COLOR] = {0};
235 int32_t nsXPLookAndFeel::sCachedColorBits[COLOR_CACHE_SIZE] = {0};
237 bool nsXPLookAndFeel::sInitialized = false;
238 bool nsXPLookAndFeel::sUseNativeColors = true;
240 nsLookAndFeel* nsXPLookAndFeel::sInstance = nullptr;
241 bool nsXPLookAndFeel::sShutdown = false;
243 // static
244 nsLookAndFeel*
245 nsXPLookAndFeel::GetInstance()
246 {
247 if (sInstance) {
248 return sInstance;
249 }
251 NS_ENSURE_TRUE(!sShutdown, nullptr);
253 sInstance = new nsLookAndFeel();
254 return sInstance;
255 }
257 // static
258 void
259 nsXPLookAndFeel::Shutdown()
260 {
261 if (sShutdown) {
262 return;
263 }
264 sShutdown = true;
265 delete sInstance;
266 sInstance = nullptr;
267 }
269 nsXPLookAndFeel::nsXPLookAndFeel() : LookAndFeel()
270 {
271 }
273 // static
274 void
275 nsXPLookAndFeel::IntPrefChanged(nsLookAndFeelIntPref *data)
276 {
277 if (!data) {
278 return;
279 }
281 int32_t intpref;
282 nsresult rv = Preferences::GetInt(data->name, &intpref);
283 if (NS_FAILED(rv)) {
284 return;
285 }
286 data->intVar = intpref;
287 data->isSet = true;
288 #ifdef DEBUG_akkana
289 printf("====== Changed int pref %s to %d\n", data->name, data->intVar);
290 #endif
291 }
293 // static
294 void
295 nsXPLookAndFeel::FloatPrefChanged(nsLookAndFeelFloatPref *data)
296 {
297 if (!data) {
298 return;
299 }
301 int32_t intpref;
302 nsresult rv = Preferences::GetInt(data->name, &intpref);
303 if (NS_FAILED(rv)) {
304 return;
305 }
306 data->floatVar = (float)intpref / 100.0f;
307 data->isSet = true;
308 #ifdef DEBUG_akkana
309 printf("====== Changed float pref %s to %f\n", data->name, data->floatVar);
310 #endif
311 }
313 // static
314 void
315 nsXPLookAndFeel::ColorPrefChanged (unsigned int index, const char *prefName)
316 {
317 nsAutoString colorStr;
318 nsresult rv = Preferences::GetString(prefName, &colorStr);
319 if (NS_FAILED(rv)) {
320 return;
321 }
322 if (!colorStr.IsEmpty()) {
323 nscolor thecolor;
324 if (colorStr[0] == char16_t('#')) {
325 if (NS_HexToRGB(nsDependentString(colorStr, 1), &thecolor)) {
326 int32_t id = NS_PTR_TO_INT32(index);
327 CACHE_COLOR(id, thecolor);
328 }
329 } else if (NS_ColorNameToRGB(colorStr, &thecolor)) {
330 int32_t id = NS_PTR_TO_INT32(index);
331 CACHE_COLOR(id, thecolor);
332 #ifdef DEBUG_akkana
333 printf("====== Changed color pref %s to 0x%lx\n",
334 prefName, thecolor);
335 #endif
336 }
337 } else {
338 // Reset to the default color, by clearing the cache
339 // to force lookup when the color is next used
340 int32_t id = NS_PTR_TO_INT32(index);
341 CLEAR_COLOR_CACHE(id);
342 }
343 }
345 void
346 nsXPLookAndFeel::InitFromPref(nsLookAndFeelIntPref* aPref)
347 {
348 int32_t intpref;
349 nsresult rv = Preferences::GetInt(aPref->name, &intpref);
350 if (NS_SUCCEEDED(rv)) {
351 aPref->isSet = true;
352 aPref->intVar = intpref;
353 }
354 }
356 void
357 nsXPLookAndFeel::InitFromPref(nsLookAndFeelFloatPref* aPref)
358 {
359 int32_t intpref;
360 nsresult rv = Preferences::GetInt(aPref->name, &intpref);
361 if (NS_SUCCEEDED(rv)) {
362 aPref->isSet = true;
363 aPref->floatVar = (float)intpref / 100.0f;
364 }
365 }
367 void
368 nsXPLookAndFeel::InitColorFromPref(int32_t i)
369 {
370 nsAutoString colorStr;
371 nsresult rv = Preferences::GetString(sColorPrefs[i], &colorStr);
372 if (NS_FAILED(rv) || colorStr.IsEmpty()) {
373 return;
374 }
375 nscolor thecolor;
376 if (colorStr[0] == char16_t('#')) {
377 nsAutoString hexString;
378 colorStr.Right(hexString, colorStr.Length() - 1);
379 if (NS_HexToRGB(hexString, &thecolor)) {
380 CACHE_COLOR(i, thecolor);
381 }
382 } else if (NS_ColorNameToRGB(colorStr, &thecolor)) {
383 CACHE_COLOR(i, thecolor);
384 }
385 }
387 // static
388 void
389 nsXPLookAndFeel::OnPrefChanged(const char* aPref, void* aClosure)
390 {
392 // looping in the same order as in ::Init
394 nsDependentCString prefName(aPref);
395 unsigned int i;
396 for (i = 0; i < ArrayLength(sIntPrefs); ++i) {
397 if (prefName.Equals(sIntPrefs[i].name)) {
398 IntPrefChanged(&sIntPrefs[i]);
399 return;
400 }
401 }
403 for (i = 0; i < ArrayLength(sFloatPrefs); ++i) {
404 if (prefName.Equals(sFloatPrefs[i].name)) {
405 FloatPrefChanged(&sFloatPrefs[i]);
406 return;
407 }
408 }
410 for (i = 0; i < ArrayLength(sColorPrefs); ++i) {
411 if (prefName.Equals(sColorPrefs[i])) {
412 ColorPrefChanged(i, sColorPrefs[i]);
413 return;
414 }
415 }
416 }
418 //
419 // Read values from the user's preferences.
420 // This is done once at startup, but since the user's preferences
421 // haven't actually been read yet at that time, we also have to
422 // set a callback to inform us of changes to each pref.
423 //
424 void
425 nsXPLookAndFeel::Init()
426 {
427 // Say we're already initialized, and take the chance that it might fail;
428 // protects against some other process writing to our static variables.
429 sInitialized = true;
431 // XXX If we could reorganize the pref names, we should separate the branch
432 // for each types. Then, we could reduce the unnecessary loop from
433 // nsXPLookAndFeel::OnPrefChanged().
434 Preferences::RegisterCallback(OnPrefChanged, "ui.");
435 Preferences::RegisterCallback(OnPrefChanged, "accessibility.tabfocus");
437 unsigned int i;
438 for (i = 0; i < ArrayLength(sIntPrefs); ++i) {
439 InitFromPref(&sIntPrefs[i]);
440 }
442 for (i = 0; i < ArrayLength(sFloatPrefs); ++i) {
443 InitFromPref(&sFloatPrefs[i]);
444 }
446 for (i = 0; i < ArrayLength(sColorPrefs); ++i) {
447 InitColorFromPref(i);
448 }
450 bool val;
451 if (NS_SUCCEEDED(Preferences::GetBool("ui.use_native_colors", &val))) {
452 sUseNativeColors = val;
453 }
454 }
456 nsXPLookAndFeel::~nsXPLookAndFeel()
457 {
458 NS_ASSERTION(sInstance == this,
459 "This destroying instance isn't the singleton instance");
460 sInstance = nullptr;
461 }
463 bool
464 nsXPLookAndFeel::IsSpecialColor(ColorID aID, nscolor &aColor)
465 {
466 switch (aID) {
467 case eColorID_TextSelectForeground:
468 return (aColor == NS_DONT_CHANGE_COLOR);
469 case eColorID_IMESelectedRawTextBackground:
470 case eColorID_IMESelectedConvertedTextBackground:
471 case eColorID_IMERawInputBackground:
472 case eColorID_IMEConvertedTextBackground:
473 case eColorID_IMESelectedRawTextForeground:
474 case eColorID_IMESelectedConvertedTextForeground:
475 case eColorID_IMERawInputForeground:
476 case eColorID_IMEConvertedTextForeground:
477 case eColorID_IMERawInputUnderline:
478 case eColorID_IMEConvertedTextUnderline:
479 case eColorID_IMESelectedRawTextUnderline:
480 case eColorID_IMESelectedConvertedTextUnderline:
481 case eColorID_SpellCheckerUnderline:
482 return NS_IS_SELECTION_SPECIAL_COLOR(aColor);
483 default:
484 /*
485 * In GetColor(), every color that is not a special color is color
486 * corrected. Use false to make other colors color corrected.
487 */
488 return false;
489 }
490 return false;
491 }
493 bool
494 nsXPLookAndFeel::ColorIsNotCSSAccessible(ColorID aID)
495 {
496 bool result = false;
498 switch (aID) {
499 case eColorID_WindowBackground:
500 case eColorID_WindowForeground:
501 case eColorID_WidgetBackground:
502 case eColorID_WidgetForeground:
503 case eColorID_WidgetSelectBackground:
504 case eColorID_WidgetSelectForeground:
505 case eColorID_Widget3DHighlight:
506 case eColorID_Widget3DShadow:
507 case eColorID_TextBackground:
508 case eColorID_TextForeground:
509 case eColorID_TextSelectBackground:
510 case eColorID_TextSelectForeground:
511 case eColorID_TextSelectBackgroundDisabled:
512 case eColorID_TextSelectBackgroundAttention:
513 case eColorID_TextHighlightBackground:
514 case eColorID_TextHighlightForeground:
515 case eColorID_IMERawInputBackground:
516 case eColorID_IMERawInputForeground:
517 case eColorID_IMERawInputUnderline:
518 case eColorID_IMESelectedRawTextBackground:
519 case eColorID_IMESelectedRawTextForeground:
520 case eColorID_IMESelectedRawTextUnderline:
521 case eColorID_IMEConvertedTextBackground:
522 case eColorID_IMEConvertedTextForeground:
523 case eColorID_IMEConvertedTextUnderline:
524 case eColorID_IMESelectedConvertedTextBackground:
525 case eColorID_IMESelectedConvertedTextForeground:
526 case eColorID_IMESelectedConvertedTextUnderline:
527 case eColorID_SpellCheckerUnderline:
528 result = true;
529 break;
530 default:
531 break;
532 }
534 return result;
535 }
537 nscolor
538 nsXPLookAndFeel::GetStandinForNativeColor(ColorID aID)
539 {
540 nscolor result = NS_RGB(0xFF, 0xFF, 0xFF);
542 // The stand-in colors are taken from the Windows 7 Aero theme
543 // except Mac-specific colors which are taken from Mac OS 10.7.
544 switch (aID) {
545 // CSS 2 colors:
546 case eColorID_activeborder: result = NS_RGB(0xB4, 0xB4, 0xB4); break;
547 case eColorID_activecaption: result = NS_RGB(0x99, 0xB4, 0xD1); break;
548 case eColorID_appworkspace: result = NS_RGB(0xAB, 0xAB, 0xAB); break;
549 case eColorID_background: result = NS_RGB(0x00, 0x00, 0x00); break;
550 case eColorID_buttonface: result = NS_RGB(0xF0, 0xF0, 0xF0); break;
551 case eColorID_buttonhighlight: result = NS_RGB(0xFF, 0xFF, 0xFF); break;
552 case eColorID_buttonshadow: result = NS_RGB(0xA0, 0xA0, 0xA0); break;
553 case eColorID_buttontext: result = NS_RGB(0x00, 0x00, 0x00); break;
554 case eColorID_captiontext: result = NS_RGB(0x00, 0x00, 0x00); break;
555 case eColorID_graytext: result = NS_RGB(0x6D, 0x6D, 0x6D); break;
556 case eColorID_highlight: result = NS_RGB(0x33, 0x99, 0xFF); break;
557 case eColorID_highlighttext: result = NS_RGB(0xFF, 0xFF, 0xFF); break;
558 case eColorID_inactiveborder: result = NS_RGB(0xF4, 0xF7, 0xFC); break;
559 case eColorID_inactivecaption: result = NS_RGB(0xBF, 0xCD, 0xDB); break;
560 case eColorID_inactivecaptiontext:
561 result = NS_RGB(0x43, 0x4E, 0x54); break;
562 case eColorID_infobackground: result = NS_RGB(0xFF, 0xFF, 0xE1); break;
563 case eColorID_infotext: result = NS_RGB(0x00, 0x00, 0x00); break;
564 case eColorID_menu: result = NS_RGB(0xF0, 0xF0, 0xF0); break;
565 case eColorID_menutext: result = NS_RGB(0x00, 0x00, 0x00); break;
566 case eColorID_scrollbar: result = NS_RGB(0xC8, 0xC8, 0xC8); break;
567 case eColorID_threeddarkshadow: result = NS_RGB(0x69, 0x69, 0x69); break;
568 case eColorID_threedface: result = NS_RGB(0xF0, 0xF0, 0xF0); break;
569 case eColorID_threedhighlight: result = NS_RGB(0xFF, 0xFF, 0xFF); break;
570 case eColorID_threedlightshadow: result = NS_RGB(0xE3, 0xE3, 0xE3); break;
571 case eColorID_threedshadow: result = NS_RGB(0xA0, 0xA0, 0xA0); break;
572 case eColorID_window: result = NS_RGB(0xFF, 0xFF, 0xFF); break;
573 case eColorID_windowframe: result = NS_RGB(0x64, 0x64, 0x64); break;
574 case eColorID_windowtext: result = NS_RGB(0x00, 0x00, 0x00); break;
575 case eColorID__moz_buttondefault:
576 result = NS_RGB(0x69, 0x69, 0x69); break;
577 case eColorID__moz_field: result = NS_RGB(0xFF, 0xFF, 0xFF); break;
578 case eColorID__moz_fieldtext: result = NS_RGB(0x00, 0x00, 0x00); break;
579 case eColorID__moz_dialog: result = NS_RGB(0xF0, 0xF0, 0xF0); break;
580 case eColorID__moz_dialogtext: result = NS_RGB(0x00, 0x00, 0x00); break;
581 case eColorID__moz_dragtargetzone:
582 result = NS_RGB(0xFF, 0xFF, 0xFF); break;
583 case eColorID__moz_cellhighlight:
584 result = NS_RGB(0xF0, 0xF0, 0xF0); break;
585 case eColorID__moz_cellhighlighttext:
586 result = NS_RGB(0x00, 0x00, 0x00); break;
587 case eColorID__moz_html_cellhighlight:
588 result = NS_RGB(0x33, 0x99, 0xFF); break;
589 case eColorID__moz_html_cellhighlighttext:
590 result = NS_RGB(0xFF, 0xFF, 0xFF); break;
591 case eColorID__moz_buttonhoverface:
592 result = NS_RGB(0xF0, 0xF0, 0xF0); break;
593 case eColorID__moz_buttonhovertext:
594 result = NS_RGB(0x00, 0x00, 0x00); break;
595 case eColorID__moz_menuhover:
596 result = NS_RGB(0x33, 0x99, 0xFF); break;
597 case eColorID__moz_menuhovertext:
598 result = NS_RGB(0x00, 0x00, 0x00); break;
599 case eColorID__moz_menubartext:
600 result = NS_RGB(0x00, 0x00, 0x00); break;
601 case eColorID__moz_menubarhovertext:
602 result = NS_RGB(0x00, 0x00, 0x00); break;
603 case eColorID__moz_oddtreerow:
604 result = NS_RGB(0xFF, 0xFF, 0xFF); break;
605 case eColorID__moz_mac_chrome_active:
606 result = NS_RGB(0xB2, 0xB2, 0xB2); break;
607 case eColorID__moz_mac_chrome_inactive:
608 result = NS_RGB(0xE1, 0xE1, 0xE1); break;
609 case eColorID__moz_mac_focusring:
610 result = NS_RGB(0x60, 0x9D, 0xD7); break;
611 case eColorID__moz_mac_menuselect:
612 result = NS_RGB(0x38, 0x75, 0xD7); break;
613 case eColorID__moz_mac_menushadow:
614 result = NS_RGB(0xA3, 0xA3, 0xA3); break;
615 case eColorID__moz_mac_menutextdisable:
616 result = NS_RGB(0x88, 0x88, 0x88); break;
617 case eColorID__moz_mac_menutextselect:
618 result = NS_RGB(0xFF, 0xFF, 0xFF); break;
619 case eColorID__moz_mac_disabledtoolbartext:
620 result = NS_RGB(0x3F, 0x3F, 0x3F); break;
621 case eColorID__moz_mac_secondaryhighlight:
622 result = NS_RGB(0xD4, 0xD4, 0xD4); break;
623 case eColorID__moz_win_mediatext:
624 result = NS_RGB(0xFF, 0xFF, 0xFF); break;
625 case eColorID__moz_win_communicationstext:
626 result = NS_RGB(0xFF, 0xFF, 0xFF); break;
627 case eColorID__moz_nativehyperlinktext:
628 result = NS_RGB(0x00, 0x66, 0xCC); break;
629 case eColorID__moz_comboboxtext:
630 result = NS_RGB(0x00, 0x00, 0x00); break;
631 case eColorID__moz_combobox:
632 result = NS_RGB(0xFF, 0xFF, 0xFF); break;
633 default:
634 break;
635 }
637 return result;
638 }
640 //
641 // All these routines will return NS_OK if they have a value,
642 // in which case the nsLookAndFeel should use that value;
643 // otherwise we'll return NS_ERROR_NOT_AVAILABLE, in which case, the
644 // platform-specific nsLookAndFeel should use its own values instead.
645 //
646 nsresult
647 nsXPLookAndFeel::GetColorImpl(ColorID aID, bool aUseStandinsForNativeColors,
648 nscolor &aResult)
649 {
650 if (!sInitialized)
651 Init();
653 // define DEBUG_SYSTEM_COLOR_USE if you want to debug system color
654 // use in a skin that uses them. When set, it will make all system
655 // color pairs that are appropriate for foreground/background
656 // pairing the same. This means if the skin is using system colors
657 // correctly you will not be able to see *any* text.
658 #undef DEBUG_SYSTEM_COLOR_USE
660 #ifdef DEBUG_SYSTEM_COLOR_USE
661 {
662 nsresult rv = NS_OK;
663 switch (aID) {
664 // css2 http://www.w3.org/TR/REC-CSS2/ui.html#system-colors
665 case eColorID_activecaption:
666 // active window caption background
667 case eColorID_captiontext:
668 // text in active window caption
669 aResult = NS_RGB(0xff, 0x00, 0x00);
670 break;
672 case eColorID_highlight:
673 // background of selected item
674 case eColorID_highlighttext:
675 // text of selected item
676 aResult = NS_RGB(0xff, 0xff, 0x00);
677 break;
679 case eColorID_inactivecaption:
680 // inactive window caption
681 case eColorID_inactivecaptiontext:
682 // text in inactive window caption
683 aResult = NS_RGB(0x66, 0x66, 0x00);
684 break;
686 case eColorID_infobackground:
687 // tooltip background color
688 case eColorID_infotext:
689 // tooltip text color
690 aResult = NS_RGB(0x00, 0xff, 0x00);
691 break;
693 case eColorID_menu:
694 // menu background
695 case eColorID_menutext:
696 // menu text
697 aResult = NS_RGB(0x00, 0xff, 0xff);
698 break;
700 case eColorID_threedface:
701 case eColorID_buttonface:
702 // 3-D face color
703 case eColorID_buttontext:
704 // text on push buttons
705 aResult = NS_RGB(0x00, 0x66, 0x66);
706 break;
708 case eColorID_window:
709 case eColorID_windowtext:
710 aResult = NS_RGB(0x00, 0x00, 0xff);
711 break;
713 // from the CSS3 working draft (not yet finalized)
714 // http://www.w3.org/tr/2000/wd-css3-userint-20000216.html#color
716 case eColorID__moz_field:
717 case eColorID__moz_fieldtext:
718 aResult = NS_RGB(0xff, 0x00, 0xff);
719 break;
721 case eColorID__moz_dialog:
722 case eColorID__moz_dialogtext:
723 aResult = NS_RGB(0x66, 0x00, 0x66);
724 break;
726 default:
727 rv = NS_ERROR_NOT_AVAILABLE;
728 }
729 if (NS_SUCCEEDED(rv))
730 return rv;
731 }
732 #endif // DEBUG_SYSTEM_COLOR_USE
734 if (aUseStandinsForNativeColors && ColorIsNotCSSAccessible(aID))
735 aUseStandinsForNativeColors = false;
737 if (!aUseStandinsForNativeColors && IS_COLOR_CACHED(aID)) {
738 aResult = sCachedColors[aID];
739 return NS_OK;
740 }
742 // There are no system color settings for these, so set them manually
743 if (aID == eColorID_TextSelectBackgroundDisabled) {
744 // This is used to gray out the selection when it's not focused
745 // Used with nsISelectionController::SELECTION_DISABLED
746 aResult = NS_RGB(0xb0, 0xb0, 0xb0);
747 return NS_OK;
748 }
750 if (aID == eColorID_TextSelectBackgroundAttention) {
751 // This makes the selection stand out when typeaheadfind is on
752 // Used with nsISelectionController::SELECTION_ATTENTION
753 aResult = NS_RGB(0x38, 0xd8, 0x78);
754 return NS_OK;
755 }
757 if (aID == eColorID_TextHighlightBackground) {
758 // This makes the matched text stand out when findbar highlighting is on
759 // Used with nsISelectionController::SELECTION_FIND
760 aResult = NS_RGB(0xef, 0x0f, 0xff);
761 return NS_OK;
762 }
764 if (aID == eColorID_TextHighlightForeground) {
765 // The foreground color for the matched text in findbar highlighting
766 // Used with nsISelectionController::SELECTION_FIND
767 aResult = NS_RGB(0xff, 0xff, 0xff);
768 return NS_OK;
769 }
771 if (sUseNativeColors && aUseStandinsForNativeColors)
772 {
773 aResult = GetStandinForNativeColor(aID);
774 return NS_OK;
775 }
777 if (sUseNativeColors && NS_SUCCEEDED(NativeGetColor(aID, aResult))) {
778 if ((gfxPlatform::GetCMSMode() == eCMSMode_All) &&
779 !IsSpecialColor(aID, aResult)) {
780 qcms_transform *transform = gfxPlatform::GetCMSInverseRGBTransform();
781 if (transform) {
782 uint8_t color[3];
783 color[0] = NS_GET_R(aResult);
784 color[1] = NS_GET_G(aResult);
785 color[2] = NS_GET_B(aResult);
786 qcms_transform_data(transform, color, color, 1);
787 aResult = NS_RGB(color[0], color[1], color[2]);
788 }
789 }
791 CACHE_COLOR(aID, aResult);
792 return NS_OK;
793 }
795 return NS_ERROR_NOT_AVAILABLE;
796 }
798 nsresult
799 nsXPLookAndFeel::GetIntImpl(IntID aID, int32_t &aResult)
800 {
801 if (!sInitialized)
802 Init();
804 // Set the default values for these prefs. but allow different platforms
805 // to override them in their nsLookAndFeel if desired.
806 switch (aID) {
807 case eIntID_ScrollButtonLeftMouseButtonAction:
808 aResult = 0;
809 return NS_OK;
810 case eIntID_ScrollButtonMiddleMouseButtonAction:
811 aResult = 3;
812 return NS_OK;
813 case eIntID_ScrollButtonRightMouseButtonAction:
814 aResult = 3;
815 return NS_OK;
816 default:
817 /*
818 * The metrics above are hardcoded platform defaults. All the other
819 * metrics are stored in sIntPrefs and can be changed at runtime.
820 */
821 break;
822 }
824 for (unsigned int i = 0; i < ArrayLength(sIntPrefs); ++i) {
825 if (sIntPrefs[i].isSet && (sIntPrefs[i].id == aID)) {
826 aResult = sIntPrefs[i].intVar;
827 return NS_OK;
828 }
829 }
831 return NS_ERROR_NOT_AVAILABLE;
832 }
834 nsresult
835 nsXPLookAndFeel::GetFloatImpl(FloatID aID, float &aResult)
836 {
837 if (!sInitialized)
838 Init();
840 for (unsigned int i = 0; i < ArrayLength(sFloatPrefs); ++i) {
841 if (sFloatPrefs[i].isSet && sFloatPrefs[i].id == aID) {
842 aResult = sFloatPrefs[i].floatVar;
843 return NS_OK;
844 }
845 }
847 return NS_ERROR_NOT_AVAILABLE;
848 }
850 void
851 nsXPLookAndFeel::RefreshImpl()
852 {
853 // Wipe out our color cache.
854 uint32_t i;
855 for (i = 0; i < eColorID_LAST_COLOR; i++)
856 sCachedColors[i] = 0;
857 for (i = 0; i < COLOR_CACHE_SIZE; i++)
858 sCachedColorBits[i] = 0;
859 }
861 namespace mozilla {
863 // static
864 nsresult
865 LookAndFeel::GetColor(ColorID aID, nscolor* aResult)
866 {
867 return nsLookAndFeel::GetInstance()->GetColorImpl(aID, false, *aResult);
868 }
870 nsresult
871 LookAndFeel::GetColor(ColorID aID, bool aUseStandinsForNativeColors,
872 nscolor* aResult)
873 {
874 return nsLookAndFeel::GetInstance()->GetColorImpl(aID,
875 aUseStandinsForNativeColors, *aResult);
876 }
878 // static
879 nsresult
880 LookAndFeel::GetColorForNativeAppearance(uint8_t aWidgetType, bool aIsDisabled,
881 nscolor* aResult)
882 {
883 NS_ENSURE_ARG_POINTER(aResult);
885 ColorID colorID = eColorID_LAST_COLOR;
886 switch (aWidgetType) {
887 case NS_THEME_TEXTFIELD:
888 case NS_THEME_TEXTFIELD_MULTILINE:
889 case NS_THEME_LISTBOX:
890 case NS_THEME_DROPDOWN:
891 case NS_THEME_DROPDOWN_TEXTFIELD:
892 case NS_THEME_TREEVIEW:
893 colorID = (aIsDisabled) ? eColorID_graytext : eColorID__moz_fieldtext;
894 break;
896 case NS_THEME_TOOLTIP:
897 colorID = eColorID_infotext;
898 break;
900 case NS_THEME_BUTTON:
901 case NS_THEME_GROUPBOX:
902 case NS_THEME_PROGRESSBAR:
903 case NS_THEME_PROGRESSBAR_VERTICAL:
904 case NS_THEME_TAB_PANEL:
905 case NS_THEME_STATUSBAR:
906 case NS_THEME_STATUSBAR_RESIZER_PANEL:
907 colorID = (aIsDisabled) ? eColorID_graytext : eColorID_buttontext;
908 break;
909 }
911 if (LookAndFeel::eColorID_LAST_COLOR == colorID)
912 return NS_ERROR_FAILURE;
914 *aResult = NS_RGB(0, 0, 0);
915 return nsLookAndFeel::GetInstance()->NativeGetColor(colorID, *aResult);
916 }
918 // static
919 nsresult
920 LookAndFeel::GetInt(IntID aID, int32_t* aResult)
921 {
922 return nsLookAndFeel::GetInstance()->GetIntImpl(aID, *aResult);
923 }
925 // static
926 nsresult
927 LookAndFeel::GetFloat(FloatID aID, float* aResult)
928 {
929 return nsLookAndFeel::GetInstance()->GetFloatImpl(aID, *aResult);
930 }
932 // static
933 bool
934 LookAndFeel::GetFont(FontID aID, nsString& aName, gfxFontStyle& aStyle,
935 float aDevPixPerCSSPixel)
936 {
937 return nsLookAndFeel::GetInstance()->GetFontImpl(aID, aName, aStyle,
938 aDevPixPerCSSPixel);
939 }
941 // static
942 char16_t
943 LookAndFeel::GetPasswordCharacter()
944 {
945 return nsLookAndFeel::GetInstance()->GetPasswordCharacterImpl();
946 }
948 // static
949 bool
950 LookAndFeel::GetEchoPassword()
951 {
952 return nsLookAndFeel::GetInstance()->GetEchoPasswordImpl();
953 }
955 // static
956 uint32_t
957 LookAndFeel::GetPasswordMaskDelay()
958 {
959 return nsLookAndFeel::GetInstance()->GetPasswordMaskDelayImpl();
960 }
962 // static
963 void
964 LookAndFeel::Refresh()
965 {
966 nsLookAndFeel::GetInstance()->RefreshImpl();
967 }
969 } // namespace mozilla