• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
IsModalWindow(WindowRef window)16 static 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 
IsContainingWindowActive(const OpaquePluginRef delegate)23 static bool IsContainingWindowActive(const OpaquePluginRef delegate) {
24   return mac_plugin_interposing::GetPluginWindowHasFocus(delegate);
25 }
26 
CGRectForWindow(WindowRef window)27 static CGRect CGRectForWindow(WindowRef window) {
28   CGRect bounds = { { 0, 0 }, { 0, 0 } };
29   HIWindowGetBounds(window, kWindowContentRgn, kHICoordSpace72DPIGlobal,
30                     &bounds);
31   return bounds;
32 }
33 
34 struct WindowInfo {
35   uint32 window_id;
36   CGRect bounds;
WindowInfoWindowInfo37   WindowInfo(WindowRef window) {
38     window_id = HIWindowGetCGWindowID(window);
39     bounds = CGRectForWindow(window);
40   }
41 };
42 
OnPluginWindowClosed(const WindowInfo & window_info)43 static void OnPluginWindowClosed(const WindowInfo& window_info) {
44   mac_plugin_interposing::NotifyBrowserOfPluginHideWindow(window_info.window_id,
45                                                           window_info.bounds);
46 }
47 
OnPluginWindowShown(WindowRef window)48 static void OnPluginWindowShown(WindowRef window) {
49   mac_plugin_interposing::NotifyBrowserOfPluginShowWindow(
50       HIWindowGetCGWindowID(window), CGRectForWindow(window),
51       IsModalWindow(window));
52 }
53 
OnPluginWindowSelected(WindowRef window)54 static void OnPluginWindowSelected(WindowRef window) {
55   mac_plugin_interposing::NotifyBrowserOfPluginSelectWindow(
56       HIWindowGetCGWindowID(window), CGRectForWindow(window),
57       IsModalWindow(window));
58 }
59 
60 #pragma mark -
61 
ChromePluginIsWindowActive(WindowRef window)62 static 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 
ChromePluginIsWindowHilited(WindowRef window)70 static 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 
ChromePluginSelectWindow(WindowRef window)78 static void ChromePluginSelectWindow(WindowRef window) {
79   mac_plugin_interposing::SwitchToPluginProcess();
80   SelectWindow(window);
81   OnPluginWindowSelected(window);
82 }
83 
ChromePluginShowWindow(WindowRef window)84 static void ChromePluginShowWindow(WindowRef window) {
85   mac_plugin_interposing::SwitchToPluginProcess();
86   ShowWindow(window);
87   OnPluginWindowShown(window);
88 }
89 
ChromePluginDisposeWindow(WindowRef window)90 static void ChromePluginDisposeWindow(WindowRef window) {
91   WindowInfo window_info(window);
92   DisposeWindow(window);
93   OnPluginWindowClosed(window_info);
94 }
95 
ChromePluginHideWindow(WindowRef window)96 static void ChromePluginHideWindow(WindowRef window) {
97   WindowInfo window_info(window);
98   HideWindow(window);
99   OnPluginWindowClosed(window_info);
100 }
101 
ChromePluginShowHide(WindowRef window,Boolean show)102 static 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 
ChromePluginReleaseWindow(WindowRef window)114 static void ChromePluginReleaseWindow(WindowRef window) {
115   WindowInfo window_info(window);
116   ReleaseWindow(window);
117   OnPluginWindowClosed(window_info);
118 }
119 
ChromePluginDisposeDialog(DialogRef dialog)120 static void ChromePluginDisposeDialog(DialogRef dialog) {
121   WindowRef window = GetDialogWindow(dialog);
122   WindowInfo window_info(window);
123   DisposeDialog(dialog);
124   OnPluginWindowClosed(window_info);
125 }
126 
ChromePluginFindWindow(Point point,WindowRef * window)127 static 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 
ChromePluginSetThemeCursor(ThemeCursor cursor)148 static 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 
ChromePluginSetCursor(const Cursor * cursor)157 static 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 
168 struct 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