Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(53)

Side by Side Diff: webkit/plugins/npapi/webplugin_delegate_impl_mac.mm

Issue 10928072: Remove all support for the Carbon NPAPI event model (Closed) Base URL: http://git.chromium.org/chromium/src.git@test-plugin-cocoa
Patch Set: Rebase Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webkit/plugins/npapi/webplugin_delegate_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 12 matching lines...) Expand all
23 #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" 23 #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h"
24 #include "webkit/glue/webkit_glue.h" 24 #include "webkit/glue/webkit_glue.h"
25 #include "webkit/plugins/npapi/plugin_instance.h" 25 #include "webkit/plugins/npapi/plugin_instance.h"
26 #include "webkit/plugins/npapi/plugin_lib.h" 26 #include "webkit/plugins/npapi/plugin_lib.h"
27 #include "webkit/plugins/npapi/plugin_list.h" 27 #include "webkit/plugins/npapi/plugin_list.h"
28 #include "webkit/plugins/npapi/plugin_stream_url.h" 28 #include "webkit/plugins/npapi/plugin_stream_url.h"
29 #include "webkit/plugins/npapi/plugin_web_event_converter_mac.h" 29 #include "webkit/plugins/npapi/plugin_web_event_converter_mac.h"
30 #include "webkit/plugins/npapi/webplugin.h" 30 #include "webkit/plugins/npapi/webplugin.h"
31 #include "webkit/plugins/npapi/webplugin_accelerated_surface_mac.h" 31 #include "webkit/plugins/npapi/webplugin_accelerated_surface_mac.h"
32 32
33 #ifndef NP_NO_CARBON
34 #include "webkit/plugins/npapi/carbon_plugin_window_tracker_mac.h"
35 #endif
36
37 #if defined(USE_SKIA) 33 #if defined(USE_SKIA)
38 #include "skia/ext/skia_utils_mac.h" 34 #include "skia/ext/skia_utils_mac.h"
39 #endif 35 #endif
40 36
41 using WebKit::WebCursorInfo; 37 using WebKit::WebCursorInfo;
42 using WebKit::WebKeyboardEvent; 38 using WebKit::WebKeyboardEvent;
43 using WebKit::WebInputEvent; 39 using WebKit::WebInputEvent;
44 using WebKit::WebMouseEvent; 40 using WebKit::WebMouseEvent;
45 using WebKit::WebMouseWheelEvent; 41 using WebKit::WebMouseWheelEvent;
46 42
47 #if defined(MAC_OS_X_VERSION_10_7) && \
48 MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
49 #ifndef NP_NO_CARBON
50 // QuickdrawAPI.h is no longer included in the 10.7 SDK, but the symbols are
51 // still exported by QD.framework (a subframework of ApplicationServices).
52 // http://developer.apple.com/legacy/mac/library/documentation/Carbon/reference/ QuickDraw_Ref/QuickDraw_Ref.pdf
53 extern "C" {
54 void SetRect(Rect* r, short left, short top, short right, short bottom);
55 void OffsetRect(Rect* r, short dh, short dv);
56 }
57 #endif // NP_NO_CARBON
58 #endif // 10.7+ SDK
59
60 // Important implementation notes: The Mac definition of NPAPI, particularly 43 // Important implementation notes: The Mac definition of NPAPI, particularly
61 // the distinction between windowed and windowless modes, differs from the 44 // the distinction between windowed and windowless modes, differs from the
62 // Windows and Linux definitions. Most of those differences are 45 // Windows and Linux definitions. Most of those differences are
63 // accomodated by the WebPluginDelegate class. 46 // accomodated by the WebPluginDelegate class.
64 47
65 namespace webkit { 48 namespace webkit {
66 namespace npapi { 49 namespace npapi {
67 50
68 namespace { 51 namespace {
69 52
(...skipping 10 matching lines...) Expand all
80 g_active_delegate = delegate; 63 g_active_delegate = delegate;
81 } 64 }
82 ~ScopedActiveDelegate() { 65 ~ScopedActiveDelegate() {
83 g_active_delegate = NULL; 66 g_active_delegate = NULL;
84 } 67 }
85 68
86 private: 69 private:
87 DISALLOW_COPY_AND_ASSIGN(ScopedActiveDelegate); 70 DISALLOW_COPY_AND_ASSIGN(ScopedActiveDelegate);
88 }; 71 };
89 72
90 #ifndef NP_NO_CARBON
91 // Timer periods for sending idle events to Carbon plugins. The visible value
92 // (50Hz) matches both Safari and Firefox. The hidden value (8Hz) matches
93 // Firefox; according to https://bugzilla.mozilla.org/show_bug.cgi?id=525533
94 // going lower than that causes issues.
95 const int kVisibleIdlePeriodMs = 20; // (50Hz)
96 const int kHiddenIdlePeriodMs = 125; // (8Hz)
97
98 class CarbonIdleEventSource {
99 public:
100 // Returns the shared Carbon idle event source.
101 static CarbonIdleEventSource* SharedInstance() {
102 DCHECK(MessageLoop::current()->type() == MessageLoop::TYPE_UI);
103 static CarbonIdleEventSource* event_source = new CarbonIdleEventSource();
104 return event_source;
105 }
106
107 // Registers the plugin delegate as interested in receiving idle events at
108 // a rate appropriate for the given visibility. A delegate can safely be
109 // re-registered any number of times, with the latest registration winning.
110 void RegisterDelegate(WebPluginDelegateImpl* delegate, bool visible) {
111 if (visible) {
112 visible_delegates_->RegisterDelegate(delegate);
113 hidden_delegates_->UnregisterDelegate(delegate);
114 } else {
115 hidden_delegates_->RegisterDelegate(delegate);
116 visible_delegates_->UnregisterDelegate(delegate);
117 }
118 }
119
120 // Removes the plugin delegate from the list of plugins receiving idle events.
121 void UnregisterDelegate(WebPluginDelegateImpl* delegate) {
122 visible_delegates_->UnregisterDelegate(delegate);
123 hidden_delegates_->UnregisterDelegate(delegate);
124 }
125
126 private:
127 class VisibilityGroup {
128 public:
129 explicit VisibilityGroup(int timer_period)
130 : timer_period_(timer_period), iterator_(delegates_.end()) {}
131
132 // Adds |delegate| to this visibility group.
133 void RegisterDelegate(WebPluginDelegateImpl* delegate) {
134 if (delegates_.empty()) {
135 timer_.Start(FROM_HERE,
136 base::TimeDelta::FromMilliseconds(timer_period_),
137 this, &VisibilityGroup::SendIdleEvents);
138 }
139 delegates_.insert(delegate);
140 }
141
142 // Removes |delegate| from this visibility group.
143 void UnregisterDelegate(WebPluginDelegateImpl* delegate) {
144 // If a plugin changes visibility during idle event handling, it
145 // may be removed from this set while SendIdleEvents is still iterating;
146 // if that happens and it's next on the list, increment the iterator
147 // before erasing so that the iteration won't be corrupted.
148 if ((iterator_ != delegates_.end()) && (*iterator_ == delegate))
149 ++iterator_;
150 size_t removed = delegates_.erase(delegate);
151 if (removed > 0 && delegates_.empty())
152 timer_.Stop();
153 }
154
155 private:
156 // Fires off idle events for each delegate in the group.
157 void SendIdleEvents() {
158 for (iterator_ = delegates_.begin(); iterator_ != delegates_.end();) {
159 // Pre-increment so that the skip logic in UnregisterDelegates works.
160 WebPluginDelegateImpl* delegate = *(iterator_++);
161 delegate->FireIdleEvent();
162 }
163 }
164
165 int timer_period_;
166 base::RepeatingTimer<VisibilityGroup> timer_;
167 std::set<WebPluginDelegateImpl*> delegates_;
168 std::set<WebPluginDelegateImpl*>::iterator iterator_;
169 };
170
171 CarbonIdleEventSource()
172 : visible_delegates_(new VisibilityGroup(kVisibleIdlePeriodMs)),
173 hidden_delegates_(new VisibilityGroup(kHiddenIdlePeriodMs)) {}
174
175 scoped_ptr<VisibilityGroup> visible_delegates_;
176 scoped_ptr<VisibilityGroup> hidden_delegates_;
177
178 DISALLOW_COPY_AND_ASSIGN(CarbonIdleEventSource);
179 };
180 #endif // !NP_NO_CARBON
181
182 } // namespace 73 } // namespace
183 74
184 // Helper to build and maintain a model of a drag entering the plugin but not 75 // Helper to build and maintain a model of a drag entering the plugin but not
185 // starting there. See explanation in PlatformHandleInputEvent. 76 // starting there. See explanation in PlatformHandleInputEvent.
186 class ExternalDragTracker { 77 class ExternalDragTracker {
187 public: 78 public:
188 ExternalDragTracker() : pressed_buttons_(0) {} 79 ExternalDragTracker() : pressed_buttons_(0) {}
189 80
190 // Returns true if an external drag is in progress. 81 // Returns true if an external drag is in progress.
191 bool IsDragInProgress() { return pressed_buttons_ != 0; }; 82 bool IsDragInProgress() { return pressed_buttons_ != 0; };
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 ime_enabled_(false), 177 ime_enabled_(false),
287 keyup_ignore_count_(0), 178 keyup_ignore_count_(0),
288 external_drag_tracker_(new ExternalDragTracker()), 179 external_drag_tracker_(new ExternalDragTracker()),
289 handle_event_depth_(0), 180 handle_event_depth_(0),
290 first_set_window_call_(true), 181 first_set_window_call_(true),
291 plugin_has_focus_(false), 182 plugin_has_focus_(false),
292 has_webkit_focus_(false), 183 has_webkit_focus_(false),
293 containing_view_has_focus_(true), 184 containing_view_has_focus_(true),
294 creation_succeeded_(false) { 185 creation_succeeded_(false) {
295 memset(&window_, 0, sizeof(window_)); 186 memset(&window_, 0, sizeof(window_));
296 #ifndef NP_NO_CARBON
297 memset(&np_cg_context_, 0, sizeof(np_cg_context_));
298 #endif
299 instance->set_windowless(true); 187 instance->set_windowless(true);
300 } 188 }
301 189
302 WebPluginDelegateImpl::~WebPluginDelegateImpl() { 190 WebPluginDelegateImpl::~WebPluginDelegateImpl() {
303 DestroyInstance(); 191 DestroyInstance();
304
305 #ifndef NP_NO_CARBON
306 if (np_cg_context_.window) {
307 CarbonPluginWindowTracker::SharedInstance()->DestroyDummyWindowForDelegate(
308 this, reinterpret_cast<WindowRef>(np_cg_context_.window));
309 }
310 #endif
311 } 192 }
312 193
313 bool WebPluginDelegateImpl::PlatformInitialize() { 194 bool WebPluginDelegateImpl::PlatformInitialize() {
314 // Don't set a NULL window handle on destroy for Mac plugins. This matches 195 // Don't set a NULL window handle on destroy for Mac plugins. This matches
315 // Safari and other Mac browsers (see PluginView::stop() in PluginView.cpp, 196 // Safari and other Mac browsers (see PluginView::stop() in PluginView.cpp,
316 // where code to do so is surrounded by an #ifdef that excludes Mac OS X, or 197 // where code to do so is surrounded by an #ifdef that excludes Mac OS X, or
317 // destroyPlugin in WebNetscapePluginView.mm, for examples). 198 // destroyPlugin in WebNetscapePluginView.mm, for examples).
318 quirks_ |= PLUGIN_QUIRK_DONT_SET_NULL_WINDOW_HANDLE_ON_DESTROY; 199 quirks_ |= PLUGIN_QUIRK_DONT_SET_NULL_WINDOW_HANDLE_ON_DESTROY;
319 200
320 // Mac plugins don't expect to be unloaded, and they don't always do so 201 // Mac plugins don't expect to be unloaded, and they don't always do so
321 // cleanly, so don't unload them at shutdown. 202 // cleanly, so don't unload them at shutdown.
322 instance()->plugin_lib()->PreventLibraryUnload(); 203 instance()->plugin_lib()->PreventLibraryUnload();
323 204
324 #ifndef NP_NO_CARBON 205 #ifndef NP_NO_CARBON
325 // Carbon is no longer supported.
326 if (instance()->event_model() == NPEventModelCarbon) 206 if (instance()->event_model() == NPEventModelCarbon)
327 return false; 207 return false;
328
329 if (instance()->event_model() == NPEventModelCarbon) {
330 // Create a stand-in for the browser window so that the plugin will have
331 // a non-NULL WindowRef to which it can refer.
332 CarbonPluginWindowTracker* window_tracker =
333 CarbonPluginWindowTracker::SharedInstance();
334 np_cg_context_.window = window_tracker->CreateDummyWindowForDelegate(this);
335 np_cg_context_.context = NULL;
336 UpdateDummyWindowBounds(gfx::Point(0, 0));
337 }
338 #endif 208 #endif
339 209
210 window_.type = NPWindowTypeDrawable;
340 NPDrawingModel drawing_model = instance()->drawing_model(); 211 NPDrawingModel drawing_model = instance()->drawing_model();
341 switch (drawing_model) { 212 switch (drawing_model) {
342 #ifndef NP_NO_QUICKDRAW 213 #ifndef NP_NO_QUICKDRAW
343 case NPDrawingModelQuickDraw: 214 case NPDrawingModelQuickDraw:
344 return false; 215 return false;
345 #endif 216 #endif
346 case NPDrawingModelCoreGraphics: 217 case NPDrawingModelCoreGraphics:
347 #ifndef NP_NO_CARBON
348 if (instance()->event_model() == NPEventModelCarbon)
349 window_.window = &np_cg_context_;
350 #endif
351 window_.type = NPWindowTypeDrawable;
352 break; 218 break;
353 case NPDrawingModelCoreAnimation: 219 case NPDrawingModelCoreAnimation:
354 case NPDrawingModelInvalidatingCoreAnimation: { 220 case NPDrawingModelInvalidatingCoreAnimation: {
355 if (instance()->event_model() != NPEventModelCocoa)
356 return false;
357 window_.type = NPWindowTypeDrawable;
358 // Ask the plug-in for the CALayer it created for rendering content. 221 // Ask the plug-in for the CALayer it created for rendering content.
359 // Create a surface to host it, and request a "window" handle to identify 222 // Create a surface to host it, and request a "window" handle to identify
360 // the surface. 223 // the surface.
361 CALayer* layer = nil; 224 CALayer* layer = nil;
362 NPError err = instance()->NPP_GetValue(NPPVpluginCoreAnimationLayer, 225 NPError err = instance()->NPP_GetValue(NPPVpluginCoreAnimationLayer,
363 reinterpret_cast<void*>(&layer)); 226 reinterpret_cast<void*>(&layer));
364 if (!err) { 227 if (!err) {
365 if (drawing_model == NPDrawingModelCoreAnimation) { 228 if (drawing_model == NPDrawingModelCoreAnimation) {
366 // Create the timer; it will be started when we get a window handle. 229 // Create the timer; it will be started when we get a window handle.
367 redraw_timer_.reset(new base::RepeatingTimer<WebPluginDelegateImpl>); 230 redraw_timer_.reset(new base::RepeatingTimer<WebPluginDelegateImpl>);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 break; 266 break;
404 } 267 }
405 268
406 // Let the WebPlugin know that we are windowless, unless this is a Core 269 // Let the WebPlugin know that we are windowless, unless this is a Core
407 // Animation plugin, in which case AcceleratedPluginEnabledRendering 270 // Animation plugin, in which case AcceleratedPluginEnabledRendering
408 // calls SetWindow. Rendering breaks if SetWindow is called before 271 // calls SetWindow. Rendering breaks if SetWindow is called before
409 // accelerated rendering is enabled. 272 // accelerated rendering is enabled.
410 if (!layer_) 273 if (!layer_)
411 plugin_->SetWindow(gfx::kNullPluginWindow); 274 plugin_->SetWindow(gfx::kNullPluginWindow);
412 275
413 #ifndef NP_NO_CARBON
414 // If the plugin wants Carbon events, hook up to the source of idle events.
415 if (instance()->event_model() == NPEventModelCarbon)
416 UpdateIdleEventRate();
417 #endif
418
419 return true; 276 return true;
420 } 277 }
421 278
422 void WebPluginDelegateImpl::PlatformDestroyInstance() { 279 void WebPluginDelegateImpl::PlatformDestroyInstance() {
423 #ifndef NP_NO_CARBON
424 if (instance()->event_model() == NPEventModelCarbon)
425 CarbonIdleEventSource::SharedInstance()->UnregisterDelegate(this);
426 #endif
427 if (redraw_timer_.get()) 280 if (redraw_timer_.get())
428 redraw_timer_->Stop(); 281 redraw_timer_->Stop();
429 [renderer_ release]; 282 [renderer_ release];
430 renderer_ = nil; 283 renderer_ = nil;
431 layer_ = nil; 284 layer_ = nil;
432 } 285 }
433 286
434 void WebPluginDelegateImpl::UpdateGeometryAndContext( 287 void WebPluginDelegateImpl::UpdateGeometryAndContext(
435 const gfx::Rect& window_rect, const gfx::Rect& clip_rect, 288 const gfx::Rect& window_rect, const gfx::Rect& clip_rect,
436 CGContextRef context) { 289 CGContextRef context) {
437 buffer_context_ = context; 290 buffer_context_ = context;
438 #ifndef NP_NO_CARBON
439 if (instance()->event_model() == NPEventModelCarbon) {
440 // Update the structure that is passed to Carbon+CoreGraphics plugins in
441 // NPP_SetWindow before calling UpdateGeometry, since that will trigger an
442 // NPP_SetWindow call if the geometry changes (which is the only time the
443 // context would be different), and some plugins (e.g., Flash) have an
444 // internal cache of the context that they only update when NPP_SetWindow
445 // is called.
446 np_cg_context_.context = context;
447 }
448 #endif
449 UpdateGeometry(window_rect, clip_rect); 291 UpdateGeometry(window_rect, clip_rect);
450 } 292 }
451 293
452 void WebPluginDelegateImpl::Paint(WebKit::WebCanvas* canvas, 294 void WebPluginDelegateImpl::Paint(WebKit::WebCanvas* canvas,
453 const gfx::Rect& rect) { 295 const gfx::Rect& rect) {
454 #if defined(USE_SKIA) 296 #if defined(USE_SKIA)
455 gfx::SkiaBitLocker bit_locker(canvas); 297 gfx::SkiaBitLocker bit_locker(canvas);
456 CGContextRef context = bit_locker.cgContext(); 298 CGContextRef context = bit_locker.cgContext();
457 #else 299 #else
458 CGContextRef context = canvas; 300 CGContextRef context = canvas;
459 #endif 301 #endif
460 CGPaint(context, rect); 302 CGPaint(context, rect);
461 } 303 }
462 304
463 void WebPluginDelegateImpl::CGPaint(CGContextRef context, 305 void WebPluginDelegateImpl::CGPaint(CGContextRef context,
464 const gfx::Rect& rect) { 306 const gfx::Rect& rect) {
465 WindowlessPaint(context, rect); 307 WindowlessPaint(context, rect);
466 } 308 }
467 309
468 bool WebPluginDelegateImpl::PlatformHandleInputEvent( 310 bool WebPluginDelegateImpl::PlatformHandleInputEvent(
469 const WebInputEvent& event, WebCursorInfo* cursor_info) { 311 const WebInputEvent& event, WebCursorInfo* cursor_info) {
470 DCHECK(cursor_info != NULL); 312 DCHECK(cursor_info != NULL);
471 313
472 // If we get an event before we've set up the plugin, bail. 314 // If an event comes in before the plugin has been set up, bail.
473 if (!have_called_set_window_) 315 if (!have_called_set_window_)
474 return false; 316 return false;
475 #ifndef NP_NO_CARBON
476 if (instance()->event_model() == NPEventModelCarbon &&
477 !np_cg_context_.context) {
478 return false;
479 }
480 #endif
481 317
482 // WebKit sometimes sends spurious mouse move events when the window doesn't 318 // WebKit sometimes sends spurious mouse move events when the window doesn't
483 // have focus; Cocoa event model plugins don't expect to receive mouse move 319 // have focus; Cocoa event model plugins don't expect to receive mouse move
484 // events when they are in a background window, so drop those events. 320 // events when they are in a background window, so drop those events.
485 if (!containing_window_has_focus_ && 321 if (!containing_window_has_focus_ &&
486 instance()->event_model() == NPEventModelCocoa &&
487 (event.type == WebInputEvent::MouseMove || 322 (event.type == WebInputEvent::MouseMove ||
488 event.type == WebInputEvent::MouseEnter || 323 event.type == WebInputEvent::MouseEnter ||
489 event.type == WebInputEvent::MouseLeave)) { 324 event.type == WebInputEvent::MouseLeave)) {
490 return false; 325 return false;
491 } 326 }
492 327
493 if (WebInputEvent::isMouseEventType(event.type) || 328 if (WebInputEvent::isMouseEventType(event.type) ||
494 event.type == WebInputEvent::MouseWheel) { 329 event.type == WebInputEvent::MouseWheel) {
495 // Check our plugin location before we send the event to the plugin, just 330 // Check our plugin location before we send the event to the plugin, just
496 // in case we somehow missed a plugin frame change. 331 // in case we somehow missed a plugin frame change.
(...skipping 21 matching lines...) Expand all
518 // Composition ends on a keydown, so ime_enabled_ will be false at keyup; 353 // Composition ends on a keydown, so ime_enabled_ will be false at keyup;
519 // because the keydown wasn't sent to the plugin, the keyup shouldn't be 354 // because the keydown wasn't sent to the plugin, the keyup shouldn't be
520 // either (per the spec). 355 // either (per the spec).
521 if (event.type == WebInputEvent::KeyDown) 356 if (event.type == WebInputEvent::KeyDown)
522 ++keyup_ignore_count_; 357 ++keyup_ignore_count_;
523 else 358 else
524 --keyup_ignore_count_; 359 --keyup_ignore_count_;
525 return true; 360 return true;
526 } 361 }
527 362
528 #ifndef NP_NO_CARBON
529 if (instance()->event_model() == NPEventModelCarbon &&
530 event.type == WebInputEvent::MouseMove) {
531 return true; // The recurring FireIdleEvent will send null events.
532 }
533 #endif
534
535 ScopedActiveDelegate active_delegate(this); 363 ScopedActiveDelegate active_delegate(this);
536 364
537 // Create the plugin event structure. 365 // Create the plugin event structure.
538 NPEventModel event_model = instance()->event_model();
539 scoped_ptr<PluginWebEventConverter> event_converter( 366 scoped_ptr<PluginWebEventConverter> event_converter(
540 PluginWebEventConverterFactory::CreateConverterForModel(event_model)); 367 new PluginWebEventConverter);
541 if (!(event_converter.get() && event_converter->InitWithEvent(event))) { 368 if (!event_converter->InitWithEvent(event)) {
542 // Silently consume any keyboard event types that we don't handle, so that 369 // Silently consume any keyboard event types that aren't handled, so that
543 // they don't fall through to the page. 370 // they don't fall through to the page.
544 if (WebInputEvent::isKeyboardEventType(event.type)) 371 if (WebInputEvent::isKeyboardEventType(event.type))
545 return true; 372 return true;
546 return false; 373 return false;
547 } 374 }
548 void* plugin_event = event_converter->plugin_event(); 375 NPCocoaEvent* plugin_event = event_converter->plugin_event();
549 376
550 if (instance()->event_model() == NPEventModelCocoa) { 377 // The plugin host recieves events related to drags starting outside the
551 // We recieve events related to drags starting outside the plugin, but the 378 // plugin, but the NPAPI Cocoa event model spec says plugins shouldn't receive
552 // NPAPI Cocoa event model spec says plugins shouldn't receive them, so 379 // them, so filter them out.
553 // filter them out. 380 // If WebKit adds a page capture mode (like the plugin capture mode that
554 // If we add a page capture mode at the WebKit layer (like the plugin 381 // handles drags starting inside) this can be removed.
555 // capture mode that handles drags starting inside) this can be removed. 382 bool drag_related = external_drag_tracker_->EventIsRelatedToDrag(event);
556 bool drag_related = external_drag_tracker_->EventIsRelatedToDrag(event); 383 external_drag_tracker_->UpdateDragStateFromEvent(event);
557 external_drag_tracker_->UpdateDragStateFromEvent(event); 384 if (drag_related) {
558 if (drag_related) { 385 if (event.type == WebInputEvent::MouseUp &&
559 if (event.type == WebInputEvent::MouseUp && 386 !external_drag_tracker_->IsDragInProgress()) {
560 !external_drag_tracker_->IsDragInProgress()) { 387 // When an external drag ends, we need to synthesize a MouseEntered.
561 // When an external drag ends, we need to synthesize a MouseEntered. 388 NPCocoaEvent enter_event = *plugin_event;
562 NPCocoaEvent enter_event = *(static_cast<NPCocoaEvent*>(plugin_event)); 389 enter_event.type = NPCocoaEventMouseEntered;
563 enter_event.type = NPCocoaEventMouseEntered; 390 ScopedCurrentPluginEvent event_scope(instance(), &enter_event);
564 ScopedCurrentPluginEvent event_scope(instance(), &enter_event); 391 instance()->NPP_HandleEvent(&enter_event);
565 instance()->NPP_HandleEvent(&enter_event);
566 }
567 return false;
568 } 392 }
393 return false;
569 } 394 }
570 395
571 // Send the plugin the event. 396 // Send the plugin the event.
572 scoped_ptr<ScopedCurrentPluginEvent> event_scope(NULL); 397 scoped_ptr<ScopedCurrentPluginEvent> event_scope(
573 if (instance()->event_model() == NPEventModelCocoa) { 398 new ScopedCurrentPluginEvent(instance(), plugin_event));
574 event_scope.reset(new ScopedCurrentPluginEvent(
575 instance(), static_cast<NPCocoaEvent*>(plugin_event)));
576 }
577 int16_t handle_response = instance()->NPP_HandleEvent(plugin_event); 399 int16_t handle_response = instance()->NPP_HandleEvent(plugin_event);
578 bool handled = handle_response != kNPEventNotHandled; 400 bool handled = handle_response != kNPEventNotHandled;
579 401
580 // Start IME if requested by the plugin. 402 // Start IME if requested by the plugin.
581 if (handled && handle_response == kNPEventStartIME && 403 if (handled && handle_response == kNPEventStartIME &&
582 event.type == WebInputEvent::KeyDown) { 404 event.type == WebInputEvent::KeyDown) {
583 StartIme(); 405 StartIme();
584 ++keyup_ignore_count_; 406 ++keyup_ignore_count_;
585 } 407 }
586 408
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
654 476
655 CGContextSaveGState(context); 477 CGContextSaveGState(context);
656 478
657 if (!use_buffer_context_) { 479 if (!use_buffer_context_) {
658 // Reposition the context origin so that plugins will draw at the correct 480 // Reposition the context origin so that plugins will draw at the correct
659 // location in the window. 481 // location in the window.
660 CGContextClipToRect(context, paint_rect.ToCGRect()); 482 CGContextClipToRect(context, paint_rect.ToCGRect());
661 CGContextTranslateCTM(context, window_rect_.x(), window_rect_.y()); 483 CGContextTranslateCTM(context, window_rect_.x(), window_rect_.y());
662 } 484 }
663 485
664 switch (instance()->event_model()) { 486 NPCocoaEvent paint_event;
665 #ifndef NP_NO_CARBON 487 memset(&paint_event, 0, sizeof(NPCocoaEvent));
666 case NPEventModelCarbon: { 488 paint_event.type = NPCocoaEventDrawRect;
667 NPEvent paint_event = { 0 }; 489 paint_event.data.draw.context = context;
668 paint_event.what = updateEvt; 490 paint_event.data.draw.x = paint_rect.x();
669 paint_event.message = reinterpret_cast<uint32>(np_cg_context_.window); 491 paint_event.data.draw.y = paint_rect.y();
670 paint_event.when = TickCount(); 492 paint_event.data.draw.width = paint_rect.width();
671 instance()->NPP_HandleEvent(&paint_event); 493 paint_event.data.draw.height = paint_rect.height();
672 break; 494 instance()->NPP_HandleEvent(&paint_event);
673 }
674 #endif
675 case NPEventModelCocoa: {
676 NPCocoaEvent paint_event;
677 memset(&paint_event, 0, sizeof(NPCocoaEvent));
678 paint_event.type = NPCocoaEventDrawRect;
679 paint_event.data.draw.context = context;
680 paint_event.data.draw.x = paint_rect.x();
681 paint_event.data.draw.y = paint_rect.y();
682 paint_event.data.draw.width = paint_rect.width();
683 paint_event.data.draw.height = paint_rect.height();
684 instance()->NPP_HandleEvent(&paint_event);
685 break;
686 }
687 }
688 495
689 if (use_buffer_context_) { 496 if (use_buffer_context_) {
690 // The backing buffer can change during the call to NPP_HandleEvent, in 497 // The backing buffer can change during the call to NPP_HandleEvent, in
691 // which case the old context is (or is about to be) invalid. 498 // which case the old context is (or is about to be) invalid.
692 if (context == buffer_context_) 499 if (context == buffer_context_)
693 CGContextRestoreGState(context); 500 CGContextRestoreGState(context);
694 } else { 501 } else {
695 // Always restore the context to the saved state. 502 // Always restore the context to the saved state.
696 CGContextRestoreGState(context); 503 CGContextRestoreGState(context);
697 } 504 }
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
760 if (!have_called_set_window_) { 567 if (!have_called_set_window_) {
761 initial_window_focus_ = has_focus; 568 initial_window_focus_ = has_focus;
762 return; 569 return;
763 } 570 }
764 571
765 if (has_focus == containing_window_has_focus_) 572 if (has_focus == containing_window_has_focus_)
766 return; 573 return;
767 containing_window_has_focus_ = has_focus; 574 containing_window_has_focus_ = has_focus;
768 575
769 ScopedActiveDelegate active_delegate(this); 576 ScopedActiveDelegate active_delegate(this);
770 switch (instance()->event_model()) { 577 NPCocoaEvent focus_event;
771 #ifndef NP_NO_CARBON 578 memset(&focus_event, 0, sizeof(focus_event));
772 case NPEventModelCarbon: { 579 focus_event.type = NPCocoaEventWindowFocusChanged;
773 NPEvent focus_event = { 0 }; 580 focus_event.data.focus.hasFocus = has_focus;
774 focus_event.what = activateEvt; 581 instance()->NPP_HandleEvent(&focus_event);
775 if (has_focus)
776 focus_event.modifiers |= activeFlag;
777 focus_event.message =
778 reinterpret_cast<unsigned long>(np_cg_context_.window);
779 focus_event.when = TickCount();
780 instance()->NPP_HandleEvent(&focus_event);
781 break;
782 }
783 #endif
784 case NPEventModelCocoa: {
785 NPCocoaEvent focus_event;
786 memset(&focus_event, 0, sizeof(focus_event));
787 focus_event.type = NPCocoaEventWindowFocusChanged;
788 focus_event.data.focus.hasFocus = has_focus;
789 instance()->NPP_HandleEvent(&focus_event);
790 break;
791 }
792 }
793 } 582 }
794 583
795 bool WebPluginDelegateImpl::PlatformSetPluginHasFocus(bool focused) { 584 bool WebPluginDelegateImpl::PlatformSetPluginHasFocus(bool focused) {
796 if (!have_called_set_window_) 585 if (!have_called_set_window_)
797 return false; 586 return false;
798 587
799 plugin_->FocusChanged(focused); 588 plugin_->FocusChanged(focused);
800 589
801 ScopedActiveDelegate active_delegate(this); 590 ScopedActiveDelegate active_delegate(this);
802 591
803 switch (instance()->event_model()) { 592 NPCocoaEvent focus_event;
804 #ifndef NP_NO_CARBON 593 memset(&focus_event, 0, sizeof(focus_event));
805 case NPEventModelCarbon: { 594 focus_event.type = NPCocoaEventFocusChanged;
806 NPEvent focus_event = { 0 }; 595 focus_event.data.focus.hasFocus = focused;
807 if (focused) 596 instance()->NPP_HandleEvent(&focus_event);
808 focus_event.what = NPEventType_GetFocusEvent; 597
809 else
810 focus_event.what = NPEventType_LoseFocusEvent;
811 focus_event.when = TickCount();
812 instance()->NPP_HandleEvent(&focus_event);
813 break;
814 }
815 #endif
816 case NPEventModelCocoa: {
817 NPCocoaEvent focus_event;
818 memset(&focus_event, 0, sizeof(focus_event));
819 focus_event.type = NPCocoaEventFocusChanged;
820 focus_event.data.focus.hasFocus = focused;
821 instance()->NPP_HandleEvent(&focus_event);
822 break;
823 }
824 }
825 return true; 598 return true;
826 } 599 }
827 600
828 void WebPluginDelegateImpl::SetContainerVisibility(bool is_visible) { 601 void WebPluginDelegateImpl::SetContainerVisibility(bool is_visible) {
829 if (is_visible == container_is_visible_) 602 if (is_visible == container_is_visible_)
830 return; 603 return;
831 container_is_visible_ = is_visible; 604 container_is_visible_ = is_visible;
832 605
833 // TODO(stuartmorgan): This is a temporary workarond for 606 // TODO(stuartmorgan): This is a temporary workarond for
834 // <http://crbug.com/34266>. When that is fixed, the cached_clip_rect_ code 607 // <http://crbug.com/34266>. When that is fixed, the cached_clip_rect_ code
(...skipping 21 matching lines...) Expand all
856 instance()->webplugin()->InvalidateRect(gfx::Rect()); 629 instance()->webplugin()->InvalidateRect(gfx::Rect());
857 } 630 }
858 631
859 void WebPluginDelegateImpl::WindowFrameChanged(const gfx::Rect& window_frame, 632 void WebPluginDelegateImpl::WindowFrameChanged(const gfx::Rect& window_frame,
860 const gfx::Rect& view_frame) { 633 const gfx::Rect& view_frame) {
861 instance()->set_window_frame(window_frame); 634 instance()->set_window_frame(window_frame);
862 SetContentAreaOrigin(gfx::Point(view_frame.x(), view_frame.y())); 635 SetContentAreaOrigin(gfx::Point(view_frame.x(), view_frame.y()));
863 } 636 }
864 637
865 void WebPluginDelegateImpl::ImeCompositionCompleted(const string16& text) { 638 void WebPluginDelegateImpl::ImeCompositionCompleted(const string16& text) {
866 if (instance()->event_model() != NPEventModelCocoa) {
867 DLOG(ERROR) << "IME notification receieved in Carbon event model";
868 return;
869 }
870
871 ime_enabled_ = false; 639 ime_enabled_ = false;
872 640
873 // If |text| is empty this was just called to tell us composition was 641 // If |text| is empty this was just called to tell us composition was
874 // cancelled externally (e.g., the user pressed esc). 642 // cancelled externally (e.g., the user pressed esc).
875 if (!text.empty()) { 643 if (!text.empty()) {
876 NPCocoaEvent text_event; 644 NPCocoaEvent text_event;
877 memset(&text_event, 0, sizeof(NPCocoaEvent)); 645 memset(&text_event, 0, sizeof(NPCocoaEvent));
878 text_event.type = NPCocoaEventTextInput; 646 text_event.type = NPCocoaEventTextInput;
879 text_event.data.text.text = 647 text_event.data.text.text =
880 reinterpret_cast<NPNSString*>(base::SysUTF16ToNSString(text)); 648 reinterpret_cast<NPNSString*>(base::SysUTF16ToNSString(text));
881 instance()->NPP_HandleEvent(&text_event); 649 instance()->NPP_HandleEvent(&text_event);
882 } 650 }
883 } 651 }
884 652
885 #ifndef NP_NO_CARBON 653 #ifndef NP_NO_CARBON
886 void WebPluginDelegateImpl::SetThemeCursor(ThemeCursor cursor) { 654 void WebPluginDelegateImpl::SetThemeCursor(ThemeCursor cursor) {
887 current_windowless_cursor_.InitFromThemeCursor(cursor); 655 current_windowless_cursor_.InitFromThemeCursor(cursor);
888 } 656 }
889 657
890 void WebPluginDelegateImpl::SetCarbonCursor(const Cursor* cursor) { 658 void WebPluginDelegateImpl::SetCarbonCursor(const Cursor* cursor) {
891 current_windowless_cursor_.InitFromCursor(cursor); 659 current_windowless_cursor_.InitFromCursor(cursor);
892 } 660 }
893 #endif 661 #endif
894 662
895 void WebPluginDelegateImpl::SetNSCursor(NSCursor* cursor) { 663 void WebPluginDelegateImpl::SetNSCursor(NSCursor* cursor) {
896 current_windowless_cursor_.InitFromNSCursor(cursor); 664 current_windowless_cursor_.InitFromNSCursor(cursor);
897 } 665 }
898 666
899 bool WebPluginDelegateImpl::AllowBufferFlipping() { 667 void WebPluginDelegateImpl::SetNoBufferContext() {
900 #ifndef NP_NO_CARBON 668 use_buffer_context_ = false;
901 // Using buffer flipping for Carbon plugins would require issuing an
902 // NPP_SetWindow() call for every frame, which would likely expose plugin
903 // bugs and/or suboptimal behaviour. So we don't allow it.
904 return instance()->event_model() != NPEventModelCarbon;
905 #else
906 return true;
907 #endif
908 } 669 }
909 670
910 #pragma mark - 671 #pragma mark -
911 #pragma mark Internal Tracking 672 #pragma mark Internal Tracking
912 673
913 void WebPluginDelegateImpl::SetPluginRect(const gfx::Rect& rect) { 674 void WebPluginDelegateImpl::SetPluginRect(const gfx::Rect& rect) {
914 bool plugin_size_changed = rect.width() != window_rect_.width() || 675 bool plugin_size_changed = rect.width() != window_rect_.width() ||
915 rect.height() != window_rect_.height(); 676 rect.height() != window_rect_.height();
916 window_rect_ = rect; 677 window_rect_ = rect;
917 PluginScreenLocationChanged(); 678 PluginScreenLocationChanged();
918 if (plugin_size_changed) 679 if (plugin_size_changed)
919 UpdateAcceleratedSurface(); 680 UpdateAcceleratedSurface();
920 } 681 }
921 682
922 void WebPluginDelegateImpl::SetContentAreaOrigin(const gfx::Point& origin) { 683 void WebPluginDelegateImpl::SetContentAreaOrigin(const gfx::Point& origin) {
923 content_area_origin_ = origin; 684 content_area_origin_ = origin;
924 PluginScreenLocationChanged(); 685 PluginScreenLocationChanged();
925 } 686 }
926 687
927 void WebPluginDelegateImpl::PluginScreenLocationChanged() { 688 void WebPluginDelegateImpl::PluginScreenLocationChanged() {
928 gfx::Point plugin_origin(content_area_origin_.x() + window_rect_.x(), 689 gfx::Point plugin_origin(content_area_origin_.x() + window_rect_.x(),
929 content_area_origin_.y() + window_rect_.y()); 690 content_area_origin_.y() + window_rect_.y());
930 instance()->set_plugin_origin(plugin_origin); 691 instance()->set_plugin_origin(plugin_origin);
931
932 #ifndef NP_NO_CARBON
933 if (instance()->event_model() == NPEventModelCarbon) {
934 UpdateDummyWindowBounds(plugin_origin);
935 }
936 #endif
937 } 692 }
938 693
939 void WebPluginDelegateImpl::PluginVisibilityChanged() { 694 void WebPluginDelegateImpl::PluginVisibilityChanged() {
940 #ifndef NP_NO_CARBON
941 if (instance()->event_model() == NPEventModelCarbon)
942 UpdateIdleEventRate();
943 #endif
944 if (instance()->drawing_model() == NPDrawingModelCoreAnimation) { 695 if (instance()->drawing_model() == NPDrawingModelCoreAnimation) {
945 bool plugin_visible = container_is_visible_ && !clip_rect_.IsEmpty(); 696 bool plugin_visible = container_is_visible_ && !clip_rect_.IsEmpty();
946 if (plugin_visible && !redraw_timer_->IsRunning() && 697 if (plugin_visible && !redraw_timer_->IsRunning() &&
947 (composited_ || windowed_handle())) { 698 (composited_ || windowed_handle())) {
948 redraw_timer_->Start(FROM_HERE, 699 redraw_timer_->Start(FROM_HERE,
949 base::TimeDelta::FromMilliseconds(kCoreAnimationRedrawPeriodMs), 700 base::TimeDelta::FromMilliseconds(kCoreAnimationRedrawPeriodMs),
950 this, &WebPluginDelegateImpl::DrawLayerInSurface); 701 this, &WebPluginDelegateImpl::DrawLayerInSurface);
951 } else if (!plugin_visible) { 702 } else if (!plugin_visible) {
952 redraw_timer_->Stop(); 703 redraw_timer_->Stop();
953 } 704 }
954 } 705 }
955 } 706 }
956 707
957 void WebPluginDelegateImpl::StartIme() { 708 void WebPluginDelegateImpl::StartIme() {
958 if (instance()->event_model() != NPEventModelCocoa)
959 return;
960 if (ime_enabled_) 709 if (ime_enabled_)
961 return; 710 return;
962 ime_enabled_ = true; 711 ime_enabled_ = true;
963 plugin_->StartIme(); 712 plugin_->StartIme();
964 } 713 }
965 714
966 #pragma mark - 715 #pragma mark -
967 #pragma mark Core Animation Support 716 #pragma mark Core Animation Support
968 717
969 void WebPluginDelegateImpl::DrawLayerInSurface() { 718 void WebPluginDelegateImpl::DrawLayerInSurface() {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1017 void WebPluginDelegateImpl::set_windowed_handle( 766 void WebPluginDelegateImpl::set_windowed_handle(
1018 gfx::PluginWindowHandle handle) { 767 gfx::PluginWindowHandle handle) {
1019 DCHECK(!composited_); 768 DCHECK(!composited_);
1020 windowed_handle_ = handle; 769 windowed_handle_ = handle;
1021 surface_->SetWindowHandle(handle); 770 surface_->SetWindowHandle(handle);
1022 UpdateAcceleratedSurface(); 771 UpdateAcceleratedSurface();
1023 // Kick off the drawing timer, if necessary. 772 // Kick off the drawing timer, if necessary.
1024 PluginVisibilityChanged(); 773 PluginVisibilityChanged();
1025 } 774 }
1026 775
1027 #pragma mark -
1028 #pragma mark Carbon Event support
1029
1030 #ifndef NP_NO_CARBON
1031 void WebPluginDelegateImpl::UpdateDummyWindowBounds(
1032 const gfx::Point& plugin_origin) {
1033 WindowRef window = reinterpret_cast<WindowRef>(np_cg_context_.window);
1034 Rect current_bounds;
1035 GetWindowBounds(window, kWindowContentRgn, &current_bounds);
1036
1037 Rect new_bounds;
1038 // We never want to resize the window to 0x0, so if the plugin is 0x0 just
1039 // move the window without resizing it.
1040 if (window_rect_.width() > 0 && window_rect_.height() > 0) {
1041 SetRect(&new_bounds, 0, 0, window_rect_.width(), window_rect_.height());
1042 OffsetRect(&new_bounds, plugin_origin.x(), plugin_origin.y());
1043 } else {
1044 new_bounds = current_bounds;
1045 OffsetRect(&new_bounds, plugin_origin.x() - current_bounds.left,
1046 plugin_origin.y() - current_bounds.top);
1047 }
1048
1049 if (new_bounds.left != current_bounds.left ||
1050 new_bounds.top != current_bounds.top ||
1051 new_bounds.right != current_bounds.right ||
1052 new_bounds.bottom != current_bounds.bottom)
1053 SetWindowBounds(window, kWindowContentRgn, &new_bounds);
1054 }
1055
1056 void WebPluginDelegateImpl::UpdateIdleEventRate() {
1057 bool plugin_visible = container_is_visible_ && !clip_rect_.IsEmpty();
1058 CarbonIdleEventSource::SharedInstance()->RegisterDelegate(this,
1059 plugin_visible);
1060 }
1061
1062 void WebPluginDelegateImpl::SetNoBufferContext() {
1063 use_buffer_context_ = false;
1064 }
1065
1066 void WebPluginDelegateImpl::FireIdleEvent() {
1067 // Avoid a race condition between IO and UI threads during plugin shutdown
1068 if (!instance())
1069 return;
1070 // Don't send idle events until we've called SetWindow.
1071 if (!have_called_set_window_)
1072 return;
1073
1074 ScopedActiveDelegate active_delegate(this);
1075
1076 // Send an idle event so that the plugin can do background work
1077 NPEvent np_event = {0};
1078 np_event.what = nullEvent;
1079 np_event.when = TickCount();
1080 np_event.modifiers = GetCurrentKeyModifiers();
1081 if (!GetCurrentButtonState())
1082 np_event.modifiers |= btnState;
1083 HIPoint mouse_location;
1084 HIGetMousePosition(kHICoordSpaceScreenPixel, NULL, &mouse_location);
1085 np_event.where.h = mouse_location.x;
1086 np_event.where.v = mouse_location.y;
1087 instance()->NPP_HandleEvent(&np_event);
1088 }
1089 #endif // !NP_NO_CARBON
1090
1091 } // namespace npapi 776 } // namespace npapi
1092 } // namespace webkit 777 } // namespace webkit
OLDNEW
« no previous file with comments | « webkit/plugins/npapi/webplugin_delegate_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698