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

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