| Index: chrome/browser/plugin_carbon_interpose_mac.cc
|
| diff --git a/chrome/browser/plugin_carbon_interpose_mac.cc b/chrome/browser/plugin_carbon_interpose_mac.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..315cdfa724e8bb9c424c32539c5c0f0b4812f73f
|
| --- /dev/null
|
| +++ b/chrome/browser/plugin_carbon_interpose_mac.cc
|
| @@ -0,0 +1,105 @@
|
| +// 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.
|
| +
|
| +#include <Carbon/Carbon.h>
|
| +
|
| +#include "webkit/glue/plugins/fake_plugin_window_tracker_mac.h"
|
| +
|
| +// The process that was frontmost when a plugin created a new window; generally
|
| +// we expect this to be the browser UI process.
|
| +static ProcessSerialNumber g_saved_front_process = { 0, 0 };
|
| +
|
| +// Bring the plugin process to the front so that the user can see it.
|
| +// TODO: Make this an IPC to order the plugin process above the browser
|
| +// process but not necessarily the frontmost.
|
| +static void SwitchToPluginProcess() {
|
| + ProcessSerialNumber this_process, front_process;
|
| + if (GetCurrentProcess(&this_process) != noErr)
|
| + return;
|
| + if (GetFrontProcess(&front_process) != noErr)
|
| + return;
|
| + Boolean matched = false;
|
| + if (SameProcess(&this_process, &front_process, &matched) != noErr)
|
| + return;
|
| + if (!matched) {
|
| + // TODO: We may need to keep a stack, or at least check the total window
|
| + // count, since this won't work if a plugin opens more than one window at
|
| + // a time.
|
| + g_saved_front_process = front_process;
|
| + SetFrontProcess(&this_process);
|
| + }
|
| +}
|
| +
|
| +// If the plugin process is still the front process, bring the prior
|
| +// front process (normally this will be the browser process) back to
|
| +// the front.
|
| +// TODO: Make this an IPC message so that the browser can properly
|
| +// reactivate the window.
|
| +static void SwitchToSavedProcess() {
|
| + ProcessSerialNumber this_process, front_process;
|
| + if (GetCurrentProcess(&this_process) != noErr)
|
| + return;
|
| + if (GetFrontProcess(&front_process) != noErr)
|
| + return;
|
| + Boolean matched = false;
|
| + if (SameProcess(&this_process, &front_process, &matched) != noErr)
|
| + return;
|
| + if (matched) {
|
| + SetFrontProcess(&g_saved_front_process);
|
| + }
|
| +}
|
| +
|
| +#pragma mark -
|
| +
|
| +static Boolean ChromePluginIsWindowHilited(WindowRef window) {
|
| + // TODO(stuartmorgan): Always returning true (instead of the real answer,
|
| + // which would be false) means that clicking works, but it's not correct
|
| + // either. Ideally we need a way to find out if the delegate corresponds
|
| + // to a browser window that is active.
|
| + const WebPluginDelegateImpl* delegate =
|
| + FakePluginWindowTracker::SharedInstance()->GetDelegateForFakeWindow(
|
| + window);
|
| + Boolean isHilited = delegate ? true : IsWindowHilited(window);
|
| + return isHilited;
|
| +}
|
| +
|
| +static void ChromePluginSelectWindow(WindowRef window) {
|
| + SwitchToPluginProcess();
|
| + SelectWindow(window);
|
| +}
|
| +
|
| +static void ChromePluginShowWindow(WindowRef window) {
|
| + SwitchToPluginProcess();
|
| + ShowWindow(window);
|
| +}
|
| +
|
| +static void ChromePluginDisposeWindow(WindowRef window) {
|
| + SwitchToSavedProcess();
|
| + DisposeWindow(window);
|
| +}
|
| +
|
| +static void ChromePluginHideWindow(WindowRef window) {
|
| + SwitchToSavedProcess();
|
| + HideWindow(window);
|
| +}
|
| +
|
| +#pragma mark -
|
| +
|
| +struct interpose_substitution {
|
| + const void* replacement;
|
| + const void* original;
|
| +};
|
| +
|
| +#define INTERPOSE_FUNCTION(function) \
|
| + { reinterpret_cast<const void*>(ChromePlugin##function), \
|
| + reinterpret_cast<const void*>(function) }
|
| +
|
| +__attribute__((used)) static const interpose_substitution substitutions[]
|
| + __attribute__((section("__DATA, __interpose"))) = {
|
| + INTERPOSE_FUNCTION(IsWindowHilited),
|
| + INTERPOSE_FUNCTION(SelectWindow),
|
| + INTERPOSE_FUNCTION(ShowWindow),
|
| + INTERPOSE_FUNCTION(DisposeWindow),
|
| + INTERPOSE_FUNCTION(HideWindow),
|
| +};
|
|
|