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