| // Copyright (c) 2012 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. |
| |
| #if !defined(__LP64__) |
| |
| #include <Carbon/Carbon.h> |
| |
| #include "content/plugin/plugin_interpose_util_mac.h" |
| #include "ui/gfx/rect.h" |
| |
| #pragma GCC diagnostic ignored "-Wdeprecated-declarations" |
| |
| // Returns true if the given window is modal. |
| static bool IsModalWindow(WindowRef window) { |
| WindowModality modality = kWindowModalityNone; |
| WindowRef modal_target = NULL; |
| OSStatus status = GetWindowModality(window, &modality, &modal_target); |
| return (status == noErr) && (modality != kWindowModalityNone); |
| } |
| |
| static CGRect CGRectForWindow(WindowRef window) { |
| CGRect bounds = { { 0, 0 }, { 0, 0 } }; |
| HIWindowGetBounds(window, kWindowContentRgn, kHICoordSpace72DPIGlobal, |
| &bounds); |
| return bounds; |
| } |
| |
| struct WindowInfo { |
| uint32 window_id; |
| CGRect bounds; |
| WindowInfo(WindowRef window) { |
| window_id = HIWindowGetCGWindowID(window); |
| bounds = CGRectForWindow(window); |
| } |
| }; |
| |
| static void OnPluginWindowClosed(const WindowInfo& window_info) { |
| mac_plugin_interposing::NotifyBrowserOfPluginHideWindow(window_info.window_id, |
| window_info.bounds); |
| } |
| |
| static void OnPluginWindowShown(WindowRef window) { |
| mac_plugin_interposing::NotifyBrowserOfPluginShowWindow( |
| HIWindowGetCGWindowID(window), CGRectForWindow(window), |
| IsModalWindow(window)); |
| } |
| |
| static void OnPluginWindowSelected(WindowRef window) { |
| mac_plugin_interposing::NotifyBrowserOfPluginSelectWindow( |
| HIWindowGetCGWindowID(window), CGRectForWindow(window), |
| IsModalWindow(window)); |
| } |
| |
| #pragma mark - |
| |
| static void ChromePluginSelectWindow(WindowRef window) { |
| mac_plugin_interposing::SwitchToPluginProcess(); |
| SelectWindow(window); |
| OnPluginWindowSelected(window); |
| } |
| |
| static void ChromePluginShowWindow(WindowRef window) { |
| mac_plugin_interposing::SwitchToPluginProcess(); |
| ShowWindow(window); |
| OnPluginWindowShown(window); |
| } |
| |
| static void ChromePluginDisposeWindow(WindowRef window) { |
| WindowInfo window_info(window); |
| DisposeWindow(window); |
| OnPluginWindowClosed(window_info); |
| } |
| |
| static void ChromePluginHideWindow(WindowRef window) { |
| WindowInfo window_info(window); |
| HideWindow(window); |
| OnPluginWindowClosed(window_info); |
| } |
| |
| static void ChromePluginShowHide(WindowRef window, Boolean show) { |
| if (show) { |
| mac_plugin_interposing::SwitchToPluginProcess(); |
| ShowHide(window, show); |
| OnPluginWindowShown(window); |
| } else { |
| WindowInfo window_info(window); |
| ShowHide(window, show); |
| OnPluginWindowClosed(window_info); |
| } |
| } |
| |
| static void ChromePluginReleaseWindow(WindowRef window) { |
| WindowInfo window_info(window); |
| ReleaseWindow(window); |
| OnPluginWindowClosed(window_info); |
| } |
| |
| static void ChromePluginDisposeDialog(DialogRef dialog) { |
| WindowRef window = GetDialogWindow(dialog); |
| WindowInfo window_info(window); |
| DisposeDialog(dialog); |
| OnPluginWindowClosed(window_info); |
| } |
| |
| #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(SelectWindow), |
| INTERPOSE_FUNCTION(ShowWindow), |
| INTERPOSE_FUNCTION(ShowHide), |
| INTERPOSE_FUNCTION(DisposeWindow), |
| INTERPOSE_FUNCTION(HideWindow), |
| INTERPOSE_FUNCTION(ReleaseWindow), |
| INTERPOSE_FUNCTION(DisposeDialog), |
| }; |
| |
| #endif // !__LP64__ |