1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/dom/ContentChild.h"
7 #include "nsStyleConsts.h"
8 #include "nsXULAppAPI.h"
9 #include "nsLookAndFeel.h"
10 #include "gfxFont.h"
11 #include "gfxFontConstants.h"
12 #include "mozilla/gfx/2D.h"
13 
14 using namespace mozilla;
15 using mozilla::dom::ContentChild;
16 
17 bool nsLookAndFeel::mInitializedSystemColors = false;
18 AndroidSystemColors nsLookAndFeel::mSystemColors;
19 
20 bool nsLookAndFeel::mInitializedShowPassword = false;
21 bool nsLookAndFeel::mShowPassword = true;
22 
23 static const char16_t UNICODE_BULLET = 0x2022;
24 
nsLookAndFeel()25 nsLookAndFeel::nsLookAndFeel()
26     : nsXPLookAndFeel()
27 {
28 }
29 
~nsLookAndFeel()30 nsLookAndFeel::~nsLookAndFeel()
31 {
32 }
33 
34 #define BG_PRELIGHT_COLOR      NS_RGB(0xee,0xee,0xee)
35 #define FG_PRELIGHT_COLOR      NS_RGB(0x77,0x77,0x77)
36 #define BLACK_COLOR            NS_RGB(0x00,0x00,0x00)
37 #define DARK_GRAY_COLOR        NS_RGB(0x40,0x40,0x40)
38 #define GRAY_COLOR             NS_RGB(0x80,0x80,0x80)
39 #define LIGHT_GRAY_COLOR       NS_RGB(0xa0,0xa0,0xa0)
40 #define RED_COLOR              NS_RGB(0xff,0x00,0x00)
41 
42 nsresult
GetSystemColors()43 nsLookAndFeel::GetSystemColors()
44 {
45     if (mInitializedSystemColors)
46         return NS_OK;
47 
48     if (!AndroidBridge::Bridge())
49         return NS_ERROR_FAILURE;
50 
51     AndroidBridge::Bridge()->GetSystemColors(&mSystemColors);
52 
53     mInitializedSystemColors = true;
54 
55     return NS_OK;
56 }
57 
58 nsresult
CallRemoteGetSystemColors()59 nsLookAndFeel::CallRemoteGetSystemColors()
60 {
61     // An array has to be used to get data from remote process
62     InfallibleTArray<uint32_t> colors;
63     uint32_t colorsCount = sizeof(AndroidSystemColors) / sizeof(nscolor);
64 
65     if (!ContentChild::GetSingleton()->SendGetSystemColors(colorsCount, &colors))
66         return NS_ERROR_FAILURE;
67 
68     NS_ASSERTION(colors.Length() == colorsCount, "System colors array is incomplete");
69     if (colors.Length() == 0)
70         return NS_ERROR_FAILURE;
71 
72     if (colors.Length() < colorsCount)
73         colorsCount = colors.Length();
74 
75     // Array elements correspond to the members of mSystemColors structure,
76     // so just copy the memory block
77     memcpy(&mSystemColors, colors.Elements(), sizeof(nscolor) * colorsCount);
78 
79     mInitializedSystemColors = true;
80 
81     return NS_OK;
82 }
83 
84 nsresult
NativeGetColor(ColorID aID,nscolor & aColor)85 nsLookAndFeel::NativeGetColor(ColorID aID, nscolor &aColor)
86 {
87     nsresult rv = NS_OK;
88 
89     if (!mInitializedSystemColors) {
90         if (XRE_IsParentProcess())
91             rv = GetSystemColors();
92         else
93             rv = CallRemoteGetSystemColors();
94         NS_ENSURE_SUCCESS(rv, rv);
95     }
96 
97     // XXX we'll want to use context.obtainStyledAttributes on the java side to
98     // get all of these; see TextView.java for a good exmaple.
99 
100     switch (aID) {
101         // These colors don't seem to be used for anything anymore in Mozilla
102         // (except here at least TextSelectBackground and TextSelectForeground)
103         // The CSS2 colors below are used.
104     case eColorID_WindowBackground:
105         aColor = NS_RGB(0xFF, 0xFF, 0xFF);
106         break;
107     case eColorID_WindowForeground:
108         aColor = mSystemColors.textColorPrimary;
109         break;
110     case eColorID_WidgetBackground:
111         aColor = mSystemColors.colorBackground;
112         break;
113     case eColorID_WidgetForeground:
114         aColor = mSystemColors.colorForeground;
115         break;
116     case eColorID_WidgetSelectBackground:
117         aColor = mSystemColors.textColorHighlight;
118         break;
119     case eColorID_WidgetSelectForeground:
120         aColor = mSystemColors.textColorPrimaryInverse;
121         break;
122     case eColorID_Widget3DHighlight:
123         aColor = LIGHT_GRAY_COLOR;
124         break;
125     case eColorID_Widget3DShadow:
126         aColor = DARK_GRAY_COLOR;
127         break;
128     case eColorID_TextBackground:
129         // not used?
130         aColor = mSystemColors.colorBackground;
131         break;
132     case eColorID_TextForeground:
133         // not used?
134         aColor = mSystemColors.textColorPrimary;
135         break;
136     case eColorID_TextSelectBackground:
137     case eColorID_IMESelectedRawTextBackground:
138     case eColorID_IMESelectedConvertedTextBackground:
139         // still used
140         aColor = mSystemColors.textColorHighlight;
141         break;
142     case eColorID_TextSelectForeground:
143     case eColorID_IMESelectedRawTextForeground:
144     case eColorID_IMESelectedConvertedTextForeground:
145         // still used
146         aColor = mSystemColors.textColorPrimaryInverse;
147         break;
148     case eColorID_IMERawInputBackground:
149     case eColorID_IMEConvertedTextBackground:
150         aColor = NS_TRANSPARENT;
151         break;
152     case eColorID_IMERawInputForeground:
153     case eColorID_IMEConvertedTextForeground:
154         aColor = NS_SAME_AS_FOREGROUND_COLOR;
155         break;
156     case eColorID_IMERawInputUnderline:
157     case eColorID_IMEConvertedTextUnderline:
158         aColor = NS_SAME_AS_FOREGROUND_COLOR;
159         break;
160     case eColorID_IMESelectedRawTextUnderline:
161     case eColorID_IMESelectedConvertedTextUnderline:
162         aColor = NS_TRANSPARENT;
163         break;
164     case eColorID_SpellCheckerUnderline:
165       aColor = RED_COLOR;
166       break;
167 
168         // css2  http://www.w3.org/TR/REC-CSS2/ui.html#system-colors
169     case eColorID_activeborder:
170         // active window border
171         aColor = mSystemColors.colorBackground;
172         break;
173     case eColorID_activecaption:
174         // active window caption background
175         aColor = mSystemColors.colorBackground;
176         break;
177     case eColorID_appworkspace:
178         // MDI background color
179         aColor = mSystemColors.colorBackground;
180         break;
181     case eColorID_background:
182         // desktop background
183         aColor = mSystemColors.colorBackground;
184         break;
185     case eColorID_captiontext:
186         // text in active window caption, size box, and scrollbar arrow box (!)
187         aColor = mSystemColors.colorForeground;
188         break;
189     case eColorID_graytext:
190         // disabled text in windows, menus, etc.
191         aColor = mSystemColors.textColorTertiary;
192         break;
193     case eColorID_highlight:
194         // background of selected item
195         aColor = mSystemColors.textColorHighlight;
196         break;
197     case eColorID_highlighttext:
198         // text of selected item
199         aColor = mSystemColors.textColorPrimaryInverse;
200         break;
201     case eColorID_inactiveborder:
202         // inactive window border
203         aColor = mSystemColors.colorBackground;
204         break;
205     case eColorID_inactivecaption:
206         // inactive window caption
207         aColor = mSystemColors.colorBackground;
208         break;
209     case eColorID_inactivecaptiontext:
210         // text in inactive window caption
211         aColor = mSystemColors.textColorTertiary;
212         break;
213     case eColorID_infobackground:
214         // tooltip background color
215         aColor = mSystemColors.colorBackground;
216         break;
217     case eColorID_infotext:
218         // tooltip text color
219         aColor = mSystemColors.colorForeground;
220         break;
221     case eColorID_menu:
222         // menu background
223         aColor = mSystemColors.colorBackground;
224         break;
225     case eColorID_menutext:
226         // menu text
227         aColor = mSystemColors.colorForeground;
228         break;
229     case eColorID_scrollbar:
230         // scrollbar gray area
231         aColor = mSystemColors.colorBackground;
232         break;
233 
234     case eColorID_threedface:
235     case eColorID_buttonface:
236         // 3-D face color
237         aColor = mSystemColors.colorBackground;
238         break;
239 
240     case eColorID_buttontext:
241         // text on push buttons
242         aColor = mSystemColors.colorForeground;
243         break;
244 
245     case eColorID_buttonhighlight:
246         // 3-D highlighted edge color
247     case eColorID_threedhighlight:
248         // 3-D highlighted outer edge color
249         aColor = LIGHT_GRAY_COLOR;
250         break;
251 
252     case eColorID_threedlightshadow:
253         // 3-D highlighted inner edge color
254         aColor = mSystemColors.colorBackground;
255         break;
256 
257     case eColorID_buttonshadow:
258         // 3-D shadow edge color
259     case eColorID_threedshadow:
260         // 3-D shadow inner edge color
261         aColor = GRAY_COLOR;
262         break;
263 
264     case eColorID_threeddarkshadow:
265         // 3-D shadow outer edge color
266         aColor = BLACK_COLOR;
267         break;
268 
269     case eColorID_window:
270     case eColorID_windowframe:
271         aColor = mSystemColors.colorBackground;
272         break;
273 
274     case eColorID_windowtext:
275         aColor = mSystemColors.textColorPrimary;
276         break;
277 
278     case eColorID__moz_eventreerow:
279     case eColorID__moz_field:
280         aColor = mSystemColors.colorBackground;
281         break;
282     case eColorID__moz_fieldtext:
283         aColor = mSystemColors.textColorPrimary;
284         break;
285     case eColorID__moz_dialog:
286         aColor = mSystemColors.colorBackground;
287         break;
288     case eColorID__moz_dialogtext:
289         aColor = mSystemColors.colorForeground;
290         break;
291     case eColorID__moz_dragtargetzone:
292         aColor = mSystemColors.textColorHighlight;
293         break;
294     case eColorID__moz_buttondefault:
295         // default button border color
296         aColor = BLACK_COLOR;
297         break;
298     case eColorID__moz_buttonhoverface:
299         aColor = BG_PRELIGHT_COLOR;
300         break;
301     case eColorID__moz_buttonhovertext:
302         aColor = FG_PRELIGHT_COLOR;
303         break;
304     case eColorID__moz_cellhighlight:
305     case eColorID__moz_html_cellhighlight:
306         aColor = mSystemColors.textColorHighlight;
307         break;
308     case eColorID__moz_cellhighlighttext:
309     case eColorID__moz_html_cellhighlighttext:
310         aColor = mSystemColors.textColorPrimaryInverse;
311         break;
312     case eColorID__moz_menuhover:
313         aColor = BG_PRELIGHT_COLOR;
314         break;
315     case eColorID__moz_menuhovertext:
316         aColor = FG_PRELIGHT_COLOR;
317         break;
318     case eColorID__moz_oddtreerow:
319         aColor = NS_TRANSPARENT;
320         break;
321     case eColorID__moz_nativehyperlinktext:
322         aColor = NS_SAME_AS_FOREGROUND_COLOR;
323         break;
324     case eColorID__moz_comboboxtext:
325         aColor = mSystemColors.colorForeground;
326         break;
327     case eColorID__moz_combobox:
328         aColor = mSystemColors.colorBackground;
329         break;
330     case eColorID__moz_menubartext:
331         aColor = mSystemColors.colorForeground;
332         break;
333     case eColorID__moz_menubarhovertext:
334         aColor = FG_PRELIGHT_COLOR;
335         break;
336     default:
337         /* default color is BLACK */
338         aColor = 0;
339         rv = NS_ERROR_FAILURE;
340         break;
341     }
342 
343     return rv;
344 }
345 
346 
347 nsresult
GetIntImpl(IntID aID,int32_t & aResult)348 nsLookAndFeel::GetIntImpl(IntID aID, int32_t &aResult)
349 {
350     nsresult rv = nsXPLookAndFeel::GetIntImpl(aID, aResult);
351     if (NS_SUCCEEDED(rv))
352         return rv;
353 
354     rv = NS_OK;
355 
356     switch (aID) {
357         case eIntID_CaretBlinkTime:
358             aResult = 500;
359             break;
360 
361         case eIntID_CaretWidth:
362             aResult = 1;
363             break;
364 
365         case eIntID_ShowCaretDuringSelection:
366             aResult = 0;
367             break;
368 
369         case eIntID_SelectTextfieldsOnKeyFocus:
370             // Select textfield content when focused by kbd
371             // used by EventStateManager::sTextfieldSelectModel
372             aResult = 1;
373             break;
374 
375         case eIntID_SubmenuDelay:
376             aResult = 200;
377             break;
378 
379         case eIntID_TooltipDelay:
380             aResult = 500;
381             break;
382 
383         case eIntID_MenusCanOverlapOSBar:
384             // we want XUL popups to be able to overlap the task bar.
385             aResult = 1;
386             break;
387 
388         case eIntID_ScrollArrowStyle:
389             aResult = eScrollArrowStyle_Single;
390             break;
391 
392         case eIntID_ScrollSliderStyle:
393             aResult = eScrollThumbStyle_Proportional;
394             break;
395 
396         case eIntID_TouchEnabled:
397             aResult = 1;
398             break;
399 
400         case eIntID_ColorPickerAvailable:
401             aResult = 1;
402             break;
403 
404         case eIntID_WindowsDefaultTheme:
405         case eIntID_WindowsThemeIdentifier:
406         case eIntID_OperatingSystemVersionIdentifier:
407             aResult = 0;
408             rv = NS_ERROR_NOT_IMPLEMENTED;
409             break;
410 
411         case eIntID_SpellCheckerUnderlineStyle:
412             aResult = NS_STYLE_TEXT_DECORATION_STYLE_WAVY;
413             break;
414 
415         case eIntID_ScrollbarButtonAutoRepeatBehavior:
416             aResult = 0;
417             break;
418 
419         case eIntID_ContextMenuOffsetVertical:
420         case eIntID_ContextMenuOffsetHorizontal:
421             aResult = 2;
422             break;
423 
424         default:
425             aResult = 0;
426             rv = NS_ERROR_FAILURE;
427     }
428 
429     return rv;
430 }
431 
432 nsresult
GetFloatImpl(FloatID aID,float & aResult)433 nsLookAndFeel::GetFloatImpl(FloatID aID, float &aResult)
434 {
435     nsresult rv = nsXPLookAndFeel::GetFloatImpl(aID, aResult);
436     if (NS_SUCCEEDED(rv))
437         return rv;
438     rv = NS_OK;
439 
440     switch (aID) {
441         case eFloatID_IMEUnderlineRelativeSize:
442             aResult = 1.0f;
443             break;
444 
445         case eFloatID_SpellCheckerUnderlineRelativeSize:
446             aResult = 1.0f;
447             break;
448 
449         default:
450             aResult = -1.0;
451             rv = NS_ERROR_FAILURE;
452             break;
453     }
454     return rv;
455 }
456 
457 /*virtual*/
458 bool
GetFontImpl(FontID aID,nsString & aFontName,gfxFontStyle & aFontStyle,float aDevPixPerCSSPixel)459 nsLookAndFeel::GetFontImpl(FontID aID, nsString& aFontName,
460                            gfxFontStyle& aFontStyle,
461                            float aDevPixPerCSSPixel)
462 {
463     aFontName.AssignLiteral("\"Droid Sans\"");
464     aFontStyle.style = NS_FONT_STYLE_NORMAL;
465     aFontStyle.weight = NS_FONT_WEIGHT_NORMAL;
466     aFontStyle.stretch = NS_FONT_STRETCH_NORMAL;
467     aFontStyle.size = 9.0 * 96.0f / 72.0f * aDevPixPerCSSPixel;
468     aFontStyle.systemFont = true;
469     return true;
470 }
471 
472 /*virtual*/
473 bool
GetEchoPasswordImpl()474 nsLookAndFeel::GetEchoPasswordImpl()
475 {
476     if (!mInitializedShowPassword) {
477         if (XRE_IsParentProcess()) {
478             mShowPassword = java::GeckoAppShell::GetShowPasswordSetting();
479         } else {
480             ContentChild::GetSingleton()->SendGetShowPasswordSetting(&mShowPassword);
481         }
482         mInitializedShowPassword = true;
483     }
484     return mShowPassword;
485 }
486 
487 uint32_t
GetPasswordMaskDelayImpl()488 nsLookAndFeel::GetPasswordMaskDelayImpl()
489 {
490   // This value is hard-coded in Android OS's PasswordTransformationMethod.java
491   return 1500;
492 }
493 
494 /* virtual */
495 char16_t
GetPasswordCharacterImpl()496 nsLookAndFeel::GetPasswordCharacterImpl()
497 {
498   // This value is hard-coded in Android OS's PasswordTransformationMethod.java
499   return UNICODE_BULLET;
500 }
501