Bug 1517200 [wpt PR 14691] - Less restrictive internal column count limit., a=testonly
[gecko.git] / widget / nsXPLookAndFeel.cpp
blob2c0133dd2b998501eb54a72b82203e0508a82901
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 "HeadlessLookAndFeel.h"
13 #include "nsCRT.h"
14 #include "nsFont.h"
15 #include "mozilla/dom/ContentChild.h"
16 #include "mozilla/Preferences.h"
17 #include "mozilla/ServoStyleSet.h"
18 #include "mozilla/gfx/2D.h"
19 #include "mozilla/widget/WidgetMessageUtils.h"
21 #include "gfxPlatform.h"
22 #include "gfxPrefs.h"
23 #include "qcms.h"
25 #ifdef DEBUG
26 # include "nsSize.h"
27 #endif
29 using namespace mozilla;
31 nsLookAndFeelIntPref nsXPLookAndFeel::sIntPrefs[] = {
32 {"ui.caretBlinkTime", eIntID_CaretBlinkTime, false, 0},
33 {"ui.caretWidth", eIntID_CaretWidth, false, 0},
34 {"ui.caretVisibleWithSelection", eIntID_ShowCaretDuringSelection, false, 0},
35 {"ui.submenuDelay", eIntID_SubmenuDelay, false, 0},
36 {"ui.dragThresholdX", eIntID_DragThresholdX, false, 0},
37 {"ui.dragThresholdY", eIntID_DragThresholdY, false, 0},
38 {"ui.useAccessibilityTheme", eIntID_UseAccessibilityTheme, false, 0},
39 {"ui.menusCanOverlapOSBar", eIntID_MenusCanOverlapOSBar, false, 0},
40 {"ui.useOverlayScrollbars", eIntID_UseOverlayScrollbars, false, 0},
41 {"ui.scrollbarDisplayOnMouseMove", eIntID_ScrollbarDisplayOnMouseMove,
42 false, 0},
43 {"ui.scrollbarFadeBeginDelay", eIntID_ScrollbarFadeBeginDelay, false, 0},
44 {"ui.scrollbarFadeDuration", eIntID_ScrollbarFadeDuration, false, 0},
45 {"ui.showHideScrollbars", eIntID_ShowHideScrollbars, false, 0},
46 {"ui.skipNavigatingDisabledMenuItem", eIntID_SkipNavigatingDisabledMenuItem,
47 false, 0},
48 {"ui.treeOpenDelay", eIntID_TreeOpenDelay, false, 0},
49 {"ui.treeCloseDelay", eIntID_TreeCloseDelay, false, 0},
50 {"ui.treeLazyScrollDelay", eIntID_TreeLazyScrollDelay, false, 0},
51 {"ui.treeScrollDelay", eIntID_TreeScrollDelay, false, 0},
52 {"ui.treeScrollLinesMax", eIntID_TreeScrollLinesMax, false, 0},
53 {"accessibility.tabfocus", eIntID_TabFocusModel, false, 0},
54 {"ui.alertNotificationOrigin", eIntID_AlertNotificationOrigin, false, 0},
55 {"ui.scrollToClick", eIntID_ScrollToClick, false, 0},
56 {"ui.IMERawInputUnderlineStyle", eIntID_IMERawInputUnderlineStyle, false,
57 0},
58 {"ui.IMESelectedRawTextUnderlineStyle",
59 eIntID_IMESelectedRawTextUnderlineStyle, false, 0},
60 {"ui.IMEConvertedTextUnderlineStyle", eIntID_IMEConvertedTextUnderlineStyle,
61 false, 0},
62 {"ui.IMESelectedConvertedTextUnderlineStyle",
63 eIntID_IMESelectedConvertedTextUnderline, false, 0},
64 {"ui.SpellCheckerUnderlineStyle", eIntID_SpellCheckerUnderlineStyle, false,
65 0},
66 {"ui.scrollbarButtonAutoRepeatBehavior",
67 eIntID_ScrollbarButtonAutoRepeatBehavior, false, 0},
68 {"ui.tooltipDelay", eIntID_TooltipDelay, false, 0},
69 {"ui.contextMenuOffsetVertical", eIntID_ContextMenuOffsetVertical, false,
70 0},
71 {"ui.contextMenuOffsetHorizontal", eIntID_ContextMenuOffsetHorizontal,
72 false, 0},
73 {"ui.GtkCSDAvailable", eIntID_GTKCSDAvailable, false, 0},
74 {"ui.GtkCSDHideTitlebarByDefault", eIntID_GTKCSDHideTitlebarByDefault,
75 false, 0},
76 {"ui.GtkCSDTransparentBackground", eIntID_GTKCSDTransparentBackground,
77 false, 0},
78 {"ui.GtkCSDMinimizeButton", eIntID_GTKCSDMinimizeButton, false, 0},
79 {"ui.GtkCSDMaximizeButton", eIntID_GTKCSDMaximizeButton, false, 0},
80 {"ui.GtkCSDCloseButton", eIntID_GTKCSDCloseButton, false, 0},
81 {"ui.GtkCSDReversedPlacement", eIntID_GTKCSDReversedPlacement, false, 0},
82 {"ui.systemUsesDarkTheme", eIntID_SystemUsesDarkTheme, false, 0},
83 {"ui.prefersReducedMotion", eIntID_PrefersReducedMotion, false, 0},
84 {"ui.primaryPointerCapabilities", eIntID_PrimaryPointerCapabilities, false,
85 6 /* fine and hover-capable pointer, i.e. mouse-type */},
86 {"ui.allPointerCapabilities", eIntID_AllPointerCapabilities, false,
87 6 /* fine and hover-capable pointer, i.e. mouse-type */},
90 nsLookAndFeelFloatPref nsXPLookAndFeel::sFloatPrefs[] = {
91 {"ui.IMEUnderlineRelativeSize", eFloatID_IMEUnderlineRelativeSize, false,
92 0},
93 {"ui.SpellCheckerUnderlineRelativeSize",
94 eFloatID_SpellCheckerUnderlineRelativeSize, false, 0},
95 {"ui.caretAspectRatio", eFloatID_CaretAspectRatio, false, 0},
98 // This array MUST be kept in the same order as the color list in LookAndFeel.h.
99 /* XXX If you add any strings longer than
100 * "ui.-moz-mac-active-source-list-selection"
101 * to the following array then you MUST update the
102 * sizes of the sColorPrefs array in nsXPLookAndFeel.h
104 const char nsXPLookAndFeel::sColorPrefs[][41] = {
105 "ui.windowBackground",
106 "ui.windowForeground",
107 "ui.widgetBackground",
108 "ui.widgetForeground",
109 "ui.widgetSelectBackground",
110 "ui.widgetSelectForeground",
111 "ui.widget3DHighlight",
112 "ui.widget3DShadow",
113 "ui.textBackground",
114 "ui.textForeground",
115 "ui.textSelectBackground",
116 "ui.textSelectForeground",
117 "ui.textSelectForegroundCustom",
118 "ui.textSelectBackgroundDisabled",
119 "ui.textSelectBackgroundAttention",
120 "ui.textHighlightBackground",
121 "ui.textHighlightForeground",
122 "ui.IMERawInputBackground",
123 "ui.IMERawInputForeground",
124 "ui.IMERawInputUnderline",
125 "ui.IMESelectedRawTextBackground",
126 "ui.IMESelectedRawTextForeground",
127 "ui.IMESelectedRawTextUnderline",
128 "ui.IMEConvertedTextBackground",
129 "ui.IMEConvertedTextForeground",
130 "ui.IMEConvertedTextUnderline",
131 "ui.IMESelectedConvertedTextBackground",
132 "ui.IMESelectedConvertedTextForeground",
133 "ui.IMESelectedConvertedTextUnderline",
134 "ui.SpellCheckerUnderline",
135 "ui.activeborder",
136 "ui.activecaption",
137 "ui.appworkspace",
138 "ui.background",
139 "ui.buttonface",
140 "ui.buttonhighlight",
141 "ui.buttonshadow",
142 "ui.buttontext",
143 "ui.captiontext",
144 "ui.graytext",
145 "ui.highlight",
146 "ui.highlighttext",
147 "ui.inactiveborder",
148 "ui.inactivecaption",
149 "ui.inactivecaptiontext",
150 "ui.infobackground",
151 "ui.infotext",
152 "ui.menu",
153 "ui.menutext",
154 "ui.scrollbar",
155 "ui.threeddarkshadow",
156 "ui.threedface",
157 "ui.threedhighlight",
158 "ui.threedlightshadow",
159 "ui.threedshadow",
160 "ui.window",
161 "ui.windowframe",
162 "ui.windowtext",
163 "ui.-moz-buttondefault",
164 "ui.-moz-field",
165 "ui.-moz-fieldtext",
166 "ui.-moz-dialog",
167 "ui.-moz-dialogtext",
168 "ui.-moz-dragtargetzone",
169 "ui.-moz-cellhighlight",
170 "ui.-moz_cellhighlighttext",
171 "ui.-moz-html-cellhighlight",
172 "ui.-moz-html-cellhighlighttext",
173 "ui.-moz-buttonhoverface",
174 "ui.-moz_buttonhovertext",
175 "ui.-moz_menuhover",
176 "ui.-moz_menuhovertext",
177 "ui.-moz_menubartext",
178 "ui.-moz_menubarhovertext",
179 "ui.-moz_eventreerow",
180 "ui.-moz_oddtreerow",
181 "ui.-moz-mac-buttonactivetext",
182 "ui.-moz_mac_chrome_active",
183 "ui.-moz_mac_chrome_inactive",
184 "ui.-moz-mac-defaultbuttontext",
185 "ui.-moz-mac-focusring",
186 "ui.-moz-mac-menuselect",
187 "ui.-moz-mac-menushadow",
188 "ui.-moz-mac-menutextdisable",
189 "ui.-moz-mac-menutextselect",
190 "ui.-moz_mac_disabledtoolbartext",
191 "ui.-moz-mac-secondaryhighlight",
192 "ui.-moz-mac-vibrancy-light",
193 "ui.-moz-mac-vibrancy-dark",
194 "ui.-moz-mac-vibrant-titlebar-light",
195 "ui.-moz-mac-vibrant-titlebar-dark",
196 "ui.-moz-mac-menupopup",
197 "ui.-moz-mac-menuitem",
198 "ui.-moz-mac-active-menuitem",
199 "ui.-moz-mac-source-list",
200 "ui.-moz-mac-source-list-selection",
201 "ui.-moz-mac-active-source-list-selection",
202 "ui.-moz-mac-tooltip",
203 "ui.-moz-win-accentcolor",
204 "ui.-moz-win-accentcolortext",
205 "ui.-moz-win-mediatext",
206 "ui.-moz-win-communicationstext",
207 "ui.-moz-nativehyperlinktext",
208 "ui.-moz-comboboxtext",
209 "ui.-moz-combobox",
210 "ui.-moz-gtk-info-bar-text"};
212 int32_t nsXPLookAndFeel::sCachedColors[LookAndFeel::eColorID_LAST_COLOR] = {0};
213 int32_t nsXPLookAndFeel::sCachedColorBits[COLOR_CACHE_SIZE] = {0};
215 bool nsXPLookAndFeel::sInitialized = false;
216 bool nsXPLookAndFeel::sUseNativeColors = true;
217 bool nsXPLookAndFeel::sFindbarModalHighlight = false;
218 bool nsXPLookAndFeel::sIsInPrefersReducedMotionForTest = false;
219 bool nsXPLookAndFeel::sPrefersReducedMotionForTest = false;
221 nsXPLookAndFeel* nsXPLookAndFeel::sInstance = nullptr;
222 bool nsXPLookAndFeel::sShutdown = false;
224 // static
225 nsXPLookAndFeel* nsXPLookAndFeel::GetInstance() {
226 if (sInstance) {
227 return sInstance;
230 NS_ENSURE_TRUE(!sShutdown, nullptr);
232 if (gfxPlatform::IsHeadless()) {
233 sInstance = new widget::HeadlessLookAndFeel();
234 } else {
235 sInstance = new nsLookAndFeel();
237 return sInstance;
240 // static
241 void nsXPLookAndFeel::Shutdown() {
242 if (sShutdown) {
243 return;
245 sShutdown = true;
246 delete sInstance;
247 sInstance = nullptr;
250 nsXPLookAndFeel::nsXPLookAndFeel()
251 : LookAndFeel(), mShouldRetainCacheForTest(false) {}
253 // static
254 void nsXPLookAndFeel::IntPrefChanged(nsLookAndFeelIntPref* data) {
255 if (!data) {
256 return;
259 int32_t intpref;
260 nsresult rv = Preferences::GetInt(data->name, &intpref);
261 if (NS_FAILED(rv)) {
262 return;
264 data->intVar = intpref;
265 data->isSet = true;
266 #ifdef DEBUG_akkana
267 printf("====== Changed int pref %s to %d\n", data->name, data->intVar);
268 #endif
271 // static
272 void nsXPLookAndFeel::FloatPrefChanged(nsLookAndFeelFloatPref* data) {
273 if (!data) {
274 return;
277 int32_t intpref;
278 nsresult rv = Preferences::GetInt(data->name, &intpref);
279 if (NS_FAILED(rv)) {
280 return;
282 data->floatVar = (float)intpref / 100.0f;
283 data->isSet = true;
284 #ifdef DEBUG_akkana
285 printf("====== Changed float pref %s to %f\n", data->name, data->floatVar);
286 #endif
289 // static
290 void nsXPLookAndFeel::ColorPrefChanged(unsigned int index,
291 const char* prefName) {
292 nsAutoString colorStr;
293 nsresult rv = Preferences::GetString(prefName, colorStr);
294 if (NS_FAILED(rv)) {
295 return;
297 if (!colorStr.IsEmpty()) {
298 nscolor thecolor;
299 if (colorStr[0] == char16_t('#')) {
300 if (NS_HexToRGBA(nsDependentString(colorStr, 1), nsHexColorType::NoAlpha,
301 &thecolor)) {
302 int32_t id = NS_PTR_TO_INT32(index);
303 CACHE_COLOR(id, thecolor);
305 } else if (NS_ColorNameToRGB(colorStr, &thecolor)) {
306 int32_t id = NS_PTR_TO_INT32(index);
307 CACHE_COLOR(id, thecolor);
308 #ifdef DEBUG_akkana
309 printf("====== Changed color pref %s to 0x%lx\n", prefName, thecolor);
310 #endif
312 } else {
313 // Reset to the default color, by clearing the cache
314 // to force lookup when the color is next used
315 int32_t id = NS_PTR_TO_INT32(index);
316 CLEAR_COLOR_CACHE(id);
320 void nsXPLookAndFeel::InitFromPref(nsLookAndFeelIntPref* aPref) {
321 int32_t intpref;
322 nsresult rv = Preferences::GetInt(aPref->name, &intpref);
323 if (NS_SUCCEEDED(rv)) {
324 aPref->isSet = true;
325 aPref->intVar = intpref;
329 void nsXPLookAndFeel::InitFromPref(nsLookAndFeelFloatPref* aPref) {
330 int32_t intpref;
331 nsresult rv = Preferences::GetInt(aPref->name, &intpref);
332 if (NS_SUCCEEDED(rv)) {
333 aPref->isSet = true;
334 aPref->floatVar = (float)intpref / 100.0f;
338 void nsXPLookAndFeel::InitColorFromPref(int32_t i) {
339 nsAutoString colorStr;
340 nsresult rv = Preferences::GetString(sColorPrefs[i], colorStr);
341 if (NS_FAILED(rv) || colorStr.IsEmpty()) {
342 return;
344 nscolor thecolor;
345 if (colorStr[0] == char16_t('#')) {
346 nsAutoString hexString;
347 colorStr.Right(hexString, colorStr.Length() - 1);
348 if (NS_HexToRGBA(hexString, nsHexColorType::NoAlpha, &thecolor)) {
349 CACHE_COLOR(i, thecolor);
351 } else if (NS_ColorNameToRGB(colorStr, &thecolor)) {
352 CACHE_COLOR(i, thecolor);
356 // static
357 void nsXPLookAndFeel::OnPrefChanged(const char* aPref, void* aClosure) {
358 // looping in the same order as in ::Init
360 nsDependentCString prefName(aPref);
361 unsigned int i;
362 for (i = 0; i < ArrayLength(sIntPrefs); ++i) {
363 if (prefName.Equals(sIntPrefs[i].name)) {
364 IntPrefChanged(&sIntPrefs[i]);
365 return;
369 for (i = 0; i < ArrayLength(sFloatPrefs); ++i) {
370 if (prefName.Equals(sFloatPrefs[i].name)) {
371 FloatPrefChanged(&sFloatPrefs[i]);
372 return;
376 for (i = 0; i < ArrayLength(sColorPrefs); ++i) {
377 if (prefName.Equals(sColorPrefs[i])) {
378 ColorPrefChanged(i, sColorPrefs[i]);
379 return;
385 // Read values from the user's preferences.
386 // This is done once at startup, but since the user's preferences
387 // haven't actually been read yet at that time, we also have to
388 // set a callback to inform us of changes to each pref.
390 void nsXPLookAndFeel::Init() {
391 MOZ_RELEASE_ASSERT(NS_IsMainThread());
393 // Say we're already initialized, and take the chance that it might fail;
394 // protects against some other process writing to our static variables.
395 sInitialized = true;
397 // XXX If we could reorganize the pref names, we should separate the branch
398 // for each types. Then, we could reduce the unnecessary loop from
399 // nsXPLookAndFeel::OnPrefChanged().
400 Preferences::RegisterPrefixCallback(OnPrefChanged, "ui.");
401 // We really do just want the accessibility.tabfocus pref, not other prefs
402 // that start with that string.
403 Preferences::RegisterCallback(OnPrefChanged, "accessibility.tabfocus");
405 unsigned int i;
406 for (i = 0; i < ArrayLength(sIntPrefs); ++i) {
407 InitFromPref(&sIntPrefs[i]);
410 for (i = 0; i < ArrayLength(sFloatPrefs); ++i) {
411 InitFromPref(&sFloatPrefs[i]);
414 for (i = 0; i < ArrayLength(sColorPrefs); ++i) {
415 InitColorFromPref(i);
418 Preferences::AddBoolVarCache(&sUseNativeColors, "ui.use_native_colors",
419 sUseNativeColors);
420 Preferences::AddBoolVarCache(&sFindbarModalHighlight,
421 "findbar.modalHighlight",
422 sFindbarModalHighlight);
424 if (XRE_IsContentProcess()) {
425 mozilla::dom::ContentChild* cc = mozilla::dom::ContentChild::GetSingleton();
427 LookAndFeel::SetIntCache(cc->LookAndFeelCache());
428 // This is only ever used once during initialization, and can be cleared
429 // now.
430 cc->LookAndFeelCache().Clear();
434 nsXPLookAndFeel::~nsXPLookAndFeel() {
435 NS_ASSERTION(sInstance == this,
436 "This destroying instance isn't the singleton instance");
437 sInstance = nullptr;
440 bool nsXPLookAndFeel::IsSpecialColor(ColorID aID, nscolor& aColor) {
441 switch (aID) {
442 case eColorID_TextSelectForeground:
443 return (aColor == NS_DONT_CHANGE_COLOR);
444 case eColorID_IMESelectedRawTextBackground:
445 case eColorID_IMESelectedConvertedTextBackground:
446 case eColorID_IMERawInputBackground:
447 case eColorID_IMEConvertedTextBackground:
448 case eColorID_IMESelectedRawTextForeground:
449 case eColorID_IMESelectedConvertedTextForeground:
450 case eColorID_IMERawInputForeground:
451 case eColorID_IMEConvertedTextForeground:
452 case eColorID_IMERawInputUnderline:
453 case eColorID_IMEConvertedTextUnderline:
454 case eColorID_IMESelectedRawTextUnderline:
455 case eColorID_IMESelectedConvertedTextUnderline:
456 case eColorID_SpellCheckerUnderline:
457 return NS_IS_SELECTION_SPECIAL_COLOR(aColor);
458 default:
460 * In GetColor(), every color that is not a special color is color
461 * corrected. Use false to make other colors color corrected.
463 return false;
465 return false;
468 bool nsXPLookAndFeel::ColorIsNotCSSAccessible(ColorID aID) {
469 bool result = false;
471 switch (aID) {
472 case eColorID_WindowBackground:
473 case eColorID_WindowForeground:
474 case eColorID_WidgetBackground:
475 case eColorID_WidgetForeground:
476 case eColorID_WidgetSelectBackground:
477 case eColorID_WidgetSelectForeground:
478 case eColorID_Widget3DHighlight:
479 case eColorID_Widget3DShadow:
480 case eColorID_TextBackground:
481 case eColorID_TextForeground:
482 case eColorID_TextSelectBackground:
483 case eColorID_TextSelectForeground:
484 case eColorID_TextSelectBackgroundDisabled:
485 case eColorID_TextSelectBackgroundAttention:
486 case eColorID_TextHighlightBackground:
487 case eColorID_TextHighlightForeground:
488 case eColorID_IMERawInputBackground:
489 case eColorID_IMERawInputForeground:
490 case eColorID_IMERawInputUnderline:
491 case eColorID_IMESelectedRawTextBackground:
492 case eColorID_IMESelectedRawTextForeground:
493 case eColorID_IMESelectedRawTextUnderline:
494 case eColorID_IMEConvertedTextBackground:
495 case eColorID_IMEConvertedTextForeground:
496 case eColorID_IMEConvertedTextUnderline:
497 case eColorID_IMESelectedConvertedTextBackground:
498 case eColorID_IMESelectedConvertedTextForeground:
499 case eColorID_IMESelectedConvertedTextUnderline:
500 case eColorID_SpellCheckerUnderline:
501 result = true;
502 break;
503 default:
504 break;
507 return result;
510 nscolor nsXPLookAndFeel::GetStandinForNativeColor(ColorID aID) {
511 nscolor result = NS_RGB(0xFF, 0xFF, 0xFF);
513 // The stand-in colors are taken from the Windows 7 Aero theme
514 // except Mac-specific colors which are taken from Mac OS 10.7.
515 switch (aID) {
516 // CSS 2 colors:
517 case eColorID_activeborder:
518 result = NS_RGB(0xB4, 0xB4, 0xB4);
519 break;
520 case eColorID_activecaption:
521 result = NS_RGB(0x99, 0xB4, 0xD1);
522 break;
523 case eColorID_appworkspace:
524 result = NS_RGB(0xAB, 0xAB, 0xAB);
525 break;
526 case eColorID_background:
527 result = NS_RGB(0x00, 0x00, 0x00);
528 break;
529 case eColorID_buttonface:
530 result = NS_RGB(0xF0, 0xF0, 0xF0);
531 break;
532 case eColorID_buttonhighlight:
533 result = NS_RGB(0xFF, 0xFF, 0xFF);
534 break;
535 case eColorID_buttonshadow:
536 result = NS_RGB(0xA0, 0xA0, 0xA0);
537 break;
538 case eColorID_buttontext:
539 result = NS_RGB(0x00, 0x00, 0x00);
540 break;
541 case eColorID_captiontext:
542 result = NS_RGB(0x00, 0x00, 0x00);
543 break;
544 case eColorID_graytext:
545 result = NS_RGB(0x6D, 0x6D, 0x6D);
546 break;
547 case eColorID_highlight:
548 result = NS_RGB(0x33, 0x99, 0xFF);
549 break;
550 case eColorID_highlighttext:
551 result = NS_RGB(0xFF, 0xFF, 0xFF);
552 break;
553 case eColorID_inactiveborder:
554 result = NS_RGB(0xF4, 0xF7, 0xFC);
555 break;
556 case eColorID_inactivecaption:
557 result = NS_RGB(0xBF, 0xCD, 0xDB);
558 break;
559 case eColorID_inactivecaptiontext:
560 result = NS_RGB(0x43, 0x4E, 0x54);
561 break;
562 case eColorID_infobackground:
563 result = NS_RGB(0xFF, 0xFF, 0xE1);
564 break;
565 case eColorID_infotext:
566 result = NS_RGB(0x00, 0x00, 0x00);
567 break;
568 case eColorID_menu:
569 result = NS_RGB(0xF0, 0xF0, 0xF0);
570 break;
571 case eColorID_menutext:
572 result = NS_RGB(0x00, 0x00, 0x00);
573 break;
574 case eColorID_scrollbar:
575 result = NS_RGB(0xC8, 0xC8, 0xC8);
576 break;
577 case eColorID_threeddarkshadow:
578 result = NS_RGB(0x69, 0x69, 0x69);
579 break;
580 case eColorID_threedface:
581 result = NS_RGB(0xF0, 0xF0, 0xF0);
582 break;
583 case eColorID_threedhighlight:
584 result = NS_RGB(0xFF, 0xFF, 0xFF);
585 break;
586 case eColorID_threedlightshadow:
587 result = NS_RGB(0xE3, 0xE3, 0xE3);
588 break;
589 case eColorID_threedshadow:
590 result = NS_RGB(0xA0, 0xA0, 0xA0);
591 break;
592 case eColorID_window:
593 result = NS_RGB(0xFF, 0xFF, 0xFF);
594 break;
595 case eColorID_windowframe:
596 result = NS_RGB(0x64, 0x64, 0x64);
597 break;
598 case eColorID_windowtext:
599 result = NS_RGB(0x00, 0x00, 0x00);
600 break;
601 case eColorID__moz_buttondefault:
602 result = NS_RGB(0x69, 0x69, 0x69);
603 break;
604 case eColorID__moz_field:
605 result = NS_RGB(0xFF, 0xFF, 0xFF);
606 break;
607 case eColorID__moz_fieldtext:
608 result = NS_RGB(0x00, 0x00, 0x00);
609 break;
610 case eColorID__moz_dialog:
611 result = NS_RGB(0xF0, 0xF0, 0xF0);
612 break;
613 case eColorID__moz_dialogtext:
614 result = NS_RGB(0x00, 0x00, 0x00);
615 break;
616 case eColorID__moz_dragtargetzone:
617 result = NS_RGB(0xFF, 0xFF, 0xFF);
618 break;
619 case eColorID__moz_cellhighlight:
620 result = NS_RGB(0xF0, 0xF0, 0xF0);
621 break;
622 case eColorID__moz_cellhighlighttext:
623 result = NS_RGB(0x00, 0x00, 0x00);
624 break;
625 case eColorID__moz_html_cellhighlight:
626 result = NS_RGB(0x33, 0x99, 0xFF);
627 break;
628 case eColorID__moz_html_cellhighlighttext:
629 result = NS_RGB(0xFF, 0xFF, 0xFF);
630 break;
631 case eColorID__moz_buttonhoverface:
632 result = NS_RGB(0xF0, 0xF0, 0xF0);
633 break;
634 case eColorID__moz_buttonhovertext:
635 result = NS_RGB(0x00, 0x00, 0x00);
636 break;
637 case eColorID__moz_menuhover:
638 result = NS_RGB(0x33, 0x99, 0xFF);
639 break;
640 case eColorID__moz_menuhovertext:
641 result = NS_RGB(0x00, 0x00, 0x00);
642 break;
643 case eColorID__moz_menubartext:
644 result = NS_RGB(0x00, 0x00, 0x00);
645 break;
646 case eColorID__moz_menubarhovertext:
647 result = NS_RGB(0x00, 0x00, 0x00);
648 break;
649 case eColorID__moz_oddtreerow:
650 result = NS_RGB(0xFF, 0xFF, 0xFF);
651 break;
652 case eColorID__moz_mac_chrome_active:
653 result = NS_RGB(0xB2, 0xB2, 0xB2);
654 break;
655 case eColorID__moz_mac_chrome_inactive:
656 result = NS_RGB(0xE1, 0xE1, 0xE1);
657 break;
658 case eColorID__moz_mac_focusring:
659 result = NS_RGB(0x60, 0x9D, 0xD7);
660 break;
661 case eColorID__moz_mac_menuselect:
662 result = NS_RGB(0x38, 0x75, 0xD7);
663 break;
664 case eColorID__moz_mac_menushadow:
665 result = NS_RGB(0xA3, 0xA3, 0xA3);
666 break;
667 case eColorID__moz_mac_menutextdisable:
668 result = NS_RGB(0x88, 0x88, 0x88);
669 break;
670 case eColorID__moz_mac_menutextselect:
671 result = NS_RGB(0xFF, 0xFF, 0xFF);
672 break;
673 case eColorID__moz_mac_disabledtoolbartext:
674 result = NS_RGB(0x3F, 0x3F, 0x3F);
675 break;
676 case eColorID__moz_mac_secondaryhighlight:
677 result = NS_RGB(0xD4, 0xD4, 0xD4);
678 break;
679 case eColorID__moz_mac_vibrancy_light:
680 case eColorID__moz_mac_vibrant_titlebar_light:
681 result = NS_RGB(0xf7, 0xf7, 0xf7);
682 break;
683 case eColorID__moz_mac_vibrancy_dark:
684 case eColorID__moz_mac_vibrant_titlebar_dark:
685 result = NS_RGB(0x28, 0x28, 0x28);
686 break;
687 case eColorID__moz_mac_menupopup:
688 result = NS_RGB(0xe6, 0xe6, 0xe6);
689 break;
690 case eColorID__moz_mac_menuitem:
691 result = NS_RGB(0xe6, 0xe6, 0xe6);
692 break;
693 case eColorID__moz_mac_active_menuitem:
694 result = NS_RGB(0x0a, 0x64, 0xdc);
695 break;
696 case eColorID__moz_mac_source_list:
697 result = NS_RGB(0xf7, 0xf7, 0xf7);
698 break;
699 case eColorID__moz_mac_source_list_selection:
700 result = NS_RGB(0xc8, 0xc8, 0xc8);
701 break;
702 case eColorID__moz_mac_active_source_list_selection:
703 result = NS_RGB(0x0a, 0x64, 0xdc);
704 break;
705 case eColorID__moz_mac_tooltip:
706 result = NS_RGB(0xf7, 0xf7, 0xf7);
707 break;
708 case eColorID__moz_win_accentcolor:
709 // Seems to be the default color (hardcoded because of bug 1065998)
710 result = NS_RGB(0x9E, 0x9E, 0x9E);
711 break;
712 case eColorID__moz_win_accentcolortext:
713 result = NS_RGB(0x00, 0x00, 0x00);
714 break;
715 case eColorID__moz_win_mediatext:
716 result = NS_RGB(0xFF, 0xFF, 0xFF);
717 break;
718 case eColorID__moz_win_communicationstext:
719 result = NS_RGB(0xFF, 0xFF, 0xFF);
720 break;
721 case eColorID__moz_nativehyperlinktext:
722 result = NS_RGB(0x00, 0x66, 0xCC);
723 break;
724 case eColorID__moz_comboboxtext:
725 result = NS_RGB(0x00, 0x00, 0x00);
726 break;
727 case eColorID__moz_combobox:
728 result = NS_RGB(0xFF, 0xFF, 0xFF);
729 break;
730 default:
731 break;
734 return result;
738 // All these routines will return NS_OK if they have a value,
739 // in which case the nsLookAndFeel should use that value;
740 // otherwise we'll return NS_ERROR_NOT_AVAILABLE, in which case, the
741 // platform-specific nsLookAndFeel should use its own values instead.
743 nsresult nsXPLookAndFeel::GetColorImpl(ColorID aID,
744 bool aUseStandinsForNativeColors,
745 nscolor& aResult) {
746 if (!sInitialized) Init();
748 // define DEBUG_SYSTEM_COLOR_USE if you want to debug system color
749 // use in a skin that uses them. When set, it will make all system
750 // color pairs that are appropriate for foreground/background
751 // pairing the same. This means if the skin is using system colors
752 // correctly you will not be able to see *any* text.
753 #undef DEBUG_SYSTEM_COLOR_USE
755 #ifdef DEBUG_SYSTEM_COLOR_USE
757 nsresult rv = NS_OK;
758 switch (aID) {
759 // css2 http://www.w3.org/TR/REC-CSS2/ui.html#system-colors
760 case eColorID_activecaption:
761 // active window caption background
762 case eColorID_captiontext:
763 // text in active window caption
764 aResult = NS_RGB(0xff, 0x00, 0x00);
765 break;
767 case eColorID_highlight:
768 // background of selected item
769 case eColorID_highlighttext:
770 // text of selected item
771 aResult = NS_RGB(0xff, 0xff, 0x00);
772 break;
774 case eColorID_inactivecaption:
775 // inactive window caption
776 case eColorID_inactivecaptiontext:
777 // text in inactive window caption
778 aResult = NS_RGB(0x66, 0x66, 0x00);
779 break;
781 case eColorID_infobackground:
782 // tooltip background color
783 case eColorID_infotext:
784 // tooltip text color
785 aResult = NS_RGB(0x00, 0xff, 0x00);
786 break;
788 case eColorID_menu:
789 // menu background
790 case eColorID_menutext:
791 // menu text
792 aResult = NS_RGB(0x00, 0xff, 0xff);
793 break;
795 case eColorID_threedface:
796 case eColorID_buttonface:
797 // 3-D face color
798 case eColorID_buttontext:
799 // text on push buttons
800 aResult = NS_RGB(0x00, 0x66, 0x66);
801 break;
803 case eColorID_window:
804 case eColorID_windowtext:
805 aResult = NS_RGB(0x00, 0x00, 0xff);
806 break;
808 // from the CSS3 working draft (not yet finalized)
809 // http://www.w3.org/tr/2000/wd-css3-userint-20000216.html#color
811 case eColorID__moz_field:
812 case eColorID__moz_fieldtext:
813 aResult = NS_RGB(0xff, 0x00, 0xff);
814 break;
816 case eColorID__moz_dialog:
817 case eColorID__moz_dialogtext:
818 aResult = NS_RGB(0x66, 0x00, 0x66);
819 break;
821 default:
822 rv = NS_ERROR_NOT_AVAILABLE;
824 if (NS_SUCCEEDED(rv)) return rv;
826 #endif // DEBUG_SYSTEM_COLOR_USE
828 if (aUseStandinsForNativeColors &&
829 (ColorIsNotCSSAccessible(aID) ||
830 !nsContentUtils::UseStandinsForNativeColors())) {
831 aUseStandinsForNativeColors = false;
834 if (!aUseStandinsForNativeColors && IS_COLOR_CACHED(aID)) {
835 aResult = sCachedColors[aID];
836 return NS_OK;
839 // There are no system color settings for these, so set them manually
840 #ifndef XP_MACOSX
841 if (aID == eColorID_TextSelectBackgroundDisabled) {
842 // This is used to gray out the selection when it's not focused
843 // Used with nsISelectionController::SELECTION_DISABLED
844 aResult = NS_RGB(0xb0, 0xb0, 0xb0);
845 return NS_OK;
847 #endif
849 if (aID == eColorID_TextSelectBackgroundAttention) {
850 if (sFindbarModalHighlight) {
851 aResult = NS_RGBA(0, 0, 0, 0);
852 return NS_OK;
855 // This makes the selection stand out when typeaheadfind is on
856 // Used with nsISelectionController::SELECTION_ATTENTION
857 aResult = NS_RGB(0x38, 0xd8, 0x78);
858 return NS_OK;
861 if (aID == eColorID_TextHighlightBackground) {
862 // This makes the matched text stand out when findbar highlighting is on
863 // Used with nsISelectionController::SELECTION_FIND
864 aResult = NS_RGB(0xef, 0x0f, 0xff);
865 return NS_OK;
868 if (aID == eColorID_TextHighlightForeground) {
869 // The foreground color for the matched text in findbar highlighting
870 // Used with nsISelectionController::SELECTION_FIND
871 aResult = NS_RGB(0xff, 0xff, 0xff);
872 return NS_OK;
875 if (sUseNativeColors && aUseStandinsForNativeColors) {
876 aResult = GetStandinForNativeColor(aID);
877 return NS_OK;
880 if (sUseNativeColors && NS_SUCCEEDED(NativeGetColor(aID, aResult))) {
881 if (!mozilla::ServoStyleSet::IsInServoTraversal()) {
882 MOZ_ASSERT(NS_IsMainThread());
883 // Make sure the preferences are initialized. In the normal run,
884 // they would already be, because gfxPlatform would have been created,
885 // but with some addon, that is not the case. See Bug 1357307.
886 gfxPrefs::GetSingleton();
887 if ((gfxPlatform::GetCMSMode() == eCMSMode_All) &&
888 !IsSpecialColor(aID, aResult)) {
889 qcms_transform* transform = gfxPlatform::GetCMSInverseRGBTransform();
890 if (transform) {
891 uint8_t color[3];
892 color[0] = NS_GET_R(aResult);
893 color[1] = NS_GET_G(aResult);
894 color[2] = NS_GET_B(aResult);
895 qcms_transform_data(transform, color, color, 1);
896 aResult = NS_RGB(color[0], color[1], color[2]);
900 CACHE_COLOR(aID, aResult);
902 return NS_OK;
905 return NS_ERROR_NOT_AVAILABLE;
908 nsresult nsXPLookAndFeel::GetIntImpl(IntID aID, int32_t& aResult) {
909 if (!sInitialized) Init();
911 // Set the default values for these prefs. but allow different platforms
912 // to override them in their nsLookAndFeel if desired.
913 switch (aID) {
914 case eIntID_ScrollButtonLeftMouseButtonAction:
915 aResult = 0;
916 return NS_OK;
917 case eIntID_ScrollButtonMiddleMouseButtonAction:
918 aResult = 3;
919 return NS_OK;
920 case eIntID_ScrollButtonRightMouseButtonAction:
921 aResult = 3;
922 return NS_OK;
923 default:
925 * The metrics above are hardcoded platform defaults. All the other
926 * metrics are stored in sIntPrefs and can be changed at runtime.
928 break;
931 for (unsigned int i = 0; i < ArrayLength(sIntPrefs); ++i) {
932 if (sIntPrefs[i].isSet && (sIntPrefs[i].id == aID)) {
933 aResult = sIntPrefs[i].intVar;
934 return NS_OK;
938 return NS_ERROR_NOT_AVAILABLE;
941 nsresult nsXPLookAndFeel::GetFloatImpl(FloatID aID, float& aResult) {
942 if (!sInitialized) Init();
944 for (unsigned int i = 0; i < ArrayLength(sFloatPrefs); ++i) {
945 if (sFloatPrefs[i].isSet && sFloatPrefs[i].id == aID) {
946 aResult = sFloatPrefs[i].floatVar;
947 return NS_OK;
951 return NS_ERROR_NOT_AVAILABLE;
954 void nsXPLookAndFeel::RefreshImpl() {
955 // Wipe out our color cache.
956 uint32_t i;
957 for (i = 0; i < eColorID_LAST_COLOR; i++) sCachedColors[i] = 0;
958 for (i = 0; i < COLOR_CACHE_SIZE; i++) sCachedColorBits[i] = 0;
961 nsTArray<LookAndFeelInt> nsXPLookAndFeel::GetIntCacheImpl() {
962 return nsTArray<LookAndFeelInt>();
965 namespace mozilla {
967 // static
968 nsresult LookAndFeel::GetColor(ColorID aID, nscolor* aResult) {
969 return nsLookAndFeel::GetInstance()->GetColorImpl(aID, false, *aResult);
972 nsresult LookAndFeel::GetColor(ColorID aID, bool aUseStandinsForNativeColors,
973 nscolor* aResult) {
974 return nsLookAndFeel::GetInstance()->GetColorImpl(
975 aID, aUseStandinsForNativeColors, *aResult);
978 // static
979 nsresult LookAndFeel::GetInt(IntID aID, int32_t* aResult) {
980 return nsLookAndFeel::GetInstance()->GetIntImpl(aID, *aResult);
983 // static
984 nsresult LookAndFeel::GetFloat(FloatID aID, float* aResult) {
985 return nsLookAndFeel::GetInstance()->GetFloatImpl(aID, *aResult);
988 // static
989 bool LookAndFeel::GetFont(FontID aID, nsString& aName, gfxFontStyle& aStyle,
990 float aDevPixPerCSSPixel) {
991 return nsLookAndFeel::GetInstance()->GetFontImpl(aID, aName, aStyle,
992 aDevPixPerCSSPixel);
995 // static
996 char16_t LookAndFeel::GetPasswordCharacter() {
997 return nsLookAndFeel::GetInstance()->GetPasswordCharacterImpl();
1000 // static
1001 bool LookAndFeel::GetEchoPassword() {
1002 return nsLookAndFeel::GetInstance()->GetEchoPasswordImpl();
1005 // static
1006 uint32_t LookAndFeel::GetPasswordMaskDelay() {
1007 return nsLookAndFeel::GetInstance()->GetPasswordMaskDelayImpl();
1010 // static
1011 void LookAndFeel::Refresh() { nsLookAndFeel::GetInstance()->RefreshImpl(); }
1013 // static
1014 void LookAndFeel::NativeInit() { nsLookAndFeel::GetInstance()->NativeInit(); }
1016 // static
1017 nsTArray<LookAndFeelInt> LookAndFeel::GetIntCache() {
1018 return nsLookAndFeel::GetInstance()->GetIntCacheImpl();
1021 // static
1022 void LookAndFeel::SetIntCache(
1023 const nsTArray<LookAndFeelInt>& aLookAndFeelIntCache) {
1024 return nsLookAndFeel::GetInstance()->SetIntCacheImpl(aLookAndFeelIntCache);
1027 // static
1028 void LookAndFeel::SetShouldRetainCacheForTest(bool aValue) {
1029 nsLookAndFeel::GetInstance()->SetShouldRetainCacheImplForTest(aValue);
1032 } // namespace mozilla