/* * Copyright (C) 2010 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include "NetscapePlugin.h" #include "PluginController.h" #include "WebEvent.h" #include <WebCore/GraphicsContext.h> #include <WebCore/LocalWindowsContext.h> #include <WebCore/NotImplemented.h> using namespace WebCore; extern "C" HINSTANCE gInstance; namespace WebKit { static LPCWSTR windowClassName = L"org.webkit.NetscapePluginWindow"; static void registerPluginView() { static bool didRegister; if (didRegister) return; didRegister = true; WNDCLASSW windowClass = {0}; windowClass.style = CS_DBLCLKS; windowClass.lpfnWndProc = ::DefWindowProcW; windowClass.hInstance = gInstance; windowClass.hCursor = ::LoadCursorW(0, IDC_ARROW); windowClass.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW + 1); windowClass.lpszClassName = windowClassName; ::RegisterClassW(&windowClass); } HWND NetscapePlugin::containingWindow() const { return m_pluginController->nativeParentWindow(); } bool NetscapePlugin::platformPostInitialize() { if (!m_isWindowed) { m_window = 0; return true; } registerPluginView(); m_window = ::CreateWindowExW(0, windowClassName, 0, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, containingWindow(), 0, 0, 0); if (!m_window) return false; // FIXME: Do we need to pass our window to setPlatformWidget? // FIXME: WebCore::PluginView sets the window proc to DefWindowProcA here for Shockwave Director. m_npWindow.type = NPWindowTypeWindow; m_npWindow.window = m_window; return true; } void NetscapePlugin::platformDestroy() { if (!m_isWindowed) { ASSERT(!m_window); return; } if (!::IsWindow(m_window)) return; ::DestroyWindow(m_window); } bool NetscapePlugin::platformInvalidate(const IntRect& invalidRect) { if (!m_isWindowed) return false; RECT rect = invalidRect; ::InvalidateRect(m_window, &rect, FALSE); return true; } enum RedrawOrNot { DoNotRedraw, Redraw }; static void setWindowRegion(HWND window, PassOwnPtr<HRGN> popRegion, RedrawOrNot redrawOrNot) { OwnPtr<HRGN> region = popRegion; if (!::SetWindowRgn(window, region.get(), redrawOrNot == Redraw)) return; // Windows owns the region now. region.leakPtr(); } void NetscapePlugin::platformGeometryDidChange() { if (!m_isWindowed) return; IntRect clipRectInPluginWindowCoordinates = m_clipRect; clipRectInPluginWindowCoordinates.move(-m_frameRect.x(), -m_frameRect.y()); OwnPtr<HRGN> clipRegion = adoptPtr(::CreateRectRgn(clipRectInPluginWindowCoordinates.x(), clipRectInPluginWindowCoordinates.y(), clipRectInPluginWindowCoordinates.maxX(), clipRectInPluginWindowCoordinates.maxY())); setWindowRegion(m_window, clipRegion.release(), Redraw); // FIXME: We should only update the size here and let the UI process update our position so // that we can keep our position in sync when scrolling, etc. ::MoveWindow(m_window, m_frameRect.x(), m_frameRect.y(), m_frameRect.width(), m_frameRect.height(), TRUE); } void NetscapePlugin::platformPaint(GraphicsContext* context, const IntRect& dirtyRect, bool) { // FIXME: Call SetWindow here if we haven't called it yet (see r59904). if (m_isWindowed) { // FIXME: Paint windowed plugins into context if context->shouldIncludeChildWindows() is true. return; } // FIXME: Support transparent plugins. LocalWindowsContext windowsContext(context, dirtyRect, false); m_npWindow.type = NPWindowTypeDrawable; m_npWindow.window = windowsContext.hdc(); WINDOWPOS windowpos = { 0, 0, 0, 0, 0, 0, 0 }; windowpos.x = m_frameRect.x(); windowpos.y = m_frameRect.y(); windowpos.cx = m_frameRect.width(); windowpos.cy = m_frameRect.height(); NPEvent npEvent; npEvent.event = WM_WINDOWPOSCHANGED; npEvent.wParam = 0; npEvent.lParam = reinterpret_cast<uintptr_t>(&windowpos); NPP_HandleEvent(&npEvent); callSetWindow(); RECT dirtyWinRect = dirtyRect; npEvent.event = WM_PAINT; npEvent.wParam = reinterpret_cast<uintptr_t>(windowsContext.hdc()); npEvent.lParam = reinterpret_cast<uintptr_t>(&dirtyWinRect); NPP_HandleEvent(&npEvent); } NPEvent toNP(const WebMouseEvent& event) { NPEvent npEvent; npEvent.wParam = 0; if (event.controlKey()) npEvent.wParam |= MK_CONTROL; if (event.shiftKey()) npEvent.wParam |= MK_SHIFT; npEvent.lParam = MAKELPARAM(event.position().x(), event.position().y()); switch (event.type()) { case WebEvent::MouseMove: npEvent.event = WM_MOUSEMOVE; switch (event.button()) { case WebMouseEvent::LeftButton: npEvent.wParam |= MK_LBUTTON; break; case WebMouseEvent::MiddleButton: npEvent.wParam |= MK_MBUTTON; break; case WebMouseEvent::RightButton: npEvent.wParam |= MK_RBUTTON; break; case WebMouseEvent::NoButton: break; } break; case WebEvent::MouseDown: switch (event.button()) { case WebMouseEvent::LeftButton: npEvent.event = WM_LBUTTONDOWN; break; case WebMouseEvent::MiddleButton: npEvent.event = WM_MBUTTONDOWN; break; case WebMouseEvent::RightButton: npEvent.event = WM_RBUTTONDOWN; break; case WebMouseEvent::NoButton: ASSERT_NOT_REACHED(); break; } break; case WebEvent::MouseUp: switch (event.button()) { case WebMouseEvent::LeftButton: npEvent.event = WM_LBUTTONUP; break; case WebMouseEvent::MiddleButton: npEvent.event = WM_MBUTTONUP; break; case WebMouseEvent::RightButton: npEvent.event = WM_RBUTTONUP; break; case WebMouseEvent::NoButton: ASSERT_NOT_REACHED(); break; } break; default: ASSERT_NOT_REACHED(); break; } return npEvent; } bool NetscapePlugin::platformHandleMouseEvent(const WebMouseEvent& event) { if (m_isWindowed) return false; NPEvent npEvent = toNP(event); NPP_HandleEvent(&npEvent); return true; } bool NetscapePlugin::platformHandleWheelEvent(const WebWheelEvent&) { notImplemented(); return false; } void NetscapePlugin::platformSetFocus(bool) { notImplemented(); } bool NetscapePlugin::platformHandleMouseEnterEvent(const WebMouseEvent& event) { if (m_isWindowed) return false; NPEvent npEvent = toNP(event); NPP_HandleEvent(&npEvent); return true; } bool NetscapePlugin::platformHandleMouseLeaveEvent(const WebMouseEvent& event) { if (m_isWindowed) return false; NPEvent npEvent = toNP(event); NPP_HandleEvent(&npEvent); return true; } bool NetscapePlugin::platformHandleKeyboardEvent(const WebKeyboardEvent&) { notImplemented(); return false; } } // namespace WebKit