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