OLD | NEW |
(Empty) | |
| 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 #include <Carbon/Carbon.h> |
| 6 |
| 7 #include "webkit/glue/plugins/fake_plugin_window_tracker_mac.h" |
| 8 |
| 9 // The process that was frontmost when a plugin created a new window; generally |
| 10 // we expect this to be the browser UI process. |
| 11 static ProcessSerialNumber g_saved_front_process = { 0, 0 }; |
| 12 |
| 13 // Bring the plugin process to the front so that the user can see it. |
| 14 // TODO: Make this an IPC to order the plugin process above the browser |
| 15 // process but not necessarily the frontmost. |
| 16 static void SwitchToPluginProcess() { |
| 17 ProcessSerialNumber this_process, front_process; |
| 18 if (GetCurrentProcess(&this_process) != noErr) |
| 19 return; |
| 20 if (GetFrontProcess(&front_process) != noErr) |
| 21 return; |
| 22 Boolean matched = false; |
| 23 if (SameProcess(&this_process, &front_process, &matched) != noErr) |
| 24 return; |
| 25 if (!matched) { |
| 26 // TODO: We may need to keep a stack, or at least check the total window |
| 27 // count, since this won't work if a plugin opens more than one window at |
| 28 // a time. |
| 29 g_saved_front_process = front_process; |
| 30 SetFrontProcess(&this_process); |
| 31 } |
| 32 } |
| 33 |
| 34 // If the plugin process is still the front process, bring the prior |
| 35 // front process (normally this will be the browser process) back to |
| 36 // the front. |
| 37 // TODO: Make this an IPC message so that the browser can properly |
| 38 // reactivate the window. |
| 39 static void SwitchToSavedProcess() { |
| 40 ProcessSerialNumber this_process, front_process; |
| 41 if (GetCurrentProcess(&this_process) != noErr) |
| 42 return; |
| 43 if (GetFrontProcess(&front_process) != noErr) |
| 44 return; |
| 45 Boolean matched = false; |
| 46 if (SameProcess(&this_process, &front_process, &matched) != noErr) |
| 47 return; |
| 48 if (matched) { |
| 49 SetFrontProcess(&g_saved_front_process); |
| 50 } |
| 51 } |
| 52 |
| 53 #pragma mark - |
| 54 |
| 55 static Boolean ChromePluginIsWindowHilited(WindowRef window) { |
| 56 // TODO(stuartmorgan): Always returning true (instead of the real answer, |
| 57 // which would be false) means that clicking works, but it's not correct |
| 58 // either. Ideally we need a way to find out if the delegate corresponds |
| 59 // to a browser window that is active. |
| 60 const WebPluginDelegateImpl* delegate = |
| 61 FakePluginWindowTracker::SharedInstance()->GetDelegateForFakeWindow( |
| 62 window); |
| 63 Boolean isHilited = delegate ? true : IsWindowHilited(window); |
| 64 return isHilited; |
| 65 } |
| 66 |
| 67 static void ChromePluginSelectWindow(WindowRef window) { |
| 68 SwitchToPluginProcess(); |
| 69 SelectWindow(window); |
| 70 } |
| 71 |
| 72 static void ChromePluginShowWindow(WindowRef window) { |
| 73 SwitchToPluginProcess(); |
| 74 ShowWindow(window); |
| 75 } |
| 76 |
| 77 static void ChromePluginDisposeWindow(WindowRef window) { |
| 78 SwitchToSavedProcess(); |
| 79 DisposeWindow(window); |
| 80 } |
| 81 |
| 82 static void ChromePluginHideWindow(WindowRef window) { |
| 83 SwitchToSavedProcess(); |
| 84 HideWindow(window); |
| 85 } |
| 86 |
| 87 #pragma mark - |
| 88 |
| 89 struct interpose_substitution { |
| 90 const void* replacement; |
| 91 const void* original; |
| 92 }; |
| 93 |
| 94 #define INTERPOSE_FUNCTION(function) \ |
| 95 { reinterpret_cast<const void*>(ChromePlugin##function), \ |
| 96 reinterpret_cast<const void*>(function) } |
| 97 |
| 98 __attribute__((used)) static const interpose_substitution substitutions[] |
| 99 __attribute__((section("__DATA, __interpose"))) = { |
| 100 INTERPOSE_FUNCTION(IsWindowHilited), |
| 101 INTERPOSE_FUNCTION(SelectWindow), |
| 102 INTERPOSE_FUNCTION(ShowWindow), |
| 103 INTERPOSE_FUNCTION(DisposeWindow), |
| 104 INTERPOSE_FUNCTION(HideWindow), |
| 105 }; |
OLD | NEW |