1 // Copyright (c) 2012 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 12 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 13 14 // Returns true if the given window is modal. 15 static bool IsModalWindow(WindowRef window) { 16 WindowModality modality = kWindowModalityNone; 17 WindowRef modal_target = NULL; 18 OSStatus status = GetWindowModality(window, &modality, &modal_target); 19 return (status == noErr) && (modality != kWindowModalityNone); 20 } 21 22 static CGRect CGRectForWindow(WindowRef window) { 23 CGRect bounds = { { 0, 0 }, { 0, 0 } }; 24 HIWindowGetBounds(window, kWindowContentRgn, kHICoordSpace72DPIGlobal, 25 &bounds); 26 return bounds; 27 } 28 29 struct WindowInfo { 30 uint32 window_id; 31 CGRect bounds; 32 WindowInfo(WindowRef window) { 33 window_id = HIWindowGetCGWindowID(window); 34 bounds = CGRectForWindow(window); 35 } 36 }; 37 38 static void OnPluginWindowClosed(const WindowInfo& window_info) { 39 mac_plugin_interposing::NotifyBrowserOfPluginHideWindow(window_info.window_id, 40 window_info.bounds); 41 } 42 43 static void OnPluginWindowShown(WindowRef window) { 44 mac_plugin_interposing::NotifyBrowserOfPluginShowWindow( 45 HIWindowGetCGWindowID(window), CGRectForWindow(window), 46 IsModalWindow(window)); 47 } 48 49 static void OnPluginWindowSelected(WindowRef window) { 50 mac_plugin_interposing::NotifyBrowserOfPluginSelectWindow( 51 HIWindowGetCGWindowID(window), CGRectForWindow(window), 52 IsModalWindow(window)); 53 } 54 55 #pragma mark - 56 57 static void ChromePluginSelectWindow(WindowRef window) { 58 mac_plugin_interposing::SwitchToPluginProcess(); 59 SelectWindow(window); 60 OnPluginWindowSelected(window); 61 } 62 63 static void ChromePluginShowWindow(WindowRef window) { 64 mac_plugin_interposing::SwitchToPluginProcess(); 65 ShowWindow(window); 66 OnPluginWindowShown(window); 67 } 68 69 static void ChromePluginDisposeWindow(WindowRef window) { 70 WindowInfo window_info(window); 71 DisposeWindow(window); 72 OnPluginWindowClosed(window_info); 73 } 74 75 static void ChromePluginHideWindow(WindowRef window) { 76 WindowInfo window_info(window); 77 HideWindow(window); 78 OnPluginWindowClosed(window_info); 79 } 80 81 static void ChromePluginShowHide(WindowRef window, Boolean show) { 82 if (show) { 83 mac_plugin_interposing::SwitchToPluginProcess(); 84 ShowHide(window, show); 85 OnPluginWindowShown(window); 86 } else { 87 WindowInfo window_info(window); 88 ShowHide(window, show); 89 OnPluginWindowClosed(window_info); 90 } 91 } 92 93 static void ChromePluginReleaseWindow(WindowRef window) { 94 WindowInfo window_info(window); 95 ReleaseWindow(window); 96 OnPluginWindowClosed(window_info); 97 } 98 99 static void ChromePluginDisposeDialog(DialogRef dialog) { 100 WindowRef window = GetDialogWindow(dialog); 101 WindowInfo window_info(window); 102 DisposeDialog(dialog); 103 OnPluginWindowClosed(window_info); 104 } 105 106 #pragma mark - 107 108 struct interpose_substitution { 109 const void* replacement; 110 const void* original; 111 }; 112 113 #define INTERPOSE_FUNCTION(function) \ 114 { reinterpret_cast<const void*>(ChromePlugin##function), \ 115 reinterpret_cast<const void*>(function) } 116 117 __attribute__((used)) static const interpose_substitution substitutions[] 118 __attribute__((section("__DATA, __interpose"))) = { 119 INTERPOSE_FUNCTION(SelectWindow), 120 INTERPOSE_FUNCTION(ShowWindow), 121 INTERPOSE_FUNCTION(ShowHide), 122 INTERPOSE_FUNCTION(DisposeWindow), 123 INTERPOSE_FUNCTION(HideWindow), 124 INTERPOSE_FUNCTION(ReleaseWindow), 125 INTERPOSE_FUNCTION(DisposeDialog), 126 }; 127 128 #endif // !__LP64__ 129