Home | History | Annotate | Download | only in web
      1 /*
      2  * Copyright (C) 2012 Google 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 are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #include "config.h"
     32 #include "PageWidgetDelegate.h"
     33 
     34 #include "PageOverlayList.h"
     35 #include "WebInputEvent.h"
     36 #include "WebInputEventConversion.h"
     37 #include "core/page/EventHandler.h"
     38 #include "core/page/Frame.h"
     39 #include "core/page/FrameView.h"
     40 #include "core/platform/graphics/GraphicsContext.h"
     41 #include "wtf/CurrentTime.h"
     42 
     43 using namespace WebCore;
     44 
     45 namespace WebKit {
     46 
     47 static inline FrameView* mainFrameView(Page* page)
     48 {
     49     if (!page)
     50         return 0;
     51     // FIXME: Can we remove this check?
     52     if (!page->mainFrame())
     53         return 0;
     54     return page->mainFrame()->view();
     55 }
     56 
     57 void PageWidgetDelegate::animate(Page* page, double monotonicFrameBeginTime)
     58 {
     59     FrameView* view = mainFrameView(page);
     60     if (!view)
     61         return;
     62     view->serviceScriptedAnimations(monotonicFrameBeginTime);
     63 }
     64 
     65 void PageWidgetDelegate::layout(Page* page)
     66 {
     67     FrameView* view = mainFrameView(page);
     68     if (!view)
     69         return;
     70     // In order for our child HWNDs (NativeWindowWidgets) to update properly,
     71     // they need to be told that we are updating the screen. The problem is that
     72     // the native widgets need to recalculate their clip region and not overlap
     73     // any of our non-native widgets. To force the resizing, call
     74     // setFrameRect(). This will be a quick operation for most frames, but the
     75     // NativeWindowWidgets will update a proper clipping region.
     76     view->setFrameRect(view->frameRect());
     77 
     78     // setFrameRect may have the side-effect of causing existing page layout to
     79     // be invalidated, so layout needs to be called last.
     80     view->updateLayoutAndStyleIfNeededRecursive();
     81 }
     82 
     83 void PageWidgetDelegate::paint(Page* page, PageOverlayList* overlays, WebCanvas* canvas, const WebRect& rect, CanvasBackground background)
     84 {
     85     if (rect.isEmpty())
     86         return;
     87     GraphicsContext gc(canvas);
     88     gc.setCertainlyOpaque(background == Opaque);
     89     gc.applyDeviceScaleFactor(page->deviceScaleFactor());
     90     gc.setUseHighResMarkers(page->deviceScaleFactor() > 1.5f);
     91     IntRect dirtyRect(rect);
     92     gc.save();
     93     FrameView* view = mainFrameView(page);
     94     // FIXME: Can we remove the mainFrame()->document() check?
     95     if (view && page->mainFrame()->document()) {
     96         gc.clip(dirtyRect);
     97         view->paint(&gc, dirtyRect);
     98         if (overlays)
     99             overlays->paintWebFrame(gc);
    100     } else {
    101         gc.fillRect(dirtyRect, Color::white);
    102     }
    103     gc.restore();
    104 }
    105 
    106 bool PageWidgetDelegate::handleInputEvent(Page* page, PageWidgetEventHandler& handler, const WebInputEvent& event)
    107 {
    108     Frame* frame = page ? page->mainFrame() : 0;
    109     switch (event.type) {
    110 
    111     // FIXME: WebKit seems to always return false on mouse events processing
    112     // methods. For now we'll assume it has processed them (as we are only
    113     // interested in whether keyboard events are processed).
    114     case WebInputEvent::MouseMove:
    115         if (!frame || !frame->view())
    116             return true;
    117         handler.handleMouseMove(*frame, *static_cast<const WebMouseEvent*>(&event));
    118         return true;
    119     case WebInputEvent::MouseLeave:
    120         if (!frame || !frame->view())
    121             return true;
    122         handler.handleMouseLeave(*frame, *static_cast<const WebMouseEvent*>(&event));
    123         return true;
    124     case WebInputEvent::MouseDown:
    125         if (!frame || !frame->view())
    126             return true;
    127         handler.handleMouseDown(*frame, *static_cast<const WebMouseEvent*>(&event));
    128         return true;
    129     case WebInputEvent::MouseUp:
    130         if (!frame || !frame->view())
    131             return true;
    132         handler.handleMouseUp(*frame, *static_cast<const WebMouseEvent*>(&event));
    133         return true;
    134 
    135     case WebInputEvent::MouseWheel:
    136         if (!frame || !frame->view())
    137             return false;
    138         return handler.handleMouseWheel(*frame, *static_cast<const WebMouseWheelEvent*>(&event));
    139 
    140     case WebInputEvent::RawKeyDown:
    141     case WebInputEvent::KeyDown:
    142     case WebInputEvent::KeyUp:
    143         return handler.handleKeyEvent(*static_cast<const WebKeyboardEvent*>(&event));
    144 
    145     case WebInputEvent::Char:
    146         return handler.handleCharEvent(*static_cast<const WebKeyboardEvent*>(&event));
    147     case WebInputEvent::GestureScrollBegin:
    148     case WebInputEvent::GestureScrollEnd:
    149     case WebInputEvent::GestureScrollUpdate:
    150     case WebInputEvent::GestureScrollUpdateWithoutPropagation:
    151     case WebInputEvent::GestureFlingStart:
    152     case WebInputEvent::GestureFlingCancel:
    153     case WebInputEvent::GestureTap:
    154     case WebInputEvent::GestureTapUnconfirmed:
    155     case WebInputEvent::GestureTapDown:
    156     case WebInputEvent::GestureTapCancel:
    157     case WebInputEvent::GestureDoubleTap:
    158     case WebInputEvent::GestureTwoFingerTap:
    159     case WebInputEvent::GestureLongPress:
    160     case WebInputEvent::GestureLongTap:
    161         return handler.handleGestureEvent(*static_cast<const WebGestureEvent*>(&event));
    162 
    163     case WebInputEvent::TouchStart:
    164     case WebInputEvent::TouchMove:
    165     case WebInputEvent::TouchEnd:
    166     case WebInputEvent::TouchCancel:
    167         if (!frame || !frame->view())
    168             return false;
    169         return handler.handleTouchEvent(*frame, *static_cast<const WebTouchEvent*>(&event));
    170 
    171     case WebInputEvent::GesturePinchBegin:
    172     case WebInputEvent::GesturePinchEnd:
    173     case WebInputEvent::GesturePinchUpdate:
    174         // FIXME: Once PlatformGestureEvent is updated to support pinch, this
    175         // should call handleGestureEvent, just like it currently does for
    176         // gesture scroll.
    177         return false;
    178 
    179     default:
    180         return false;
    181     }
    182 }
    183 
    184 // ----------------------------------------------------------------
    185 // Default handlers for PageWidgetEventHandler
    186 
    187 void PageWidgetEventHandler::handleMouseMove(Frame& mainFrame, const WebMouseEvent& event)
    188 {
    189     // We call mouseMoved here instead of handleMouseMovedEvent because we need
    190     // our ChromeClientImpl to receive changes to the mouse position and tooltip
    191     // text, and mouseMoved handles all of that.
    192     mainFrame.eventHandler()->mouseMoved(PlatformMouseEventBuilder(mainFrame.view(), event));
    193 }
    194 
    195 void PageWidgetEventHandler::handleMouseLeave(Frame& mainFrame, const WebMouseEvent& event)
    196 {
    197     mainFrame.eventHandler()->handleMouseMoveEvent(PlatformMouseEventBuilder(mainFrame.view(), event));
    198 }
    199 
    200 void PageWidgetEventHandler::handleMouseDown(Frame& mainFrame, const WebMouseEvent& event)
    201 {
    202     mainFrame.eventHandler()->handleMousePressEvent(PlatformMouseEventBuilder(mainFrame.view(), event));
    203 }
    204 
    205 void PageWidgetEventHandler::handleMouseUp(Frame& mainFrame, const WebMouseEvent& event)
    206 {
    207     mainFrame.eventHandler()->handleMouseReleaseEvent(PlatformMouseEventBuilder(mainFrame.view(), event));
    208 }
    209 
    210 bool PageWidgetEventHandler::handleMouseWheel(Frame& mainFrame, const WebMouseWheelEvent& event)
    211 {
    212     return mainFrame.eventHandler()->handleWheelEvent(PlatformWheelEventBuilder(mainFrame.view(), event));
    213 }
    214 
    215 bool PageWidgetEventHandler::handleTouchEvent(Frame& mainFrame, const WebTouchEvent& event)
    216 {
    217     return mainFrame.eventHandler()->handleTouchEvent(PlatformTouchEventBuilder(mainFrame.view(), event));
    218 }
    219 
    220 }
    221