1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2009 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if !defined(__LP64__) 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <Carbon/Carbon.h> 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/plugin/plugin_interpose_util_mac.h" 1072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/rect.h" 1121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "webkit/plugins/npapi/carbon_plugin_window_tracker_mac.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#pragma GCC diagnostic ignored "-Wdeprecated-declarations" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Returns true if the given window is modal. 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic bool IsModalWindow(WindowRef window) { 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WindowModality modality = kWindowModalityNone; 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WindowRef modal_target = NULL; 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OSStatus status = GetWindowModality(window, &modality, &modal_target); 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return (status == noErr) && (modality != kWindowModalityNone); 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 23513209b27ff55e2841eac0e4120199c23acce758Ben Murdochstatic bool IsContainingWindowActive(const OpaquePluginRef delegate) { 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return mac_plugin_interposing::GetPluginWindowHasFocus(delegate); 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic CGRect CGRectForWindow(WindowRef window) { 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CGRect bounds = { { 0, 0 }, { 0, 0 } }; 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HIWindowGetBounds(window, kWindowContentRgn, kHICoordSpace72DPIGlobal, 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &bounds); 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return bounds; 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct WindowInfo { 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint32 window_id; 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CGRect bounds; 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WindowInfo(WindowRef window) { 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch window_id = HIWindowGetCGWindowID(window); 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bounds = CGRectForWindow(window); 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void OnPluginWindowClosed(const WindowInfo& window_info) { 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mac_plugin_interposing::NotifyBrowserOfPluginHideWindow(window_info.window_id, 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch window_info.bounds); 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void OnPluginWindowShown(WindowRef window) { 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mac_plugin_interposing::NotifyBrowserOfPluginShowWindow( 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HIWindowGetCGWindowID(window), CGRectForWindow(window), 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IsModalWindow(window)); 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void OnPluginWindowSelected(WindowRef window) { 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mac_plugin_interposing::NotifyBrowserOfPluginSelectWindow( 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HIWindowGetCGWindowID(window), CGRectForWindow(window), 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IsModalWindow(window)); 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#pragma mark - 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic Boolean ChromePluginIsWindowActive(WindowRef window) { 63513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const OpaquePluginRef delegate = 6421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen webkit::npapi::CarbonPluginWindowTracker::SharedInstance()-> 6521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen GetDelegateForDummyWindow(window); 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return delegate ? IsContainingWindowActive(delegate) 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : IsWindowActive(window); 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic Boolean ChromePluginIsWindowHilited(WindowRef window) { 71513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const OpaquePluginRef delegate = 7221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen webkit::npapi::CarbonPluginWindowTracker::SharedInstance()-> 7321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen GetDelegateForDummyWindow(window); 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return delegate ? IsContainingWindowActive(delegate) 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : IsWindowHilited(window); 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void ChromePluginSelectWindow(WindowRef window) { 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mac_plugin_interposing::SwitchToPluginProcess(); 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SelectWindow(window); 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OnPluginWindowSelected(window); 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void ChromePluginShowWindow(WindowRef window) { 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mac_plugin_interposing::SwitchToPluginProcess(); 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ShowWindow(window); 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OnPluginWindowShown(window); 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void ChromePluginDisposeWindow(WindowRef window) { 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WindowInfo window_info(window); 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DisposeWindow(window); 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OnPluginWindowClosed(window_info); 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void ChromePluginHideWindow(WindowRef window) { 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WindowInfo window_info(window); 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HideWindow(window); 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OnPluginWindowClosed(window_info); 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void ChromePluginShowHide(WindowRef window, Boolean show) { 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (show) { 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mac_plugin_interposing::SwitchToPluginProcess(); 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ShowHide(window, show); 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OnPluginWindowShown(window); 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WindowInfo window_info(window); 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ShowHide(window, show); 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OnPluginWindowClosed(window_info); 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void ChromePluginReleaseWindow(WindowRef window) { 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WindowInfo window_info(window); 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ReleaseWindow(window); 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OnPluginWindowClosed(window_info); 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void ChromePluginDisposeDialog(DialogRef dialog) { 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WindowRef window = GetDialogWindow(dialog); 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WindowInfo window_info(window); 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DisposeDialog(dialog); 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OnPluginWindowClosed(window_info); 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic WindowPartCode ChromePluginFindWindow(Point point, WindowRef* window) { 128513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch OpaquePluginRef delegate = mac_plugin_interposing::GetActiveDelegate(); 12921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen webkit::npapi::CarbonPluginWindowTracker* tracker = 13021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen webkit::npapi::CarbonPluginWindowTracker::SharedInstance(); 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WindowRef plugin_window = tracker->GetDummyWindowForDelegate(delegate); 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (plugin_window) { 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If plugin_window is non-NULL, then we are in the middle of routing an 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // event to the plugin, so we know it's destined for this window already, 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // so we don't have to worry that we'll be stealing an event meant for an 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // overlapping window. 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Rect window_bounds; 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GetWindowBounds(plugin_window, kWindowContentRgn, &window_bounds); 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (PtInRect(point, &window_bounds)) { 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (window) 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *window = plugin_window; 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return inContent; 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return FindWindow(point, window); 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic OSStatus ChromePluginSetThemeCursor(ThemeCursor cursor) { 149513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch OpaquePluginRef delegate = mac_plugin_interposing::GetActiveDelegate(); 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (delegate) { 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mac_plugin_interposing::NotifyPluginOfSetThemeCursor(delegate, cursor); 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return noErr; 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return SetThemeCursor(cursor); 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void ChromePluginSetCursor(const Cursor* cursor) { 158513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch OpaquePluginRef delegate = mac_plugin_interposing::GetActiveDelegate(); 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (delegate) { 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mac_plugin_interposing::NotifyPluginOfSetCursor(delegate, cursor); 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return SetCursor(cursor); 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#pragma mark - 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct interpose_substitution { 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const void* replacement; 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const void* original; 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define INTERPOSE_FUNCTION(function) \ 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { reinterpret_cast<const void*>(ChromePlugin##function), \ 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch reinterpret_cast<const void*>(function) } 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch__attribute__((used)) static const interpose_substitution substitutions[] 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch __attribute__((section("__DATA, __interpose"))) = { 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch INTERPOSE_FUNCTION(IsWindowActive), 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch INTERPOSE_FUNCTION(IsWindowHilited), 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch INTERPOSE_FUNCTION(SelectWindow), 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch INTERPOSE_FUNCTION(ShowWindow), 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch INTERPOSE_FUNCTION(ShowHide), 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch INTERPOSE_FUNCTION(DisposeWindow), 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch INTERPOSE_FUNCTION(HideWindow), 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch INTERPOSE_FUNCTION(ReleaseWindow), 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch INTERPOSE_FUNCTION(DisposeDialog), 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch INTERPOSE_FUNCTION(FindWindow), 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch INTERPOSE_FUNCTION(SetThemeCursor), 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch INTERPOSE_FUNCTION(SetCursor), 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif // !__LP64__ 194