1 /* 2 * Copyright (C) 2010 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #import "config.h" 27 #import "PluginProcess.h" 28 29 #if ENABLE(PLUGIN_PROCESS) 30 31 #import "NetscapePlugin.h" 32 #import "PluginProcessShim.h" 33 #import "PluginProcessProxyMessages.h" 34 #import "PluginProcessCreationParameters.h" 35 #import <WebCore/LocalizedStrings.h> 36 #import <WebKitSystemInterface.h> 37 #import <dlfcn.h> 38 #import <wtf/HashSet.h> 39 40 namespace WebKit { 41 42 class FullscreenWindowTracker { 43 WTF_MAKE_NONCOPYABLE(FullscreenWindowTracker); 44 45 public: 46 FullscreenWindowTracker() { } 47 48 template<typename T> void windowShown(T window); 49 template<typename T> void windowHidden(T window); 50 51 private: 52 typedef HashSet<void*> WindowSet; 53 WindowSet m_windows; 54 }; 55 56 static bool rectCoversAnyScreen(NSRect rect) 57 { 58 for (NSScreen *screen in [NSScreen screens]) { 59 if (NSContainsRect(rect, [screen frame])) 60 return YES; 61 } 62 return NO; 63 } 64 65 #ifndef NP_NO_CARBON 66 static bool windowCoversAnyScreen(WindowRef window) 67 { 68 HIRect bounds; 69 HIWindowGetBounds(window, kWindowStructureRgn, kHICoordSpaceScreenPixel, &bounds); 70 71 // Convert to Cocoa-style screen coordinates that use a Y offset relative to the zeroth screen's origin. 72 bounds.origin.y = NSHeight([[[NSScreen screens] objectAtIndex:0] frame]) - CGRectGetMaxY(bounds); 73 74 return rectCoversAnyScreen(NSRectFromCGRect(bounds)); 75 } 76 #endif 77 78 static bool windowCoversAnyScreen(NSWindow* window) 79 { 80 return rectCoversAnyScreen([window frame]); 81 } 82 83 template<typename T> void FullscreenWindowTracker::windowShown(T window) 84 { 85 // If this window is already visible then there is nothing to do. 86 WindowSet::iterator it = m_windows.find(window); 87 if (it != m_windows.end()) 88 return; 89 90 // If the window is not full-screen then we're not interested in it. 91 if (!windowCoversAnyScreen(window)) 92 return; 93 94 bool windowSetWasEmpty = m_windows.isEmpty(); 95 96 m_windows.add(window); 97 98 // If this is the first full screen window to be shown, notify the UI process. 99 if (windowSetWasEmpty) 100 PluginProcess::shared().setFullscreenWindowIsShowing(true); 101 } 102 103 template<typename T> void FullscreenWindowTracker::windowHidden(T window) 104 { 105 // If this is not a window that we're tracking then there is nothing to do. 106 WindowSet::iterator it = m_windows.find(window); 107 if (it == m_windows.end()) 108 return; 109 110 m_windows.remove(it); 111 112 // If this was the last full screen window that was visible, notify the UI process. 113 if (m_windows.isEmpty()) 114 PluginProcess::shared().setFullscreenWindowIsShowing(false); 115 } 116 117 static FullscreenWindowTracker& fullscreenWindowTracker() 118 { 119 DEFINE_STATIC_LOCAL(FullscreenWindowTracker, fullscreenWindowTracker, ()); 120 return fullscreenWindowTracker; 121 } 122 123 static bool isUserbreakSet = false; 124 125 static void initShouldCallRealDebugger() 126 { 127 char* var = getenv("USERBREAK"); 128 129 if (var) 130 isUserbreakSet = atoi(var); 131 } 132 133 static bool shouldCallRealDebugger() 134 { 135 static pthread_once_t shouldCallRealDebuggerOnce = PTHREAD_ONCE_INIT; 136 pthread_once(&shouldCallRealDebuggerOnce, initShouldCallRealDebugger); 137 138 return isUserbreakSet; 139 } 140 141 static bool isWindowActive(WindowRef windowRef, bool& result) 142 { 143 #ifndef NP_NO_CARBON 144 if (NetscapePlugin* plugin = NetscapePlugin::netscapePluginFromWindow(windowRef)) { 145 result = plugin->isWindowActive(); 146 return true; 147 } 148 #endif 149 return false; 150 } 151 152 static UInt32 getCurrentEventButtonState() 153 { 154 #ifndef NP_NO_CARBON 155 return NetscapePlugin::buttonState(); 156 #else 157 ASSERT_NOT_REACHED(); 158 return 0; 159 #endif 160 } 161 162 static void cocoaWindowShown(NSWindow *window) 163 { 164 fullscreenWindowTracker().windowShown(window); 165 } 166 167 static void cocoaWindowHidden(NSWindow *window) 168 { 169 fullscreenWindowTracker().windowHidden(window); 170 } 171 172 static void carbonWindowShown(WindowRef window) 173 { 174 #ifndef NP_NO_CARBON 175 fullscreenWindowTracker().windowShown(window); 176 #endif 177 } 178 179 static void carbonWindowHidden(WindowRef window) 180 { 181 #ifndef NP_NO_CARBON 182 fullscreenWindowTracker().windowHidden(window); 183 #endif 184 } 185 186 static void setModal(bool modalWindowIsShowing) 187 { 188 PluginProcess::shared().setModalWindowIsShowing(modalWindowIsShowing); 189 } 190 191 void PluginProcess::initializeShim() 192 { 193 const PluginProcessShimCallbacks callbacks = { 194 shouldCallRealDebugger, 195 isWindowActive, 196 getCurrentEventButtonState, 197 cocoaWindowShown, 198 cocoaWindowHidden, 199 carbonWindowShown, 200 carbonWindowHidden, 201 setModal, 202 }; 203 204 PluginProcessShimInitializeFunc initFunc = reinterpret_cast<PluginProcessShimInitializeFunc>(dlsym(RTLD_DEFAULT, "WebKitPluginProcessShimInitialize")); 205 initFunc(callbacks); 206 } 207 208 void PluginProcess::setModalWindowIsShowing(bool modalWindowIsShowing) 209 { 210 m_connection->send(Messages::PluginProcessProxy::SetModalWindowIsShowing(modalWindowIsShowing), 0); 211 } 212 213 void PluginProcess::setFullscreenWindowIsShowing(bool fullscreenWindowIsShowing) 214 { 215 m_connection->send(Messages::PluginProcessProxy::SetFullscreenWindowIsShowing(fullscreenWindowIsShowing), 0); 216 } 217 218 void PluginProcess::platformInitialize(const PluginProcessCreationParameters& parameters) 219 { 220 m_compositingRenderServerPort = parameters.acceleratedCompositingPort.port(); 221 222 NSString *applicationName = [NSString stringWithFormat:WEB_UI_STRING("%@ (%@ Internet plug-in)", 223 "visible name of the plug-in host process. The first argument is the plug-in name " 224 "and the second argument is the application name."), 225 [[(NSString *)parameters.pluginPath lastPathComponent] stringByDeletingPathExtension], 226 (NSString *)parameters.parentProcessName]; 227 228 WKSetVisibleApplicationName((CFStringRef)applicationName); 229 } 230 231 } // namespace WebKit 232 233 #endif // ENABLE(PLUGIN_PROCESS) 234