1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "base/bind_helpers.h" 6 #include "base/command_line.h" 7 #include "base/logging.h" 8 #include "base/message_loop/message_loop.h" 9 #include "content/browser/browser_plugin/browser_plugin_guest.h" 10 #include "content/browser/renderer_host/render_view_host_impl.h" 11 #include "content/browser/renderer_host/render_widget_host_view_guest.h" 12 #include "content/common/browser_plugin/browser_plugin_messages.h" 13 #include "content/common/gpu/gpu_messages.h" 14 #include "content/common/view_messages.h" 15 #include "content/common/webplugin_geometry.h" 16 #include "content/public/common/content_switches.h" 17 #include "skia/ext/platform_canvas.h" 18 #include "third_party/WebKit/public/platform/WebScreenInfo.h" 19 20 #if defined(OS_MACOSX) 21 #import "content/browser/renderer_host/render_widget_host_view_mac_dictionary_helper.h" 22 #endif 23 24 #if defined(OS_WIN) || defined(USE_AURA) 25 #include "content/browser/renderer_host/ui_events_helper.h" 26 #endif 27 28 namespace content { 29 30 namespace { 31 32 #if defined(OS_WIN) || defined(USE_AURA) 33 bool ShouldSendPinchGesture() { 34 static bool pinch_allowed = 35 CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnablePinch); 36 return pinch_allowed; 37 } 38 39 blink::WebGestureEvent CreateFlingCancelEvent(double time_stamp) { 40 blink::WebGestureEvent gesture_event; 41 gesture_event.timeStampSeconds = time_stamp; 42 gesture_event.type = blink::WebGestureEvent::GestureFlingCancel; 43 gesture_event.sourceDevice = blink::WebGestureEvent::Touchscreen; 44 return gesture_event; 45 } 46 #endif // defined(OS_WIN) || defined(USE_AURA) 47 48 } // namespace 49 50 RenderWidgetHostViewGuest::RenderWidgetHostViewGuest( 51 RenderWidgetHost* widget_host, 52 BrowserPluginGuest* guest, 53 RenderWidgetHostView* platform_view) 54 : host_(RenderWidgetHostImpl::From(widget_host)), 55 guest_(guest), 56 platform_view_(static_cast<RenderWidgetHostViewPort*>(platform_view)) { 57 #if defined(OS_WIN) || defined(USE_AURA) 58 gesture_recognizer_.reset(ui::GestureRecognizer::Create()); 59 gesture_recognizer_->AddGestureEventHelper(this); 60 #endif // defined(OS_WIN) || defined(USE_AURA) 61 host_->SetView(this); 62 } 63 64 RenderWidgetHostViewGuest::~RenderWidgetHostViewGuest() { 65 #if defined(OS_WIN) || defined(USE_AURA) 66 gesture_recognizer_->RemoveGestureEventHelper(this); 67 #endif // defined(OS_WIN) || defined(USE_AURA) 68 } 69 70 RenderWidgetHost* RenderWidgetHostViewGuest::GetRenderWidgetHost() const { 71 return host_; 72 } 73 74 void RenderWidgetHostViewGuest::WasShown() { 75 // If the WebContents associated with us showed an interstitial page in the 76 // beginning, the teardown path might call WasShown() while |host_| is in 77 // the process of destruction. Avoid calling WasShown below in this case. 78 // TODO(lazyboy): We shouldn't be showing interstitial pages in guests in the 79 // first place: http://crbug.com/273089. 80 // 81 // |guest_| is NULL during test. 82 if ((guest_ && guest_->is_in_destruction()) || !host_->is_hidden()) 83 return; 84 host_->WasShown(); 85 } 86 87 void RenderWidgetHostViewGuest::WasHidden() { 88 // |guest_| is NULL during test. 89 if ((guest_ && guest_->is_in_destruction()) || host_->is_hidden()) 90 return; 91 host_->WasHidden(); 92 } 93 94 void RenderWidgetHostViewGuest::SetSize(const gfx::Size& size) { 95 size_ = size; 96 host_->WasResized(); 97 } 98 99 gfx::Rect RenderWidgetHostViewGuest::GetBoundsInRootWindow() { 100 // We do not have any root window specific parts in this view. 101 return GetViewBounds(); 102 } 103 104 gfx::GLSurfaceHandle RenderWidgetHostViewGuest::GetCompositingSurface() { 105 return gfx::GLSurfaceHandle(gfx::kNullPluginWindow, gfx::TEXTURE_TRANSPORT); 106 } 107 108 #if defined(OS_WIN) || defined(USE_AURA) 109 void RenderWidgetHostViewGuest::ProcessAckedTouchEvent( 110 const TouchEventWithLatencyInfo& touch, InputEventAckState ack_result) { 111 // TODO(fsamuel): Currently we will only take this codepath if the guest has 112 // requested touch events. A better solution is to always forward touchpresses 113 // to the embedder process to target a BrowserPlugin, and then route all 114 // subsequent touch points of that touchdown to the appropriate guest until 115 // that touch point is released. 116 ScopedVector<ui::TouchEvent> events; 117 if (!MakeUITouchEventsFromWebTouchEvents(touch, &events, LOCAL_COORDINATES)) 118 return; 119 120 ui::EventResult result = (ack_result == 121 INPUT_EVENT_ACK_STATE_CONSUMED) ? ui::ER_HANDLED : ui::ER_UNHANDLED; 122 for (ScopedVector<ui::TouchEvent>::iterator iter = events.begin(), 123 end = events.end(); iter != end; ++iter) { 124 scoped_ptr<ui::GestureRecognizer::Gestures> gestures; 125 gestures.reset(gesture_recognizer_->ProcessTouchEventForGesture( 126 *(*iter), result, this)); 127 ProcessGestures(gestures.get()); 128 } 129 } 130 #endif 131 132 void RenderWidgetHostViewGuest::Show() { 133 WasShown(); 134 } 135 136 void RenderWidgetHostViewGuest::Hide() { 137 WasHidden(); 138 } 139 140 bool RenderWidgetHostViewGuest::IsShowing() { 141 return !host_->is_hidden(); 142 } 143 144 gfx::Rect RenderWidgetHostViewGuest::GetViewBounds() const { 145 RenderWidgetHostViewPort* rwhv = static_cast<RenderWidgetHostViewPort*>( 146 guest_->GetEmbedderRenderWidgetHostView()); 147 gfx::Rect embedder_bounds; 148 if (rwhv) 149 embedder_bounds = rwhv->GetViewBounds(); 150 gfx::Rect shifted_rect = guest_->ToGuestRect(embedder_bounds); 151 shifted_rect.set_width(size_.width()); 152 shifted_rect.set_height(size_.height()); 153 return shifted_rect; 154 } 155 156 void RenderWidgetHostViewGuest::RenderProcessGone( 157 base::TerminationStatus status, 158 int error_code) { 159 platform_view_->RenderProcessGone(status, error_code); 160 // Destroy the guest view instance only, so we don't end up calling 161 // platform_view_->Destroy(). 162 DestroyGuestView(); 163 } 164 165 void RenderWidgetHostViewGuest::Destroy() { 166 // The RenderWidgetHost's destruction led here, so don't call it. 167 DestroyGuestView(); 168 169 platform_view_->Destroy(); 170 } 171 172 void RenderWidgetHostViewGuest::SetTooltipText( 173 const base::string16& tooltip_text) { 174 platform_view_->SetTooltipText(tooltip_text); 175 } 176 177 void RenderWidgetHostViewGuest::AcceleratedSurfaceInitialized(int host_id, 178 int route_id) { 179 } 180 181 void RenderWidgetHostViewGuest::AcceleratedSurfaceBuffersSwapped( 182 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params, 183 int gpu_host_id) { 184 // If accelerated surface buffers are getting swapped then we're not using 185 // the software path. 186 guest_->clear_damage_buffer(); 187 BrowserPluginMsg_BuffersSwapped_Params guest_params; 188 guest_params.size = params.size; 189 guest_params.mailbox_name = params.mailbox_name; 190 guest_params.route_id = params.route_id; 191 guest_params.host_id = gpu_host_id; 192 guest_->SendMessageToEmbedder( 193 new BrowserPluginMsg_BuffersSwapped(guest_->instance_id(), guest_params)); 194 } 195 196 void RenderWidgetHostViewGuest::AcceleratedSurfacePostSubBuffer( 197 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params, 198 int gpu_host_id) { 199 NOTREACHED(); 200 } 201 202 void RenderWidgetHostViewGuest::OnSwapCompositorFrame( 203 uint32 output_surface_id, 204 scoped_ptr<cc::CompositorFrame> frame) { 205 if (frame->software_frame_data) { 206 cc::SoftwareFrameData* frame_data = frame->software_frame_data.get(); 207 #ifdef OS_WIN 208 base::SharedMemory shared_memory(frame_data->handle, true, 209 host_->GetProcess()->GetHandle()); 210 #else 211 base::SharedMemory shared_memory(frame_data->handle, true); 212 #endif 213 214 RenderWidgetHostView* embedder_view = 215 guest_->GetEmbedderRenderWidgetHostView(); 216 base::ProcessHandle embedder_pid = 217 embedder_view->GetRenderWidgetHost()->GetProcess()->GetHandle(); 218 219 shared_memory.GiveToProcess(embedder_pid, &frame_data->handle); 220 } 221 222 guest_->clear_damage_buffer(); 223 guest_->SendMessageToEmbedder( 224 new BrowserPluginMsg_CompositorFrameSwapped( 225 guest_->instance_id(), 226 *frame, 227 host_->GetRoutingID(), 228 output_surface_id, 229 host_->GetProcess()->GetID())); 230 } 231 232 void RenderWidgetHostViewGuest::SetBounds(const gfx::Rect& rect) { 233 SetSize(rect.size()); 234 } 235 236 bool RenderWidgetHostViewGuest::OnMessageReceived(const IPC::Message& msg) { 237 return platform_view_->OnMessageReceived(msg); 238 } 239 240 void RenderWidgetHostViewGuest::InitAsChild( 241 gfx::NativeView parent_view) { 242 platform_view_->InitAsChild(parent_view); 243 } 244 245 void RenderWidgetHostViewGuest::InitAsPopup( 246 RenderWidgetHostView* parent_host_view, const gfx::Rect& pos) { 247 // This should never get called. 248 NOTREACHED(); 249 } 250 251 void RenderWidgetHostViewGuest::InitAsFullscreen( 252 RenderWidgetHostView* reference_host_view) { 253 // This should never get called. 254 NOTREACHED(); 255 } 256 257 gfx::NativeView RenderWidgetHostViewGuest::GetNativeView() const { 258 return guest_->GetEmbedderRenderWidgetHostView()->GetNativeView(); 259 } 260 261 gfx::NativeViewId RenderWidgetHostViewGuest::GetNativeViewId() const { 262 if (guest_->GetEmbedderRenderWidgetHostView()) 263 return guest_->GetEmbedderRenderWidgetHostView()->GetNativeViewId(); 264 return static_cast<gfx::NativeViewId>(NULL); 265 } 266 267 gfx::NativeViewAccessible RenderWidgetHostViewGuest::GetNativeViewAccessible() { 268 return guest_->GetEmbedderRenderWidgetHostView()->GetNativeViewAccessible(); 269 } 270 271 void RenderWidgetHostViewGuest::MovePluginWindows( 272 const gfx::Vector2d& scroll_offset, 273 const std::vector<WebPluginGeometry>& moves) { 274 platform_view_->MovePluginWindows(scroll_offset, moves); 275 } 276 277 void RenderWidgetHostViewGuest::Focus() { 278 } 279 280 void RenderWidgetHostViewGuest::Blur() { 281 } 282 283 bool RenderWidgetHostViewGuest::HasFocus() const { 284 return false; 285 } 286 287 bool RenderWidgetHostViewGuest::IsSurfaceAvailableForCopy() const { 288 NOTIMPLEMENTED(); 289 return false; 290 } 291 292 void RenderWidgetHostViewGuest::UpdateCursor(const WebCursor& cursor) { 293 platform_view_->UpdateCursor(cursor); 294 } 295 296 void RenderWidgetHostViewGuest::SetIsLoading(bool is_loading) { 297 platform_view_->SetIsLoading(is_loading); 298 } 299 300 void RenderWidgetHostViewGuest::TextInputTypeChanged( 301 ui::TextInputType type, 302 ui::TextInputMode input_mode, 303 bool can_compose_inline) { 304 RenderWidgetHostViewPort* rwhv = RenderWidgetHostViewPort::FromRWHV( 305 guest_->GetEmbedderRenderWidgetHostView()); 306 if (!rwhv) 307 return; 308 // Forward the information to embedding RWHV. 309 rwhv->TextInputTypeChanged(type, input_mode, can_compose_inline); 310 } 311 312 void RenderWidgetHostViewGuest::ImeCancelComposition() { 313 RenderWidgetHostViewPort* rwhv = RenderWidgetHostViewPort::FromRWHV( 314 guest_->GetEmbedderRenderWidgetHostView()); 315 if (!rwhv) 316 return; 317 // Forward the information to embedding RWHV. 318 rwhv->ImeCancelComposition(); 319 } 320 321 #if defined(OS_MACOSX) || defined(OS_WIN) || defined(USE_AURA) 322 void RenderWidgetHostViewGuest::ImeCompositionRangeChanged( 323 const gfx::Range& range, 324 const std::vector<gfx::Rect>& character_bounds) { 325 RenderWidgetHostViewPort* rwhv = RenderWidgetHostViewPort::FromRWHV( 326 guest_->GetEmbedderRenderWidgetHostView()); 327 if (!rwhv) 328 return; 329 std::vector<gfx::Rect> guest_character_bounds; 330 for (size_t i = 0; i < character_bounds.size(); ++i) { 331 gfx::Rect guest_rect = guest_->ToGuestRect(character_bounds[i]); 332 guest_character_bounds.push_back(guest_rect); 333 } 334 // Forward the information to embedding RWHV. 335 rwhv->ImeCompositionRangeChanged(range, guest_character_bounds); 336 } 337 #endif 338 339 void RenderWidgetHostViewGuest::DidUpdateBackingStore( 340 const gfx::Rect& scroll_rect, 341 const gfx::Vector2d& scroll_delta, 342 const std::vector<gfx::Rect>& copy_rects, 343 const ui::LatencyInfo& latency_info) { 344 NOTREACHED(); 345 } 346 347 void RenderWidgetHostViewGuest::SelectionChanged(const base::string16& text, 348 size_t offset, 349 const gfx::Range& range) { 350 RenderWidgetHostViewPort* rwhv = RenderWidgetHostViewPort::FromRWHV( 351 guest_->GetEmbedderRenderWidgetHostView()); 352 if (!rwhv) 353 return; 354 // Forward the information to embedding RWHV. 355 rwhv->SelectionChanged(text, offset, range); 356 } 357 358 void RenderWidgetHostViewGuest::SelectionBoundsChanged( 359 const ViewHostMsg_SelectionBounds_Params& params) { 360 RenderWidgetHostViewPort* rwhv = RenderWidgetHostViewPort::FromRWHV( 361 guest_->GetEmbedderRenderWidgetHostView()); 362 if (!rwhv) 363 return; 364 ViewHostMsg_SelectionBounds_Params guest_params(params); 365 guest_params.anchor_rect = guest_->ToGuestRect(params.anchor_rect); 366 guest_params.focus_rect = guest_->ToGuestRect(params.focus_rect); 367 rwhv->SelectionBoundsChanged(guest_params); 368 } 369 370 void RenderWidgetHostViewGuest::ScrollOffsetChanged() { 371 } 372 373 BackingStore* RenderWidgetHostViewGuest::AllocBackingStore( 374 const gfx::Size& size) { 375 NOTREACHED(); 376 return NULL; 377 } 378 379 void RenderWidgetHostViewGuest::CopyFromCompositingSurface( 380 const gfx::Rect& src_subrect, 381 const gfx::Size& dst_size, 382 const base::Callback<void(bool, const SkBitmap&)>& callback) { 383 CHECK(guest_); 384 guest_->CopyFromCompositingSurface(src_subrect, dst_size, callback); 385 } 386 387 void RenderWidgetHostViewGuest::CopyFromCompositingSurfaceToVideoFrame( 388 const gfx::Rect& src_subrect, 389 const scoped_refptr<media::VideoFrame>& target, 390 const base::Callback<void(bool)>& callback) { 391 NOTIMPLEMENTED(); 392 callback.Run(false); 393 } 394 395 bool RenderWidgetHostViewGuest::CanCopyToVideoFrame() const { 396 return false; 397 } 398 399 void RenderWidgetHostViewGuest::AcceleratedSurfaceSuspend() { 400 NOTREACHED(); 401 } 402 403 void RenderWidgetHostViewGuest::AcceleratedSurfaceRelease() { 404 } 405 406 bool RenderWidgetHostViewGuest::HasAcceleratedSurface( 407 const gfx::Size& desired_size) { 408 return false; 409 } 410 411 void RenderWidgetHostViewGuest::SetBackground(const SkBitmap& background) { 412 platform_view_->SetBackground(background); 413 } 414 415 #if defined(OS_WIN) && !defined(USE_AURA) 416 void RenderWidgetHostViewGuest::SetClickthroughRegion(SkRegion* region) { 417 } 418 #endif 419 420 void RenderWidgetHostViewGuest::SetHasHorizontalScrollbar( 421 bool has_horizontal_scrollbar) { 422 platform_view_->SetHasHorizontalScrollbar(has_horizontal_scrollbar); 423 } 424 425 void RenderWidgetHostViewGuest::SetScrollOffsetPinning( 426 bool is_pinned_to_left, bool is_pinned_to_right) { 427 platform_view_->SetScrollOffsetPinning( 428 is_pinned_to_left, is_pinned_to_right); 429 } 430 431 void RenderWidgetHostViewGuest::OnAcceleratedCompositingStateChange() { 432 } 433 434 bool RenderWidgetHostViewGuest::LockMouse() { 435 return platform_view_->LockMouse(); 436 } 437 438 void RenderWidgetHostViewGuest::UnlockMouse() { 439 return platform_view_->UnlockMouse(); 440 } 441 442 void RenderWidgetHostViewGuest::GetScreenInfo(blink::WebScreenInfo* results) { 443 RenderWidgetHostViewPort* embedder_view = 444 RenderWidgetHostViewPort::FromRWHV( 445 guest_->GetEmbedderRenderWidgetHostView()); 446 if (embedder_view) 447 embedder_view->GetScreenInfo(results); 448 } 449 450 void RenderWidgetHostViewGuest::OnAccessibilityEvents( 451 const std::vector<AccessibilityHostMsg_EventParams>& params) { 452 } 453 454 #if defined(OS_MACOSX) 455 void RenderWidgetHostViewGuest::SetActive(bool active) { 456 platform_view_->SetActive(active); 457 } 458 459 void RenderWidgetHostViewGuest::SetTakesFocusOnlyOnMouseDown(bool flag) { 460 platform_view_->SetTakesFocusOnlyOnMouseDown(flag); 461 } 462 463 void RenderWidgetHostViewGuest::SetWindowVisibility(bool visible) { 464 platform_view_->SetWindowVisibility(visible); 465 } 466 467 void RenderWidgetHostViewGuest::WindowFrameChanged() { 468 platform_view_->WindowFrameChanged(); 469 } 470 471 void RenderWidgetHostViewGuest::ShowDefinitionForSelection() { 472 gfx::Point origin; 473 gfx::Rect guest_bounds = GetViewBounds(); 474 gfx::Rect embedder_bounds = 475 guest_->GetEmbedderRenderWidgetHostView()->GetViewBounds(); 476 477 gfx::Vector2d guest_offset = gfx::Vector2d( 478 // Horizontal offset of guest from embedder. 479 guest_bounds.x() - embedder_bounds.x(), 480 // Vertical offset from guest's top to embedder's bottom edge. 481 embedder_bounds.bottom() - guest_bounds.y()); 482 483 RenderWidgetHostViewMacDictionaryHelper helper(platform_view_); 484 helper.SetTargetView(guest_->GetEmbedderRenderWidgetHostView()); 485 helper.set_offset(guest_offset); 486 helper.ShowDefinitionForSelection(); 487 } 488 489 bool RenderWidgetHostViewGuest::SupportsSpeech() const { 490 return platform_view_->SupportsSpeech(); 491 } 492 493 void RenderWidgetHostViewGuest::SpeakSelection() { 494 platform_view_->SpeakSelection(); 495 } 496 497 bool RenderWidgetHostViewGuest::IsSpeaking() const { 498 return platform_view_->IsSpeaking(); 499 } 500 501 void RenderWidgetHostViewGuest::StopSpeaking() { 502 platform_view_->StopSpeaking(); 503 } 504 505 void RenderWidgetHostViewGuest::AboutToWaitForBackingStoreMsg() { 506 NOTREACHED(); 507 } 508 509 bool RenderWidgetHostViewGuest::PostProcessEventForPluginIme( 510 const NativeWebKeyboardEvent& event) { 511 return false; 512 } 513 514 #endif // defined(OS_MACOSX) 515 516 #if defined(OS_ANDROID) 517 void RenderWidgetHostViewGuest::ShowDisambiguationPopup( 518 const gfx::Rect& target_rect, 519 const SkBitmap& zoomed_bitmap) { 520 } 521 522 void RenderWidgetHostViewGuest::HasTouchEventHandlers(bool need_touch_events) { 523 } 524 #endif // defined(OS_ANDROID) 525 526 #if defined(TOOLKIT_GTK) 527 GdkEventButton* RenderWidgetHostViewGuest::GetLastMouseDown() { 528 return NULL; 529 } 530 531 gfx::NativeView RenderWidgetHostViewGuest::BuildInputMethodsGtkMenu() { 532 return platform_view_->BuildInputMethodsGtkMenu(); 533 } 534 #endif // defined(TOOLKIT_GTK) 535 536 #if defined(OS_WIN) && !defined(USE_AURA) 537 void RenderWidgetHostViewGuest::WillWmDestroy() { 538 } 539 #endif 540 541 #if defined(OS_WIN) && defined(USE_AURA) 542 void RenderWidgetHostViewGuest::SetParentNativeViewAccessible( 543 gfx::NativeViewAccessible accessible_parent) { 544 } 545 546 gfx::NativeViewId RenderWidgetHostViewGuest::GetParentForWindowlessPlugin() 547 const { 548 return NULL; 549 } 550 #endif 551 552 void RenderWidgetHostViewGuest::DestroyGuestView() { 553 host_->SetView(NULL); 554 host_ = NULL; 555 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); 556 } 557 558 bool RenderWidgetHostViewGuest::CanDispatchToConsumer( 559 ui::GestureConsumer* consumer) { 560 CHECK_EQ(static_cast<RenderWidgetHostViewGuest*>(consumer), this); 561 return true; 562 } 563 564 void RenderWidgetHostViewGuest::DispatchPostponedGestureEvent( 565 ui::GestureEvent* event) { 566 ForwardGestureEventToRenderer(event); 567 } 568 569 void RenderWidgetHostViewGuest::DispatchCancelTouchEvent( 570 ui::TouchEvent* event) { 571 if (!host_) 572 return; 573 574 blink::WebTouchEvent cancel_event; 575 cancel_event.type = blink::WebInputEvent::TouchCancel; 576 cancel_event.timeStampSeconds = event->time_stamp().InSecondsF(); 577 host_->ForwardTouchEventWithLatencyInfo(cancel_event, *event->latency()); 578 } 579 580 bool RenderWidgetHostViewGuest::ForwardGestureEventToRenderer( 581 ui::GestureEvent* gesture) { 582 #if defined(OS_WIN) || defined(USE_AURA) 583 if (!host_) 584 return false; 585 586 // Pinch gestures are disabled by default on windows desktop. See 587 // crbug.com/128477 and crbug.com/148816 588 if ((gesture->type() == ui::ET_GESTURE_PINCH_BEGIN || 589 gesture->type() == ui::ET_GESTURE_PINCH_UPDATE || 590 gesture->type() == ui::ET_GESTURE_PINCH_END) && 591 !ShouldSendPinchGesture()) { 592 return true; 593 } 594 595 blink::WebGestureEvent web_gesture = 596 MakeWebGestureEventFromUIEvent(*gesture); 597 const gfx::Point& client_point = gesture->location(); 598 const gfx::Point& screen_point = gesture->location(); 599 600 web_gesture.x = client_point.x(); 601 web_gesture.y = client_point.y(); 602 web_gesture.globalX = screen_point.x(); 603 web_gesture.globalY = screen_point.y(); 604 605 if (web_gesture.type == blink::WebGestureEvent::Undefined) 606 return false; 607 if (web_gesture.type == blink::WebGestureEvent::GestureTapDown) { 608 host_->ForwardGestureEvent( 609 CreateFlingCancelEvent(gesture->time_stamp().InSecondsF())); 610 } 611 host_->ForwardGestureEvent(web_gesture); 612 return true; 613 #else 614 return false; 615 #endif 616 } 617 618 void RenderWidgetHostViewGuest::ProcessGestures( 619 ui::GestureRecognizer::Gestures* gestures) { 620 if ((gestures == NULL) || gestures->empty()) 621 return; 622 for (ui::GestureRecognizer::Gestures::iterator g_it = gestures->begin(); 623 g_it != gestures->end(); 624 ++g_it) { 625 ForwardGestureEventToRenderer(*g_it); 626 } 627 } 628 629 630 } // namespace content 631