| 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 <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "base/file_util.h" | 12 #include "base/file_util.h" |
| 13 #include "base/lazy_instance.h" | 13 #include "base/lazy_instance.h" |
| 14 #include "base/message_loop.h" | 14 #include "base/message_loop.h" |
| 15 #include "base/scoped_ptr.h" | 15 #include "base/scoped_ptr.h" |
| 16 #include "base/stats_counters.h" | 16 #include "base/stats_counters.h" |
| 17 #include "base/string_util.h" | 17 #include "base/string_util.h" |
| 18 #include "webkit/api/public/WebInputEvent.h" | 18 #include "webkit/api/public/WebInputEvent.h" |
| 19 #include "webkit/default_plugin/plugin_impl.h" | 19 #include "webkit/default_plugin/plugin_impl.h" |
| 20 #include "webkit/glue/glue_util.h" | 20 #include "webkit/glue/glue_util.h" |
| 21 #include "webkit/glue/webplugin.h" | 21 #include "webkit/glue/webplugin.h" |
| 22 #include "webkit/glue/plugins/fake_plugin_window_tracker_mac.h" | 22 #include "webkit/glue/plugins/fake_plugin_window_tracker_mac.h" |
| 23 #include "webkit/glue/plugins/plugin_constants_win.h" | 23 #include "webkit/glue/plugins/plugin_constants_win.h" |
| 24 #include "webkit/glue/plugins/plugin_instance.h" | 24 #include "webkit/glue/plugins/plugin_instance.h" |
| 25 #include "webkit/glue/plugins/plugin_lib.h" | 25 #include "webkit/glue/plugins/plugin_lib.h" |
| 26 #include "webkit/glue/plugins/plugin_list.h" | 26 #include "webkit/glue/plugins/plugin_list.h" |
| 27 #include "webkit/glue/plugins/plugin_stream_url.h" | 27 #include "webkit/glue/plugins/plugin_stream_url.h" |
| 28 #include "webkit/glue/webkit_glue.h" | 28 #include "webkit/glue/webkit_glue.h" |
| 29 | 29 |
| 30 // If we're compiling support for the QuickDraw drawing model, turn off GCC |
| 31 // warnings about deprecated functions (since QuickDraw is a deprecated API). |
| 32 // According to the GCC documentation, this can only be done per file, not |
| 33 // pushed and popped like some options can be. |
| 34 #ifndef NP_NO_QUICKDRAW |
| 35 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" |
| 36 #endif |
| 37 |
| 30 using webkit_glue::WebPlugin; | 38 using webkit_glue::WebPlugin; |
| 31 using webkit_glue::WebPluginDelegate; | 39 using webkit_glue::WebPluginDelegate; |
| 32 using webkit_glue::WebPluginResourceClient; | 40 using webkit_glue::WebPluginResourceClient; |
| 33 using WebKit::WebCursorInfo; | 41 using WebKit::WebCursorInfo; |
| 34 using WebKit::WebKeyboardEvent; | 42 using WebKit::WebKeyboardEvent; |
| 35 using WebKit::WebInputEvent; | 43 using WebKit::WebInputEvent; |
| 36 using WebKit::WebMouseEvent; | 44 using WebKit::WebMouseEvent; |
| 37 | 45 |
| 38 // Important implementation notes: The Mac definition of NPAPI, particularly | 46 // Important implementation notes: The Mac definition of NPAPI, particularly |
| 39 // the distinction between windowed and windowless modes, differs from the | 47 // the distinction between windowed and windowless modes, differs from the |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 quirks_(0), | 99 quirks_(0), |
| 92 plugin_(NULL), | 100 plugin_(NULL), |
| 93 // all Mac plugins are "windowless" in the Windows/X11 sense | 101 // all Mac plugins are "windowless" in the Windows/X11 sense |
| 94 windowless_(true), | 102 windowless_(true), |
| 95 windowless_needs_set_window_(true), | 103 windowless_needs_set_window_(true), |
| 96 handle_event_depth_(0), | 104 handle_event_depth_(0), |
| 97 user_gesture_message_posted_(this), | 105 user_gesture_message_posted_(this), |
| 98 user_gesture_msg_factory_(this), | 106 user_gesture_msg_factory_(this), |
| 99 null_event_factory_(this), | 107 null_event_factory_(this), |
| 100 last_mouse_x_(0), | 108 last_mouse_x_(0), |
| 101 last_mouse_y_(0) { | 109 last_mouse_y_(0), |
| 110 qd_world_(0) { |
| 102 memset(&window_, 0, sizeof(window_)); | 111 memset(&window_, 0, sizeof(window_)); |
| 112 #ifndef NP_NO_QUICKDRAW |
| 113 memset(&qd_port_, 0, sizeof(qd_port_)); |
| 114 #endif |
| 103 } | 115 } |
| 104 | 116 |
| 105 WebPluginDelegateImpl::~WebPluginDelegateImpl() { | 117 WebPluginDelegateImpl::~WebPluginDelegateImpl() { |
| 118 #ifndef NP_NO_QUICKDRAW |
| 119 if (qd_port_.port) { |
| 120 DisposeGWorld(qd_port_.port); |
| 121 DisposeGWorld(qd_world_); |
| 122 } |
| 123 #endif |
| 106 FakePluginWindowTracker::SharedInstance()->RemoveFakeWindowForDelegate( | 124 FakePluginWindowTracker::SharedInstance()->RemoveFakeWindowForDelegate( |
| 107 this, reinterpret_cast<WindowRef>(cg_context_.window)); | 125 this, reinterpret_cast<WindowRef>(cg_context_.window)); |
| 108 DestroyInstance(); | 126 DestroyInstance(); |
| 109 } | 127 } |
| 110 | 128 |
| 111 void WebPluginDelegateImpl::PluginDestroyed() { | 129 void WebPluginDelegateImpl::PluginDestroyed() { |
| 112 delete this; | 130 delete this; |
| 113 } | 131 } |
| 114 | 132 |
| 115 bool WebPluginDelegateImpl::Initialize(const GURL& url, | 133 bool WebPluginDelegateImpl::Initialize(const GURL& url, |
| (...skipping 28 matching lines...) Expand all Loading... |
| 144 if (!start_result) | 162 if (!start_result) |
| 145 return false; | 163 return false; |
| 146 | 164 |
| 147 FakePluginWindowTracker* window_tracker = | 165 FakePluginWindowTracker* window_tracker = |
| 148 FakePluginWindowTracker::SharedInstance(); | 166 FakePluginWindowTracker::SharedInstance(); |
| 149 cg_context_.window = window_tracker->GenerateFakeWindowForDelegate(this); | 167 cg_context_.window = window_tracker->GenerateFakeWindowForDelegate(this); |
| 150 cg_context_.context = NULL; | 168 cg_context_.context = NULL; |
| 151 Rect window_bounds = { 0, 0, window_rect_.height(), window_rect_.width() }; | 169 Rect window_bounds = { 0, 0, window_rect_.height(), window_rect_.width() }; |
| 152 SetWindowBounds(reinterpret_cast<WindowRef>(cg_context_.window), | 170 SetWindowBounds(reinterpret_cast<WindowRef>(cg_context_.window), |
| 153 kWindowContentRgn, &window_bounds); | 171 kWindowContentRgn, &window_bounds); |
| 154 window_.window = &cg_context_; | 172 |
| 155 window_.type = NPWindowTypeWindow; | 173 switch (instance_->drawing_model()) { |
| 174 #ifndef NP_NO_QUICKDRAW |
| 175 case NPDrawingModelQuickDraw: |
| 176 window_.window = &qd_port_; |
| 177 window_.type = NPWindowTypeDrawable; |
| 178 break; |
| 179 #endif |
| 180 case NPDrawingModelCoreGraphics: |
| 181 window_.window = &cg_context_; |
| 182 window_.type = NPWindowTypeDrawable; |
| 183 break; |
| 184 default: |
| 185 NOTREACHED(); |
| 186 break; |
| 187 } |
| 156 | 188 |
| 157 plugin->SetWindow(NULL); | 189 plugin->SetWindow(NULL); |
| 158 plugin_url_ = url.spec(); | 190 plugin_url_ = url.spec(); |
| 159 | 191 |
| 160 MessageLoop::current()->PostDelayedTask(FROM_HERE, | 192 MessageLoop::current()->PostDelayedTask(FROM_HERE, |
| 161 null_event_factory_.NewRunnableMethod( | 193 null_event_factory_.NewRunnableMethod( |
| 162 &WebPluginDelegateImpl::OnNullEvent), | 194 &WebPluginDelegateImpl::OnNullEvent), |
| 163 kPluginIdleThrottleDelayMs); | 195 kPluginIdleThrottleDelayMs); |
| 164 return true; | 196 return true; |
| 165 } | 197 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 192 WindowlessUpdateGeometry(window_rect, clip_rect); | 224 WindowlessUpdateGeometry(window_rect, clip_rect); |
| 193 } | 225 } |
| 194 | 226 |
| 195 void WebPluginDelegateImpl::UpdateContext(CGContextRef context) { | 227 void WebPluginDelegateImpl::UpdateContext(CGContextRef context) { |
| 196 // Flash on the Mac apparently caches the context from the struct it recieves | 228 // Flash on the Mac apparently caches the context from the struct it recieves |
| 197 // in NPP_SetWindow, and continue to use it even when the contents of the | 229 // in NPP_SetWindow, and continue to use it even when the contents of the |
| 198 // struct have changed, so we need to call NPP_SetWindow again if the context | 230 // struct have changed, so we need to call NPP_SetWindow again if the context |
| 199 // changes. | 231 // changes. |
| 200 if (context != cg_context_.context) { | 232 if (context != cg_context_.context) { |
| 201 cg_context_.context = context; | 233 cg_context_.context = context; |
| 234 #ifndef NP_NO_QUICKDRAW |
| 235 if (instance()->drawing_model() == NPDrawingModelQuickDraw) { |
| 236 if (qd_port_.port) { |
| 237 DisposeGWorld(qd_port_.port); |
| 238 DisposeGWorld(qd_world_); |
| 239 qd_port_.port = NULL; |
| 240 qd_world_ = NULL; |
| 241 } |
| 242 Rect window_bounds = { |
| 243 0, 0, window_rect_.height(), window_rect_.width() |
| 244 }; |
| 245 // Create a GWorld pointing at the same bits as our CGContextRef |
| 246 NewGWorldFromPtr(&qd_world_, k32BGRAPixelFormat, &window_bounds, |
| 247 NULL, NULL, 0, |
| 248 static_cast<Ptr>(CGBitmapContextGetData(context)), |
| 249 static_cast<SInt32>(CGBitmapContextGetBytesPerRow(context))); |
| 250 // Create a GWorld for the plugin to paint into whenever it wants |
| 251 NewGWorld(&qd_port_.port, k32ARGBPixelFormat, &window_bounds, |
| 252 NULL, NULL, kNativeEndianPixMap); |
| 253 SetGWorld(qd_port_.port, NULL); |
| 254 // Fill with black |
| 255 ForeColor(blackColor); |
| 256 BackColor(whiteColor); |
| 257 PaintRect(&window_bounds); |
| 258 } |
| 259 #endif |
| 202 WindowlessSetWindow(true); | 260 WindowlessSetWindow(true); |
| 203 } | 261 } |
| 204 } | 262 } |
| 205 | 263 |
| 206 void WebPluginDelegateImpl::Paint(CGContextRef context, const gfx::Rect& rect) { | 264 void WebPluginDelegateImpl::Paint(CGContextRef context, const gfx::Rect& rect) { |
| 207 DCHECK(windowless_); | 265 DCHECK(windowless_); |
| 208 WindowlessPaint(context, rect); | 266 WindowlessPaint(context, rect); |
| 209 } | 267 } |
| 210 | 268 |
| 211 void WebPluginDelegateImpl::Print(CGContextRef context) { | 269 void WebPluginDelegateImpl::Print(CGContextRef context) { |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 void WebPluginDelegateImpl::WindowlessPaint(gfx::NativeDrawingContext context, | 347 void WebPluginDelegateImpl::WindowlessPaint(gfx::NativeDrawingContext context, |
| 290 const gfx::Rect& damage_rect) { | 348 const gfx::Rect& damage_rect) { |
| 291 // If we somehow get a paint before we've set up the plugin window, bail. | 349 // If we somehow get a paint before we've set up the plugin window, bail. |
| 292 if (!cg_context_.context) | 350 if (!cg_context_.context) |
| 293 return; | 351 return; |
| 294 DCHECK(cg_context_.context == context); | 352 DCHECK(cg_context_.context == context); |
| 295 | 353 |
| 296 static StatsRate plugin_paint("Plugin.Paint"); | 354 static StatsRate plugin_paint("Plugin.Paint"); |
| 297 StatsScope<StatsRate> scope(plugin_paint); | 355 StatsScope<StatsRate> scope(plugin_paint); |
| 298 | 356 |
| 299 // We save and restore the NSGraphicsContext state in case the plugin uses | 357 switch (instance()->drawing_model()) { |
| 300 // Cocoa drawing. | 358 #ifndef NP_NO_QUICKDRAW |
| 301 [NSGraphicsContext saveGraphicsState]; | 359 case NPDrawingModelQuickDraw: |
| 302 [NSGraphicsContext setCurrentContext:[NSGraphicsContext | 360 { |
| 303 graphicsContextWithGraphicsPort:context | 361 // Plugins using the QuickDraw drawing model do not restrict their |
| 304 flipped:YES]]; | 362 // drawing to update events the way that CoreGraphics-based plugins |
| 305 CGContextSaveGState(context); | 363 // do. When we are asked to paint, we therefore just copy from the |
| 364 // plugin's persistent offscreen GWorld into our shared memory bitmap |
| 365 // context. |
| 366 Rect window_bounds = { |
| 367 0, 0, window_rect_.height(), window_rect_.width() |
| 368 }; |
| 369 PixMapHandle plugin_pixmap = GetGWorldPixMap(qd_port_.port); |
| 370 if (LockPixels(plugin_pixmap)) { |
| 371 PixMapHandle shared_pixmap = GetGWorldPixMap(qd_world_); |
| 372 if (LockPixels(shared_pixmap)) { |
| 373 SetGWorld(qd_world_, NULL); |
| 374 // Set foreground and background colors to avoid "colorizing" the |
| 375 // image. |
| 376 ForeColor(blackColor); |
| 377 BackColor(whiteColor); |
| 378 CopyBits(reinterpret_cast<BitMap*>(*plugin_pixmap), |
| 379 reinterpret_cast<BitMap*>(*shared_pixmap), |
| 380 &window_bounds, &window_bounds, srcCopy, NULL); |
| 381 UnlockPixels(shared_pixmap); |
| 382 } |
| 383 UnlockPixels(plugin_pixmap); |
| 384 } |
| 385 break; |
| 386 } |
| 387 #endif |
| 388 case NPDrawingModelCoreGraphics: |
| 389 { |
| 390 NPEvent paint_event; |
| 306 | 391 |
| 307 NPEvent paint_event; | 392 // Save and restore the NSGraphicsContext state in case the plugin uses |
| 308 paint_event.what = updateEvt; | 393 // Cocoa drawing. |
| 309 paint_event.message = reinterpret_cast<uint32>(cg_context_.window); | 394 [NSGraphicsContext saveGraphicsState]; |
| 310 paint_event.when = TickCount(); | 395 [NSGraphicsContext setCurrentContext: |
| 311 paint_event.where.h = 0; | 396 [NSGraphicsContext graphicsContextWithGraphicsPort:context |
| 312 paint_event.where.v = 0; | 397 flipped:YES]]; |
| 313 paint_event.modifiers = 0; | 398 CGContextSaveGState(context); |
| 314 instance()->NPP_HandleEvent(&paint_event); | |
| 315 | 399 |
| 316 CGContextRestoreGState(context); | 400 paint_event.what = updateEvt; |
| 317 [NSGraphicsContext restoreGraphicsState]; | 401 paint_event.message = reinterpret_cast<uint32>(cg_context_.window); |
| 402 paint_event.when = TickCount(); |
| 403 paint_event.where.h = 0; |
| 404 paint_event.where.v = 0; |
| 405 paint_event.modifiers = 0; |
| 406 instance()->NPP_HandleEvent(&paint_event); |
| 407 |
| 408 CGContextRestoreGState(context); |
| 409 [NSGraphicsContext restoreGraphicsState]; |
| 410 break; |
| 411 } |
| 412 } |
| 318 } | 413 } |
| 319 | 414 |
| 320 // Moves our dummy window to the given offset relative to the last known | 415 // Moves our dummy window to the given offset relative to the last known |
| 321 // location of the real renderer window's content view. | 416 // location of the real renderer window's content view. |
| 322 // If new_width or new_height is non-zero, the window size (content region) | 417 // If new_width or new_height is non-zero, the window size (content region) |
| 323 // will be updated accordingly; if they are zero, the existing size will be | 418 // will be updated accordingly; if they are zero, the existing size will be |
| 324 // preserved. | 419 // preserved. |
| 325 static void UpdateDummyWindowBoundsWithOffset(WindowRef window, | 420 static void UpdateDummyWindowBoundsWithOffset(WindowRef window, |
| 326 int x_offset, int y_offset, | 421 int x_offset, int y_offset, |
| 327 int new_width, int new_height) { | 422 int new_width, int new_height) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 357 window_.height = window_rect_.height(); | 452 window_.height = window_rect_.height(); |
| 358 window_.width = window_rect_.width(); | 453 window_.width = window_rect_.width(); |
| 359 window_.x = 0; | 454 window_.x = 0; |
| 360 window_.y = 0; | 455 window_.y = 0; |
| 361 | 456 |
| 362 UpdateDummyWindowBoundsWithOffset( | 457 UpdateDummyWindowBoundsWithOffset( |
| 363 reinterpret_cast<WindowRef>(cg_context_.window), window_rect_.x(), | 458 reinterpret_cast<WindowRef>(cg_context_.window), window_rect_.x(), |
| 364 window_rect_.y(), window_rect_.width(), window_rect_.height()); | 459 window_rect_.y(), window_rect_.width(), window_rect_.height()); |
| 365 | 460 |
| 366 NPError err = instance()->NPP_SetWindow(&window_); | 461 NPError err = instance()->NPP_SetWindow(&window_); |
| 462 |
| 367 DCHECK(err == NPERR_NO_ERROR); | 463 DCHECK(err == NPERR_NO_ERROR); |
| 368 } | 464 } |
| 369 | 465 |
| 370 void WebPluginDelegateImpl::SetFocus() { | 466 void WebPluginDelegateImpl::SetFocus() { |
| 371 NPEvent focus_event = { 0 }; | 467 NPEvent focus_event = { 0 }; |
| 372 focus_event.what = NPEventType_GetFocusEvent; | 468 focus_event.what = NPEventType_GetFocusEvent; |
| 373 focus_event.when = TickCount(); | 469 focus_event.when = TickCount(); |
| 374 instance()->NPP_HandleEvent(&focus_event); | 470 instance()->NPP_HandleEvent(&focus_event); |
| 375 } | 471 } |
| 376 | 472 |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 508 bool WebPluginDelegateImpl::HandleInputEvent(const WebInputEvent& event, | 604 bool WebPluginDelegateImpl::HandleInputEvent(const WebInputEvent& event, |
| 509 WebCursorInfo* cursor) { | 605 WebCursorInfo* cursor) { |
| 510 // If we somehow get an event before we've set up the plugin window, bail. | 606 // If we somehow get an event before we've set up the plugin window, bail. |
| 511 if (!cg_context_.context) | 607 if (!cg_context_.context) |
| 512 return false; | 608 return false; |
| 513 DCHECK(windowless_) << "events should only be received in windowless mode"; | 609 DCHECK(windowless_) << "events should only be received in windowless mode"; |
| 514 DCHECK(cursor != NULL); | 610 DCHECK(cursor != NULL); |
| 515 | 611 |
| 516 NPEvent np_event = {0}; | 612 NPEvent np_event = {0}; |
| 517 if (!NPEventFromWebInputEvent(event, &np_event)) { | 613 if (!NPEventFromWebInputEvent(event, &np_event)) { |
| 614 LOG(WARNING) << "NPEventFromWebInputEvent failed"; |
| 518 return false; | 615 return false; |
| 519 } | 616 } |
| 520 np_event.when = TickCount(); | 617 np_event.when = TickCount(); |
| 521 if (np_event.what == nullEvent) { | 618 if (np_event.what == nullEvent) { |
| 522 last_mouse_x_ = np_event.where.h; | 619 last_mouse_x_ = np_event.where.h; |
| 523 last_mouse_y_ = np_event.where.v; | 620 last_mouse_y_ = np_event.where.v; |
| 524 return true; // Let the recurring task actually send the event. | 621 return true; // Let the recurring task actually send the event. |
| 525 } | 622 } |
| 526 | 623 |
| 527 // If this is a mouse event, we need to make sure our dummy window has the | 624 // If this is a mouse event, we need to make sure our dummy window has the |
| 528 // correct location before we send the event to the plugin, so that any | 625 // correct location before we send the event to the plugin, so that any |
| 529 // coordinate conversion the plugin does will work out. | 626 // coordinate conversion the plugin does will work out. |
| 530 if (WebInputEventIsWebMouseEvent(event)) { | 627 if (WebInputEventIsWebMouseEvent(event)) { |
| 531 const WebMouseEvent* mouse_event = | 628 const WebMouseEvent* mouse_event = |
| 532 static_cast<const WebMouseEvent*>(&event); | 629 static_cast<const WebMouseEvent*>(&event); |
| 533 UpdateWindowLocation(reinterpret_cast<WindowRef>(cg_context_.window), | 630 UpdateWindowLocation(reinterpret_cast<WindowRef>(cg_context_.window), |
| 534 *mouse_event); | 631 *mouse_event); |
| 535 } | 632 } |
| 536 CGContextSaveGState(cg_context_.context); | 633 bool ret = false; |
| 537 bool ret = instance()->NPP_HandleEvent(&np_event) != 0; | 634 switch (instance()->drawing_model()) { |
| 538 CGContextRestoreGState(cg_context_.context); | 635 #ifndef NP_NO_QUICKDRAW |
| 636 case NPDrawingModelQuickDraw: |
| 637 SetGWorld(qd_port_.port, NULL); |
| 638 ret = instance()->NPP_HandleEvent(&np_event) != 0; |
| 639 break; |
| 640 #endif |
| 641 case NPDrawingModelCoreGraphics: |
| 642 CGContextSaveGState(cg_context_.context); |
| 643 ret = instance()->NPP_HandleEvent(&np_event) != 0; |
| 644 CGContextRestoreGState(cg_context_.context); |
| 645 break; |
| 646 } |
| 539 return ret; | 647 return ret; |
| 540 } | 648 } |
| 541 | 649 |
| 542 WebPluginResourceClient* WebPluginDelegateImpl::CreateResourceClient( | 650 WebPluginResourceClient* WebPluginDelegateImpl::CreateResourceClient( |
| 543 int resource_id, const GURL& url, bool notify_needed, | 651 int resource_id, const GURL& url, bool notify_needed, |
| 544 intptr_t notify_data, intptr_t existing_stream) { | 652 intptr_t notify_data, intptr_t existing_stream) { |
| 545 // Stream already exists. This typically happens for range requests | 653 // Stream already exists. This typically happens for range requests |
| 546 // initiated via NPN_RequestRead. | 654 // initiated via NPN_RequestRead. |
| 547 if (existing_stream) { | 655 if (existing_stream) { |
| 548 NPAPI::PluginStream* plugin_stream = | 656 NPAPI::PluginStream* plugin_stream = |
| 549 reinterpret_cast<NPAPI::PluginStream*>(existing_stream); | 657 reinterpret_cast<NPAPI::PluginStream*>(existing_stream); |
| 550 | 658 |
| 551 plugin_stream->CancelRequest(); | 659 plugin_stream->CancelRequest(); |
| 552 | 660 |
| 553 return plugin_stream->AsResourceClient(); | 661 return plugin_stream->AsResourceClient(); |
| 554 } | 662 } |
| 555 | 663 |
| 556 std::string mime_type; | 664 std::string mime_type; |
| 557 NPAPI::PluginStreamUrl *stream = instance()->CreateStream( | 665 NPAPI::PluginStreamUrl *stream = instance()->CreateStream( |
| 558 resource_id, url, mime_type, notify_needed, | 666 resource_id, url, mime_type, notify_needed, |
| 559 reinterpret_cast<void*>(notify_data)); | 667 reinterpret_cast<void*>(notify_data)); |
| 560 return stream; | 668 return stream; |
| 561 } | 669 } |
| 562 | 670 |
| 563 void WebPluginDelegateImpl::OnNullEvent() { | 671 void WebPluginDelegateImpl::OnNullEvent() { |
| 672 // Dispatch any pending Carbon events so that the plugin's event handlers |
| 673 // will get called on any windows it has created. |
| 674 EventRef event; |
| 675 while (ReceiveNextEvent( |
| 676 0, NULL, kEventDurationNoWait, kEventRemoveFromQueue, &event) == noErr) { |
| 677 SendEventToEventTarget(event, GetEventDispatcherTarget()); |
| 678 ReleaseEvent(event); |
| 679 } |
| 680 |
| 681 // Send an idle event so that the plugin can do background work |
| 564 NPEvent np_event = {0}; | 682 NPEvent np_event = {0}; |
| 565 np_event.what = nullEvent; | 683 np_event.what = nullEvent; |
| 566 np_event.when = TickCount(); | 684 np_event.when = TickCount(); |
| 567 np_event.modifiers = GetCurrentKeyModifiers(); | 685 np_event.modifiers = GetCurrentKeyModifiers(); |
| 568 if (!Button()) | 686 if (!Button()) |
| 569 np_event.modifiers |= btnState; | 687 np_event.modifiers |= btnState; |
| 570 np_event.where.h = last_mouse_x_; | 688 np_event.where.h = last_mouse_x_; |
| 571 np_event.where.v = last_mouse_y_; | 689 np_event.where.v = last_mouse_y_; |
| 572 instance()->NPP_HandleEvent(&np_event); | 690 instance()->NPP_HandleEvent(&np_event); |
| 573 | 691 |
| 692 #ifndef NP_NO_QUICKDRAW |
| 693 // Quickdraw-based plugins can draw at any time, so tell the renderer to |
| 694 // repaint. |
| 695 // TODO: only do this if the contents of the offscreen GWorld has changed, |
| 696 // so as not to spam the renderer with an unchanging image. |
| 697 if (instance_->drawing_model() == NPDrawingModelQuickDraw) |
| 698 instance()->webplugin()->Invalidate(); |
| 699 #endif |
| 700 |
| 574 MessageLoop::current()->PostDelayedTask(FROM_HERE, | 701 MessageLoop::current()->PostDelayedTask(FROM_HERE, |
| 575 null_event_factory_.NewRunnableMethod( | 702 null_event_factory_.NewRunnableMethod( |
| 576 &WebPluginDelegateImpl::OnNullEvent), | 703 &WebPluginDelegateImpl::OnNullEvent), |
| 577 kPluginIdleThrottleDelayMs); | 704 kPluginIdleThrottleDelayMs); |
| 578 } | 705 } |
| OLD | NEW |