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 #include "config.h"
27 #include "NetscapePlugin.h"
28
29 #include "PluginController.h"
30 #include "WebEvent.h"
31 #include <WebCore/GraphicsContext.h>
32 #include <WebCore/LocalWindowsContext.h>
33 #include <WebCore/NotImplemented.h>
34
35 using namespace WebCore;
36
37 extern "C" HINSTANCE gInstance;
38
39 namespace WebKit {
40
41 static LPCWSTR windowClassName = L"org.webkit.NetscapePluginWindow";
42
registerPluginView()43 static void registerPluginView()
44 {
45 static bool didRegister;
46 if (didRegister)
47 return;
48 didRegister = true;
49
50 WNDCLASSW windowClass = {0};
51 windowClass.style = CS_DBLCLKS;
52 windowClass.lpfnWndProc = ::DefWindowProcW;
53 windowClass.hInstance = gInstance;
54 windowClass.hCursor = ::LoadCursorW(0, IDC_ARROW);
55 windowClass.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW + 1);
56 windowClass.lpszClassName = windowClassName;
57
58 ::RegisterClassW(&windowClass);
59 }
60
containingWindow() const61 HWND NetscapePlugin::containingWindow() const
62 {
63 return m_pluginController->nativeParentWindow();
64 }
65
platformPostInitialize()66 bool NetscapePlugin::platformPostInitialize()
67 {
68 if (!m_isWindowed) {
69 m_window = 0;
70 return true;
71 }
72
73 registerPluginView();
74
75 m_window = ::CreateWindowExW(0, windowClassName, 0, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, containingWindow(), 0, 0, 0);
76 if (!m_window)
77 return false;
78
79 // FIXME: Do we need to pass our window to setPlatformWidget?
80 // FIXME: WebCore::PluginView sets the window proc to DefWindowProcA here for Shockwave Director.
81
82 m_npWindow.type = NPWindowTypeWindow;
83 m_npWindow.window = m_window;
84
85 return true;
86 }
87
platformDestroy()88 void NetscapePlugin::platformDestroy()
89 {
90 if (!m_isWindowed) {
91 ASSERT(!m_window);
92 return;
93 }
94
95 if (!::IsWindow(m_window))
96 return;
97 ::DestroyWindow(m_window);
98 }
99
platformInvalidate(const IntRect & invalidRect)100 bool NetscapePlugin::platformInvalidate(const IntRect& invalidRect)
101 {
102 if (!m_isWindowed)
103 return false;
104
105 RECT rect = invalidRect;
106 ::InvalidateRect(m_window, &rect, FALSE);
107 return true;
108 }
109
110 enum RedrawOrNot { DoNotRedraw, Redraw };
setWindowRegion(HWND window,PassOwnPtr<HRGN> popRegion,RedrawOrNot redrawOrNot)111 static void setWindowRegion(HWND window, PassOwnPtr<HRGN> popRegion, RedrawOrNot redrawOrNot)
112 {
113 OwnPtr<HRGN> region = popRegion;
114
115 if (!::SetWindowRgn(window, region.get(), redrawOrNot == Redraw))
116 return;
117
118 // Windows owns the region now.
119 region.leakPtr();
120 }
121
platformGeometryDidChange()122 void NetscapePlugin::platformGeometryDidChange()
123 {
124 if (!m_isWindowed)
125 return;
126
127 IntRect clipRectInPluginWindowCoordinates = m_clipRect;
128 clipRectInPluginWindowCoordinates.move(-m_frameRect.x(), -m_frameRect.y());
129
130 OwnPtr<HRGN> clipRegion = adoptPtr(::CreateRectRgn(clipRectInPluginWindowCoordinates.x(), clipRectInPluginWindowCoordinates.y(), clipRectInPluginWindowCoordinates.maxX(), clipRectInPluginWindowCoordinates.maxY()));
131 setWindowRegion(m_window, clipRegion.release(), Redraw);
132
133 // FIXME: We should only update the size here and let the UI process update our position so
134 // that we can keep our position in sync when scrolling, etc.
135 ::MoveWindow(m_window, m_frameRect.x(), m_frameRect.y(), m_frameRect.width(), m_frameRect.height(), TRUE);
136 }
137
platformPaint(GraphicsContext * context,const IntRect & dirtyRect,bool)138 void NetscapePlugin::platformPaint(GraphicsContext* context, const IntRect& dirtyRect, bool)
139 {
140 // FIXME: Call SetWindow here if we haven't called it yet (see r59904).
141
142 if (m_isWindowed) {
143 // FIXME: Paint windowed plugins into context if context->shouldIncludeChildWindows() is true.
144 return;
145 }
146
147 // FIXME: Support transparent plugins.
148 LocalWindowsContext windowsContext(context, dirtyRect, false);
149
150 m_npWindow.type = NPWindowTypeDrawable;
151 m_npWindow.window = windowsContext.hdc();
152
153 WINDOWPOS windowpos = { 0, 0, 0, 0, 0, 0, 0 };
154
155 windowpos.x = m_frameRect.x();
156 windowpos.y = m_frameRect.y();
157 windowpos.cx = m_frameRect.width();
158 windowpos.cy = m_frameRect.height();
159
160 NPEvent npEvent;
161 npEvent.event = WM_WINDOWPOSCHANGED;
162 npEvent.wParam = 0;
163 npEvent.lParam = reinterpret_cast<uintptr_t>(&windowpos);
164
165 NPP_HandleEvent(&npEvent);
166
167 callSetWindow();
168
169 RECT dirtyWinRect = dirtyRect;
170
171 npEvent.event = WM_PAINT;
172 npEvent.wParam = reinterpret_cast<uintptr_t>(windowsContext.hdc());
173 npEvent.lParam = reinterpret_cast<uintptr_t>(&dirtyWinRect);
174
175 NPP_HandleEvent(&npEvent);
176 }
177
toNP(const WebMouseEvent & event)178 NPEvent toNP(const WebMouseEvent& event)
179 {
180 NPEvent npEvent;
181
182 npEvent.wParam = 0;
183 if (event.controlKey())
184 npEvent.wParam |= MK_CONTROL;
185 if (event.shiftKey())
186 npEvent.wParam |= MK_SHIFT;
187
188 npEvent.lParam = MAKELPARAM(event.position().x(), event.position().y());
189
190 switch (event.type()) {
191 case WebEvent::MouseMove:
192 npEvent.event = WM_MOUSEMOVE;
193 switch (event.button()) {
194 case WebMouseEvent::LeftButton:
195 npEvent.wParam |= MK_LBUTTON;
196 break;
197 case WebMouseEvent::MiddleButton:
198 npEvent.wParam |= MK_MBUTTON;
199 break;
200 case WebMouseEvent::RightButton:
201 npEvent.wParam |= MK_RBUTTON;
202 break;
203 case WebMouseEvent::NoButton:
204 break;
205 }
206 break;
207 case WebEvent::MouseDown:
208 switch (event.button()) {
209 case WebMouseEvent::LeftButton:
210 npEvent.event = WM_LBUTTONDOWN;
211 break;
212 case WebMouseEvent::MiddleButton:
213 npEvent.event = WM_MBUTTONDOWN;
214 break;
215 case WebMouseEvent::RightButton:
216 npEvent.event = WM_RBUTTONDOWN;
217 break;
218 case WebMouseEvent::NoButton:
219 ASSERT_NOT_REACHED();
220 break;
221 }
222 break;
223 case WebEvent::MouseUp:
224 switch (event.button()) {
225 case WebMouseEvent::LeftButton:
226 npEvent.event = WM_LBUTTONUP;
227 break;
228 case WebMouseEvent::MiddleButton:
229 npEvent.event = WM_MBUTTONUP;
230 break;
231 case WebMouseEvent::RightButton:
232 npEvent.event = WM_RBUTTONUP;
233 break;
234 case WebMouseEvent::NoButton:
235 ASSERT_NOT_REACHED();
236 break;
237 }
238 break;
239 default:
240 ASSERT_NOT_REACHED();
241 break;
242 }
243
244 return npEvent;
245 }
246
platformHandleMouseEvent(const WebMouseEvent & event)247 bool NetscapePlugin::platformHandleMouseEvent(const WebMouseEvent& event)
248 {
249 if (m_isWindowed)
250 return false;
251
252 NPEvent npEvent = toNP(event);
253 NPP_HandleEvent(&npEvent);
254 return true;
255 }
256
platformHandleWheelEvent(const WebWheelEvent &)257 bool NetscapePlugin::platformHandleWheelEvent(const WebWheelEvent&)
258 {
259 notImplemented();
260 return false;
261 }
262
platformSetFocus(bool)263 void NetscapePlugin::platformSetFocus(bool)
264 {
265 notImplemented();
266 }
267
platformHandleMouseEnterEvent(const WebMouseEvent & event)268 bool NetscapePlugin::platformHandleMouseEnterEvent(const WebMouseEvent& event)
269 {
270 if (m_isWindowed)
271 return false;
272
273 NPEvent npEvent = toNP(event);
274 NPP_HandleEvent(&npEvent);
275 return true;
276 }
277
platformHandleMouseLeaveEvent(const WebMouseEvent & event)278 bool NetscapePlugin::platformHandleMouseLeaveEvent(const WebMouseEvent& event)
279 {
280 if (m_isWindowed)
281 return false;
282
283 NPEvent npEvent = toNP(event);
284 NPP_HandleEvent(&npEvent);
285 return true;
286 }
287
platformHandleKeyboardEvent(const WebKeyboardEvent &)288 bool NetscapePlugin::platformHandleKeyboardEvent(const WebKeyboardEvent&)
289 {
290 notImplemented();
291 return false;
292 }
293
294 } // namespace WebKit
295