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 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 61 HWND NetscapePlugin::containingWindow() const 62 { 63 return m_pluginController->nativeParentWindow(); 64 } 65 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 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 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 }; 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 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 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 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 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 257 bool NetscapePlugin::platformHandleWheelEvent(const WebWheelEvent&) 258 { 259 notImplemented(); 260 return false; 261 } 262 263 void NetscapePlugin::platformSetFocus(bool) 264 { 265 notImplemented(); 266 } 267 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 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 288 bool NetscapePlugin::platformHandleKeyboardEvent(const WebKeyboardEvent&) 289 { 290 notImplemented(); 291 return false; 292 } 293 294 } // namespace WebKit 295