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