Home | History | Annotate | Download | only in plugin
      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