1/* 2 * Copyright (C) 2010 Apple Inc. All rights reserved. 3 * Portions Copyright (c) 2010 Motorola Mobility, Inc. All rights reserved. 4 * Copyright (C) 2011 Igalia S.L. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 17 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 19 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 25 * THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28#include "config.h" 29#include "PageClientImpl.h" 30 31#include "DrawingAreaProxyImpl.h" 32#include "NativeWebKeyboardEvent.h" 33#include "NativeWebMouseEvent.h" 34#include "NotImplemented.h" 35#include "WebContext.h" 36#include "WebContextMenuProxyGtk.h" 37#include "WebEventFactory.h" 38#include "WebKitWebViewBasePrivate.h" 39#include "WebPageProxy.h" 40#include "WebPopupMenuProxyGtk.h" 41#include <WebCore/Cursor.h> 42#include <WebCore/EventNames.h> 43#include <WebCore/GtkUtilities.h> 44#include <wtf/text/CString.h> 45#include <wtf/text/WTFString.h> 46 47using namespace WebCore; 48 49namespace WebKit { 50 51PageClientImpl::PageClientImpl(GtkWidget* viewWidget) 52 : m_viewWidget(viewWidget) 53{ 54} 55 56void PageClientImpl::getEditorCommandsForKeyEvent(const NativeWebKeyboardEvent& event, const AtomicString& eventType, Vector<WTF::String>& commandList) 57{ 58 ASSERT(eventType == eventNames().keydownEvent || eventType == eventNames().keypressEvent); 59 60 KeyBindingTranslator::EventType type = eventType == eventNames().keydownEvent ? 61 KeyBindingTranslator::KeyDown : KeyBindingTranslator::KeyPress; 62 m_keyBindingTranslator.getEditorCommandsForKeyEvent(const_cast<GdkEventKey*>(&event.nativeEvent()->key), type, commandList); 63} 64 65// PageClient's pure virtual functions 66std::unique_ptr<DrawingAreaProxy> PageClientImpl::createDrawingAreaProxy() 67{ 68 return std::make_unique<DrawingAreaProxyImpl>(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(m_viewWidget))); 69} 70 71void PageClientImpl::setViewNeedsDisplay(const WebCore::IntRect& rect) 72{ 73 gtk_widget_queue_draw_area(m_viewWidget, rect.x(), rect.y(), rect.width(), rect.height()); 74} 75 76void PageClientImpl::displayView() 77{ 78 notImplemented(); 79} 80 81void PageClientImpl::scrollView(const WebCore::IntRect& scrollRect, const WebCore::IntSize& /* scrollOffset */) 82{ 83 setViewNeedsDisplay(scrollRect); 84} 85 86void PageClientImpl::requestScroll(const WebCore::FloatPoint&, bool) 87{ 88 notImplemented(); 89} 90 91WebCore::IntSize PageClientImpl::viewSize() 92{ 93 if (!gtk_widget_get_realized(m_viewWidget)) 94 return IntSize(); 95 GtkAllocation allocation; 96 gtk_widget_get_allocation(m_viewWidget, &allocation); 97 return IntSize(allocation.width, allocation.height); 98} 99 100bool PageClientImpl::isViewWindowActive() 101{ 102 return webkitWebViewBaseIsInWindowActive(WEBKIT_WEB_VIEW_BASE(m_viewWidget)); 103} 104 105bool PageClientImpl::isViewFocused() 106{ 107 return webkitWebViewBaseIsFocused(WEBKIT_WEB_VIEW_BASE(m_viewWidget)); 108} 109 110bool PageClientImpl::isViewVisible() 111{ 112 return webkitWebViewBaseIsVisible(WEBKIT_WEB_VIEW_BASE(m_viewWidget)); 113} 114 115bool PageClientImpl::isViewInWindow() 116{ 117 return webkitWebViewBaseIsInWindow(WEBKIT_WEB_VIEW_BASE(m_viewWidget)); 118} 119 120void PageClientImpl::PageClientImpl::processDidExit() 121{ 122 notImplemented(); 123} 124 125void PageClientImpl::didRelaunchProcess() 126{ 127 notImplemented(); 128} 129 130void PageClientImpl::toolTipChanged(const String&, const String& newToolTip) 131{ 132 webkitWebViewBaseSetTooltipText(WEBKIT_WEB_VIEW_BASE(m_viewWidget), newToolTip.utf8().data()); 133} 134 135void PageClientImpl::setCursor(const Cursor& cursor) 136{ 137 if (!gtk_widget_get_realized(m_viewWidget)) 138 return; 139 140 // [GTK] Widget::setCursor() gets called frequently 141 // http://bugs.webkit.org/show_bug.cgi?id=16388 142 // Setting the cursor may be an expensive operation in some backends, 143 // so don't re-set the cursor if it's already set to the target value. 144 GdkWindow* window = gtk_widget_get_window(m_viewWidget); 145 GdkCursor* currentCursor = gdk_window_get_cursor(window); 146 GdkCursor* newCursor = cursor.platformCursor().get(); 147 if (currentCursor != newCursor) 148 gdk_window_set_cursor(window, newCursor); 149} 150 151void PageClientImpl::setCursorHiddenUntilMouseMoves(bool /* hiddenUntilMouseMoves */) 152{ 153 notImplemented(); 154} 155 156void PageClientImpl::didChangeViewportProperties(const WebCore::ViewportAttributes&) 157{ 158 notImplemented(); 159} 160 161void PageClientImpl::registerEditCommand(PassRefPtr<WebEditCommandProxy> command, WebPageProxy::UndoOrRedo undoOrRedo) 162{ 163 m_undoController.registerEditCommand(command, undoOrRedo); 164} 165 166void PageClientImpl::clearAllEditCommands() 167{ 168 m_undoController.clearAllEditCommands(); 169} 170 171bool PageClientImpl::canUndoRedo(WebPageProxy::UndoOrRedo undoOrRedo) 172{ 173 return m_undoController.canUndoRedo(undoOrRedo); 174} 175 176void PageClientImpl::executeUndoRedo(WebPageProxy::UndoOrRedo undoOrRedo) 177{ 178 m_undoController.executeUndoRedo(undoOrRedo); 179} 180 181FloatRect PageClientImpl::convertToDeviceSpace(const FloatRect& viewRect) 182{ 183 notImplemented(); 184 return viewRect; 185} 186 187FloatRect PageClientImpl::convertToUserSpace(const FloatRect& viewRect) 188{ 189 notImplemented(); 190 return viewRect; 191} 192 193IntPoint PageClientImpl::screenToRootView(const IntPoint& point) 194{ 195 IntPoint widgetPositionOnScreen = convertWidgetPointToScreenPoint(m_viewWidget, IntPoint()); 196 IntPoint result(point); 197 result.move(-widgetPositionOnScreen.x(), -widgetPositionOnScreen.y()); 198 return result; 199} 200 201IntRect PageClientImpl::rootViewToScreen(const IntRect& rect) 202{ 203 return IntRect(convertWidgetPointToScreenPoint(m_viewWidget, rect.location()), rect.size()); 204} 205 206void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent& event, bool wasEventHandled) 207{ 208 if (wasEventHandled) 209 return; 210 if (event.isFakeEventForComposition()) 211 return; 212 213 WebKitWebViewBase* webkitWebViewBase = WEBKIT_WEB_VIEW_BASE(m_viewWidget); 214 webkitWebViewBaseForwardNextKeyEvent(webkitWebViewBase); 215 gtk_main_do_event(event.nativeEvent()); 216} 217 218PassRefPtr<WebPopupMenuProxy> PageClientImpl::createPopupMenuProxy(WebPageProxy* page) 219{ 220 return WebPopupMenuProxyGtk::create(m_viewWidget, page); 221} 222 223PassRefPtr<WebContextMenuProxy> PageClientImpl::createContextMenuProxy(WebPageProxy* page) 224{ 225 return WebContextMenuProxyGtk::create(m_viewWidget, page); 226} 227 228#if ENABLE(INPUT_TYPE_COLOR) 229PassRefPtr<WebColorPicker> PageClientImpl::createColorPicker(WebPageProxy*, const WebCore::Color&, const WebCore::IntRect&) 230{ 231 notImplemented(); 232 return 0; 233} 234#endif 235 236void PageClientImpl::setFindIndicator(PassRefPtr<FindIndicator>, bool /* fadeOut */, bool /* animate */) 237{ 238 notImplemented(); 239} 240 241void PageClientImpl::enterAcceleratedCompositingMode(const LayerTreeContext&) 242{ 243 notImplemented(); 244} 245 246void PageClientImpl::exitAcceleratedCompositingMode() 247{ 248 notImplemented(); 249} 250 251void PageClientImpl::updateAcceleratedCompositingMode(const LayerTreeContext&) 252{ 253 notImplemented(); 254} 255 256void PageClientImpl::pageClosed() 257{ 258 notImplemented(); 259} 260 261void PageClientImpl::preferencesDidChange() 262{ 263 notImplemented(); 264} 265 266void PageClientImpl::updateTextInputState() 267{ 268 webkitWebViewBaseUpdateTextInputState(WEBKIT_WEB_VIEW_BASE(m_viewWidget)); 269} 270 271void PageClientImpl::startDrag(const WebCore::DragData& dragData, PassRefPtr<ShareableBitmap> dragImage) 272{ 273 webkitWebViewBaseStartDrag(WEBKIT_WEB_VIEW_BASE(m_viewWidget), dragData, dragImage); 274} 275 276void PageClientImpl::handleDownloadRequest(DownloadProxy* download) 277{ 278 webkitWebViewBaseHandleDownloadRequest(WEBKIT_WEB_VIEW_BASE(m_viewWidget), download); 279} 280 281void PageClientImpl::didCommitLoadForMainFrame(const String& /* mimeType */, bool /* useCustomContentProvider */ ) 282{ 283 webkitWebViewBaseResetClickCounter(WEBKIT_WEB_VIEW_BASE(m_viewWidget)); 284} 285 286#if ENABLE(FULLSCREEN_API) 287WebFullScreenManagerProxyClient& PageClientImpl::fullScreenManagerProxyClient() 288{ 289 return *this; 290} 291 292void PageClientImpl::closeFullScreenManager() 293{ 294 notImplemented(); 295} 296 297bool PageClientImpl::isFullScreen() 298{ 299 notImplemented(); 300 return false; 301} 302 303void PageClientImpl::enterFullScreen() 304{ 305 if (!m_viewWidget) 306 return; 307 308 webkitWebViewBaseEnterFullScreen(WEBKIT_WEB_VIEW_BASE(m_viewWidget)); 309} 310 311void PageClientImpl::exitFullScreen() 312{ 313 if (!m_viewWidget) 314 return; 315 316 webkitWebViewBaseExitFullScreen(WEBKIT_WEB_VIEW_BASE(m_viewWidget)); 317} 318 319void PageClientImpl::beganEnterFullScreen(const IntRect& /* initialFrame */, const IntRect& /* finalFrame */) 320{ 321 notImplemented(); 322} 323 324void PageClientImpl::beganExitFullScreen(const IntRect& /* initialFrame */, const IntRect& /* finalFrame */) 325{ 326 notImplemented(); 327} 328 329#endif // ENABLE(FULLSCREEN_API) 330 331void PageClientImpl::doneWithTouchEvent(const NativeWebTouchEvent& event, bool wasEventHandled) 332{ 333 if (wasEventHandled) 334 return; 335 336 // Emulate pointer events if unhandled. 337 const GdkEvent* touchEvent = event.nativeEvent(); 338 339 if (!touchEvent->touch.emulating_pointer) 340 return; 341 342 GUniquePtr<GdkEvent> pointerEvent; 343 344 if (touchEvent->type == GDK_TOUCH_UPDATE) { 345 pointerEvent.reset(gdk_event_new(GDK_MOTION_NOTIFY)); 346 pointerEvent->motion.time = touchEvent->touch.time; 347 pointerEvent->motion.x = touchEvent->touch.x; 348 pointerEvent->motion.y = touchEvent->touch.y; 349 pointerEvent->motion.x_root = touchEvent->touch.x_root; 350 pointerEvent->motion.y_root = touchEvent->touch.y_root; 351 pointerEvent->motion.state = touchEvent->touch.state | GDK_BUTTON1_MASK; 352 } else { 353 switch (touchEvent->type) { 354 case GDK_TOUCH_END: 355 pointerEvent.reset(gdk_event_new(GDK_BUTTON_RELEASE)); 356 pointerEvent->button.state = touchEvent->touch.state | GDK_BUTTON1_MASK; 357 break; 358 case GDK_TOUCH_BEGIN: 359 pointerEvent.reset(gdk_event_new(GDK_BUTTON_PRESS)); 360 break; 361 default: 362 ASSERT_NOT_REACHED(); 363 } 364 365 pointerEvent->button.button = 1; 366 pointerEvent->button.time = touchEvent->touch.time; 367 pointerEvent->button.x = touchEvent->touch.x; 368 pointerEvent->button.y = touchEvent->touch.y; 369 pointerEvent->button.x_root = touchEvent->touch.x_root; 370 pointerEvent->button.y_root = touchEvent->touch.y_root; 371 } 372 373 gdk_event_set_device(pointerEvent.get(), gdk_event_get_device(touchEvent)); 374 gdk_event_set_source_device(pointerEvent.get(), gdk_event_get_source_device(touchEvent)); 375 pointerEvent->any.window = GDK_WINDOW(g_object_ref(touchEvent->any.window)); 376 pointerEvent->any.send_event = TRUE; 377 378 gtk_widget_event(m_viewWidget, pointerEvent.get()); 379} 380 381void PageClientImpl::didFinishLoadingDataForCustomContentProvider(const String&, const IPC::DataReference&) 382{ 383} 384 385void PageClientImpl::navigationGestureDidBegin() 386{ 387} 388 389void PageClientImpl::navigationGestureWillEnd(bool, WebBackForwardListItem&) 390{ 391} 392 393void PageClientImpl::navigationGestureDidEnd(bool, WebBackForwardListItem&) 394{ 395} 396 397void PageClientImpl::willRecordNavigationSnapshot(WebBackForwardListItem&) 398{ 399} 400 401} // namespace WebKit 402