Home | History | Annotate | Download | only in win
      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