| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 | 6 |
| 7 #include "webkit/glue/plugins/webplugin_delegate_impl.h" | 7 #include "webkit/glue/plugins/webplugin_delegate_impl.h" |
| 8 | 8 |
| 9 #include <string> | 9 #include <string> |
| 10 #include <unistd.h> |
| 10 #include <vector> | 11 #include <vector> |
| 11 | 12 |
| 12 #include "base/file_util.h" | 13 #include "base/file_util.h" |
| 13 #include "base/lazy_instance.h" | 14 #include "base/lazy_instance.h" |
| 14 #include "base/message_loop.h" | 15 #include "base/message_loop.h" |
| 15 #include "base/scoped_ptr.h" | 16 #include "base/scoped_ptr.h" |
| 16 #include "base/stats_counters.h" | 17 #include "base/stats_counters.h" |
| 17 #include "base/string_util.h" | 18 #include "base/string_util.h" |
| 18 #include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h" | 19 #include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h" |
| 19 #include "webkit/default_plugin/plugin_impl.h" | 20 #include "webkit/default_plugin/plugin_impl.h" |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 // this to keep the placeholder Carbon WindowRef's origin in sync with the | 66 // this to keep the placeholder Carbon WindowRef's origin in sync with the |
| 66 // actual browser window, without having to pass that geometry over IPC. If we | 67 // actual browser window, without having to pass that geometry over IPC. If we |
| 67 // end up needing to interpose on Carbon APIs in the plugin process (in order | 68 // end up needing to interpose on Carbon APIs in the plugin process (in order |
| 68 // to simulate window activation, for example), this could be replaced by | 69 // to simulate window activation, for example), this could be replaced by |
| 69 // interposing on GlobalToLocal and/or LocalToGlobal (see related TODO comments | 70 // interposing on GlobalToLocal and/or LocalToGlobal (see related TODO comments |
| 70 // below in WebPluginDelegateImpl::OnNullEvent()). | 71 // below in WebPluginDelegateImpl::OnNullEvent()). |
| 71 | 72 |
| 72 int g_current_x_offset = 0; | 73 int g_current_x_offset = 0; |
| 73 int g_current_y_offset = 0; | 74 int g_current_y_offset = 0; |
| 74 | 75 |
| 76 base::LazyInstance<std::set<WebPluginDelegateImpl*> > g_active_delegates( |
| 77 base::LINKER_INITIALIZED); |
| 78 |
| 75 } // namespace | 79 } // namespace |
| 76 | 80 |
| 77 WebPluginDelegateImpl::WebPluginDelegateImpl( | 81 WebPluginDelegateImpl::WebPluginDelegateImpl( |
| 78 gfx::PluginWindowHandle containing_view, | 82 gfx::PluginWindowHandle containing_view, |
| 79 NPAPI::PluginInstance *instance) | 83 NPAPI::PluginInstance *instance) |
| 80 : windowless_needs_set_window_(true), | 84 : windowless_needs_set_window_(true), |
| 81 // all Mac plugins are "windowless" in the Windows/X11 sense | 85 // all Mac plugins are "windowless" in the Windows/X11 sense |
| 82 windowless_(true), | 86 windowless_(true), |
| 83 plugin_(NULL), | 87 plugin_(NULL), |
| 84 instance_(instance), | 88 instance_(instance), |
| 85 parent_(containing_view), | 89 parent_(containing_view), |
| 86 qd_world_(0), | 90 qd_world_(0), |
| 87 quirks_(0), | 91 quirks_(0), |
| 88 null_event_factory_(this), | 92 null_event_factory_(this), |
| 89 waiting_to_die_(false), | 93 waiting_to_die_(false), |
| 90 last_mouse_x_(0), | 94 last_mouse_x_(0), |
| 91 last_mouse_y_(0), | 95 last_mouse_y_(0), |
| 96 have_focus_(false), |
| 92 handle_event_depth_(0), | 97 handle_event_depth_(0), |
| 93 user_gesture_message_posted_(this), | 98 user_gesture_message_posted_(this), |
| 94 user_gesture_msg_factory_(this) { | 99 user_gesture_msg_factory_(this) { |
| 95 memset(&window_, 0, sizeof(window_)); | 100 memset(&window_, 0, sizeof(window_)); |
| 96 #ifndef NP_NO_QUICKDRAW | 101 #ifndef NP_NO_QUICKDRAW |
| 97 memset(&qd_port_, 0, sizeof(qd_port_)); | 102 memset(&qd_port_, 0, sizeof(qd_port_)); |
| 98 #endif | 103 #endif |
| 99 instance->set_windowless(true); | 104 instance->set_windowless(true); |
| 100 | 105 |
| 101 const WebPluginInfo& plugin_info = instance_->plugin_lib()->plugin_info(); | 106 const WebPluginInfo& plugin_info = instance_->plugin_lib()->plugin_info(); |
| 102 if (plugin_info.name.find(L"QuickTime") != std::wstring::npos) { | 107 if (plugin_info.name.find(L"QuickTime") != std::wstring::npos) { |
| 103 // In some cases, QuickTime inexpicably negotiates the CoreGraphics drawing | 108 // In some cases, QuickTime inexpicably negotiates the CoreGraphics drawing |
| 104 // model, but then proceeds as if it were using QuickDraw. Until we support | 109 // model, but then proceeds as if it were using QuickDraw. Until we support |
| 105 // CoreAnimation, just ignore what QuickTime asks for. | 110 // CoreAnimation, just ignore what QuickTime asks for. |
| 106 quirks_ |= PLUGIN_QUIRK_IGNORE_NEGOTIATED_DRAWING_MODEL; | 111 quirks_ |= PLUGIN_QUIRK_IGNORE_NEGOTIATED_DRAWING_MODEL; |
| 107 } | 112 } |
| 113 std::set<WebPluginDelegateImpl*>* delegates = g_active_delegates.Pointer(); |
| 114 delegates->insert(this); |
| 108 } | 115 } |
| 109 | 116 |
| 110 WebPluginDelegateImpl::~WebPluginDelegateImpl() { | 117 WebPluginDelegateImpl::~WebPluginDelegateImpl() { |
| 118 std::set<WebPluginDelegateImpl*>* delegates = g_active_delegates.Pointer(); |
| 119 delegates->erase(this); |
| 111 #ifndef NP_NO_QUICKDRAW | 120 #ifndef NP_NO_QUICKDRAW |
| 112 if (qd_port_.port) { | 121 if (qd_port_.port) { |
| 113 DisposeGWorld(qd_port_.port); | 122 DisposeGWorld(qd_port_.port); |
| 114 DisposeGWorld(qd_world_); | 123 DisposeGWorld(qd_world_); |
| 115 } | 124 } |
| 116 #endif | 125 #endif |
| 117 } | 126 } |
| 118 | 127 |
| 119 void WebPluginDelegateImpl::PluginDestroyed() { | 128 void WebPluginDelegateImpl::PluginDestroyed() { |
| 120 FakePluginWindowTracker::SharedInstance()->RemoveFakeWindowForDelegate( | 129 FakePluginWindowTracker::SharedInstance()->RemoveFakeWindowForDelegate( |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 395 | 404 |
| 396 UpdateDummyWindowBoundsWithOffset( | 405 UpdateDummyWindowBoundsWithOffset( |
| 397 reinterpret_cast<WindowRef>(cg_context_.window), window_rect_.x(), | 406 reinterpret_cast<WindowRef>(cg_context_.window), window_rect_.x(), |
| 398 window_rect_.y(), window_rect_.width(), window_rect_.height()); | 407 window_rect_.y(), window_rect_.width(), window_rect_.height()); |
| 399 | 408 |
| 400 NPError err = instance()->NPP_SetWindow(&window_); | 409 NPError err = instance()->NPP_SetWindow(&window_); |
| 401 | 410 |
| 402 DCHECK(err == NPERR_NO_ERROR); | 411 DCHECK(err == NPERR_NO_ERROR); |
| 403 } | 412 } |
| 404 | 413 |
| 405 void WebPluginDelegateImpl::SetFocus() { | 414 std::set<WebPluginDelegateImpl*> WebPluginDelegateImpl::GetActiveDelegates() { |
| 415 std::set<WebPluginDelegateImpl*>* delegates = g_active_delegates.Pointer(); |
| 416 return *delegates; |
| 417 } |
| 418 |
| 419 void WebPluginDelegateImpl::FocusNotify(WebPluginDelegateImpl* delegate) { |
| 420 if (waiting_to_die_) |
| 421 return; |
| 422 |
| 423 have_focus_ = (delegate == this); |
| 424 |
| 406 switch (instance()->event_model()) { | 425 switch (instance()->event_model()) { |
| 407 case NPEventModelCarbon: { | 426 case NPEventModelCarbon: { |
| 408 NPEvent focus_event = { 0 }; | 427 NPEvent focus_event = { 0 }; |
| 409 focus_event.what = NPEventType_GetFocusEvent; | 428 if (have_focus_) |
| 429 focus_event.what = NPEventType_GetFocusEvent; |
| 430 else |
| 431 focus_event.what = NPEventType_LoseFocusEvent; |
| 410 focus_event.when = TickCount(); | 432 focus_event.when = TickCount(); |
| 411 instance()->NPP_HandleEvent(&focus_event); | 433 instance()->NPP_HandleEvent(&focus_event); |
| 412 break; | 434 break; |
| 413 } | 435 } |
| 414 case NPEventModelCocoa: { | 436 case NPEventModelCocoa: { |
| 415 NPCocoaEvent focus_event; | 437 NPCocoaEvent focus_event; |
| 416 memset(&focus_event, 0, sizeof(focus_event)); | 438 memset(&focus_event, 0, sizeof(focus_event)); |
| 417 focus_event.type = NPCocoaEventFocusChanged; | 439 focus_event.type = NPCocoaEventFocusChanged; |
| 418 focus_event.data.focus.hasFocus = true; | 440 focus_event.data.focus.hasFocus = have_focus_; |
| 419 instance()->NPP_HandleEvent(reinterpret_cast<NPEvent*>(&focus_event)); | 441 instance()->NPP_HandleEvent(reinterpret_cast<NPEvent*>(&focus_event)); |
| 420 break; | 442 break; |
| 421 } | 443 } |
| 422 } | 444 } |
| 423 } | 445 } |
| 424 | 446 |
| 447 void WebPluginDelegateImpl::SetFocus() { |
| 448 if (focus_notifier_) |
| 449 focus_notifier_(this); |
| 450 else |
| 451 FocusNotify(this); |
| 452 } |
| 453 |
| 425 int WebPluginDelegateImpl::PluginDrawingModel() { | 454 int WebPluginDelegateImpl::PluginDrawingModel() { |
| 426 if (quirks_ & PLUGIN_QUIRK_IGNORE_NEGOTIATED_DRAWING_MODEL) | 455 if (quirks_ & PLUGIN_QUIRK_IGNORE_NEGOTIATED_DRAWING_MODEL) |
| 427 return NPDrawingModelQuickDraw; | 456 return NPDrawingModelQuickDraw; |
| 428 return instance()->drawing_model(); | 457 return instance()->drawing_model(); |
| 429 } | 458 } |
| 430 | 459 |
| 431 static bool WebInputEventIsWebMouseEvent(const WebInputEvent& event) { | 460 static bool WebInputEventIsWebMouseEvent(const WebInputEvent& event) { |
| 432 switch (event.type) { | 461 switch (event.type) { |
| 433 case WebInputEvent::MouseMove: | 462 case WebInputEvent::MouseMove: |
| 434 case WebInputEvent::MouseLeave: | 463 case WebInputEvent::MouseLeave: |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 692 } else { | 721 } else { |
| 693 // If this is a mouse event, we need to make sure our dummy window | 722 // If this is a mouse event, we need to make sure our dummy window |
| 694 // has the correct location before we send the event to the plugin, | 723 // has the correct location before we send the event to the plugin, |
| 695 // so that any coordinate conversion the plugin does will work out. | 724 // so that any coordinate conversion the plugin does will work out. |
| 696 if (WebInputEventIsWebMouseEvent(event)) { | 725 if (WebInputEventIsWebMouseEvent(event)) { |
| 697 const WebMouseEvent* mouse_event = | 726 const WebMouseEvent* mouse_event = |
| 698 static_cast<const WebMouseEvent*>(&event); | 727 static_cast<const WebMouseEvent*>(&event); |
| 699 UpdateWindowLocation(reinterpret_cast<WindowRef>(cg_context_.window), | 728 UpdateWindowLocation(reinterpret_cast<WindowRef>(cg_context_.window), |
| 700 *mouse_event); | 729 *mouse_event); |
| 701 } | 730 } |
| 731 // if we do not currently have focus and this is a mouseDown, trigger a |
| 732 // notification that we are taking the keyboard focus. We can't just key |
| 733 // off of incoming calls to SetFocus, since WebKit may already think we |
| 734 // have it if we were the most recently focused element on our parent tab. |
| 735 if (np_event.what == mouseDown && !have_focus_) |
| 736 SetFocus(); |
| 702 } | 737 } |
| 703 #endif | 738 #endif |
| 704 | 739 |
| 705 bool ret = false; | 740 bool ret = false; |
| 706 switch (PluginDrawingModel()) { | 741 switch (PluginDrawingModel()) { |
| 707 #ifndef NP_NO_QUICKDRAW | 742 #ifndef NP_NO_QUICKDRAW |
| 708 case NPDrawingModelQuickDraw: | 743 case NPDrawingModelQuickDraw: |
| 709 SetGWorld(qd_port_.port, NULL); | 744 SetGWorld(qd_port_.port, NULL); |
| 710 ret = instance()->NPP_HandleEvent(&np_event) != 0; | 745 ret = instance()->NPP_HandleEvent(&np_event) != 0; |
| 711 break; | 746 break; |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 788 | 823 |
| 789 #ifndef NP_NO_CARBON | 824 #ifndef NP_NO_CARBON |
| 790 if (instance_->event_model() == NPEventModelCarbon) { | 825 if (instance_->event_model() == NPEventModelCarbon) { |
| 791 MessageLoop::current()->PostDelayedTask(FROM_HERE, | 826 MessageLoop::current()->PostDelayedTask(FROM_HERE, |
| 792 null_event_factory_.NewRunnableMethod( | 827 null_event_factory_.NewRunnableMethod( |
| 793 &WebPluginDelegateImpl::OnNullEvent), | 828 &WebPluginDelegateImpl::OnNullEvent), |
| 794 kPluginIdleThrottleDelayMs); | 829 kPluginIdleThrottleDelayMs); |
| 795 } | 830 } |
| 796 #endif | 831 #endif |
| 797 } | 832 } |
| OLD | NEW |