OSDN Git Service

Merge WebKit at r84325: Initial merge by git.
[android-x86/external-webkit.git] / Source / WebKit2 / PluginProcess / mac / PluginProcessMac.mm
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)