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