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

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 void SetSavedKeyState(WPARAM vkey) {
101 g_saved_key_state[vkey / kBitsPerType] |= 1 << (vkey % kBitsPerType);
102 }
103
104 void UnsetSavedKeyState(WPARAM vkey) {
105 g_saved_key_state[vkey / kBitsPerType] &= ~(1 << (vkey % kBitsPerType));
106 }
107
108 void ClearSavedKeyState() {
109 ::ZeroMemory(g_saved_key_state, sizeof(g_saved_key_state));
110 }
cpu_(ooo_6.6-7.5) 2011/08/09 20:07:31 zeromemory is just a macro to memset
jschuh 2011/08/09 20:57:27 I know. It's just a habit I have, but I'm happy to
111
112
89 // http://crbug.com/16114 113 // http://crbug.com/16114
90 // Enforces providing a valid device context in NPWindow, so that NPP_SetWindow 114 // Enforces providing a valid device context in NPWindow, so that NPP_SetWindow
91 // is never called with NPNWindoTypeDrawable and NPWindow set to NULL. 115 // is never called with NPNWindoTypeDrawable and NPWindow set to NULL.
92 // Doing so allows removing NPP_SetWindow call during painting a windowless 116 // Doing so allows removing NPP_SetWindow call during painting a windowless
93 // plugin, which otherwise could trigger layout change while painting by 117 // plugin, which otherwise could trigger layout change while painting by
94 // invoking NPN_Evaluate. Which would cause bad, bad crashes. Bad crashes. 118 // invoking NPN_Evaluate. Which would cause bad, bad crashes. Bad crashes.
95 // TODO(dglazkov): If this approach doesn't produce regressions, move class to 119 // TODO(dglazkov): If this approach doesn't produce regressions, move class to
96 // webplugin_delegate_impl.h and implement for other platforms. 120 // webplugin_delegate_impl.h and implement for other platforms.
97 class DrawableContextEnforcer { 121 class DrawableContextEnforcer {
98 public: 122 public:
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 int code, WPARAM wParam, LPARAM lParam) { 274 int code, WPARAM wParam, LPARAM lParam) {
251 if (code == HC_ACTION) { 275 if (code == HC_ACTION) {
252 MOUSEHOOKSTRUCT* hook_struct = reinterpret_cast<MOUSEHOOKSTRUCT*>(lParam); 276 MOUSEHOOKSTRUCT* hook_struct = reinterpret_cast<MOUSEHOOKSTRUCT*>(lParam);
253 if (hook_struct) 277 if (hook_struct)
254 HandleCaptureForMessage(hook_struct->hwnd, wParam); 278 HandleCaptureForMessage(hook_struct->hwnd, wParam);
255 } 279 }
256 280
257 return CallNextHookEx(NULL, code, wParam, lParam); 281 return CallNextHookEx(NULL, code, wParam, lParam);
258 } 282 }
259 283
284 // In addition to the key state we maintain, we also mask in the original
285 // return value. This is done because system keys (e.g. tab, enter, shift)
286 // and toggles (e.g. capslock, numlock) don't ever seem to be blocked.
287 SHORT WINAPI WebPluginDelegateImpl::GetKeyStatePatch(int vkey) {
288 if (g_saved_key_state[vkey / kBitsPerType] & 1 << (vkey % kBitsPerType))
289 return 0x8000 | g_iat_orig_get_key_state(vkey);
290 return g_iat_orig_get_key_state(vkey);
291 }
292
260 WebPluginDelegateImpl::WebPluginDelegateImpl( 293 WebPluginDelegateImpl::WebPluginDelegateImpl(
261 gfx::PluginWindowHandle containing_view, 294 gfx::PluginWindowHandle containing_view,
262 PluginInstance *instance) 295 PluginInstance *instance)
263 : parent_(containing_view), 296 : parent_(containing_view),
264 instance_(instance), 297 instance_(instance),
265 quirks_(0), 298 quirks_(0),
266 plugin_(NULL), 299 plugin_(NULL),
267 windowless_(false), 300 windowless_(false),
268 windowed_handle_(NULL), 301 windowed_handle_(NULL),
269 windowed_did_set_window_(false), 302 windowed_did_set_window_(false),
(...skipping 22 matching lines...) Expand all
292 325
293 if (instance_->mime_type() == "application/x-shockwave-flash" || 326 if (instance_->mime_type() == "application/x-shockwave-flash" ||
294 filename == kFlashPlugin) { 327 filename == kFlashPlugin) {
295 // Flash only requests windowless plugins if we return a Mozilla user 328 // Flash only requests windowless plugins if we return a Mozilla user
296 // agent. 329 // agent.
297 instance_->set_use_mozilla_user_agent(); 330 instance_->set_use_mozilla_user_agent();
298 quirks_ |= PLUGIN_QUIRK_THROTTLE_WM_USER_PLUS_ONE; 331 quirks_ |= PLUGIN_QUIRK_THROTTLE_WM_USER_PLUS_ONE;
299 quirks_ |= PLUGIN_QUIRK_PATCH_SETCURSOR; 332 quirks_ |= PLUGIN_QUIRK_PATCH_SETCURSOR;
300 quirks_ |= PLUGIN_QUIRK_ALWAYS_NOTIFY_SUCCESS; 333 quirks_ |= PLUGIN_QUIRK_ALWAYS_NOTIFY_SUCCESS;
301 quirks_ |= PLUGIN_QUIRK_HANDLE_MOUSE_CAPTURE; 334 quirks_ |= PLUGIN_QUIRK_HANDLE_MOUSE_CAPTURE;
302 if (filename == kBuiltinFlashPlugin) 335 if (filename == kBuiltinFlashPlugin &&
303 quirks_ |= PLUGIN_QUIRK_REPARENT_IN_BROWSER; 336 base::win::GetVersion() >= base::win::VERSION_VISTA) {
337 quirks_ |= PLUGIN_QUIRK_REPARENT_IN_BROWSER |
338 PLUGIN_QUIRK_PATCH_GETKEYSTATE;
339 }
304 } else if (filename == kAcrobatReaderPlugin) { 340 } else if (filename == kAcrobatReaderPlugin) {
305 // Check for the version number above or equal 9. 341 // Check for the version number above or equal 9.
306 int major_version = GetPluginMajorVersion(plugin_info); 342 int major_version = GetPluginMajorVersion(plugin_info);
307 if (major_version >= 9) { 343 if (major_version >= 9) {
308 quirks_ |= PLUGIN_QUIRK_DIE_AFTER_UNLOAD; 344 quirks_ |= PLUGIN_QUIRK_DIE_AFTER_UNLOAD;
309 // 9.2 needs this. 345 // 9.2 needs this.
310 quirks_ |= PLUGIN_QUIRK_SETWINDOW_TWICE; 346 quirks_ |= PLUGIN_QUIRK_SETWINDOW_TWICE;
311 } 347 }
312 quirks_ |= PLUGIN_QUIRK_BLOCK_NONSTANDARD_GETURL_REQUESTS; 348 quirks_ |= PLUGIN_QUIRK_BLOCK_NONSTANDARD_GETURL_REQUESTS;
313 } else if (plugin_info.name.find(L"Windows Media Player") != 349 } 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 && 470 base::win::GetVersion() == base::win::VERSION_XP &&
435 (base::win::RegKey().Open(HKEY_LOCAL_MACHINE, 471 (base::win::RegKey().Open(HKEY_LOCAL_MACHINE,
436 L"SOFTWARE\\Microsoft\\MediaPlayer\\ShimInclusionList\\chrome.exe", 472 L"SOFTWARE\\Microsoft\\MediaPlayer\\ShimInclusionList\\chrome.exe",
437 KEY_READ) != ERROR_SUCCESS) && 473 KEY_READ) != ERROR_SUCCESS) &&
438 !g_iat_patch_reg_enum_key_ex_w.Pointer()->is_patched()) { 474 !g_iat_patch_reg_enum_key_ex_w.Pointer()->is_patched()) {
439 g_iat_patch_reg_enum_key_ex_w.Pointer()->Patch( 475 g_iat_patch_reg_enum_key_ex_w.Pointer()->Patch(
440 L"wmpdxm.dll", "advapi32.dll", "RegEnumKeyExW", 476 L"wmpdxm.dll", "advapi32.dll", "RegEnumKeyExW",
441 WebPluginDelegateImpl::RegEnumKeyExWPatch); 477 WebPluginDelegateImpl::RegEnumKeyExWPatch);
442 } 478 }
443 479
480 // Under UIPI the key state does not get forwarded properly to the child
481 // plugin window. So, instead we track the key state manually and intercept
482 // GetKeyState.
483 if ((quirks_ & PLUGIN_QUIRK_PATCH_GETKEYSTATE) &&
484 !g_iat_patch_get_key_state.Pointer()->is_patched()) {
485 g_iat_orig_get_key_state = ::GetKeyState;
486 g_iat_patch_get_key_state.Pointer()->Patch(
487 L"gcswf32.dll", "user32.dll", "GetKeyState",
488 WebPluginDelegateImpl::GetKeyStatePatch);
489 }
490
444 return true; 491 return true;
445 } 492 }
446 493
447 void WebPluginDelegateImpl::PlatformDestroyInstance() { 494 void WebPluginDelegateImpl::PlatformDestroyInstance() {
448 if (!instance_->plugin_lib()) 495 if (!instance_->plugin_lib())
449 return; 496 return;
450 497
451 // Unpatch if this is the last plugin instance. 498 // Unpatch if this is the last plugin instance.
452 if (instance_->plugin_lib()->instance_count() != 1) 499 if (instance_->plugin_lib()->instance_count() != 1)
453 return; 500 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 981 // 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 982 // usage. See https://bugzilla.mozilla.org/show_bug.cgi?id=132759. We
936 // prevent this by throttling the messages. 983 // prevent this by throttling the messages.
937 if (message == WM_USER + 1 && 984 if (message == WM_USER + 1 &&
938 delegate->GetQuirks() & PLUGIN_QUIRK_THROTTLE_WM_USER_PLUS_ONE) { 985 delegate->GetQuirks() & PLUGIN_QUIRK_THROTTLE_WM_USER_PLUS_ONE) {
939 WebPluginDelegateImpl::ThrottleMessage(delegate->plugin_wnd_proc_, hwnd, 986 WebPluginDelegateImpl::ThrottleMessage(delegate->plugin_wnd_proc_, hwnd,
940 message, wparam, lparam); 987 message, wparam, lparam);
941 return FALSE; 988 return FALSE;
942 } 989 }
943 990
991 // Track the keystate to work around a UIPI issue.
992 if (delegate->GetQuirks() & PLUGIN_QUIRK_PATCH_GETKEYSTATE) {
993 switch (message) {
994 case WM_KEYDOWN:
995 SetSavedKeyState(wparam);
cpu_(ooo_6.6-7.5) 2011/08/09 20:07:31 wparam % 256 Here or inside, your choice.
jschuh 2011/08/09 20:57:27 I assumed we shouldn't ever see a value larger tha
996 break;
997
998 case WM_KEYUP:
999 UnsetSavedKeyState(wparam);
1000 break;
1001
1002 // Clear out the saved keystate whenever the Flash thread loses focus.
1003 case WM_KILLFOCUS:
1004 case WM_SETFOCUS:
1005 if (::GetCurrentThreadId() != ::GetWindowThreadProcessId(
1006 reinterpret_cast<HWND>(wparam), NULL)) {
1007 ClearSavedKeyState();
1008 }
1009 break;
1010
1011 default:
1012 break;
1013 }
1014 }
1015
944 LRESULT result; 1016 LRESULT result;
945 uint32 old_message = delegate->last_message_; 1017 uint32 old_message = delegate->last_message_;
946 delegate->last_message_ = message; 1018 delegate->last_message_ = message;
947 1019
948 static UINT custom_msg = RegisterWindowMessage(kPaintMessageName); 1020 static UINT custom_msg = RegisterWindowMessage(kPaintMessageName);
949 if (message == custom_msg) { 1021 if (message == custom_msg) {
950 // Get the invalid rect which is in screen coordinates and convert to 1022 // Get the invalid rect which is in screen coordinates and convert to
951 // window coordinates. 1023 // window coordinates.
952 gfx::Rect invalid_rect; 1024 gfx::Rect invalid_rect;
953 invalid_rect.set_x(wparam >> 16); 1025 invalid_rect.set_x(wparam >> 16);
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after
1432 ::ReleaseCapture(); 1504 ::ReleaseCapture();
1433 break; 1505 break;
1434 1506
1435 default: 1507 default:
1436 break; 1508 break;
1437 } 1509 }
1438 } 1510 }
1439 1511
1440 } // namespace npapi 1512 } // namespace npapi
1441 } // namespace webkit 1513 } // 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