summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
authorjschuh@chromium.org <jschuh@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-09 20:58:07 +0000
committerjschuh@chromium.org <jschuh@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-09 20:58:07 +0000
commitd4a94c2a3e6650c96e71b70a2aa1d992b963b248 (patch)
treed547a3a2b3727eb398777a11d6db99cdf0a0bb9b /webkit
parentbaa90006985d456c64a8e34a229e96adfd3978d8 (diff)
downloadchromium_src-d4a94c2a3e6650c96e71b70a2aa1d992b963b248.zip
chromium_src-d4a94c2a3e6650c96e71b70a2aa1d992b963b248.tar.gz
chromium_src-d4a94c2a3e6650c96e71b70a2aa1d992b963b248.tar.bz2
Maintain key state in the plugin delegate if UIPI is enabled.
UIPI blocks keystate across process boundaries in certain situations. To be safe we maintain our own key state and intercept calls to GetKeyState. BUG=86895 TEST=Adobe has test coverage. Review URL: http://codereview.chromium.org/7529041 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@96069 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r--webkit/plugins/npapi/webplugin_delegate_impl.h4
-rw-r--r--webkit/plugins/npapi/webplugin_delegate_impl_win.cc85
2 files changed, 87 insertions, 2 deletions
diff --git a/webkit/plugins/npapi/webplugin_delegate_impl.h b/webkit/plugins/npapi/webplugin_delegate_impl.h
index 0b9359c..1eacc6f 100644
--- a/webkit/plugins/npapi/webplugin_delegate_impl.h
+++ b/webkit/plugins/npapi/webplugin_delegate_impl.h
@@ -78,6 +78,7 @@ class WebPluginDelegateImpl : public WebPluginDelegate {
PLUGIN_QUIRK_WINDOWLESS_NO_RIGHT_CLICK = 32768, // Linux
PLUGIN_QUIRK_IGNORE_FIRST_SETWINDOW_CALL = 65536, // Windows.
PLUGIN_QUIRK_REPARENT_IN_BROWSER = 131072, // Windows
+ PLUGIN_QUIRK_PATCH_GETKEYSTATE = 262144, // Windows
};
static WebPluginDelegateImpl* Create(const FilePath& filename,
@@ -375,6 +376,9 @@ class WebPluginDelegateImpl : public WebPluginDelegate {
// SetCursor interceptor for windowless plugins.
static HCURSOR WINAPI SetCursorPatch(HCURSOR cursor);
+ // GetKeyStatePatch interceptor for UIPI Flash plugin.
+ static SHORT WINAPI GetKeyStatePatch(int vkey);
+
// RegEnumKeyExW interceptor.
static LONG WINAPI RegEnumKeyExWPatch(
HKEY key, DWORD index, LPWSTR name, LPDWORD name_size, LPDWORD reserved,
diff --git a/webkit/plugins/npapi/webplugin_delegate_impl_win.cc b/webkit/plugins/npapi/webplugin_delegate_impl_win.cc
index c3f010b..2211f6c 100644
--- a/webkit/plugins/npapi/webplugin_delegate_impl_win.cc
+++ b/webkit/plugins/npapi/webplugin_delegate_impl_win.cc
@@ -86,6 +86,39 @@ base::LazyInstance<base::win::IATPatchFunction> g_iat_patch_set_cursor(
base::LazyInstance<base::win::IATPatchFunction> g_iat_patch_reg_enum_key_ex_w(
base::LINKER_INITIALIZED);
+// Helper object for patching the GetKeyState API.
+base::LazyInstance<base::win::IATPatchFunction> g_iat_patch_get_key_state(
+ base::LINKER_INITIALIZED);
+
+// Saved key state globals and helper access functions.
+SHORT (WINAPI *g_iat_orig_get_key_state)(int vkey);
+typedef size_t SavedStateType;
+const size_t kBitsPerType = sizeof(SavedStateType) * 8;
+// Bit array of key state corresponding to virtual key index (0=up, 1=down).
+SavedStateType g_saved_key_state[256 / kBitsPerType];
+
+bool GetSavedKeyState(WPARAM vkey) {
+ CHECK_LT(vkey, kBitsPerType * sizeof(g_saved_key_state));
+ if (g_saved_key_state[vkey / kBitsPerType] & 1 << (vkey % kBitsPerType))
+ return true;
+ return false;
+}
+
+void SetSavedKeyState(WPARAM vkey) {
+ CHECK_LT(vkey, kBitsPerType * sizeof(g_saved_key_state));
+ g_saved_key_state[vkey / kBitsPerType] |= 1 << (vkey % kBitsPerType);
+}
+
+void UnsetSavedKeyState(WPARAM vkey) {
+ CHECK_LT(vkey, kBitsPerType * sizeof(g_saved_key_state));
+ g_saved_key_state[vkey / kBitsPerType] &= ~(1 << (vkey % kBitsPerType));
+}
+
+void ClearSavedKeyState() {
+ memset(g_saved_key_state, 0, sizeof(g_saved_key_state));
+}
+
+
// http://crbug.com/16114
// Enforces providing a valid device context in NPWindow, so that NPP_SetWindow
// is never called with NPNWindoTypeDrawable and NPWindow set to NULL.
@@ -257,6 +290,15 @@ LRESULT CALLBACK WebPluginDelegateImpl::MouseHookProc(
return CallNextHookEx(NULL, code, wParam, lParam);
}
+// In addition to the key state we maintain, we also mask in the original
+// return value. This is done because system keys (e.g. tab, enter, shift)
+// and toggles (e.g. capslock, numlock) don't ever seem to be blocked.
+SHORT WINAPI WebPluginDelegateImpl::GetKeyStatePatch(int vkey) {
+ if (GetSavedKeyState(vkey))
+ return g_iat_orig_get_key_state(vkey) | 0x8000;
+ return g_iat_orig_get_key_state(vkey);
+}
+
WebPluginDelegateImpl::WebPluginDelegateImpl(
gfx::PluginWindowHandle containing_view,
PluginInstance *instance)
@@ -299,8 +341,11 @@ WebPluginDelegateImpl::WebPluginDelegateImpl(
quirks_ |= PLUGIN_QUIRK_PATCH_SETCURSOR;
quirks_ |= PLUGIN_QUIRK_ALWAYS_NOTIFY_SUCCESS;
quirks_ |= PLUGIN_QUIRK_HANDLE_MOUSE_CAPTURE;
- if (filename == kBuiltinFlashPlugin)
- quirks_ |= PLUGIN_QUIRK_REPARENT_IN_BROWSER;
+ if (filename == kBuiltinFlashPlugin &&
+ base::win::GetVersion() >= base::win::VERSION_VISTA) {
+ quirks_ |= PLUGIN_QUIRK_REPARENT_IN_BROWSER |
+ PLUGIN_QUIRK_PATCH_GETKEYSTATE;
+ }
} else if (filename == kAcrobatReaderPlugin) {
// Check for the version number above or equal 9.
int major_version = GetPluginMajorVersion(plugin_info);
@@ -441,6 +486,17 @@ bool WebPluginDelegateImpl::PlatformInitialize() {
WebPluginDelegateImpl::RegEnumKeyExWPatch);
}
+ // Under UIPI the key state does not get forwarded properly to the child
+ // plugin window. So, instead we track the key state manually and intercept
+ // GetKeyState.
+ if ((quirks_ & PLUGIN_QUIRK_PATCH_GETKEYSTATE) &&
+ !g_iat_patch_get_key_state.Pointer()->is_patched()) {
+ g_iat_orig_get_key_state = ::GetKeyState;
+ g_iat_patch_get_key_state.Pointer()->Patch(
+ L"gcswf32.dll", "user32.dll", "GetKeyState",
+ WebPluginDelegateImpl::GetKeyStatePatch);
+ }
+
return true;
}
@@ -941,6 +997,31 @@ LRESULT CALLBACK WebPluginDelegateImpl::NativeWndProc(
return FALSE;
}
+ // Track the keystate to work around a UIPI issue.
+ if (delegate->GetQuirks() & PLUGIN_QUIRK_PATCH_GETKEYSTATE) {
+ switch (message) {
+ case WM_KEYDOWN:
+ SetSavedKeyState(wparam);
+ break;
+
+ case WM_KEYUP:
+ UnsetSavedKeyState(wparam);
+ break;
+
+ // Clear out the saved keystate whenever the Flash thread loses focus.
+ case WM_KILLFOCUS:
+ case WM_SETFOCUS:
+ if (::GetCurrentThreadId() != ::GetWindowThreadProcessId(
+ reinterpret_cast<HWND>(wparam), NULL)) {
+ ClearSavedKeyState();
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
LRESULT result;
uint32 old_message = delegate->last_message_;
delegate->last_message_ = message;