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