Coverage Report

Created: 2018-09-25 14:53

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