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