OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #import <Cocoa/Cocoa.h> | 5 #import <Cocoa/Cocoa.h> |
6 #import <QuartzCore/QuartzCore.h> | 6 #import <QuartzCore/QuartzCore.h> |
7 | 7 |
8 #include "webkit/plugins/npapi/webplugin_delegate_impl.h" | 8 #include "webkit/plugins/npapi/webplugin_delegate_impl.h" |
9 | 9 |
10 #include <string> | 10 #include <string> |
(...skipping 15 matching lines...) Expand all Loading... |
26 #include "webkit/plugins/npapi/plugin_list.h" | 26 #include "webkit/plugins/npapi/plugin_list.h" |
27 #include "webkit/plugins/npapi/plugin_stream_url.h" | 27 #include "webkit/plugins/npapi/plugin_stream_url.h" |
28 #include "webkit/plugins/npapi/plugin_web_event_converter_mac.h" | 28 #include "webkit/plugins/npapi/plugin_web_event_converter_mac.h" |
29 #include "webkit/plugins/npapi/webplugin.h" | 29 #include "webkit/plugins/npapi/webplugin.h" |
30 #include "webkit/plugins/npapi/webplugin_accelerated_surface_mac.h" | 30 #include "webkit/plugins/npapi/webplugin_accelerated_surface_mac.h" |
31 | 31 |
32 #ifndef NP_NO_CARBON | 32 #ifndef NP_NO_CARBON |
33 #include "webkit/plugins/npapi/carbon_plugin_window_tracker_mac.h" | 33 #include "webkit/plugins/npapi/carbon_plugin_window_tracker_mac.h" |
34 #endif | 34 #endif |
35 | 35 |
36 #ifndef NP_NO_QUICKDRAW | |
37 #include "webkit/plugins/npapi/quickdraw_drawing_manager_mac.h" | |
38 #endif | |
39 | |
40 #if defined(USE_SKIA) | 36 #if defined(USE_SKIA) |
41 #include "skia/ext/skia_utils_mac.h" | 37 #include "skia/ext/skia_utils_mac.h" |
42 #endif | 38 #endif |
43 | 39 |
44 using WebKit::WebCursorInfo; | 40 using WebKit::WebCursorInfo; |
45 using WebKit::WebKeyboardEvent; | 41 using WebKit::WebKeyboardEvent; |
46 using WebKit::WebInputEvent; | 42 using WebKit::WebInputEvent; |
47 using WebKit::WebMouseEvent; | 43 using WebKit::WebMouseEvent; |
48 using WebKit::WebMouseWheelEvent; | 44 using WebKit::WebMouseWheelEvent; |
49 | 45 |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 handle_event_depth_(0), | 275 handle_event_depth_(0), |
280 first_set_window_call_(true), | 276 first_set_window_call_(true), |
281 plugin_has_focus_(false), | 277 plugin_has_focus_(false), |
282 has_webkit_focus_(false), | 278 has_webkit_focus_(false), |
283 containing_view_has_focus_(true), | 279 containing_view_has_focus_(true), |
284 creation_succeeded_(false) { | 280 creation_succeeded_(false) { |
285 memset(&window_, 0, sizeof(window_)); | 281 memset(&window_, 0, sizeof(window_)); |
286 #ifndef NP_NO_CARBON | 282 #ifndef NP_NO_CARBON |
287 memset(&np_cg_context_, 0, sizeof(np_cg_context_)); | 283 memset(&np_cg_context_, 0, sizeof(np_cg_context_)); |
288 #endif | 284 #endif |
289 #ifndef NP_NO_QUICKDRAW | |
290 memset(&qd_port_, 0, sizeof(qd_port_)); | |
291 #endif | |
292 instance->set_windowless(true); | 285 instance->set_windowless(true); |
293 } | 286 } |
294 | 287 |
295 WebPluginDelegateImpl::~WebPluginDelegateImpl() { | 288 WebPluginDelegateImpl::~WebPluginDelegateImpl() { |
296 DestroyInstance(); | 289 DestroyInstance(); |
297 | 290 |
298 #ifndef NP_NO_CARBON | 291 #ifndef NP_NO_CARBON |
299 if (np_cg_context_.window) { | 292 if (np_cg_context_.window) { |
300 CarbonPluginWindowTracker::SharedInstance()->DestroyDummyWindowForDelegate( | 293 CarbonPluginWindowTracker::SharedInstance()->DestroyDummyWindowForDelegate( |
301 this, reinterpret_cast<WindowRef>(np_cg_context_.window)); | 294 this, reinterpret_cast<WindowRef>(np_cg_context_.window)); |
(...skipping 21 matching lines...) Expand all Loading... |
323 np_cg_context_.window = window_tracker->CreateDummyWindowForDelegate(this); | 316 np_cg_context_.window = window_tracker->CreateDummyWindowForDelegate(this); |
324 np_cg_context_.context = NULL; | 317 np_cg_context_.context = NULL; |
325 UpdateDummyWindowBounds(gfx::Point(0, 0)); | 318 UpdateDummyWindowBounds(gfx::Point(0, 0)); |
326 } | 319 } |
327 #endif | 320 #endif |
328 | 321 |
329 NPDrawingModel drawing_model = instance()->drawing_model(); | 322 NPDrawingModel drawing_model = instance()->drawing_model(); |
330 switch (drawing_model) { | 323 switch (drawing_model) { |
331 #ifndef NP_NO_QUICKDRAW | 324 #ifndef NP_NO_QUICKDRAW |
332 case NPDrawingModelQuickDraw: | 325 case NPDrawingModelQuickDraw: |
333 if (instance()->event_model() != NPEventModelCarbon) | 326 return false; |
334 return false; | |
335 qd_manager_.reset(new QuickDrawDrawingManager()); | |
336 qd_manager_->SetPluginWindow( | |
337 reinterpret_cast<WindowRef>(np_cg_context_.window)); | |
338 qd_port_.port = qd_manager_->port(); | |
339 window_.window = &qd_port_; | |
340 window_.type = NPWindowTypeDrawable; | |
341 break; | |
342 #endif | 327 #endif |
343 case NPDrawingModelCoreGraphics: | 328 case NPDrawingModelCoreGraphics: |
344 #ifndef NP_NO_CARBON | 329 #ifndef NP_NO_CARBON |
345 if (instance()->event_model() == NPEventModelCarbon) | 330 if (instance()->event_model() == NPEventModelCarbon) |
346 window_.window = &np_cg_context_; | 331 window_.window = &np_cg_context_; |
347 #endif | 332 #endif |
348 window_.type = NPWindowTypeDrawable; | 333 window_.type = NPWindowTypeDrawable; |
349 break; | 334 break; |
350 case NPDrawingModelCoreAnimation: | 335 case NPDrawingModelCoreAnimation: |
351 case NPDrawingModelInvalidatingCoreAnimation: { | 336 case NPDrawingModelInvalidatingCoreAnimation: { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 // accelerated rendering is enabled. | 391 // accelerated rendering is enabled. |
407 if (!layer_) | 392 if (!layer_) |
408 plugin_->SetWindow(gfx::kNullPluginWindow); | 393 plugin_->SetWindow(gfx::kNullPluginWindow); |
409 | 394 |
410 #ifndef NP_NO_CARBON | 395 #ifndef NP_NO_CARBON |
411 // If the plugin wants Carbon events, hook up to the source of idle events. | 396 // If the plugin wants Carbon events, hook up to the source of idle events. |
412 if (instance()->event_model() == NPEventModelCarbon) | 397 if (instance()->event_model() == NPEventModelCarbon) |
413 UpdateIdleEventRate(); | 398 UpdateIdleEventRate(); |
414 #endif | 399 #endif |
415 | 400 |
416 // QuickTime (in QD mode only) can crash if it gets other calls (e.g., | |
417 // NPP_Write) before it gets a SetWindow call, so call SetWindow (with a 0x0 | |
418 // rect) immediately. | |
419 #ifndef NP_NO_QUICKDRAW | |
420 if (instance()->drawing_model() == NPDrawingModelQuickDraw) { | |
421 const WebPluginInfo& plugin_info = instance_->plugin_lib()->plugin_info(); | |
422 if (plugin_info.name.find(ASCIIToUTF16("QuickTime")) != string16::npos) | |
423 WindowlessSetWindow(); | |
424 } | |
425 #endif | |
426 | |
427 return true; | 401 return true; |
428 } | 402 } |
429 | 403 |
430 void WebPluginDelegateImpl::PlatformDestroyInstance() { | 404 void WebPluginDelegateImpl::PlatformDestroyInstance() { |
431 #ifndef NP_NO_CARBON | 405 #ifndef NP_NO_CARBON |
432 if (instance()->event_model() == NPEventModelCarbon) | 406 if (instance()->event_model() == NPEventModelCarbon) |
433 CarbonIdleEventSource::SharedInstance()->UnregisterDelegate(this); | 407 CarbonIdleEventSource::SharedInstance()->UnregisterDelegate(this); |
434 #endif | 408 #endif |
435 if (redraw_timer_.get()) | 409 if (redraw_timer_.get()) |
436 redraw_timer_->Stop(); | 410 redraw_timer_->Stop(); |
(...skipping 10 matching lines...) Expand all Loading... |
447 if (instance()->event_model() == NPEventModelCarbon) { | 421 if (instance()->event_model() == NPEventModelCarbon) { |
448 // Update the structure that is passed to Carbon+CoreGraphics plugins in | 422 // Update the structure that is passed to Carbon+CoreGraphics plugins in |
449 // NPP_SetWindow before calling UpdateGeometry, since that will trigger an | 423 // NPP_SetWindow before calling UpdateGeometry, since that will trigger an |
450 // NPP_SetWindow call if the geometry changes (which is the only time the | 424 // NPP_SetWindow call if the geometry changes (which is the only time the |
451 // context would be different), and some plugins (e.g., Flash) have an | 425 // context would be different), and some plugins (e.g., Flash) have an |
452 // internal cache of the context that they only update when NPP_SetWindow | 426 // internal cache of the context that they only update when NPP_SetWindow |
453 // is called. | 427 // is called. |
454 np_cg_context_.context = context; | 428 np_cg_context_.context = context; |
455 } | 429 } |
456 #endif | 430 #endif |
457 #ifndef NP_NO_QUICKDRAW | |
458 if (instance()->drawing_model() == NPDrawingModelQuickDraw) | |
459 qd_manager_->SetTargetContext(context, window_rect.size()); | |
460 #endif | |
461 UpdateGeometry(window_rect, clip_rect); | 431 UpdateGeometry(window_rect, clip_rect); |
462 } | 432 } |
463 | 433 |
464 void WebPluginDelegateImpl::Paint(WebKit::WebCanvas* canvas, | 434 void WebPluginDelegateImpl::Paint(WebKit::WebCanvas* canvas, |
465 const gfx::Rect& rect) { | 435 const gfx::Rect& rect) { |
466 #if defined(USE_SKIA) | 436 #if defined(USE_SKIA) |
467 gfx::SkiaBitLocker bit_locker(canvas); | 437 gfx::SkiaBitLocker bit_locker(canvas); |
468 CGContextRef context = bit_locker.cgContext(); | 438 CGContextRef context = bit_locker.cgContext(); |
469 #else | 439 #else |
470 CGContextRef context = canvas; | 440 CGContextRef context = canvas; |
471 #endif | 441 #endif |
472 CGPaint(context, rect); | 442 CGPaint(context, rect); |
473 } | 443 } |
474 | 444 |
475 void WebPluginDelegateImpl::CGPaint(CGContextRef context, | 445 void WebPluginDelegateImpl::CGPaint(CGContextRef context, |
476 const gfx::Rect& rect) { | 446 const gfx::Rect& rect) { |
477 WindowlessPaint(context, rect); | 447 WindowlessPaint(context, rect); |
478 | |
479 #ifndef NP_NO_QUICKDRAW | |
480 // Paint events are our cue to dump the current plugin bits into the buffer | |
481 // context if we are dealing with a QuickDraw plugin. | |
482 if (instance()->drawing_model() == NPDrawingModelQuickDraw) { | |
483 qd_manager_->UpdateContext(); | |
484 } | |
485 #endif | |
486 } | 448 } |
487 | 449 |
488 bool WebPluginDelegateImpl::PlatformHandleInputEvent( | 450 bool WebPluginDelegateImpl::PlatformHandleInputEvent( |
489 const WebInputEvent& event, WebCursorInfo* cursor_info) { | 451 const WebInputEvent& event, WebCursorInfo* cursor_info) { |
490 DCHECK(cursor_info != NULL); | 452 DCHECK(cursor_info != NULL); |
491 | 453 |
492 // If we get an event before we've set up the plugin, bail. | 454 // If we get an event before we've set up the plugin, bail. |
493 if (!have_called_set_window_) | 455 if (!have_called_set_window_) |
494 return false; | 456 return false; |
495 #ifndef NP_NO_CARBON | 457 #ifndef NP_NO_CARBON |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
539 // because the keydown wasn't sent to the plugin, the keyup shouldn't be | 501 // because the keydown wasn't sent to the plugin, the keyup shouldn't be |
540 // either (per the spec). | 502 // either (per the spec). |
541 if (event.type == WebInputEvent::KeyDown) | 503 if (event.type == WebInputEvent::KeyDown) |
542 ++keyup_ignore_count_; | 504 ++keyup_ignore_count_; |
543 else | 505 else |
544 --keyup_ignore_count_; | 506 --keyup_ignore_count_; |
545 return true; | 507 return true; |
546 } | 508 } |
547 | 509 |
548 #ifndef NP_NO_CARBON | 510 #ifndef NP_NO_CARBON |
549 if (instance()->event_model() == NPEventModelCarbon) { | 511 if (instance()->event_model() == NPEventModelCarbon && |
550 #ifndef NP_NO_QUICKDRAW | 512 event.type == WebInputEvent::MouseMove) { |
551 if (instance()->drawing_model() == NPDrawingModelQuickDraw) | 513 return true; // The recurring FireIdleEvent will send null events. |
552 qd_manager_->MakePortCurrent(); | |
553 #endif | |
554 | |
555 if (event.type == WebInputEvent::MouseMove) { | |
556 return true; // The recurring FireIdleEvent will send null events. | |
557 } | |
558 } | 514 } |
559 #endif | 515 #endif |
560 | 516 |
561 ScopedActiveDelegate active_delegate(this); | 517 ScopedActiveDelegate active_delegate(this); |
562 | 518 |
563 // Create the plugin event structure. | 519 // Create the plugin event structure. |
564 NPEventModel event_model = instance()->event_model(); | 520 NPEventModel event_model = instance()->event_model(); |
565 scoped_ptr<PluginWebEventConverter> event_converter( | 521 scoped_ptr<PluginWebEventConverter> event_converter( |
566 PluginWebEventConverterFactory::CreateConverterForModel(event_model)); | 522 PluginWebEventConverterFactory::CreateConverterForModel(event_model)); |
567 if (!(event_converter.get() && event_converter->InitWithEvent(event))) { | 523 if (!(event_converter.get() && event_converter->InitWithEvent(event))) { |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
633 void WebPluginDelegateImpl::WindowlessUpdateGeometry( | 589 void WebPluginDelegateImpl::WindowlessUpdateGeometry( |
634 const gfx::Rect& window_rect, | 590 const gfx::Rect& window_rect, |
635 const gfx::Rect& clip_rect) { | 591 const gfx::Rect& clip_rect) { |
636 gfx::Rect old_clip_rect = clip_rect_; | 592 gfx::Rect old_clip_rect = clip_rect_; |
637 cached_clip_rect_ = clip_rect; | 593 cached_clip_rect_ = clip_rect; |
638 if (container_is_visible_) // Remove check when cached_clip_rect_ is removed. | 594 if (container_is_visible_) // Remove check when cached_clip_rect_ is removed. |
639 clip_rect_ = clip_rect; | 595 clip_rect_ = clip_rect; |
640 bool clip_rect_changed = (clip_rect_ != old_clip_rect); | 596 bool clip_rect_changed = (clip_rect_ != old_clip_rect); |
641 bool window_size_changed = (window_rect.size() != window_rect_.size()); | 597 bool window_size_changed = (window_rect.size() != window_rect_.size()); |
642 | 598 |
643 bool force_set_window = false; | 599 if (window_rect == window_rect_ && !clip_rect_changed) |
644 #ifndef NP_NO_QUICKDRAW | |
645 // In a QuickDraw plugin, a geometry update might have caused a port change; | |
646 // if so, we need to call SetWindow even if nothing else changed. | |
647 if (qd_manager_.get() && (qd_port_.port != qd_manager_->port())) { | |
648 qd_port_.port = qd_manager_->port(); | |
649 force_set_window = true; | |
650 } | |
651 #endif | |
652 | |
653 if (window_rect == window_rect_ && !clip_rect_changed && !force_set_window) | |
654 return; | 600 return; |
655 | 601 |
656 if (old_clip_rect.IsEmpty() != clip_rect_.IsEmpty()) { | 602 if (old_clip_rect.IsEmpty() != clip_rect_.IsEmpty()) { |
657 PluginVisibilityChanged(); | 603 PluginVisibilityChanged(); |
658 } | 604 } |
659 | 605 |
660 SetPluginRect(window_rect); | 606 SetPluginRect(window_rect); |
661 | 607 |
662 if (window_size_changed || clip_rect_changed || force_set_window) | 608 if (window_size_changed || clip_rect_changed) |
663 WindowlessSetWindow(); | 609 WindowlessSetWindow(); |
664 } | 610 } |
665 | 611 |
666 void WebPluginDelegateImpl::WindowlessPaint(gfx::NativeDrawingContext context, | 612 void WebPluginDelegateImpl::WindowlessPaint(gfx::NativeDrawingContext context, |
667 const gfx::Rect& damage_rect) { | 613 const gfx::Rect& damage_rect) { |
668 // If we get a paint event before we are completely set up (e.g., a nested | 614 // If we get a paint event before we are completely set up (e.g., a nested |
669 // call while the plugin is still in NPP_SetWindow), bail. | 615 // call while the plugin is still in NPP_SetWindow), bail. |
670 if (!have_called_set_window_ || (use_buffer_context_ && !buffer_context_)) | 616 if (!have_called_set_window_ || (use_buffer_context_ && !buffer_context_)) |
671 return; | 617 return; |
672 DCHECK(!use_buffer_context_ || buffer_context_ == context); | 618 DCHECK(!use_buffer_context_ || buffer_context_ == context); |
673 | 619 |
674 base::StatsRate plugin_paint("Plugin.Paint"); | 620 base::StatsRate plugin_paint("Plugin.Paint"); |
675 base::StatsScope<base::StatsRate> scope(plugin_paint); | 621 base::StatsScope<base::StatsRate> scope(plugin_paint); |
676 | 622 |
677 gfx::Rect paint_rect; | 623 gfx::Rect paint_rect; |
678 if (use_buffer_context_) { | 624 if (use_buffer_context_) { |
679 // Plugin invalidates trigger asynchronous paints with the original | 625 // Plugin invalidates trigger asynchronous paints with the original |
680 // invalidation rect; the plugin may be resized before the paint is handled, | 626 // invalidation rect; the plugin may be resized before the paint is handled, |
681 // so we need to ensure that the damage rect is still sane. | 627 // so we need to ensure that the damage rect is still sane. |
682 paint_rect = damage_rect.Intersect( | 628 paint_rect = damage_rect.Intersect( |
683 gfx::Rect(0, 0, window_rect_.width(), window_rect_.height())); | 629 gfx::Rect(0, 0, window_rect_.width(), window_rect_.height())); |
684 } else { | 630 } else { |
685 // Use the actual window region when drawing directly to the window context. | 631 // Use the actual window region when drawing directly to the window context. |
686 paint_rect = damage_rect.Intersect(window_rect_); | 632 paint_rect = damage_rect.Intersect(window_rect_); |
687 } | 633 } |
688 | 634 |
689 ScopedActiveDelegate active_delegate(this); | 635 ScopedActiveDelegate active_delegate(this); |
690 | 636 |
691 #ifndef NP_NO_QUICKDRAW | |
692 if (instance()->drawing_model() == NPDrawingModelQuickDraw) | |
693 qd_manager_->MakePortCurrent(); | |
694 #endif | |
695 | |
696 CGContextSaveGState(context); | 637 CGContextSaveGState(context); |
697 | 638 |
698 if (!use_buffer_context_) { | 639 if (!use_buffer_context_) { |
699 // Reposition the context origin so that plugins will draw at the correct | 640 // Reposition the context origin so that plugins will draw at the correct |
700 // location in the window. | 641 // location in the window. |
701 CGContextClipToRect(context, paint_rect.ToCGRect()); | 642 CGContextClipToRect(context, paint_rect.ToCGRect()); |
702 CGContextTranslateCTM(context, window_rect_.x(), window_rect_.y()); | 643 CGContextTranslateCTM(context, window_rect_.x(), window_rect_.y()); |
703 } | 644 } |
704 | 645 |
705 switch (instance()->event_model()) { | 646 switch (instance()->event_model()) { |
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1110 void WebPluginDelegateImpl::FireIdleEvent() { | 1051 void WebPluginDelegateImpl::FireIdleEvent() { |
1111 // Avoid a race condition between IO and UI threads during plugin shutdown | 1052 // Avoid a race condition between IO and UI threads during plugin shutdown |
1112 if (!instance()) | 1053 if (!instance()) |
1113 return; | 1054 return; |
1114 // Don't send idle events until we've called SetWindow. | 1055 // Don't send idle events until we've called SetWindow. |
1115 if (!have_called_set_window_) | 1056 if (!have_called_set_window_) |
1116 return; | 1057 return; |
1117 | 1058 |
1118 ScopedActiveDelegate active_delegate(this); | 1059 ScopedActiveDelegate active_delegate(this); |
1119 | 1060 |
1120 #ifndef NP_NO_QUICKDRAW | |
1121 if (instance()->drawing_model() == NPDrawingModelQuickDraw) | |
1122 qd_manager_->MakePortCurrent(); | |
1123 #endif | |
1124 | |
1125 // Send an idle event so that the plugin can do background work | 1061 // Send an idle event so that the plugin can do background work |
1126 NPEvent np_event = {0}; | 1062 NPEvent np_event = {0}; |
1127 np_event.what = nullEvent; | 1063 np_event.what = nullEvent; |
1128 np_event.when = TickCount(); | 1064 np_event.when = TickCount(); |
1129 np_event.modifiers = GetCurrentKeyModifiers(); | 1065 np_event.modifiers = GetCurrentKeyModifiers(); |
1130 if (!Button()) | 1066 if (!Button()) |
1131 np_event.modifiers |= btnState; | 1067 np_event.modifiers |= btnState; |
1132 HIPoint mouse_location; | 1068 HIPoint mouse_location; |
1133 HIGetMousePosition(kHICoordSpaceScreenPixel, NULL, &mouse_location); | 1069 HIGetMousePosition(kHICoordSpaceScreenPixel, NULL, &mouse_location); |
1134 np_event.where.h = mouse_location.x; | 1070 np_event.where.h = mouse_location.x; |
1135 np_event.where.v = mouse_location.y; | 1071 np_event.where.v = mouse_location.y; |
1136 instance()->NPP_HandleEvent(&np_event); | 1072 instance()->NPP_HandleEvent(&np_event); |
1137 | |
1138 #ifndef NP_NO_QUICKDRAW | |
1139 // Quickdraw-based plugins can draw at any time, so tell the renderer to | |
1140 // repaint. | |
1141 if (instance() && instance()->drawing_model() == NPDrawingModelQuickDraw) | |
1142 instance()->webplugin()->Invalidate(); | |
1143 #endif | |
1144 } | 1073 } |
1145 #endif // !NP_NO_CARBON | 1074 #endif // !NP_NO_CARBON |
1146 | 1075 |
1147 } // namespace npapi | 1076 } // namespace npapi |
1148 } // namespace webkit | 1077 } // namespace webkit |
OLD | NEW |