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 40namespace WebKit { 41 42class FullscreenWindowTracker { 43 WTF_MAKE_NONCOPYABLE(FullscreenWindowTracker); 44 45public: 46 FullscreenWindowTracker() { } 47 48 template<typename T> void windowShown(T window); 49 template<typename T> void windowHidden(T window); 50 51private: 52 typedef HashSet<void*> WindowSet; 53 WindowSet m_windows; 54}; 55 56static 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 66static 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 78static bool windowCoversAnyScreen(NSWindow* window) 79{ 80 return rectCoversAnyScreen([window frame]); 81} 82 83template<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 103template<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 117static FullscreenWindowTracker& fullscreenWindowTracker() 118{ 119 DEFINE_STATIC_LOCAL(FullscreenWindowTracker, fullscreenWindowTracker, ()); 120 return fullscreenWindowTracker; 121} 122 123static bool isUserbreakSet = false; 124 125static void initShouldCallRealDebugger() 126{ 127 char* var = getenv("USERBREAK"); 128 129 if (var) 130 isUserbreakSet = atoi(var); 131} 132 133static bool shouldCallRealDebugger() 134{ 135 static pthread_once_t shouldCallRealDebuggerOnce = PTHREAD_ONCE_INIT; 136 pthread_once(&shouldCallRealDebuggerOnce, initShouldCallRealDebugger); 137 138 return isUserbreakSet; 139} 140 141static 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 152static 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 162static void cocoaWindowShown(NSWindow *window) 163{ 164 fullscreenWindowTracker().windowShown(window); 165} 166 167static void cocoaWindowHidden(NSWindow *window) 168{ 169 fullscreenWindowTracker().windowHidden(window); 170} 171 172static void carbonWindowShown(WindowRef window) 173{ 174#ifndef NP_NO_CARBON 175 fullscreenWindowTracker().windowShown(window); 176#endif 177} 178 179static void carbonWindowHidden(WindowRef window) 180{ 181#ifndef NP_NO_CARBON 182 fullscreenWindowTracker().windowHidden(window); 183#endif 184} 185 186static void setModal(bool modalWindowIsShowing) 187{ 188 PluginProcess::shared().setModalWindowIsShowing(modalWindowIsShowing); 189} 190 191void 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 208void PluginProcess::setModalWindowIsShowing(bool modalWindowIsShowing) 209{ 210 m_connection->send(Messages::PluginProcessProxy::SetModalWindowIsShowing(modalWindowIsShowing), 0); 211} 212 213void PluginProcess::setFullscreenWindowIsShowing(bool fullscreenWindowIsShowing) 214{ 215 m_connection->send(Messages::PluginProcessProxy::SetFullscreenWindowIsShowing(fullscreenWindowIsShowing), 0); 216} 217 218void 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