diff options
Diffstat (limited to 'chrome_frame')
-rw-r--r-- | chrome_frame/chrome_frame.gyp | 17 | ||||
-rw-r--r-- | chrome_frame/chrome_frame_plugin.h | 7 | ||||
-rw-r--r-- | chrome_frame/resources/chrome_frame_resources.grd | 15 | ||||
-rw-r--r-- | chrome_frame/simple_resource_loader.cc | 136 | ||||
-rw-r--r-- | chrome_frame/simple_resource_loader.h | 55 | ||||
-rw-r--r-- | chrome_frame/utils.cc | 27 |
6 files changed, 222 insertions, 35 deletions
diff --git a/chrome_frame/chrome_frame.gyp b/chrome_frame/chrome_frame.gyp index 159b762..66514ef 100644 --- a/chrome_frame/chrome_frame.gyp +++ b/chrome_frame/chrome_frame.gyp @@ -284,6 +284,7 @@ '../third_party/libxml/libxml.gyp:libxml', '../third_party/libxslt/libxslt.gyp:libxslt', 'chrome_frame_strings', + 'chrome_frame_utils', 'npchrome_frame', 'xulrunner_sdk', ], @@ -459,6 +460,7 @@ 'type': 'static_library', 'dependencies': [ 'chrome_frame_strings', + 'chrome_frame_utils', '../chrome/chrome.gyp:common', 'xulrunner_sdk', ], @@ -570,10 +572,24 @@ ], }, { + 'target_name': 'chrome_frame_utils', + # The intent is that shared util code can be built into a separate lib. + # Currently on the resource loading code is here. + 'type': 'static_library', + 'dependencies': [ + '../base/base.gyp:base_i18n', + ], + 'sources': [ + 'simple_resource_loader.cc', + 'simple_resource_loader.h', + ], + }, + { 'target_name': 'chrome_frame_ie', 'type': 'static_library', 'dependencies': [ 'chrome_frame_strings', + 'chrome_frame_utils', '../chrome/chrome.gyp:common', '../chrome/chrome.gyp:utility', '../build/temp_gyp/googleurl.gyp:googleurl', @@ -667,6 +683,7 @@ 'chrome_frame_ie', 'chrome_frame_npapi', 'chrome_frame_strings', + 'chrome_frame_utils', 'chrome_launcher', 'xulrunner_sdk', '../chrome/chrome.gyp:common', diff --git a/chrome_frame/chrome_frame_plugin.h b/chrome_frame/chrome_frame_plugin.h index 078a611..17fb6572 100644 --- a/chrome_frame/chrome_frame_plugin.h +++ b/chrome_frame/chrome_frame_plugin.h @@ -8,8 +8,11 @@ #include "base/ref_counted.h" #include "base/win_util.h" #include "chrome_frame/chrome_frame_automation.h" +#include "chrome_frame/simple_resource_loader.h" #include "chrome_frame/utils.h" +#include "grit/chromium_strings.h" + #define IDC_ABOUT_CHROME_FRAME 40018 // A class to implement common functionality for all types of @@ -181,10 +184,8 @@ END_MSG_MAP() // Override in most-derived class if needed. bool PreProcessContextMenu(HMENU menu) { // Add an "About" item. - // TODO: The string should be localized and menu should - // be modified in ExternalTabContainer:: once we go public. AppendMenu(menu, MF_STRING, IDC_ABOUT_CHROME_FRAME, - L"About Chrome Frame..."); + SimpleResourceLoader::Get(IDS_CHROME_FRAME_MENU_ABOUT).c_str()); return true; } diff --git a/chrome_frame/resources/chrome_frame_resources.grd b/chrome_frame/resources/chrome_frame_resources.grd index ee6a846..abd6547 100644 --- a/chrome_frame/resources/chrome_frame_resources.grd +++ b/chrome_frame/resources/chrome_frame_resources.grd @@ -20,20 +20,7 @@ for localizable strings <output filename="chrome_frame_resources.pak" type="data_package" /> </outputs> <release seq="1"> - <messages> - <message name="IDS_VERSIONMISMATCH_HEADER"> - ChromeFrame Update. - </message> - <message name="IDS_VERSIONMISMATCH"> - ChromeFrame has been updated. Please restart your browser. Chrome version: <ph name="TODO_0001">%ls<ex>TODO</ex></ph>, Chrome Frame version: <ph name="TODO_0002">%ls<ex>TODO</ex></ph> - </message> - <message name="IDS_VERSIONUNKNOWN"> - Very old - </message> - <message name="IDS_CHROME_FRAME_MENU_ABOUT" desc="About Chrome Frame label"> - About Chrome Frame... - </message> - </messages> + <!-- TODO(robertshield): All that's left now is to localize the dialog resource. --> <structures first_id="50000"> <structure name="IDD_FIND_DIALOG" file="structured_resources.rc" type="dialog" > </structure> diff --git a/chrome_frame/simple_resource_loader.cc b/chrome_frame/simple_resource_loader.cc new file mode 100644 index 0000000..2eb2167 --- /dev/null +++ b/chrome_frame/simple_resource_loader.cc @@ -0,0 +1,136 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome_frame/simple_resource_loader.h" + +#include <atlbase.h> +#include <string> + +#include "base/base_paths.h" +#include "base/file_path.h" +#include "base/file_util.h" +#include "base/path_service.h" +#include "base/i18n/rtl.h" +#include "base/string_util.h" +#include "base/win_util.h" + +const wchar_t kLocalesDirName[] = L"Locales"; + +HINSTANCE SimpleResourceLoader::locale_dll_handle_; + +SimpleResourceLoader::SimpleResourceLoader() { + // Find and load the resource DLL. + std::wstring locale = GetSystemLocale(); + std::wstring locale_dll_path; + + if (GetLocaleFilePath(locale, &locale_dll_path)) { + DCHECK(locale_dll_handle_ == NULL) << "Locale DLL is already loaded!"; + locale_dll_handle_ = LoadLocaleDll(locale_dll_path); + DCHECK(locale_dll_handle_ != NULL) << "Failed to load locale dll!"; + } +} + + +std::wstring SimpleResourceLoader::GetSystemLocale() { + std::string language, region; + base::i18n::GetLanguageAndRegionFromOS(&language, ®ion); + std::string ret; + if (!language.empty()) + ret.append(language); + if (!region.empty()) { + ret.append("-"); + ret.append(region); + } + return ASCIIToWide(ret); +} + +bool SimpleResourceLoader::GetLocaleFilePath(const std::wstring& locale, + std::wstring* file_path) { + DCHECK(file_path); + + FilePath module_path; + PathService::Get(base::DIR_MODULE, &module_path); + FilePath locales_path = module_path.Append(kLocalesDirName); + + // We may be residing in the "locales" directory's parent, or we might be + // in a sibling directory. Move up one and look for Locales again in the + // latter case. + if (!file_util::DirectoryExists(locales_path)) { + locales_path = module_path.DirName(); + locales_path = locales_path.Append(kLocalesDirName); + } + + bool found_dll = false; + if (file_util::DirectoryExists(locales_path)) { + std::wstring dll_name(locale); + dll_name += L".dll"; + + // First look for the named locale DLL. + FilePath look_path(locales_path.Append(dll_name)); + if (file_util::PathExists(look_path)) { + *file_path = look_path.value(); + found_dll = true; + } else { + + // If we didn't find it, try defaulting to en-US.dll. + dll_name = L"en-US.dll"; + look_path = locales_path.Append(dll_name); + if (file_util::PathExists(look_path)) { + *file_path = look_path.value(); + found_dll = true; + } + } + } else { + NOTREACHED() << "Could not locate locales DLL directory."; + } + + return found_dll; +} + +HINSTANCE SimpleResourceLoader::LoadLocaleDll(const std::wstring& dll_path) { + DWORD load_flags = 0; + if (win_util::GetWinVersion() >= win_util::WINVERSION_VISTA) { + load_flags = LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE | + LOAD_LIBRARY_AS_IMAGE_RESOURCE; + } else { + load_flags = DONT_RESOLVE_DLL_REFERENCES; + } + + // The dll should only have resources, not executable code. + HINSTANCE locale_dll_handle = LoadLibraryEx(dll_path.c_str(), NULL, + load_flags); + DCHECK(locale_dll_handle != NULL) << "unable to load generated resources: " + << GetLastError(); + + return locale_dll_handle; +} + +std::wstring SimpleResourceLoader::GetLocalizedResource(int message_id) { + if (!locale_dll_handle_) { + LOG(WARNING) << "locale resources are not loaded"; + return std::wstring(); + } + + DCHECK(IS_INTRESOURCE(message_id)); + + const ATLSTRINGRESOURCEIMAGE* image = AtlGetStringResourceImage( + locale_dll_handle_, message_id); + if (!image) { + // Fall back on the current module (shouldn't be any strings here except + // in unittests). + image = AtlGetStringResourceImage(_AtlBaseModule.GetModuleInstance(), + message_id); + if (!image) { + NOTREACHED() << "unable to find resource: " << message_id; + return std::wstring(); + } + } + return std::wstring(image->achString, image->nLength); +} + +// static +std::wstring SimpleResourceLoader::Get(int message_id) { + SimpleResourceLoader* loader = SimpleResourceLoader::instance(); + return loader->GetLocalizedResource(message_id); +} diff --git a/chrome_frame/simple_resource_loader.h b/chrome_frame/simple_resource_loader.h new file mode 100644 index 0000000..2ec9860 --- /dev/null +++ b/chrome_frame/simple_resource_loader.h @@ -0,0 +1,55 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// This class implements a simplified and much stripped down version of +// Chrome's app/resource_bundle machinery. It notably avoids unwanted +// dependencies on things like Skia. +// + +#ifndef CHROME_FRAME_SIMPLE_RESOURCE_LOADER_H_ +#define CHROME_FRAME_SIMPLE_RESOURCE_LOADER_H_ + +#include <windows.h> +#include <string> + +#include "base/singleton.h" + +class SimpleResourceLoader { + public: + + static SimpleResourceLoader* instance() { + return Singleton<SimpleResourceLoader>::get(); + } + + // Helper method to return the string resource identified by message_id + // from the currently loaded locale dll. + static std::wstring Get(int message_id); + + private: + SimpleResourceLoader(); + + // Retrieves the system locale in the <language>-<region> format using ICU. + std::wstring GetSystemLocale(); + + // Uses |locale| to build the resource DLL name and then looks for the named + // DLL in known locales paths. If it doesn't find it, it falls back to + // looking for an en-US.dll. + // + // Returns true if a locale DLL can be found, false otherwise. + bool GetLocaleFilePath(const std::wstring& locale, std::wstring* file_path); + + // Loads the locale dll at the given path. Returns a handle to the DLL or + // NULL on failure. + HINSTANCE LoadLocaleDll(const std::wstring& dll_path); + + // Returns the string resource identified by message_id from the currently + // loaded locale dll. + std::wstring GetLocalizedResource(int message_id); + + friend struct DefaultSingletonTraits<SimpleResourceLoader>; + + static HINSTANCE locale_dll_handle_; +}; + +#endif // CHROME_FRAME_SIMPLE_RESOURCE_LOADER_H_ diff --git a/chrome_frame/utils.cc b/chrome_frame/utils.cc index bec0595..7fcdde8 100644 --- a/chrome_frame/utils.cc +++ b/chrome_frame/utils.cc @@ -22,10 +22,12 @@ #include "chrome/installer/util/chrome_frame_distribution.h" #include "chrome_frame/extra_system_apis.h" #include "chrome_frame/html_utils.h" +#include "chrome_frame/simple_resource_loader.h" #include "chrome_frame/utils.h" #include "googleurl/src/gurl.h" #include "googleurl/src/url_canon.h" -#include "grit/chrome_frame_resources.h" + +#include "grit/chromium_strings.h" // Note that these values are all lower case and are compared to // lower-case-transformed values. @@ -285,19 +287,6 @@ HRESULT UtilGetXUACompatContentValue(const std::wstring& html_string, return E_FAIL; } -std::wstring GetResourceString(int resource_id) { - std::wstring resource_string; - HMODULE this_module = reinterpret_cast<HMODULE>(&__ImageBase); - const ATLSTRINGRESOURCEIMAGE* image = AtlGetStringResourceImage( - this_module, resource_id); - if (image) { - resource_string.assign(image->achString, image->nLength); - } else { - NOTREACHED() << "Unable to find resource id " << resource_id; - } - return resource_string; -} - void DisplayVersionMismatchWarning(HWND parent, const std::string& server_version) { // Obtain the current module version. @@ -307,14 +296,16 @@ void DisplayVersionMismatchWarning(HWND parent, std::wstring version_string(file_version_info->file_version()); std::wstring wide_server_version; if (server_version.empty()) { - wide_server_version = GetResourceString(IDS_VERSIONUNKNOWN); + wide_server_version = SimpleResourceLoader::Get(IDS_VERSIONUNKNOWN); } else { wide_server_version = ASCIIToWide(server_version); } - std::wstring title = GetResourceString(IDS_VERSIONMISMATCH_HEADER); + std::wstring title = SimpleResourceLoader::Get(IDS_VERSIONMISMATCH_HEADER); std::wstring message; - SStringPrintf(&message, GetResourceString(IDS_VERSIONMISMATCH).c_str(), - wide_server_version.c_str(), version_string.c_str()); + SStringPrintf(&message, + SimpleResourceLoader::Get(IDS_VERSIONMISMATCH).c_str(), + wide_server_version.c_str(), + version_string.c_str()); ::MessageBox(parent, message.c_str(), title.c_str(), MB_OK); } |