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

Unified Diff: win8/metro_driver/ime/keyevent_filter.cc

Issue 53553003: WIP: Ash IME support (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 7 years, 1 month 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « win8/metro_driver/ime/keyevent_filter.h ('k') | win8/metro_driver/ime/language_profile_monitor.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: win8/metro_driver/ime/keyevent_filter.cc
diff --git a/win8/metro_driver/ime/keyevent_filter.cc b/win8/metro_driver/ime/keyevent_filter.cc
new file mode 100644
index 0000000000000000000000000000000000000000..7b974800ba689139073690c773cea9c69aee44a3
--- /dev/null
+++ b/win8/metro_driver/ime/keyevent_filter.cc
@@ -0,0 +1,80 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "win8/metro_driver/ime/keyevent_filter.h"
+
+#include <Windows.h>
+#include <msctf.h>
+
+#include "base/win/scoped_comptr.h"
+
+namespace metro_driver {
+namespace {
+
+ITfKeystrokeMgr* g_keystroke_manager = NULL;
+HHOOK g_hook = NULL;
+
+LRESULT CALLBACK GetMsgProc(int code, WPARAM wparam, LPARAM lparam) {
+ MSG* msg = reinterpret_cast<MSG*>(lparam);
+ if (code >= 0 && (wparam & PM_REMOVE) == PM_REMOVE &&
+ (msg->message == WM_KEYDOWN || msg->message == WM_KEYUP)) {
+ HRESULT hr = S_OK;
+ BOOL eaten = FALSE;
+ if (msg->message == WM_KEYDOWN)
+ hr = g_keystroke_manager->KeyDown(msg->wParam, msg->lParam, &eaten);
+ else
+ hr = g_keystroke_manager->KeyUp(msg->wParam, msg->lParam, &eaten);
+
+ // Emulate IMM32. Any key event that is eaten by an IME will be replaced
+ // with a key event whose virtual key code is VK_PROCESSKEY.
+ if (SUCCEEDED(hr) && !!eaten)
+ msg->wParam = VK_PROCESSKEY;
+ }
+ return CallNextHookEx(g_hook, code, wparam, lparam);
+}
+
+} // namespace
+
+bool InstallKeyEventFilter() {
+ base::win::ScopedComPtr<ITfThreadMgr2> thread_manager;
+ if (FAILED(thread_manager.CreateInstance(CLSID_TF_ThreadMgr)))
+ return false;
+ base::win::ScopedComPtr<ITfKeystrokeMgr> keystroke_manager;
+ if (FAILED(keystroke_manager.QueryFrom(thread_manager)))
+ return false;
+ base::win::ScopedComPtr<ITfConfigureSystemKeystrokeFeed> feed;
+ if (FAILED(feed.QueryFrom(thread_manager)))
+ return false;
+
+ // Here we replace CUAS's message hook with our own message hook so that
+ // ITfKeystrokeMgr::KeyDown/KeyUp can be called only once per key event.
+
+ // Disables CUAS's own message hook.
+ if (FAILED(feed->DisableSystemKeystrokeFeed()))
+ return false;
+ g_keystroke_manager = keystroke_manager.Detach();
+
+ // Installs our own message hook.
+ g_hook = ::SetWindowsHookExW(
+ WH_GETMESSAGE, GetMsgProc, NULL, GetCurrentThreadId());
+ if (g_hook == NULL) {
+ g_keystroke_manager->Release();
+ g_keystroke_manager = NULL;
+ return false;
+ }
+ return true;
+}
+
+void UninstallKeyEventFilter() {
+ if (g_hook) {
+ UnhookWindowsHookEx(g_hook);
+ g_hook = NULL;
+ }
+ if (g_keystroke_manager) {
+ g_keystroke_manager->Release();
+ g_keystroke_manager = NULL;
+ }
+}
+
+} // namespace metro_driver
« no previous file with comments | « win8/metro_driver/ime/keyevent_filter.h ('k') | win8/metro_driver/ime/language_profile_monitor.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698