michael@0: /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "mozilla/dom/ContentChild.h" michael@0: #include "nsStyleConsts.h" michael@0: #include "nsXULAppAPI.h" michael@0: #include "nsLookAndFeel.h" michael@0: #include "gfxFont.h" michael@0: #include "gfxFontConstants.h" michael@0: #include "mozilla/gfx/2D.h" michael@0: michael@0: using namespace mozilla; michael@0: using mozilla::dom::ContentChild; michael@0: michael@0: bool nsLookAndFeel::mInitializedSystemColors = false; michael@0: AndroidSystemColors nsLookAndFeel::mSystemColors; michael@0: michael@0: bool nsLookAndFeel::mInitializedShowPassword = false; michael@0: bool nsLookAndFeel::mShowPassword = true; michael@0: michael@0: static const char16_t UNICODE_BULLET = 0x2022; michael@0: michael@0: nsLookAndFeel::nsLookAndFeel() michael@0: : nsXPLookAndFeel() michael@0: { michael@0: } michael@0: michael@0: nsLookAndFeel::~nsLookAndFeel() michael@0: { michael@0: } michael@0: michael@0: #define BG_PRELIGHT_COLOR NS_RGB(0xee,0xee,0xee) michael@0: #define FG_PRELIGHT_COLOR NS_RGB(0x77,0x77,0x77) michael@0: #define BLACK_COLOR NS_RGB(0x00,0x00,0x00) michael@0: #define DARK_GRAY_COLOR NS_RGB(0x40,0x40,0x40) michael@0: #define GRAY_COLOR NS_RGB(0x80,0x80,0x80) michael@0: #define LIGHT_GRAY_COLOR NS_RGB(0xa0,0xa0,0xa0) michael@0: #define RED_COLOR NS_RGB(0xff,0x00,0x00) michael@0: michael@0: nsresult michael@0: nsLookAndFeel::GetSystemColors() michael@0: { michael@0: if (mInitializedSystemColors) michael@0: return NS_OK; michael@0: michael@0: if (!AndroidBridge::Bridge()) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: AndroidBridge::Bridge()->GetSystemColors(&mSystemColors); michael@0: michael@0: mInitializedSystemColors = true; michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: nsLookAndFeel::CallRemoteGetSystemColors() michael@0: { michael@0: // An array has to be used to get data from remote process michael@0: InfallibleTArray colors; michael@0: uint32_t colorsCount = sizeof(AndroidSystemColors) / sizeof(nscolor); michael@0: michael@0: if (!ContentChild::GetSingleton()->SendGetSystemColors(colorsCount, &colors)) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: NS_ASSERTION(colors.Length() == colorsCount, "System colors array is incomplete"); michael@0: if (colors.Length() == 0) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: if (colors.Length() < colorsCount) michael@0: colorsCount = colors.Length(); michael@0: michael@0: // Array elements correspond to the members of mSystemColors structure, michael@0: // so just copy the memory block michael@0: memcpy(&mSystemColors, colors.Elements(), sizeof(nscolor) * colorsCount); michael@0: michael@0: mInitializedSystemColors = true; michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: nsLookAndFeel::NativeGetColor(ColorID aID, nscolor &aColor) michael@0: { michael@0: nsresult rv = NS_OK; michael@0: michael@0: if (!mInitializedSystemColors) { michael@0: if (XRE_GetProcessType() == GeckoProcessType_Default) michael@0: rv = GetSystemColors(); michael@0: else michael@0: rv = CallRemoteGetSystemColors(); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: } michael@0: michael@0: // XXX we'll want to use context.obtainStyledAttributes on the java side to michael@0: // get all of these; see TextView.java for a good exmaple. michael@0: michael@0: switch (aID) { michael@0: // These colors don't seem to be used for anything anymore in Mozilla michael@0: // (except here at least TextSelectBackground and TextSelectForeground) michael@0: // The CSS2 colors below are used. michael@0: case eColorID_WindowBackground: michael@0: aColor = NS_RGB(0xFF, 0xFF, 0xFF); michael@0: break; michael@0: case eColorID_WindowForeground: michael@0: aColor = mSystemColors.textColorPrimary; michael@0: break; michael@0: case eColorID_WidgetBackground: michael@0: aColor = mSystemColors.colorBackground; michael@0: break; michael@0: case eColorID_WidgetForeground: michael@0: aColor = mSystemColors.colorForeground; michael@0: break; michael@0: case eColorID_WidgetSelectBackground: michael@0: aColor = mSystemColors.textColorHighlight; michael@0: break; michael@0: case eColorID_WidgetSelectForeground: michael@0: aColor = mSystemColors.textColorPrimaryInverse; michael@0: break; michael@0: case eColorID_Widget3DHighlight: michael@0: aColor = LIGHT_GRAY_COLOR; michael@0: break; michael@0: case eColorID_Widget3DShadow: michael@0: aColor = DARK_GRAY_COLOR; michael@0: break; michael@0: case eColorID_TextBackground: michael@0: // not used? michael@0: aColor = mSystemColors.colorBackground; michael@0: break; michael@0: case eColorID_TextForeground: michael@0: // not used? michael@0: aColor = mSystemColors.textColorPrimary; michael@0: break; michael@0: case eColorID_TextSelectBackground: michael@0: case eColorID_IMESelectedRawTextBackground: michael@0: case eColorID_IMESelectedConvertedTextBackground: michael@0: // still used michael@0: aColor = mSystemColors.textColorHighlight; michael@0: break; michael@0: case eColorID_TextSelectForeground: michael@0: case eColorID_IMESelectedRawTextForeground: michael@0: case eColorID_IMESelectedConvertedTextForeground: michael@0: // still used michael@0: aColor = mSystemColors.textColorPrimaryInverse; michael@0: break; michael@0: case eColorID_IMERawInputBackground: michael@0: case eColorID_IMEConvertedTextBackground: michael@0: aColor = NS_TRANSPARENT; michael@0: break; michael@0: case eColorID_IMERawInputForeground: michael@0: case eColorID_IMEConvertedTextForeground: michael@0: aColor = NS_SAME_AS_FOREGROUND_COLOR; michael@0: break; michael@0: case eColorID_IMERawInputUnderline: michael@0: case eColorID_IMEConvertedTextUnderline: michael@0: aColor = NS_SAME_AS_FOREGROUND_COLOR; michael@0: break; michael@0: case eColorID_IMESelectedRawTextUnderline: michael@0: case eColorID_IMESelectedConvertedTextUnderline: michael@0: aColor = NS_TRANSPARENT; michael@0: break; michael@0: case eColorID_SpellCheckerUnderline: michael@0: aColor = RED_COLOR; michael@0: break; michael@0: michael@0: // css2 http://www.w3.org/TR/REC-CSS2/ui.html#system-colors michael@0: case eColorID_activeborder: michael@0: // active window border michael@0: aColor = mSystemColors.colorBackground; michael@0: break; michael@0: case eColorID_activecaption: michael@0: // active window caption background michael@0: aColor = mSystemColors.colorBackground; michael@0: break; michael@0: case eColorID_appworkspace: michael@0: // MDI background color michael@0: aColor = mSystemColors.colorBackground; michael@0: break; michael@0: case eColorID_background: michael@0: // desktop background michael@0: aColor = mSystemColors.colorBackground; michael@0: break; michael@0: case eColorID_captiontext: michael@0: // text in active window caption, size box, and scrollbar arrow box (!) michael@0: aColor = mSystemColors.colorForeground; michael@0: break; michael@0: case eColorID_graytext: michael@0: // disabled text in windows, menus, etc. michael@0: aColor = mSystemColors.textColorTertiary; michael@0: break; michael@0: case eColorID_highlight: michael@0: // background of selected item michael@0: aColor = mSystemColors.textColorHighlight; michael@0: break; michael@0: case eColorID_highlighttext: michael@0: // text of selected item michael@0: aColor = mSystemColors.textColorPrimaryInverse; michael@0: break; michael@0: case eColorID_inactiveborder: michael@0: // inactive window border michael@0: aColor = mSystemColors.colorBackground; michael@0: break; michael@0: case eColorID_inactivecaption: michael@0: // inactive window caption michael@0: aColor = mSystemColors.colorBackground; michael@0: break; michael@0: case eColorID_inactivecaptiontext: michael@0: // text in inactive window caption michael@0: aColor = mSystemColors.textColorTertiary; michael@0: break; michael@0: case eColorID_infobackground: michael@0: // tooltip background color michael@0: aColor = mSystemColors.colorBackground; michael@0: break; michael@0: case eColorID_infotext: michael@0: // tooltip text color michael@0: aColor = mSystemColors.colorForeground; michael@0: break; michael@0: case eColorID_menu: michael@0: // menu background michael@0: aColor = mSystemColors.colorBackground; michael@0: break; michael@0: case eColorID_menutext: michael@0: // menu text michael@0: aColor = mSystemColors.colorForeground; michael@0: break; michael@0: case eColorID_scrollbar: michael@0: // scrollbar gray area michael@0: aColor = mSystemColors.colorBackground; michael@0: break; michael@0: michael@0: case eColorID_threedface: michael@0: case eColorID_buttonface: michael@0: // 3-D face color michael@0: aColor = mSystemColors.colorBackground; michael@0: break; michael@0: michael@0: case eColorID_buttontext: michael@0: // text on push buttons michael@0: aColor = mSystemColors.colorForeground; michael@0: break; michael@0: michael@0: case eColorID_buttonhighlight: michael@0: // 3-D highlighted edge color michael@0: case eColorID_threedhighlight: michael@0: // 3-D highlighted outer edge color michael@0: aColor = LIGHT_GRAY_COLOR; michael@0: break; michael@0: michael@0: case eColorID_threedlightshadow: michael@0: // 3-D highlighted inner edge color michael@0: aColor = mSystemColors.colorBackground; michael@0: break; michael@0: michael@0: case eColorID_buttonshadow: michael@0: // 3-D shadow edge color michael@0: case eColorID_threedshadow: michael@0: // 3-D shadow inner edge color michael@0: aColor = GRAY_COLOR; michael@0: break; michael@0: michael@0: case eColorID_threeddarkshadow: michael@0: // 3-D shadow outer edge color michael@0: aColor = BLACK_COLOR; michael@0: break; michael@0: michael@0: case eColorID_window: michael@0: case eColorID_windowframe: michael@0: aColor = mSystemColors.colorBackground; michael@0: break; michael@0: michael@0: case eColorID_windowtext: michael@0: aColor = mSystemColors.textColorPrimary; michael@0: break; michael@0: michael@0: case eColorID__moz_eventreerow: michael@0: case eColorID__moz_field: michael@0: aColor = mSystemColors.colorBackground; michael@0: break; michael@0: case eColorID__moz_fieldtext: michael@0: aColor = mSystemColors.textColorPrimary; michael@0: break; michael@0: case eColorID__moz_dialog: michael@0: aColor = mSystemColors.colorBackground; michael@0: break; michael@0: case eColorID__moz_dialogtext: michael@0: aColor = mSystemColors.colorForeground; michael@0: break; michael@0: case eColorID__moz_dragtargetzone: michael@0: aColor = mSystemColors.textColorHighlight; michael@0: break; michael@0: case eColorID__moz_buttondefault: michael@0: // default button border color michael@0: aColor = BLACK_COLOR; michael@0: break; michael@0: case eColorID__moz_buttonhoverface: michael@0: aColor = BG_PRELIGHT_COLOR; michael@0: break; michael@0: case eColorID__moz_buttonhovertext: michael@0: aColor = FG_PRELIGHT_COLOR; michael@0: break; michael@0: case eColorID__moz_cellhighlight: michael@0: case eColorID__moz_html_cellhighlight: michael@0: aColor = mSystemColors.textColorHighlight; michael@0: break; michael@0: case eColorID__moz_cellhighlighttext: michael@0: case eColorID__moz_html_cellhighlighttext: michael@0: aColor = mSystemColors.textColorPrimaryInverse; michael@0: break; michael@0: case eColorID__moz_menuhover: michael@0: aColor = BG_PRELIGHT_COLOR; michael@0: break; michael@0: case eColorID__moz_menuhovertext: michael@0: aColor = FG_PRELIGHT_COLOR; michael@0: break; michael@0: case eColorID__moz_oddtreerow: michael@0: aColor = NS_TRANSPARENT; michael@0: break; michael@0: case eColorID__moz_nativehyperlinktext: michael@0: aColor = NS_SAME_AS_FOREGROUND_COLOR; michael@0: break; michael@0: case eColorID__moz_comboboxtext: michael@0: aColor = mSystemColors.colorForeground; michael@0: break; michael@0: case eColorID__moz_combobox: michael@0: aColor = mSystemColors.colorBackground; michael@0: break; michael@0: case eColorID__moz_menubartext: michael@0: aColor = mSystemColors.colorForeground; michael@0: break; michael@0: case eColorID__moz_menubarhovertext: michael@0: aColor = FG_PRELIGHT_COLOR; michael@0: break; michael@0: default: michael@0: /* default color is BLACK */ michael@0: aColor = 0; michael@0: rv = NS_ERROR_FAILURE; michael@0: break; michael@0: } michael@0: michael@0: return rv; michael@0: } michael@0: michael@0: michael@0: nsresult michael@0: nsLookAndFeel::GetIntImpl(IntID aID, int32_t &aResult) michael@0: { michael@0: nsresult rv = nsXPLookAndFeel::GetIntImpl(aID, aResult); michael@0: if (NS_SUCCEEDED(rv)) michael@0: return rv; michael@0: michael@0: rv = NS_OK; michael@0: michael@0: switch (aID) { michael@0: case eIntID_CaretBlinkTime: michael@0: aResult = 500; michael@0: break; michael@0: michael@0: case eIntID_CaretWidth: michael@0: aResult = 1; michael@0: break; michael@0: michael@0: case eIntID_ShowCaretDuringSelection: michael@0: aResult = 0; michael@0: break; michael@0: michael@0: case eIntID_SelectTextfieldsOnKeyFocus: michael@0: // Select textfield content when focused by kbd michael@0: // used by EventStateManager::sTextfieldSelectModel michael@0: aResult = 1; michael@0: break; michael@0: michael@0: case eIntID_SubmenuDelay: michael@0: aResult = 200; michael@0: break; michael@0: michael@0: case eIntID_TooltipDelay: michael@0: aResult = 500; michael@0: break; michael@0: michael@0: case eIntID_MenusCanOverlapOSBar: michael@0: // we want XUL popups to be able to overlap the task bar. michael@0: aResult = 1; michael@0: break; michael@0: michael@0: case eIntID_ScrollArrowStyle: michael@0: aResult = eScrollArrowStyle_Single; michael@0: break; michael@0: michael@0: case eIntID_ScrollSliderStyle: michael@0: aResult = eScrollThumbStyle_Proportional; michael@0: break; michael@0: michael@0: case eIntID_TouchEnabled: michael@0: aResult = 1; michael@0: break; michael@0: michael@0: case eIntID_ColorPickerAvailable: michael@0: aResult = 1; michael@0: break; michael@0: michael@0: case eIntID_WindowsDefaultTheme: michael@0: case eIntID_WindowsThemeIdentifier: michael@0: case eIntID_OperatingSystemVersionIdentifier: michael@0: aResult = 0; michael@0: rv = NS_ERROR_NOT_IMPLEMENTED; michael@0: break; michael@0: michael@0: case eIntID_SpellCheckerUnderlineStyle: michael@0: aResult = NS_STYLE_TEXT_DECORATION_STYLE_WAVY; michael@0: break; michael@0: michael@0: case eIntID_ScrollbarButtonAutoRepeatBehavior: michael@0: aResult = 0; michael@0: break; michael@0: michael@0: default: michael@0: aResult = 0; michael@0: rv = NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: return rv; michael@0: } michael@0: michael@0: nsresult michael@0: nsLookAndFeel::GetFloatImpl(FloatID aID, float &aResult) michael@0: { michael@0: nsresult rv = nsXPLookAndFeel::GetFloatImpl(aID, aResult); michael@0: if (NS_SUCCEEDED(rv)) michael@0: return rv; michael@0: rv = NS_OK; michael@0: michael@0: switch (aID) { michael@0: case eFloatID_IMEUnderlineRelativeSize: michael@0: aResult = 1.0f; michael@0: break; michael@0: michael@0: case eFloatID_SpellCheckerUnderlineRelativeSize: michael@0: aResult = 1.0f; michael@0: break; michael@0: michael@0: default: michael@0: aResult = -1.0; michael@0: rv = NS_ERROR_FAILURE; michael@0: break; michael@0: } michael@0: return rv; michael@0: } michael@0: michael@0: /*virtual*/ michael@0: bool michael@0: nsLookAndFeel::GetFontImpl(FontID aID, nsString& aFontName, michael@0: gfxFontStyle& aFontStyle, michael@0: float aDevPixPerCSSPixel) michael@0: { michael@0: aFontName.AssignLiteral("\"Droid Sans\""); michael@0: aFontStyle.style = NS_FONT_STYLE_NORMAL; michael@0: aFontStyle.weight = NS_FONT_WEIGHT_NORMAL; michael@0: aFontStyle.stretch = NS_FONT_STRETCH_NORMAL; michael@0: aFontStyle.size = 9.0 * 96.0f / 72.0f * aDevPixPerCSSPixel; michael@0: aFontStyle.systemFont = true; michael@0: return true; michael@0: } michael@0: michael@0: /*virtual*/ michael@0: bool michael@0: nsLookAndFeel::GetEchoPasswordImpl() michael@0: { michael@0: if (!mInitializedShowPassword) { michael@0: if (XRE_GetProcessType() == GeckoProcessType_Default) { michael@0: mShowPassword = mozilla::widget::android::GeckoAppShell::GetShowPasswordSetting(); michael@0: } else { michael@0: ContentChild::GetSingleton()->SendGetShowPasswordSetting(&mShowPassword); michael@0: } michael@0: mInitializedShowPassword = true; michael@0: } michael@0: return mShowPassword; michael@0: } michael@0: michael@0: uint32_t michael@0: nsLookAndFeel::GetPasswordMaskDelayImpl() michael@0: { michael@0: // This value is hard-coded in Android OS's PasswordTransformationMethod.java michael@0: return 1500; michael@0: } michael@0: michael@0: /* virtual */ michael@0: char16_t michael@0: nsLookAndFeel::GetPasswordCharacterImpl() michael@0: { michael@0: // This value is hard-coded in Android OS's PasswordTransformationMethod.java michael@0: return UNICODE_BULLET; michael@0: }