summaryrefslogtreecommitdiffstats
path: root/chrome_frame/chrome_frame_plugin.h
diff options
context:
space:
mode:
authorslightlyoff@chromium.org <slightlyoff@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-24 05:11:58 +0000
committerslightlyoff@chromium.org <slightlyoff@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-24 05:11:58 +0000
commitf781782dd67077478e117c61dca4ea5eefce3544 (patch)
tree4801f724123cfdcbb69c4e7fe40a565b331723ae /chrome_frame/chrome_frame_plugin.h
parent63cf4759efa2373e33436fb5df6849f930081226 (diff)
downloadchromium_src-f781782dd67077478e117c61dca4ea5eefce3544.zip
chromium_src-f781782dd67077478e117c61dca4ea5eefce3544.tar.gz
chromium_src-f781782dd67077478e117c61dca4ea5eefce3544.tar.bz2
Initial import of the Chrome Frame codebase. Integration in chrome.gyp coming in a separate CL.
BUG=None TEST=None Review URL: http://codereview.chromium.org/218019 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@27042 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame/chrome_frame_plugin.h')
-rw-r--r--chrome_frame/chrome_frame_plugin.h214
1 files changed, 214 insertions, 0 deletions
diff --git a/chrome_frame/chrome_frame_plugin.h b/chrome_frame/chrome_frame_plugin.h
new file mode 100644
index 0000000..b0814bb
--- /dev/null
+++ b/chrome_frame/chrome_frame_plugin.h
@@ -0,0 +1,214 @@
+// Copyright (c) 2009 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.
+
+#ifndef CHROME_FRAME_CHROME_FRAME_PLUGIN_H_
+#define CHROME_FRAME_CHROME_FRAME_PLUGIN_H_
+
+#include "base/win_util.h"
+#include "chrome_frame/chrome_frame_automation.h"
+#include "chrome_frame/utils.h"
+
+#define IDC_ABOUT_CHROME_FRAME 40018
+
+// A class to implement common functionality for all types of
+// plugins: NPAPI. ActiveX and ActiveDoc
+template <typename T>
+class ChromeFramePlugin : public ChromeFrameDelegateImpl {
+ public:
+ ChromeFramePlugin()
+ : ignore_setfocus_(false),
+ is_privileged_(false) {
+ }
+ ~ChromeFramePlugin() {
+ Uninitialize();
+ }
+
+BEGIN_MSG_MAP(ChromeFrameActivex)
+ MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
+ MESSAGE_HANDLER(WM_SIZE, OnSize)
+ MESSAGE_HANDLER(WM_PARENTNOTIFY, OnParentNotify)
+END_MSG_MAP()
+
+ bool Initialize() {
+ DCHECK(!automation_client_.get());
+ automation_client_.reset(CreateAutomationClient());
+ if (!automation_client_.get()) {
+ NOTREACHED() << "new ChromeFrameAutomationClient";
+ return false;
+ }
+
+ return true;
+ }
+
+ void Uninitialize() {
+ if (automation_client_.get()) {
+ automation_client_->Uninitialize();
+ automation_client_.reset();
+ }
+ }
+
+ bool InitializeAutomation(const std::wstring& profile_name,
+ const std::wstring& extra_chrome_arguments,
+ bool incognito) {
+ // We don't want to do incognito when privileged, since we're
+ // running in browser chrome or some other privileged context.
+ bool incognito_mode = !is_privileged_ && incognito;
+ return automation_client_->Initialize(this, kCommandExecutionTimeout, true,
+ profile_name, extra_chrome_arguments,
+ incognito_mode);
+ }
+
+ // ChromeFrameDelegate implementation
+ virtual WindowType GetWindow() const {
+ return (static_cast<const T*>(this))->m_hWnd;
+ }
+
+ virtual void GetBounds(RECT* bounds) {
+ if (bounds) {
+ if (::IsWindow(GetWindow())) {
+ (static_cast<T*>(this))->GetClientRect(bounds);
+ }
+ }
+ }
+ virtual std::string GetDocumentUrl() {
+ return document_url_;
+ }
+ virtual void OnAutomationServerReady() {
+ // Issue the extension automation request if we're privileged to
+ // allow this control to handle extension requests from Chrome.
+ if (is_privileged_)
+ automation_client_->SetEnableExtensionAutomation(true);
+ }
+
+ virtual bool IsValid() const {
+ return automation_client_.get() != NULL;
+ }
+
+ protected:
+ virtual void OnNavigationFailed(int tab_handle, int error_code,
+ const GURL& gurl) {
+ OnLoadFailed(error_code, gurl.spec());
+ }
+
+ virtual void OnHandleContextMenu(int tab_handle, HANDLE menu_handle,
+ int x_pos, int y_pos, int align_flags) {
+ if (!menu_handle || !automation_client_.get()) {
+ NOTREACHED();
+ return;
+ }
+
+ // TrackPopupMenuEx call will fail on IE on Vista running
+ // in low integrity mode. We DO seem to be able to enumerate the menu
+ // though, so just clone it and show the copy:
+ HMENU copy = UtilCloneContextMenu(static_cast<HMENU>(menu_handle));
+ if (!copy)
+ return;
+
+ T* pThis = static_cast<T*>(this);
+ if (pThis->PreProcessContextMenu(copy)) {
+ UINT flags = align_flags | TPM_LEFTBUTTON | TPM_RETURNCMD | TPM_RECURSE;
+ UINT selected = TrackPopupMenuEx(copy, flags, x_pos, y_pos, GetWindow(),
+ NULL);
+ if (selected != 0 && !pThis->HandleContextMenuCommand(selected)) {
+ automation_client_->SendContextMenuCommandToChromeFrame(selected);
+ }
+ }
+
+ DestroyMenu(copy);
+ }
+
+ LRESULT OnSetFocus(UINT message, WPARAM wparam, LPARAM lparam,
+ BOOL& handled) { // NO_LINT
+ if (!ignore_setfocus_ && automation_client_ != NULL) {
+ TabProxy* tab = automation_client_->tab();
+ HWND chrome_window = automation_client_->tab_window();
+ if (tab && ::IsWindow(chrome_window)) {
+ DLOG(INFO) << "Setting initial focus";
+ tab->SetInitialFocus(win_util::IsShiftPressed());
+ }
+ }
+
+ return 0;
+ }
+
+ LRESULT OnSize(UINT message, WPARAM wparam, LPARAM lparam,
+ BOOL& handled) { // NO_LINT
+ handled = FALSE;
+ // When we get resized, we need to resize the external tab window too.
+ if (automation_client_.get())
+ automation_client_->Resize(LOWORD(lparam), HIWORD(lparam),
+ SWP_NOACTIVATE | SWP_NOZORDER);
+ return 0;
+ }
+
+ LRESULT OnParentNotify(UINT message, WPARAM wparam, LPARAM lparam,
+ BOOL& handled) { // NO_LINT
+ switch (LOWORD(wparam)) {
+ case WM_LBUTTONDOWN:
+ case WM_MBUTTONDOWN:
+ case WM_RBUTTONDOWN:
+ case WM_XBUTTONDOWN: {
+ // If we got activated via mouse click on the external tab,
+ // we need to update the state of this thread and tell the
+ // browser that we now have the focus.
+ HWND focus = ::GetFocus();
+ HWND plugin_window = GetWindow();
+ if (focus != plugin_window && !IsChild(plugin_window, focus)) {
+ ignore_setfocus_ = true;
+ SetFocus(plugin_window);
+ ignore_setfocus_ = false;
+ }
+ break;
+ }
+ }
+
+ return 0;
+ }
+
+ // Return true if context menu should be displayed. The menu could be
+ // modified as well (enable/disable commands, add/remove items).
+ // 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...");
+ return true;
+ }
+
+ // Return true if menu command is processed, otherwise the command will be
+ // passed to Chrome for execution. Override in most-derived class if needed.
+ bool HandleContextMenuCommand(UINT cmd) {
+ return false;
+ }
+
+ // Allow overriding the type of automation client used, for unit tests.
+ virtual ChromeFrameAutomationClient* CreateAutomationClient() {
+ return new ChromeFrameAutomationClient;
+ }
+
+ protected:
+ // Our gateway to chrome land
+ scoped_ptr<ChromeFrameAutomationClient> automation_client_;
+
+ // Url of the containing document.
+ std::string document_url_;
+
+ // We set this flag when we're taking the focus ourselves
+ // and notifying the host browser that we're doing so.
+ // When the flag is not set, we transfer the focus to chrome.
+ bool ignore_setfocus_;
+
+ // The plugin is privileged if it is:
+ // * Invoked by a window running under the system principal in FireFox.
+ // * Being hosted by a custom host exposing the SID_ChromeFramePrivileged
+ // service.
+ //
+ // When privileged, additional interfaces are made available to the user.
+ bool is_privileged_;
+};
+
+#endif // CHROME_FRAME_CHROME_FRAME_PLUGIN_H_
+