• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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