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

Side by Side Diff: webkit/plugins/npapi/webplugin_delegate_impl_win.cc

Issue 7529041: Maintain key state in the plugin delegate if UIPI is enabled. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 4 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 | Annotate | Revision Log
« 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/plugins/npapi/webplugin_delegate_impl.h" 5 #include "webkit/plugins/npapi/webplugin_delegate_impl.h"
6 6
7 #include <map> 7 #include <map>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 base::LINKER_INITIALIZED); 79 base::LINKER_INITIALIZED);
80 80
81 // Helper object for patching the SetCursor API. 81 // Helper object for patching the SetCursor API.
82 base::LazyInstance<base::win::IATPatchFunction> g_iat_patch_set_cursor( 82 base::LazyInstance<base::win::IATPatchFunction> g_iat_patch_set_cursor(
83 base::LINKER_INITIALIZED); 83 base::LINKER_INITIALIZED);
84 84
85 // Helper object for patching the RegEnumKeyExW API. 85 // Helper object for patching the RegEnumKeyExW API.
86 base::LazyInstance<base::win::IATPatchFunction> g_iat_patch_reg_enum_key_ex_w( 86 base::LazyInstance<base::win::IATPatchFunction> g_iat_patch_reg_enum_key_ex_w(
87 base::LINKER_INITIALIZED); 87 base::LINKER_INITIALIZED);
88 88
89 // Helper object for patching the GetKeyState API.
90 base::LazyInstance<base::win::IATPatchFunction> g_iat_patch_get_key_state(
91 base::LINKER_INITIALIZED);
92
93 // Saved key state globals and helper access functions.
94 SHORT (WINAPI *g_iat_orig_get_key_state)(int vkey);
95 typedef size_t SavedStateType;
96 const size_t kBitsPerType = sizeof(SavedStateType) * 8;
97 // Bit array of key state corresponding to virtual key index (0=up, 1=down).
98 SavedStateType g_saved_key_state[256 / kBitsPerType];
99
100 bool GetSavedKeyState(WPARAM vkey) {
101 CHECK_LT(vkey, kBitsPerType * sizeof(g_saved_key_state));
102 if (g_saved_key_state[vkey / kBitsPerType] & 1 << (vkey % kBitsPerType))
103 return true;
104 return false;
105 }
106
107 void SetSavedKeyState(WPARAM vkey) {
108 CHECK_LT(vkey, kBitsPerType * sizeof(g_saved_key_state));
109 g_saved_key_state[vkey / kBitsPerType] |= 1 << (vkey % kBitsPerType);
110 }
111
112 void UnsetSavedKeyState(WPARAM vkey) {
113 CHECK_LT(vkey, kBitsPerType * sizeof(g_saved_key_state));
114 g_saved_key_state[vkey / kBitsPerType] &= ~(1 << (vkey % kBitsPerType));
115 }
116
117 void ClearSavedKeyState() {
118 memset(g_saved_key_state, 0, sizeof(g_saved_key_state));
119 }
120
121
89 // http://crbug.com/16114 122 // http://crbug.com/16114
90 // Enforces providing a valid device context in NPWindow, so that NPP_SetWindow 123 // Enforces providing a valid device context in NPWindow, so that NPP_SetWindow
91 // is never called with NPNWindoTypeDrawable and NPWindow set to NULL. 124 // is never called with NPNWindoTypeDrawable and NPWindow set to NULL.
92 // Doing so allows removing NPP_SetWindow call during painting a windowless 125 // Doing so allows removing NPP_SetWindow call during painting a windowless
93 // plugin, which otherwise could trigger layout change while painting by 126 // plugin, which otherwise could trigger layout change while painting by
94 // invoking NPN_Evaluate. Which would cause bad, bad crashes. Bad crashes. 127 // invoking NPN_Evaluate. Which would cause bad, bad crashes. Bad crashes.
95 // TODO(dglazkov): If this approach doesn't produce regressions, move class to 128 // TODO(dglazkov): If this approach doesn't produce regressions, move class to
96 // webplugin_delegate_impl.h and implement for other platforms. 129 // webplugin_delegate_impl.h and implement for other platforms.
97 class DrawableContextEnforcer { 130 class DrawableContextEnforcer {
98 public: 131 public:
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 int code, WPARAM wParam, LPARAM lParam) { 283 int code, WPARAM wParam, LPARAM lParam) {
251 if (code == HC_ACTION) { 284 if (code == HC_ACTION) {
252 MOUSEHOOKSTRUCT* hook_struct = reinterpret_cast<MOUSEHOOKSTRUCT*>(lParam); 285 MOUSEHOOKSTRUCT* hook_struct = reinterpret_cast<MOUSEHOOKSTRUCT*>(lParam);
253 if (hook_struct) 286 if (hook_struct)
254 HandleCaptureForMessage(hook_struct->hwnd, wParam); 287 HandleCaptureForMessage(hook_struct->hwnd, wParam);
255 } 288 }
256 289
257 return CallNextHookEx(NULL, code, wParam, lParam); 290 return CallNextHookEx(NULL, code, wParam, lParam);
258 } 291 }
259 292
293 // In addition to the key state we maintain, we also mask in the original
294 // return value. This is done because system keys (e.g. tab, enter, shift)
295 // and toggles (e.g. capslock, numlock) don't ever seem to be blocked.
296 SHORT WINAPI WebPluginDelegateImpl::GetKeyStatePatch(int vkey) {
297 if (GetSavedKeyState(vkey))
298 return g_iat_orig_get_key_state(vkey) | 0x8000;
299 return g_iat_orig_get_key_state(vkey);
300 }
301
260 WebPluginDelegateImpl::WebPluginDelegateImpl( 302 WebPluginDelegateImpl::WebPluginDelegateImpl(
261 gfx::PluginWindowHandle containing_view, 303 gfx::PluginWindowHandle containing_view,
262 PluginInstance *instance) 304 PluginInstance *instance)
263 : parent_(containing_view), 305 : parent_(containing_view),
264 instance_(instance), 306 instance_(instance),
265 quirks_(0), 307 quirks_(0),
266 plugin_(NULL), 308 plugin_(NULL),
267 windowless_(false), 309 windowless_(false),
268 windowed_handle_(NULL), 310 windowed_handle_(NULL),
269 windowed_did_set_window_(false), 311 windowed_did_set_window_(false),
(...skipping 22 matching lines...) Expand all
292 334
293 if (instance_->mime_type() == "application/x-shockwave-flash" || 335 if (instance_->mime_type() == "application/x-shockwave-flash" ||
294 filename == kFlashPlugin) { 336 filename == kFlashPlugin) {
295 // Flash only requests windowless plugins if we return a Mozilla user 337 // Flash only requests windowless plugins if we return a Mozilla user
296 // agent. 338 // agent.
297 instance_->set_use_mozilla_user_agent(); 339 instance_->set_use_mozilla_user_agent();
298 quirks_ |= PLUGIN_QUIRK_THROTTLE_WM_USER_PLUS_ONE; 340 quirks_ |= PLUGIN_QUIRK_THROTTLE_WM_USER_PLUS_ONE;
299 quirks_ |= PLUGIN_QUIRK_PATCH_SETCURSOR; 341 quirks_ |= PLUGIN_QUIRK_PATCH_SETCURSOR;
300 quirks_ |= PLUGIN_QUIRK_ALWAYS_NOTIFY_SUCCESS; 342 quirks_ |= PLUGIN_QUIRK_ALWAYS_NOTIFY_SUCCESS;
301 quirks_ |= PLUGIN_QUIRK_HANDLE_MOUSE_CAPTURE; 343 quirks_ |= PLUGIN_QUIRK_HANDLE_MOUSE_CAPTURE;
302 if (filename == kBuiltinFlashPlugin) 344 if (filename == kBuiltinFlashPlugin &&
303 quirks_ |= PLUGIN_QUIRK_REPARENT_IN_BROWSER; 345 base::win::GetVersion() >= base::win::VERSION_VISTA) {
346 quirks_ |= PLUGIN_QUIRK_REPARENT_IN_BROWSER |
347 PLUGIN_QUIRK_PATCH_GETKEYSTATE;
348 }
304 } else if (filename == kAcrobatReaderPlugin) { 349 } else if (filename == kAcrobatReaderPlugin) {
305 // Check for the version number above or equal 9. 350 // Check for the version number above or equal 9.
306 int major_version = GetPluginMajorVersion(plugin_info); 351 int major_version = GetPluginMajorVersion(plugin_info);
307 if (major_version >= 9) { 352 if (major_version >= 9) {
308 quirks_ |= PLUGIN_QUIRK_DIE_AFTER_UNLOAD; 353 quirks_ |= PLUGIN_QUIRK_DIE_AFTER_UNLOAD;
309 // 9.2 needs this. 354 // 9.2 needs this.
310 quirks_ |= PLUGIN_QUIRK_SETWINDOW_TWICE; 355 quirks_ |= PLUGIN_QUIRK_SETWINDOW_TWICE;
311 } 356 }
312 quirks_ |= PLUGIN_QUIRK_BLOCK_NONSTANDARD_GETURL_REQUESTS; 357 quirks_ |= PLUGIN_QUIRK_BLOCK_NONSTANDARD_GETURL_REQUESTS;
313 } else if (plugin_info.name.find(L"Windows Media Player") != 358 } else if (plugin_info.name.find(L"Windows Media Player") !=
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 base::win::GetVersion() == base::win::VERSION_XP && 479 base::win::GetVersion() == base::win::VERSION_XP &&
435 (base::win::RegKey().Open(HKEY_LOCAL_MACHINE, 480 (base::win::RegKey().Open(HKEY_LOCAL_MACHINE,
436 L"SOFTWARE\\Microsoft\\MediaPlayer\\ShimInclusionList\\chrome.exe", 481 L"SOFTWARE\\Microsoft\\MediaPlayer\\ShimInclusionList\\chrome.exe",
437 KEY_READ) != ERROR_SUCCESS) && 482 KEY_READ) != ERROR_SUCCESS) &&
438 !g_iat_patch_reg_enum_key_ex_w.Pointer()->is_patched()) { 483 !g_iat_patch_reg_enum_key_ex_w.Pointer()->is_patched()) {
439 g_iat_patch_reg_enum_key_ex_w.Pointer()->Patch( 484 g_iat_patch_reg_enum_key_ex_w.Pointer()->Patch(
440 L"wmpdxm.dll", "advapi32.dll", "RegEnumKeyExW", 485 L"wmpdxm.dll", "advapi32.dll", "RegEnumKeyExW",
441 WebPluginDelegateImpl::RegEnumKeyExWPatch); 486 WebPluginDelegateImpl::RegEnumKeyExWPatch);
442 } 487 }
443 488
489 // Under UIPI the key state does not get forwarded properly to the child
490 // plugin window. So, instead we track the key state manually and intercept
491 // GetKeyState.
492 if ((quirks_ & PLUGIN_QUIRK_PATCH_GETKEYSTATE) &&
493 !g_iat_patch_get_key_state.Pointer()->is_patched()) {
494 g_iat_orig_get_key_state = ::GetKeyState;
495 g_iat_patch_get_key_state.Pointer()->Patch(
496 L"gcswf32.dll", "user32.dll", "GetKeyState",
497 WebPluginDelegateImpl::GetKeyStatePatch);
498 }
499
444 return true; 500 return true;
445 } 501 }
446 502
447 void WebPluginDelegateImpl::PlatformDestroyInstance() { 503 void WebPluginDelegateImpl::PlatformDestroyInstance() {
448 if (!instance_->plugin_lib()) 504 if (!instance_->plugin_lib())
449 return; 505 return;
450 506
451 // Unpatch if this is the last plugin instance. 507 // Unpatch if this is the last plugin instance.
452 if (instance_->plugin_lib()->instance_count() != 1) 508 if (instance_->plugin_lib()->instance_count() != 1)
453 return; 509 return;
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after
934 // Flash may flood the message queue with WM_USER+1 message causing 100% CPU 990 // Flash may flood the message queue with WM_USER+1 message causing 100% CPU
935 // usage. See https://bugzilla.mozilla.org/show_bug.cgi?id=132759. We 991 // usage. See https://bugzilla.mozilla.org/show_bug.cgi?id=132759. We
936 // prevent this by throttling the messages. 992 // prevent this by throttling the messages.
937 if (message == WM_USER + 1 && 993 if (message == WM_USER + 1 &&
938 delegate->GetQuirks() & PLUGIN_QUIRK_THROTTLE_WM_USER_PLUS_ONE) { 994 delegate->GetQuirks() & PLUGIN_QUIRK_THROTTLE_WM_USER_PLUS_ONE) {
939 WebPluginDelegateImpl::ThrottleMessage(delegate->plugin_wnd_proc_, hwnd, 995 WebPluginDelegateImpl::ThrottleMessage(delegate->plugin_wnd_proc_, hwnd,
940 message, wparam, lparam); 996 message, wparam, lparam);
941 return FALSE; 997 return FALSE;
942 } 998 }
943 999
1000 // Track the keystate to work around a UIPI issue.
1001 if (delegate->GetQuirks() & PLUGIN_QUIRK_PATCH_GETKEYSTATE) {
1002 switch (message) {
1003 case WM_KEYDOWN:
1004 SetSavedKeyState(wparam);
1005 break;
1006
1007 case WM_KEYUP:
1008 UnsetSavedKeyState(wparam);
1009 break;
1010
1011 // Clear out the saved keystate whenever the Flash thread loses focus.
1012 case WM_KILLFOCUS:
1013 case WM_SETFOCUS:
1014 if (::GetCurrentThreadId() != ::GetWindowThreadProcessId(
1015 reinterpret_cast<HWND>(wparam), NULL)) {
1016 ClearSavedKeyState();
1017 }
1018 break;
1019
1020 default:
1021 break;
1022 }
1023 }
1024
944 LRESULT result; 1025 LRESULT result;
945 uint32 old_message = delegate->last_message_; 1026 uint32 old_message = delegate->last_message_;
946 delegate->last_message_ = message; 1027 delegate->last_message_ = message;
947 1028
948 static UINT custom_msg = RegisterWindowMessage(kPaintMessageName); 1029 static UINT custom_msg = RegisterWindowMessage(kPaintMessageName);
949 if (message == custom_msg) { 1030 if (message == custom_msg) {
950 // Get the invalid rect which is in screen coordinates and convert to 1031 // Get the invalid rect which is in screen coordinates and convert to
951 // window coordinates. 1032 // window coordinates.
952 gfx::Rect invalid_rect; 1033 gfx::Rect invalid_rect;
953 invalid_rect.set_x(wparam >> 16); 1034 invalid_rect.set_x(wparam >> 16);
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after
1432 ::ReleaseCapture(); 1513 ::ReleaseCapture();
1433 break; 1514 break;
1434 1515
1435 default: 1516 default:
1436 break; 1517 break;
1437 } 1518 }
1438 } 1519 }
1439 1520
1440 } // namespace npapi 1521 } // namespace npapi
1441 } // namespace webkit 1522 } // 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