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

Side by Side Diff: webkit/glue/plugins/webplugin_delegate_impl.cc

Issue 18712: Attempt to fix a IAT unpatch crash. (Closed)
Patch Set: Created 11 years, 11 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/glue/plugins/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) 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 #include "webkit/glue/plugins/webplugin_delegate_impl.h" 5 #include "webkit/glue/plugins/webplugin_delegate_impl.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/file_util.h" 10 #include "base/file_util.h"
11 #include "base/iat_patch.h"
12 #include "base/lazy_instance.h"
11 #include "base/message_loop.h" 13 #include "base/message_loop.h"
12 #include "base/stats_counters.h" 14 #include "base/stats_counters.h"
13 #include "base/string_util.h" 15 #include "base/string_util.h"
14 #include "webkit/default_plugin/plugin_impl.h" 16 #include "webkit/default_plugin/plugin_impl.h"
15 #include "webkit/glue/glue_util.h" 17 #include "webkit/glue/glue_util.h"
16 #include "webkit/glue/webplugin.h" 18 #include "webkit/glue/webplugin.h"
17 #include "webkit/glue/plugins/plugin_constants_win.h" 19 #include "webkit/glue/plugins/plugin_constants_win.h"
18 #include "webkit/glue/plugins/plugin_instance.h" 20 #include "webkit/glue/plugins/plugin_instance.h"
19 #include "webkit/glue/plugins/plugin_lib.h" 21 #include "webkit/glue/plugins/plugin_lib.h"
20 #include "webkit/glue/plugins/plugin_list.h" 22 #include "webkit/glue/plugins/plugin_list.h"
21 #include "webkit/glue/plugins/plugin_stream_url.h" 23 #include "webkit/glue/plugins/plugin_stream_url.h"
22 #include "webkit/glue/webkit_glue.h" 24 #include "webkit/glue/webkit_glue.h"
23 25
24 static StatsCounter windowless_queue("Plugin.ThrottleQueue"); 26 namespace {
25 27
26 static const wchar_t kWebPluginDelegateProperty[] = 28 const wchar_t kWebPluginDelegateProperty[] = L"WebPluginDelegateProperty";
27 L"WebPluginDelegateProperty"; 29 const wchar_t kPluginNameAtomProperty[] = L"PluginNameAtom";
28 static const wchar_t kPluginNameAtomProperty[] = L"PluginNameAtom"; 30 const wchar_t kDummyActivationWindowName[] = L"DummyWindowForActivation";
29 static const wchar_t kDummyActivationWindowName[] = L"DummyWindowForActivation"; 31 const wchar_t kPluginOrigProc[] = L"OriginalPtr";
30 static const wchar_t kPluginOrigProc[] = L"OriginalPtr"; 32 const wchar_t kPluginFlashThrottle[] = L"FlashThrottle";
31 static const wchar_t kPluginFlashThrottle[] = L"FlashThrottle";
32 33
33 // The fastest we are willing to process WM_USER+1 events for Flash. 34 // The fastest we are willing to process WM_USER+1 events for Flash.
34 // Flash can easily exceed the limits of our CPU if we don't throttle it. 35 // Flash can easily exceed the limits of our CPU if we don't throttle it.
35 // The throttle has been chosen by testing various delays and compromising 36 // The throttle has been chosen by testing various delays and compromising
36 // on acceptable Flash performance and reasonable CPU consumption. 37 // on acceptable Flash performance and reasonable CPU consumption.
37 // 38 //
38 // I'd like to make the throttle delay variable, based on the amount of 39 // I'd like to make the throttle delay variable, based on the amount of
39 // time currently required to paint Flash plugins. There isn't a good 40 // time currently required to paint Flash plugins. There isn't a good
40 // way to count the time spent in aggregate plugin painting, however, so 41 // way to count the time spent in aggregate plugin painting, however, so
41 // this seems to work well enough. 42 // this seems to work well enough.
42 static const int kFlashWMUSERMessageThrottleDelayMs = 5; 43 const int kFlashWMUSERMessageThrottleDelayMs = 5;
43 44
44 std::list<MSG> WebPluginDelegateImpl::throttle_queue_; 45 // The current instance of the plugin which entered the modal loop.
46 WebPluginDelegateImpl* g_current_plugin_instance = NULL;
45 47
46 WebPluginDelegateImpl* WebPluginDelegateImpl::current_plugin_instance_ = NULL; 48 base::LazyInstance<std::list<MSG> > g_throttle_queue(base::LINKER_INITIALIZED);
47 49
48 iat_patch::IATPatchFunction WebPluginDelegateImpl::iat_patch_track_popup_menu_; 50 // Helper object for patching the TrackPopupMenu API.
49 iat_patch::IATPatchFunction WebPluginDelegateImpl::iat_patch_set_cursor_; 51 base::LazyInstance<iat_patch::IATPatchFunction> g_iat_patch_track_popup_menu(
52 base::LINKER_INITIALIZED);
53
54 // Helper object for patching the SetCursor API.
55 base::LazyInstance<iat_patch::IATPatchFunction> g_iat_patch_set_cursor(
56 base::LINKER_INITIALIZED);
57
58 } // namespace
50 59
51 WebPluginDelegateImpl* WebPluginDelegateImpl::Create( 60 WebPluginDelegateImpl* WebPluginDelegateImpl::Create(
52 const FilePath& filename, 61 const FilePath& filename,
53 const std::string& mime_type, 62 const std::string& mime_type,
54 gfx::NativeView containing_view) { 63 gfx::NativeView containing_view) {
55 scoped_refptr<NPAPI::PluginLib> plugin = 64 scoped_refptr<NPAPI::PluginLib> plugin =
56 NPAPI::PluginLib::CreatePluginLib(filename); 65 NPAPI::PluginLib::CreatePluginLib(filename);
57 if (plugin.get() == NULL) 66 if (plugin.get() == NULL)
58 return NULL; 67 return NULL;
59 68
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 wchar_t window_title[MAX_PATH + 1] = {0}; 114 wchar_t window_title[MAX_PATH + 1] = {0};
106 if (GetWindowText(window, window_title, arraysize(window_title))) { 115 if (GetWindowText(window, window_title, arraysize(window_title))) {
107 return (0 == lstrcmpiW(window_title, kDummyActivationWindowName)); 116 return (0 == lstrcmpiW(window_title, kDummyActivationWindowName));
108 } 117 }
109 return false; 118 return false;
110 } 119 }
111 120
112 LRESULT CALLBACK WebPluginDelegateImpl::HandleEventMessageFilterHook( 121 LRESULT CALLBACK WebPluginDelegateImpl::HandleEventMessageFilterHook(
113 int code, WPARAM wParam, LPARAM lParam) { 122 int code, WPARAM wParam, LPARAM lParam) {
114 123
115 DCHECK(current_plugin_instance_); 124 DCHECK(g_current_plugin_instance);
116 current_plugin_instance_->OnModalLoopEntered(); 125 g_current_plugin_instance->OnModalLoopEntered();
117 return CallNextHookEx(NULL, code, wParam, lParam); 126 return CallNextHookEx(NULL, code, wParam, lParam);
118 } 127 }
119 128
120 WebPluginDelegateImpl::WebPluginDelegateImpl( 129 WebPluginDelegateImpl::WebPluginDelegateImpl(
121 gfx::NativeView containing_view, 130 gfx::NativeView containing_view,
122 NPAPI::PluginInstance *instance) 131 NPAPI::PluginInstance *instance)
123 : parent_(containing_view), 132 : parent_(containing_view),
124 instance_(instance), 133 instance_(instance),
125 quirks_(0), 134 quirks_(0),
126 plugin_(NULL), 135 plugin_(NULL),
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 plugin_url_ = url.spec(); 263 plugin_url_ = url.spec();
255 264
256 // The windowless version of the Silverlight plugin calls the 265 // The windowless version of the Silverlight plugin calls the
257 // WindowFromPoint API and passes the result of that to the 266 // WindowFromPoint API and passes the result of that to the
258 // TrackPopupMenu API call as the owner window. This causes the API 267 // TrackPopupMenu API call as the owner window. This causes the API
259 // to fail as the API expects the window handle to live on the same 268 // to fail as the API expects the window handle to live on the same
260 // thread as the caller. It works in the other browsers as the plugin 269 // thread as the caller. It works in the other browsers as the plugin
261 // lives on the browser thread. Our workaround is to intercept the 270 // lives on the browser thread. Our workaround is to intercept the
262 // TrackPopupMenu API for Silverlight and replace the window handle 271 // TrackPopupMenu API for Silverlight and replace the window handle
263 // with the dummy activation window. 272 // with the dummy activation window.
264 if (windowless_ && !iat_patch_track_popup_menu_.is_patched() && 273 if (windowless_ && !g_iat_patch_track_popup_menu.Pointer()->is_patched() &&
265 (quirks_ & PLUGIN_QUIRK_PATCH_TRACKPOPUP_MENU)) { 274 (quirks_ & PLUGIN_QUIRK_PATCH_TRACKPOPUP_MENU)) {
266 iat_patch_track_popup_menu_.Patch( 275 g_iat_patch_track_popup_menu.Pointer()->Patch(
267 plugin_module_handle_, "user32.dll", "TrackPopupMenu", 276 plugin_module_handle_, "user32.dll", "TrackPopupMenu",
268 WebPluginDelegateImpl::TrackPopupMenuPatch); 277 WebPluginDelegateImpl::TrackPopupMenuPatch);
269 } 278 }
270 279
271 // Windowless plugins can set cursors by calling the SetCursor API. This 280 // Windowless plugins can set cursors by calling the SetCursor API. This
272 // works because the thread inputs of the browser UI thread and the plugin 281 // works because the thread inputs of the browser UI thread and the plugin
273 // thread are attached. We intercept the SetCursor API for windowless plugins 282 // thread are attached. We intercept the SetCursor API for windowless plugins
274 // and remember the cursor being set. This is shipped over to the browser 283 // and remember the cursor being set. This is shipped over to the browser
275 // in the HandleEvent call, which ensures that the cursor does not change 284 // in the HandleEvent call, which ensures that the cursor does not change
276 // when a windowless plugin instance changes the cursor in a background tab. 285 // when a windowless plugin instance changes the cursor in a background tab.
277 if (windowless_ && !iat_patch_set_cursor_.is_patched() && 286 if (windowless_ && !g_iat_patch_set_cursor.Pointer()->is_patched() &&
278 (quirks_ & PLUGIN_QUIRK_PATCH_SETCURSOR)) { 287 (quirks_ & PLUGIN_QUIRK_PATCH_SETCURSOR)) {
279 iat_patch_set_cursor_.Patch(plugin_module_handle_, "user32.dll", 288 g_iat_patch_set_cursor.Pointer()->Patch(
280 "SetCursor", 289 plugin_module_handle_, "user32.dll", "SetCursor",
281 WebPluginDelegateImpl::SetCursorPatch); 290 WebPluginDelegateImpl::SetCursorPatch);
282 } 291 }
283 return true; 292 return true;
284 } 293 }
285 294
286 void WebPluginDelegateImpl::DestroyInstance() { 295 void WebPluginDelegateImpl::DestroyInstance() {
287 if (instance_ && (instance_->npp()->ndata != NULL)) { 296 if (instance_ && (instance_->npp()->ndata != NULL)) {
288 // Shutdown all streams before destroying so that 297 // Shutdown all streams before destroying so that
289 // no streams are left "in progress". Need to do 298 // no streams are left "in progress". Need to do
290 // this before calling set_web_plugin(NULL) because the 299 // this before calling set_web_plugin(NULL) because the
291 // instance uses the helper to do the download. 300 // instance uses the helper to do the download.
292 instance_->CloseStreams(); 301 instance_->CloseStreams();
293 302
294 window_.window = NULL; 303 window_.window = NULL;
295 if (!(quirks_ & PLUGIN_QUIRK_DONT_SET_NULL_WINDOW_HANDLE_ON_DESTROY)) { 304 if (!(quirks_ & PLUGIN_QUIRK_DONT_SET_NULL_WINDOW_HANDLE_ON_DESTROY)) {
296 instance_->NPP_SetWindow(&window_); 305 instance_->NPP_SetWindow(&window_);
297 } 306 }
298 307
299 instance_->NPP_Destroy(); 308 instance_->NPP_Destroy();
300 309
301 instance_->set_web_plugin(NULL); 310 instance_->set_web_plugin(NULL);
302 311
303 if (instance_->plugin_lib()) { 312 if (instance_->plugin_lib()) {
304 // Unpatch if this is the last plugin instance. 313 // Unpatch if this is the last plugin instance.
305 if (instance_->plugin_lib()->instance_count() == 1) { 314 if (instance_->plugin_lib()->instance_count() == 1) {
306 if (iat_patch_set_cursor_.is_patched()) { 315 if (g_iat_patch_set_cursor.Pointer()->is_patched()) {
307 iat_patch_set_cursor_.Unpatch(); 316 g_iat_patch_set_cursor.Pointer()->Unpatch();
308 } 317 }
309 318
310 if (iat_patch_track_popup_menu_.is_patched()) { 319 if (g_iat_patch_track_popup_menu.Pointer()->is_patched()) {
311 iat_patch_track_popup_menu_.Unpatch(); 320 g_iat_patch_track_popup_menu.Pointer()->Unpatch();
312 } 321 }
313 } 322 }
314 } 323 }
315 324
316 instance_ = 0; 325 instance_ = 0;
317 } 326 }
318 } 327 }
319 328
320 void WebPluginDelegateImpl::UpdateGeometry( 329 void WebPluginDelegateImpl::UpdateGeometry(
321 const gfx::Rect& window_rect, 330 const gfx::Rect& window_rect,
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 DestroyWindow(windowed_handle_); 506 DestroyWindow(windowed_handle_);
498 windowed_handle_ = 0; 507 windowed_handle_ = 0;
499 } 508 }
500 } 509 }
501 510
502 // Erase all messages in the queue destined for a particular window. 511 // Erase all messages in the queue destined for a particular window.
503 // When windows are closing, callers should use this function to clear 512 // When windows are closing, callers should use this function to clear
504 // the queue. 513 // the queue.
505 // static 514 // static
506 void WebPluginDelegateImpl::ClearThrottleQueueForWindow(HWND window) { 515 void WebPluginDelegateImpl::ClearThrottleQueueForWindow(HWND window) {
516 std::list<MSG>* throttle_queue = g_throttle_queue.Pointer();
517
507 std::list<MSG>::iterator it; 518 std::list<MSG>::iterator it;
508 for (it = throttle_queue_.begin(); it != throttle_queue_.end(); ) { 519 for (it = throttle_queue->begin(); it != throttle_queue->end(); ) {
509 if (it->hwnd == window) { 520 if (it->hwnd == window) {
510 it = throttle_queue_.erase(it); 521 it = throttle_queue->erase(it);
511 windowless_queue.Decrement();
512 } else { 522 } else {
513 it++; 523 it++;
514 } 524 }
515 } 525 }
516 } 526 }
517 527
518 // Delayed callback for processing throttled messages. 528 // Delayed callback for processing throttled messages.
519 // Throttled messages are aggregated globally across all plugins. 529 // Throttled messages are aggregated globally across all plugins.
520 // static 530 // static
521 void WebPluginDelegateImpl::OnThrottleMessage() { 531 void WebPluginDelegateImpl::OnThrottleMessage() {
522 // The current algorithm walks the list and processes the first 532 // The current algorithm walks the list and processes the first
523 // message it finds for each plugin. It is important to service 533 // message it finds for each plugin. It is important to service
524 // all active plugins with each pass through the throttle, otherwise 534 // all active plugins with each pass through the throttle, otherwise
525 // we see video jankiness. 535 // we see video jankiness.
536 std::list<MSG>* throttle_queue = g_throttle_queue.Pointer();
526 std::map<HWND, int> processed; 537 std::map<HWND, int> processed;
527 538
528 std::list<MSG>::iterator it = throttle_queue_.begin(); 539 std::list<MSG>::iterator it = throttle_queue->begin();
529 while (it != throttle_queue_.end()) { 540 while (it != throttle_queue->end()) {
530 const MSG& msg = *it; 541 const MSG& msg = *it;
531 if (processed.find(msg.hwnd) == processed.end()) { 542 if (processed.find(msg.hwnd) == processed.end()) {
532 WNDPROC proc = reinterpret_cast<WNDPROC>(msg.time); 543 WNDPROC proc = reinterpret_cast<WNDPROC>(msg.time);
533 // It is possible that the window was closed after we queued 544 // It is possible that the window was closed after we queued
534 // this message. This is a rare event; just verify the window 545 // this message. This is a rare event; just verify the window
535 // is alive. (see also bug 1259488) 546 // is alive. (see also bug 1259488)
536 if (IsWindow(msg.hwnd)) 547 if (IsWindow(msg.hwnd))
537 CallWindowProc(proc, msg.hwnd, msg.message, msg.wParam, msg.lParam); 548 CallWindowProc(proc, msg.hwnd, msg.message, msg.wParam, msg.lParam);
538 processed[msg.hwnd] = 1; 549 processed[msg.hwnd] = 1;
539 it = throttle_queue_.erase(it); 550 it = throttle_queue->erase(it);
540 windowless_queue.Decrement();
541 } else { 551 } else {
542 it++; 552 it++;
543 } 553 }
544 } 554 }
545 555
546 if (throttle_queue_.size() > 0) 556 if (throttle_queue->size() > 0)
547 MessageLoop::current()->PostDelayedTask(FROM_HERE, 557 MessageLoop::current()->PostDelayedTask(FROM_HERE,
548 NewRunnableFunction(&WebPluginDelegateImpl::OnThrottleMessage), 558 NewRunnableFunction(&WebPluginDelegateImpl::OnThrottleMessage),
549 kFlashWMUSERMessageThrottleDelayMs); 559 kFlashWMUSERMessageThrottleDelayMs);
550 } 560 }
551 561
552 // Schedule a windows message for delivery later. 562 // Schedule a windows message for delivery later.
553 // static 563 // static
554 void WebPluginDelegateImpl::ThrottleMessage(WNDPROC proc, HWND hwnd, 564 void WebPluginDelegateImpl::ThrottleMessage(WNDPROC proc, HWND hwnd,
555 UINT message, WPARAM wParam, 565 UINT message, WPARAM wParam,
556 LPARAM lParam) { 566 LPARAM lParam) {
557 MSG msg; 567 MSG msg;
558 msg.time = reinterpret_cast<DWORD>(proc); 568 msg.time = reinterpret_cast<DWORD>(proc);
559 msg.hwnd = hwnd; 569 msg.hwnd = hwnd;
560 msg.message = message; 570 msg.message = message;
561 msg.wParam = wParam; 571 msg.wParam = wParam;
562 msg.lParam = lParam; 572 msg.lParam = lParam;
563 throttle_queue_.push_back(msg);
564 windowless_queue.Increment();
565 573
566 if (throttle_queue_.size() == 1) { 574 std::list<MSG>* throttle_queue = g_throttle_queue.Pointer();
575
jam 2009/01/23 19:26:23 nit: no need for extra line?
576 throttle_queue->push_back(msg);
577
578 if (throttle_queue->size() == 1) {
567 MessageLoop::current()->PostDelayedTask(FROM_HERE, 579 MessageLoop::current()->PostDelayedTask(FROM_HERE,
568 NewRunnableFunction(&WebPluginDelegateImpl::OnThrottleMessage), 580 NewRunnableFunction(&WebPluginDelegateImpl::OnThrottleMessage),
569 kFlashWMUSERMessageThrottleDelayMs); 581 kFlashWMUSERMessageThrottleDelayMs);
570 } 582 }
571 } 583 }
572 584
573 // We go out of our way to find the hidden windows created by Flash for 585 // We go out of our way to find the hidden windows created by Flash for
574 // windowless plugins. We throttle the rate at which they deliver messages 586 // windowless plugins. We throttle the rate at which they deliver messages
575 // so that they will not consume outrageous amounts of CPU. 587 // so that they will not consume outrageous amounts of CPU.
576 // static 588 // static
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
808 invalid_rect.Offset(-window_rect.left, -window_rect.top); 820 invalid_rect.Offset(-window_rect.left, -window_rect.top);
809 821
810 // The plugin window might have non-client area. If we don't pass in 822 // The plugin window might have non-client area. If we don't pass in
811 // RDW_FRAME then the children don't receive WM_NCPAINT messages while 823 // RDW_FRAME then the children don't receive WM_NCPAINT messages while
812 // scrolling, which causes painting problems (http://b/issue?id=923945). 824 // scrolling, which causes painting problems (http://b/issue?id=923945).
813 RedrawWindow(hwnd, &invalid_rect.ToRECT(), NULL, 825 RedrawWindow(hwnd, &invalid_rect.ToRECT(), NULL,
814 RDW_UPDATENOW | RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_FRAME); 826 RDW_UPDATENOW | RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_FRAME);
815 return FALSE; 827 return FALSE;
816 } 828 }
817 829
818 current_plugin_instance_ = delegate; 830 g_current_plugin_instance = delegate;
819 831
820 switch (message) { 832 switch (message) {
821 case WM_NCDESTROY: { 833 case WM_NCDESTROY: {
822 RemoveProp(hwnd, kWebPluginDelegateProperty); 834 RemoveProp(hwnd, kWebPluginDelegateProperty);
823 ATOM plugin_name_atom = reinterpret_cast <ATOM>( 835 ATOM plugin_name_atom = reinterpret_cast <ATOM>(
824 RemoveProp(hwnd, kPluginNameAtomProperty)); 836 RemoveProp(hwnd, kPluginNameAtomProperty));
825 if (plugin_name_atom != 0) 837 if (plugin_name_atom != 0)
826 GlobalDeleteAtom(plugin_name_atom); 838 GlobalDeleteAtom(plugin_name_atom);
827 ClearThrottleQueueForWindow(hwnd); 839 ClearThrottleQueueForWindow(hwnd);
828 break; 840 break;
829 } 841 }
830 // Flash may flood the message queue with WM_USER+1 message causing 100% CPU 842 // Flash may flood the message queue with WM_USER+1 message causing 100% CPU
831 // usage. See https://bugzilla.mozilla.org/show_bug.cgi?id=132759. We 843 // usage. See https://bugzilla.mozilla.org/show_bug.cgi?id=132759. We
832 // prevent this by throttling the messages. 844 // prevent this by throttling the messages.
833 case WM_USER + 1: { 845 case WM_USER + 1: {
834 if (delegate->quirks() & PLUGIN_QUIRK_THROTTLE_WM_USER_PLUS_ONE) { 846 if (delegate->quirks() & PLUGIN_QUIRK_THROTTLE_WM_USER_PLUS_ONE) {
835 WebPluginDelegateImpl::ThrottleMessage(delegate->plugin_wnd_proc_, hwnd, 847 WebPluginDelegateImpl::ThrottleMessage(delegate->plugin_wnd_proc_, hwnd,
836 message, wparam, lparam); 848 message, wparam, lparam);
837 current_plugin_instance_ = NULL; 849 g_current_plugin_instance = NULL;
838 return FALSE; 850 return FALSE;
839 } 851 }
840 break; 852 break;
841 } 853 }
842 default: { 854 default: {
843 break; 855 break;
844 } 856 }
845 } 857 }
846 858
847 delegate->last_message_ = message; 859 delegate->last_message_ = message;
848 delegate->is_calling_wndproc = true; 860 delegate->is_calling_wndproc = true;
849 861
850 if (!delegate->user_gesture_message_posted_ && 862 if (!delegate->user_gesture_message_posted_ &&
851 IsUserGestureMessage(message)) { 863 IsUserGestureMessage(message)) {
852 delegate->user_gesture_message_posted_ = true; 864 delegate->user_gesture_message_posted_ = true;
853 865
854 delegate->instance()->PushPopupsEnabledState(true); 866 delegate->instance()->PushPopupsEnabledState(true);
855 867
856 MessageLoop::current()->PostTask(FROM_HERE, 868 MessageLoop::current()->PostTask(FROM_HERE,
857 delegate->user_gesture_msg_factory_.NewRunnableMethod( 869 delegate->user_gesture_msg_factory_.NewRunnableMethod(
858 &WebPluginDelegateImpl::OnUserGestureEnd)); 870 &WebPluginDelegateImpl::OnUserGestureEnd));
859 } 871 }
860 872
861 LRESULT result = CallWindowProc(delegate->plugin_wnd_proc_, hwnd, message, 873 LRESULT result = CallWindowProc(delegate->plugin_wnd_proc_, hwnd, message,
862 wparam, lparam); 874 wparam, lparam);
863 delegate->is_calling_wndproc = false; 875 delegate->is_calling_wndproc = false;
864 current_plugin_instance_ = NULL; 876 g_current_plugin_instance = NULL;
865 return result; 877 return result;
866 } 878 }
867 879
868 void WebPluginDelegateImpl::WindowlessUpdateGeometry( 880 void WebPluginDelegateImpl::WindowlessUpdateGeometry(
869 const gfx::Rect& window_rect, 881 const gfx::Rect& window_rect,
870 const gfx::Rect& clip_rect) { 882 const gfx::Rect& clip_rect) {
871 // Only resend to the instance if the geometry has changed. 883 // Only resend to the instance if the geometry has changed.
872 if (window_rect == window_rect_ && clip_rect == clip_rect_) 884 if (window_rect == window_rect_ && clip_rect == clip_rect_)
873 return; 885 return;
874 886
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
996 // in that context we unhook on receiving the first notification in 1008 // in that context we unhook on receiving the first notification in
997 // the message filter hook. 1009 // the message filter hook.
998 handle_event_message_filter_hook_ = 1010 handle_event_message_filter_hook_ =
999 SetWindowsHookEx(WH_MSGFILTER, HandleEventMessageFilterHook, NULL, 1011 SetWindowsHookEx(WH_MSGFILTER, HandleEventMessageFilterHook, NULL,
1000 GetCurrentThreadId()); 1012 GetCurrentThreadId());
1001 } 1013 }
1002 1014
1003 bool old_task_reentrancy_state = 1015 bool old_task_reentrancy_state =
1004 MessageLoop::current()->NestableTasksAllowed(); 1016 MessageLoop::current()->NestableTasksAllowed();
1005 1017
1006 current_plugin_instance_ = this; 1018 g_current_plugin_instance = this;
1007 1019
1008 handle_event_depth_++; 1020 handle_event_depth_++;
1009 1021
1010 bool pop_user_gesture = false; 1022 bool pop_user_gesture = false;
1011 1023
1012 if (IsUserGestureMessage(event->event)) { 1024 if (IsUserGestureMessage(event->event)) {
1013 pop_user_gesture = true; 1025 pop_user_gesture = true;
1014 instance()->PushPopupsEnabledState(true); 1026 instance()->PushPopupsEnabledState(true);
1015 } 1027 }
1016 1028
1017 bool ret = instance()->NPP_HandleEvent(event) != 0; 1029 bool ret = instance()->NPP_HandleEvent(event) != 0;
1018 1030
1019 if (event->event == WM_MOUSEMOVE) { 1031 if (event->event == WM_MOUSEMOVE) {
1020 // Snag a reference to the current cursor ASAP in case the plugin modified 1032 // Snag a reference to the current cursor ASAP in case the plugin modified
1021 // it. There is a nasty race condition here with the multiprocess browser 1033 // it. There is a nasty race condition here with the multiprocess browser
1022 // as someone might be setting the cursor in the main process as well. 1034 // as someone might be setting the cursor in the main process as well.
1023 *cursor = current_windowless_cursor_; 1035 *cursor = current_windowless_cursor_;
1024 } 1036 }
1025 1037
1026 if (pop_user_gesture) { 1038 if (pop_user_gesture) {
1027 instance()->PopPopupsEnabledState(); 1039 instance()->PopPopupsEnabledState();
1028 } 1040 }
1029 1041
1030 handle_event_depth_--; 1042 handle_event_depth_--;
1031 1043
1032 current_plugin_instance_ = NULL; 1044 g_current_plugin_instance = NULL;
1033 1045
1034 MessageLoop::current()->SetNestableTasksAllowed(old_task_reentrancy_state); 1046 MessageLoop::current()->SetNestableTasksAllowed(old_task_reentrancy_state);
1035 1047
1036 if (handle_event_message_filter_hook_) { 1048 if (handle_event_message_filter_hook_) {
1037 UnhookWindowsHookEx(handle_event_message_filter_hook_); 1049 UnhookWindowsHookEx(handle_event_message_filter_hook_);
1038 handle_event_message_filter_hook_ = NULL; 1050 handle_event_message_filter_hook_ = NULL;
1039 } 1051 }
1040 1052
1041 // We could have multiple NPP_HandleEvent calls nested together in case 1053 // We could have multiple NPP_HandleEvent calls nested together in case
1042 // the plugin enters a modal loop. Reset the pump messages event when 1054 // the plugin enters a modal loop. Reset the pump messages event when
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1118 } 1130 }
1119 1131
1120 void WebPluginDelegateImpl::OnUserGestureEnd() { 1132 void WebPluginDelegateImpl::OnUserGestureEnd() {
1121 user_gesture_message_posted_ = false; 1133 user_gesture_message_posted_ = false;
1122 instance()->PopPopupsEnabledState(); 1134 instance()->PopPopupsEnabledState();
1123 } 1135 }
1124 1136
1125 BOOL WINAPI WebPluginDelegateImpl::TrackPopupMenuPatch( 1137 BOOL WINAPI WebPluginDelegateImpl::TrackPopupMenuPatch(
1126 HMENU menu, unsigned int flags, int x, int y, int reserved, 1138 HMENU menu, unsigned int flags, int x, int y, int reserved,
1127 HWND window, const RECT* rect) { 1139 HWND window, const RECT* rect) {
1128 if (current_plugin_instance_) { 1140 if (g_current_plugin_instance) {
1129 unsigned long window_process_id = 0; 1141 unsigned long window_process_id = 0;
1130 unsigned long window_thread_id = 1142 unsigned long window_thread_id =
1131 GetWindowThreadProcessId(window, &window_process_id); 1143 GetWindowThreadProcessId(window, &window_process_id);
1132 // TrackPopupMenu fails if the window passed in belongs to a different 1144 // TrackPopupMenu fails if the window passed in belongs to a different
1133 // thread. 1145 // thread.
1134 if (::GetCurrentThreadId() != window_thread_id) { 1146 if (::GetCurrentThreadId() != window_thread_id) {
1135 window = current_plugin_instance_->dummy_window_for_activation_; 1147 window = g_current_plugin_instance->dummy_window_for_activation_;
1136 } 1148 }
1137 } 1149 }
1138 return TrackPopupMenu(menu, flags, x, y, reserved, window, rect); 1150 return TrackPopupMenu(menu, flags, x, y, reserved, window, rect);
1139 } 1151 }
1140 1152
1141 HCURSOR WINAPI WebPluginDelegateImpl::SetCursorPatch(HCURSOR cursor) { 1153 HCURSOR WINAPI WebPluginDelegateImpl::SetCursorPatch(HCURSOR cursor) {
1142 // The windowless flash plugin periodically calls SetCursor in a wndproc 1154 // The windowless flash plugin periodically calls SetCursor in a wndproc
1143 // instantiated on the plugin thread. This causes annoying cursor flicker 1155 // instantiated on the plugin thread. This causes annoying cursor flicker
1144 // when the mouse is moved on a foreground tab, with a windowless plugin 1156 // when the mouse is moved on a foreground tab, with a windowless plugin
1145 // instance in a background tab. We just ignore the call here. 1157 // instance in a background tab. We just ignore the call here.
1146 if (!current_plugin_instance_) 1158 if (!g_current_plugin_instance)
1147 return GetCursor(); 1159 return GetCursor();
1148 1160
1149 if (!current_plugin_instance_->windowless()) { 1161 if (!g_current_plugin_instance->windowless()) {
1150 return SetCursor(cursor); 1162 return SetCursor(cursor);
1151 } 1163 }
1152 1164
1153 // It is ok to pass NULL here to GetCursor as we are not looking for cursor 1165 // It is ok to pass NULL here to GetCursor as we are not looking for cursor
1154 // types defined by Webkit. 1166 // types defined by Webkit.
1155 HCURSOR previous_cursor = 1167 HCURSOR previous_cursor =
1156 current_plugin_instance_->current_windowless_cursor_.GetCursor(NULL); 1168 g_current_plugin_instance->current_windowless_cursor_.GetCursor(NULL);
1157 1169
1158 current_plugin_instance_->current_windowless_cursor_.InitFromExternalCursor( 1170 g_current_plugin_instance->current_windowless_cursor_.InitFromExternalCursor(
1159 cursor); 1171 cursor);
1160 return previous_cursor; 1172 return previous_cursor;
1161 } 1173 }
OLDNEW
« no previous file with comments | « webkit/glue/plugins/webplugin_delegate_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698