15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(__LP64__)
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <Carbon/Carbon.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/plugin/plugin_interpose_util_mac.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/rect.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns true if the given window is modal.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool IsModalWindow(WindowRef window) {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WindowModality modality = kWindowModalityNone;
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WindowRef modal_target = NULL;
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OSStatus status = GetWindowModality(window, &modality, &modal_target);
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (status == noErr) && (modality != kWindowModalityNone);
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static CGRect CGRectForWindow(WindowRef window) {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CGRect bounds = { { 0, 0 }, { 0, 0 } };
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HIWindowGetBounds(window, kWindowContentRgn, kHICoordSpace72DPIGlobal,
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    &bounds);
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return bounds;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct WindowInfo {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 window_id;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CGRect bounds;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WindowInfo(WindowRef window) {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window_id = HIWindowGetCGWindowID(window);
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bounds = CGRectForWindow(window);
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void OnPluginWindowClosed(const WindowInfo& window_info) {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mac_plugin_interposing::NotifyBrowserOfPluginHideWindow(window_info.window_id,
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                          window_info.bounds);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void OnPluginWindowShown(WindowRef window) {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mac_plugin_interposing::NotifyBrowserOfPluginShowWindow(
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HIWindowGetCGWindowID(window), CGRectForWindow(window),
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IsModalWindow(window));
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void OnPluginWindowSelected(WindowRef window) {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mac_plugin_interposing::NotifyBrowserOfPluginSelectWindow(
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HIWindowGetCGWindowID(window), CGRectForWindow(window),
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IsModalWindow(window));
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma mark -
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void ChromePluginSelectWindow(WindowRef window) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mac_plugin_interposing::SwitchToPluginProcess();
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SelectWindow(window);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OnPluginWindowSelected(window);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void ChromePluginShowWindow(WindowRef window) {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mac_plugin_interposing::SwitchToPluginProcess();
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ShowWindow(window);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OnPluginWindowShown(window);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void ChromePluginDisposeWindow(WindowRef window) {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WindowInfo window_info(window);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DisposeWindow(window);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OnPluginWindowClosed(window_info);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void ChromePluginHideWindow(WindowRef window) {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WindowInfo window_info(window);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HideWindow(window);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OnPluginWindowClosed(window_info);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void ChromePluginShowHide(WindowRef window, Boolean show) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (show) {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mac_plugin_interposing::SwitchToPluginProcess();
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ShowHide(window, show);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnPluginWindowShown(window);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WindowInfo window_info(window);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ShowHide(window, show);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnPluginWindowClosed(window_info);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void ChromePluginReleaseWindow(WindowRef window) {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WindowInfo window_info(window);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReleaseWindow(window);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OnPluginWindowClosed(window_info);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void ChromePluginDisposeDialog(DialogRef dialog) {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WindowRef window = GetDialogWindow(dialog);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WindowInfo window_info(window);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DisposeDialog(dialog);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OnPluginWindowClosed(window_info);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma mark -
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct interpose_substitution {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const void* replacement;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const void* original;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define INTERPOSE_FUNCTION(function) \
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { reinterpret_cast<const void*>(ChromePlugin##function), \
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<const void*>(function) }
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)__attribute__((used)) static const interpose_substitution substitutions[]
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    __attribute__((section("__DATA, __interpose"))) = {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  INTERPOSE_FUNCTION(SelectWindow),
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  INTERPOSE_FUNCTION(ShowWindow),
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  INTERPOSE_FUNCTION(ShowHide),
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  INTERPOSE_FUNCTION(DisposeWindow),
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  INTERPOSE_FUNCTION(HideWindow),
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  INTERPOSE_FUNCTION(ReleaseWindow),
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  INTERPOSE_FUNCTION(DisposeDialog),
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // !__LP64__
129