OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "ui/base/ime/input_method_ibus.h" | 5 #include "ui/base/ime/input_method_ibus.h" |
6 | 6 |
7 #include <X11/X.h> | 7 #include <X11/X.h> |
8 #include <X11/Xlib.h> | 8 #include <X11/Xlib.h> |
9 #include <X11/Xutil.h> | 9 #include <X11/Xutil.h> |
10 #undef FocusIn | 10 #undef FocusIn |
11 #undef FocusOut | 11 #undef FocusOut |
12 | 12 |
13 #include <algorithm> | 13 #include <algorithm> |
14 #include <cstring> | 14 #include <cstring> |
15 #include <set> | 15 #include <set> |
16 #include <vector> | 16 #include <vector> |
17 | 17 |
18 #include "base/basictypes.h" | 18 #include "base/basictypes.h" |
19 #include "base/bind.h" | 19 #include "base/bind.h" |
20 #include "base/i18n/char_iterator.h" | 20 #include "base/i18n/char_iterator.h" |
21 #include "base/logging.h" | 21 #include "base/logging.h" |
22 #include "base/strings/string_util.h" | 22 #include "base/strings/string_util.h" |
23 #include "base/strings/utf_string_conversions.h" | 23 #include "base/strings/utf_string_conversions.h" |
24 #include "base/third_party/icu/icu_utf.h" | 24 #include "base/third_party/icu/icu_utf.h" |
25 #include "chromeos/dbus/ibus/ibus_text.h" | 25 #include "chromeos/dbus/ibus/ibus_text.h" |
| 26 #include "chromeos/ime/ibus_keymap.h" |
26 #include "chromeos/ime/input_method_descriptor.h" | 27 #include "chromeos/ime/input_method_descriptor.h" |
27 #include "chromeos/ime/input_method_manager.h" | 28 #include "chromeos/ime/input_method_manager.h" |
28 #include "ui/base/ime/text_input_client.h" | 29 #include "ui/base/ime/text_input_client.h" |
29 #include "ui/events/event.h" | 30 #include "ui/events/event.h" |
30 #include "ui/events/event_constants.h" | 31 #include "ui/events/event_constants.h" |
31 #include "ui/events/event_utils.h" | 32 #include "ui/events/event_utils.h" |
32 #include "ui/events/keycodes/keyboard_code_conversion.h" | 33 #include "ui/events/keycodes/keyboard_code_conversion.h" |
33 #include "ui/events/keycodes/keyboard_code_conversion_x.h" | 34 #include "ui/events/keycodes/keyboard_code_conversion_x.h" |
34 #include "ui/events/keycodes/keyboard_codes.h" | 35 #include "ui/events/keycodes/keyboard_codes.h" |
35 #include "ui/gfx/rect.h" | 36 #include "ui/gfx/rect.h" |
36 | 37 |
37 namespace { | 38 namespace { |
38 | 39 |
39 const int kIBusReleaseMask = 1 << 30; | 40 const int kIBusReleaseMask = 1 << 30; |
40 | 41 |
41 XKeyEvent* GetKeyEvent(XEvent* event) { | 42 void IBusKeyEventFromKeyEvent(const ui::KeyEvent& event, |
42 DCHECK(event && (event->type == KeyPress || event->type == KeyRelease)); | 43 uint32* ibus_keyval, |
43 return &event->xkey; | 44 uint32* ibus_keycode) { |
| 45 DCHECK(event.type() == ui::ET_KEY_PRESSED || |
| 46 event.type() == ui::ET_KEY_RELEASED); |
| 47 if (event.HasNativeEvent()) { |
| 48 XKeyEvent* x_key = &(event.native_event()->xkey); |
| 49 |
| 50 // Yes, ibus uses X11 keysym. We cannot use XLookupKeysym(), which |
| 51 // doesn't translate Shift and CapsLock states. |
| 52 KeySym keysym = NoSymbol; |
| 53 ::XLookupString(x_key, NULL, 0, &keysym, NULL); |
| 54 *ibus_keyval = keysym; |
| 55 *ibus_keycode = x_key->keycode; |
| 56 } else { |
| 57 // TODO(komatsu): Fill the correct values. |
| 58 } |
44 } | 59 } |
45 | 60 |
46 // Converts X (and ibus) state to event flags. | 61 // Converts X (and ibus) state to event flags. |
47 int EventFlagsFromXState(unsigned int state) { | 62 int EventFlagsFromXState(unsigned int state) { |
48 return (state & LockMask ? ui::EF_CAPS_LOCK_DOWN : 0) | | 63 return (state & LockMask ? ui::EF_CAPS_LOCK_DOWN : 0) | |
49 (state & ControlMask ? ui::EF_CONTROL_DOWN : 0) | | 64 (state & ControlMask ? ui::EF_CONTROL_DOWN : 0) | |
50 (state & ShiftMask ? ui::EF_SHIFT_DOWN : 0) | | 65 (state & ShiftMask ? ui::EF_SHIFT_DOWN : 0) | |
51 (state & Mod1Mask ? ui::EF_ALT_DOWN : 0) | | 66 (state & Mod1Mask ? ui::EF_ALT_DOWN : 0) | |
52 (state & Button1Mask ? ui::EF_LEFT_MOUSE_BUTTON : 0) | | 67 (state & Button1Mask ? ui::EF_LEFT_MOUSE_BUTTON : 0) | |
53 (state & Button2Mask ? ui::EF_MIDDLE_MOUSE_BUTTON : 0) | | 68 (state & Button2Mask ? ui::EF_MIDDLE_MOUSE_BUTTON : 0) | |
54 (state & Button3Mask ? ui::EF_RIGHT_MOUSE_BUTTON : 0); | 69 (state & Button3Mask ? ui::EF_RIGHT_MOUSE_BUTTON : 0); |
55 } | 70 } |
56 | 71 |
57 // Converts X state to ibus key and button state. | |
58 uint32 IBusStateFromXState(unsigned int state) { | |
59 return (state & (LockMask | ControlMask | ShiftMask | Mod1Mask | | |
60 Button1Mask | Button2Mask | Button3Mask)); | |
61 } | |
62 | |
63 // Converts gfx::Rect to ibus::Rect. | 72 // Converts gfx::Rect to ibus::Rect. |
64 chromeos::ibus::Rect GfxRectToIBusRect(const gfx::Rect& rect) { | 73 chromeos::ibus::Rect GfxRectToIBusRect(const gfx::Rect& rect) { |
65 return chromeos::ibus::Rect(rect.x(), rect.y(), rect.width(), rect.height()); | 74 return chromeos::ibus::Rect(rect.x(), rect.y(), rect.width(), rect.height()); |
66 } | 75 } |
67 | 76 |
68 chromeos::IBusEngineHandlerInterface* GetEngine() { | 77 chromeos::IBusEngineHandlerInterface* GetEngine() { |
69 return chromeos::IBusBridge::Get()->GetEngineHandler(); | 78 return chromeos::IBusBridge::Get()->GetEngineHandler(); |
70 } | 79 } |
71 | 80 |
72 // Check ui::TextInputType and chrome::ibus::TextInputType is kept in sync. | 81 // Check ui::TextInputType and chrome::ibus::TextInputType is kept in sync. |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 mismatching_enums); | 122 mismatching_enums); |
114 | 123 |
115 chromeos::ibus::TextInputType UiToIbusTextInputType(ui::TextInputType type) { | 124 chromeos::ibus::TextInputType UiToIbusTextInputType(ui::TextInputType type) { |
116 // Check the type is in the range representable by | 125 // Check the type is in the range representable by |
117 // chrome::ibus::TextInputType. | 126 // chrome::ibus::TextInputType. |
118 DCHECK_LE(type, static_cast<int>(chromeos::ibus::TEXT_INPUT_TYPE_MAX)) << | 127 DCHECK_LE(type, static_cast<int>(chromeos::ibus::TEXT_INPUT_TYPE_MAX)) << |
119 "ui::TextInputType and chromeos::ibus::TextInputType not synchronized"; | 128 "ui::TextInputType and chromeos::ibus::TextInputType not synchronized"; |
120 return static_cast<chromeos::ibus::TextInputType>(type); | 129 return static_cast<chromeos::ibus::TextInputType>(type); |
121 } | 130 } |
122 | 131 |
| 132 std::string GetIBusKeyCodeFromKeyboardCode(ui::KeyboardCode keycode) { |
| 133 // See also: |
| 134 // src/chrome/test/remoting/key_code_map.h |
| 135 // src/chromeos/ime/ibus_keymap.cc |
| 136 switch (keycode) { |
| 137 case ui::VKEY_BACK: return "Backspace"; // 0x08 -> 0x16 |
| 138 case ui::VKEY_TAB: return "Tab"; // 0x09 -> 0x17 |
| 139 case ui::VKEY_BACKTAB: return ""; // 0x0A |
| 140 case ui::VKEY_CLEAR: return ""; // 0x0C |
| 141 case ui::VKEY_RETURN: return "Enter"; // 0x0D -> 0x24 |
| 142 case ui::VKEY_SHIFT: return "ShiftLeft"; // 0x10 -> 0x32 |
| 143 case ui::VKEY_CONTROL: return "ControlLeft"; // 0x11 -> 0x25 |
| 144 case ui::VKEY_MENU: return ""; // 0x12 |
| 145 case ui::VKEY_PAUSE: return "Pause"; // 0x13 -> 0x7F |
| 146 case ui::VKEY_CAPITAL: return "CapsLock"; // 0x14 -> 0x42 |
| 147 case ui::VKEY_KANA: return "KanaMode"; // 0x15 -> 0x65 |
| 148 // case ui::VKEY_HANGUL: return "HangulMode"; // 0x15 -> 0x82 |
| 149 /* |
| 150 case ui::VKEY_JUNJA: return "JUNJA"; // 0x17 |
| 151 case ui::VKEY_FINAL: return "FINAL"; // 0x18 |
| 152 case ui::VKEY_HANJA: return "HANJA"; // 0x19 |
| 153 case ui::VKEY_KANJI: return "KANJI"; // 0x19 |
| 154 case ui::VKEY_ESCAPE: return "ESCAPE"; // 0x1B |
| 155 case ui::VKEY_CONVERT: return "CONVERT"; // 0x1C |
| 156 case ui::VKEY_NONCONVERT: return "NONCONVERT"; // 0x1D |
| 157 case ui::VKEY_ACCEPT: return "ACCEPT"; // 0x1E |
| 158 case ui::VKEY_MODECHANGE: return "MODECHANGE"; // 0x1F |
| 159 */ |
| 160 case ui::VKEY_SPACE: return "Space"; // 0x20 -> 0x41 |
| 161 /* |
| 162 case ui::VKEY_PRIOR: return "PRIOR"; // 0x21 |
| 163 case ui::VKEY_NEXT: return "NEXT"; // 0x22 |
| 164 case ui::VKEY_END: return "END"; // 0x23 |
| 165 case ui::VKEY_HOME: return "HOME"; // 0x24 |
| 166 */ |
| 167 case ui::VKEY_LEFT: return "ArrowLeft"; // 0x25 -> 0x71 |
| 168 case ui::VKEY_UP: return "ArrowUp"; // 0x26 -> 0x6f |
| 169 case ui::VKEY_RIGHT: return "ArrowRight"; // 0x27 -> 0x72 |
| 170 case ui::VKEY_DOWN: return "ArrowDown"; // 0x28 -> 0x74 |
| 171 /* |
| 172 case ui::VKEY_SELECT: return "SELECT"; // 0x29 |
| 173 case ui::VKEY_PRINT: return "PRINT"; // 0x2A |
| 174 case ui::VKEY_EXECUTE: return "EXECUTE"; // 0x2B |
| 175 case ui::VKEY_SNAPSHOT: return "SNAPSHOT"; // 0x2C |
| 176 case ui::VKEY_INSERT: return "INSERT"; // 0x2D |
| 177 case ui::VKEY_DELETE: return "DELETE"; // 0x2E |
| 178 case ui::VKEY_HELP: return "HELP"; // 0x2F |
| 179 */ |
| 180 case ui::VKEY_0: return "Digit0"; // 0x30 |
| 181 case ui::VKEY_1: return "Digit1"; // 0x31 |
| 182 case ui::VKEY_2: return "Digit2"; // 0x32 |
| 183 case ui::VKEY_3: return "Digit3"; // 0x33 |
| 184 case ui::VKEY_4: return "Digit4"; // 0x34 |
| 185 case ui::VKEY_5: return "Digit5"; // 0x35 |
| 186 case ui::VKEY_6: return "Digit6"; // 0x36 |
| 187 case ui::VKEY_7: return "Digit7"; // 0x37 |
| 188 case ui::VKEY_8: return "Digit8"; // 0x38 |
| 189 case ui::VKEY_9: return "Digit9"; // 0x39 |
| 190 case ui::VKEY_A: return "KeyA"; // 0x41 |
| 191 case ui::VKEY_B: return "KeyB"; // 0x42 |
| 192 case ui::VKEY_C: return "KeyC"; // 0x43 |
| 193 case ui::VKEY_D: return "KeyD"; // 0x44 |
| 194 case ui::VKEY_E: return "KeyE"; // 0x45 |
| 195 case ui::VKEY_F: return "KeyF"; // 0x46 |
| 196 case ui::VKEY_G: return "KeyG"; // 0x47 |
| 197 case ui::VKEY_H: return "KeyH"; // 0x48 |
| 198 case ui::VKEY_I: return "KeyI"; // 0x49 |
| 199 case ui::VKEY_J: return "KeyJ"; // 0x4A |
| 200 case ui::VKEY_K: return "KeyK"; // 0x4B |
| 201 case ui::VKEY_L: return "KeyL"; // 0x4C |
| 202 case ui::VKEY_M: return "KeyM"; // 0x4D |
| 203 case ui::VKEY_N: return "KeyN"; // 0x4E |
| 204 case ui::VKEY_O: return "KeyO"; // 0x4F |
| 205 case ui::VKEY_P: return "KeyP"; // 0x50 |
| 206 case ui::VKEY_Q: return "KeyQ"; // 0x51 |
| 207 case ui::VKEY_R: return "KeyR"; // 0x52 |
| 208 case ui::VKEY_S: return "KeyS"; // 0x53 |
| 209 case ui::VKEY_T: return "KeyT"; // 0x54 |
| 210 case ui::VKEY_U: return "KeyU"; // 0x55 |
| 211 case ui::VKEY_V: return "KeyV"; // 0x56 |
| 212 case ui::VKEY_W: return "KeyW"; // 0x57 |
| 213 case ui::VKEY_X: return "KeyX"; // 0x58 |
| 214 case ui::VKEY_Y: return "KeyY"; // 0x59 |
| 215 case ui::VKEY_Z: return "KeyZ"; // 0x5A |
| 216 /* |
| 217 case ui::VKEY_LWIN: return "LWIN"; // 0x5B |
| 218 case ui::VKEY_COMMAND: return "COMMAND"; // VKEY_LWIN // Provide the Mac n
ame for convenience. |
| 219 case ui::VKEY_RWIN: return "RWIN"; // 0x5C |
| 220 case ui::VKEY_APPS: return "APPS"; // 0x5D |
| 221 case ui::VKEY_SLEEP: return "SLEEP"; // 0x5F |
| 222 case ui::VKEY_NUMPAD0: return "NUMPAD0"; // 0x60 |
| 223 case ui::VKEY_NUMPAD1: return "NUMPAD1"; // 0x61 |
| 224 case ui::VKEY_NUMPAD2: return "NUMPAD2"; // 0x62 |
| 225 case ui::VKEY_NUMPAD3: return "NUMPAD3"; // 0x63 |
| 226 case ui::VKEY_NUMPAD4: return "NUMPAD4"; // 0x64 |
| 227 case ui::VKEY_NUMPAD5: return "NUMPAD5"; // 0x65 |
| 228 case ui::VKEY_NUMPAD6: return "NUMPAD6"; // 0x66 |
| 229 case ui::VKEY_NUMPAD7: return "NUMPAD7"; // 0x67 |
| 230 case ui::VKEY_NUMPAD8: return "NUMPAD8"; // 0x68 |
| 231 case ui::VKEY_NUMPAD9: return "NUMPAD9"; // 0x69 |
| 232 case ui::VKEY_MULTIPLY: return "MULTIPLY"; // 0x6A |
| 233 case ui::VKEY_ADD: return "ADD"; // 0x6B |
| 234 case ui::VKEY_SEPARATOR: return "SEPARATOR"; // 0x6C |
| 235 case ui::VKEY_SUBTRACT: return "SUBTRACT"; // 0x6D |
| 236 case ui::VKEY_DECIMAL: return "DECIMAL"; // 0x6E |
| 237 case ui::VKEY_DIVIDE: return "DIVIDE"; // 0x6F |
| 238 */ |
| 239 case ui::VKEY_F1: return "F1"; // 0x70 |
| 240 case ui::VKEY_F2: return "F2"; // 0x71 |
| 241 case ui::VKEY_F3: return "F3"; // 0x72 |
| 242 case ui::VKEY_F4: return "F4"; // 0x73 |
| 243 case ui::VKEY_F5: return "F5"; // 0x74 |
| 244 case ui::VKEY_F6: return "F6"; // 0x75 |
| 245 case ui::VKEY_F7: return "F7"; // 0x76 |
| 246 case ui::VKEY_F8: return "F8"; // 0x77 |
| 247 case ui::VKEY_F9: return "F9"; // 0x78 |
| 248 case ui::VKEY_F10: return "F10"; // 0x79 |
| 249 case ui::VKEY_F11: return "F11"; // 0x7A |
| 250 case ui::VKEY_F12: return "F12"; // 0x7B |
| 251 case ui::VKEY_F13: return "F13"; // 0x7C |
| 252 case ui::VKEY_F14: return "F14"; // 0x7D |
| 253 case ui::VKEY_F15: return "F15"; // 0x7E |
| 254 case ui::VKEY_F16: return "F16"; // 0x7F |
| 255 case ui::VKEY_F17: return "F17"; // 0x80 |
| 256 case ui::VKEY_F18: return "F18"; // 0x81 |
| 257 case ui::VKEY_F19: return "F19"; // 0x82 |
| 258 case ui::VKEY_F20: return "F20"; // 0x83 |
| 259 case ui::VKEY_F21: return "F21"; // 0x84 |
| 260 case ui::VKEY_F22: return "F22"; // 0x85 |
| 261 case ui::VKEY_F23: return "F23"; // 0x86 |
| 262 case ui::VKEY_F24: return "F24"; // 0x87 |
| 263 /* |
| 264 case ui::VKEY_NUMLOCK: return "NUMLOCK"; // 0x90 |
| 265 case ui::VKEY_SCROLL: return "SCROLL"; // 0x91 |
| 266 case ui::VKEY_LSHIFT: return "LSHIFT"; // 0xA0 |
| 267 case ui::VKEY_RSHIFT: return "RSHIFT"; // 0xA1 |
| 268 case ui::VKEY_LCONTROL: return "LCONTROL"; // 0xA2 |
| 269 case ui::VKEY_RCONTROL: return "RCONTROL"; // 0xA3 |
| 270 case ui::VKEY_LMENU: return "LMENU"; // 0xA4 |
| 271 case ui::VKEY_RMENU: return "RMENU"; // 0xA5 |
| 272 case ui::VKEY_BROWSER_BACK: return "BROWSER_BACK"; // 0xA6 |
| 273 case ui::VKEY_BROWSER_FORWARD: return "BROWSER_FORWARD"; // 0xA7 |
| 274 case ui::VKEY_BROWSER_REFRESH: return "BROWSER_REFRESH"; // 0xA8 |
| 275 case ui::VKEY_BROWSER_STOP: return "BROWSER_STOP"; // 0xA9 |
| 276 case ui::VKEY_BROWSER_SEARCH: return "BROWSER_SEARCH"; // 0xAA |
| 277 case ui::VKEY_BROWSER_FAVORITES: return "BROWSER_FAVORITES"; // 0xAB |
| 278 case ui::VKEY_BROWSER_HOME: return "BROWSER_HOME"; // 0xAC |
| 279 case ui::VKEY_VOLUME_MUTE: return "VOLUME_MUTE"; // 0xAD |
| 280 case ui::VKEY_VOLUME_DOWN: return "VOLUME_DOWN"; // 0xAE |
| 281 case ui::VKEY_VOLUME_UP: return "VOLUME_UP"; // 0xAF |
| 282 case ui::VKEY_MEDIA_NEXT_TRACK: return "MEDIA_NEXT_TRACK"; // 0xB0 |
| 283 case ui::VKEY_MEDIA_PREV_TRACK: return "MEDIA_PREV_TRACK"; // 0xB1 |
| 284 case ui::VKEY_MEDIA_STOP: return "MEDIA_STOP"; // 0xB2 |
| 285 case ui::VKEY_MEDIA_PLAY_PAUSE: return "MEDIA_PLAY_PAUSE"; // 0xB3 |
| 286 case ui::VKEY_MEDIA_LAUNCH_MAIL: return "MEDIA_LAUNCH_MAIL"; // 0xB4 |
| 287 case ui::VKEY_MEDIA_LAUNCH_MEDIA_SELECT: return "MEDIA_LAUNCH_MEDIA_SELECT";
// 0xB5 |
| 288 case ui::VKEY_MEDIA_LAUNCH_APP1: return "MEDIA_LAUNCH_APP1"; // 0xB6 |
| 289 case ui::VKEY_MEDIA_LAUNCH_APP2: return "MEDIA_LAUNCH_APP2"; // 0xB7 |
| 290 */ |
| 291 case ui::VKEY_OEM_1: return "Semicolon"; // 0xBA -> 0x2F |
| 292 case ui::VKEY_OEM_PLUS: return "Equal"; // 0xBB -> 0x15 |
| 293 case ui::VKEY_OEM_COMMA: return "Comma"; // 0xBC -> 0x3B |
| 294 case ui::VKEY_OEM_MINUS: return "Minus"; // 0xBD -> 0x14 |
| 295 case ui::VKEY_OEM_PERIOD: return "Period"; // 0xBE -> 0x3C |
| 296 case ui::VKEY_OEM_2: return "Slash"; // 0xBF -> 0x3D |
| 297 case ui::VKEY_OEM_3: return "Backquote"; // 0xC0 -> 0x31 |
| 298 case ui::VKEY_OEM_4: return "BracketLeft"; // 0xDB -> 0x22 |
| 299 case ui::VKEY_OEM_5: return "Backslash"; // 0xDC -> 0x33 |
| 300 case ui::VKEY_OEM_6: return "BracketRight"; // 0xDD -> 0x23 |
| 301 case ui::VKEY_OEM_7: return "Quote"; // 0xDE -> 0x30 |
| 302 /* |
| 303 case ui::VKEY_OEM_8: return "OEM_8"; // 0xDF |
| 304 case ui::VKEY_OEM_102: return "OEM_102"; // 0xE2 |
| 305 case ui::VKEY_OEM_103: return "OEM_103"; // 0xE3 // GTV KEYCODE_MEDIA_REWI
ND |
| 306 case ui::VKEY_OEM_104: return "OEM_104"; // 0xE4 // GTV KEYCODE_MEDIA_FAST
_FORWARD |
| 307 case ui::VKEY_PROCESSKEY: return "PROCESSKEY"; // 0xE5 |
| 308 case ui::VKEY_PACKET: return "PACKET"; // 0xE7 |
| 309 case ui::VKEY_DBE_SBCSCHAR: return "DBE_SBCSCHAR"; // 0xF3 |
| 310 case ui::VKEY_DBE_DBCSCHAR: return "DBE_DBCSCHAR"; // 0xF4 |
| 311 case ui::VKEY_ATTN: return "ATTN"; // 0xF6 |
| 312 case ui::VKEY_CRSEL: return "CRSEL"; // 0xF7 |
| 313 case ui::VKEY_EXSEL: return "EXSEL"; // 0xF8 |
| 314 case ui::VKEY_EREOF: return "EREOF"; // 0xF9 |
| 315 case ui::VKEY_PLAY: return "PLAY"; // 0xFA |
| 316 case ui::VKEY_ZOOM: return "ZOOM"; // 0xFB |
| 317 case ui::VKEY_NONAME: return "NONAME"; // 0xFC |
| 318 case ui::VKEY_PA1: return "PA1"; // 0xFD |
| 319 case ui::VKEY_OEM_CLEAR: return "OEM_CLEAR"; // 0xFE |
| 320 case ui::VKEY_UNKNOWN: return "UNKNOWN"; // 0 |
| 321 |
| 322 // POSIX specific VKEYs. Note that as of Windows SDK 7.1, 0x97-9F, 0xD8-DA, |
| 323 // and 0xE8 are unassigned. |
| 324 case ui::VKEY_WLAN: return "WLAN"; // 0x97 |
| 325 case ui::VKEY_POWER: return "POWER"; // 0x98 |
| 326 case ui::VKEY_BRIGHTNESS_DOWN: return "BRIGHTNESS_DOWN"; // 0xD8 |
| 327 case ui::VKEY_BRIGHTNESS_UP: return "BRIGHTNESS_UP"; // 0xD9 |
| 328 case ui::VKEY_KBD_BRIGHTNESS_DOWN: return "KBD_BRIGHTNESS_DOWN"; // 0xDA |
| 329 case ui::VKEY_KBD_BRIGHTNESS_UP: return "KBD_BRIGHTNESS_UP"; // 0xE8 |
| 330 |
| 331 // Windows does not have a specific key code for AltGr. We use the unused 0xE1 |
| 332 // (VK_OEM_AX) code to represent AltGr, matching the behaviour of Firefox on |
| 333 // Linux. |
| 334 case ui::VKEY_ALTGR: return "ALTGR"; // 0xE1 |
| 335 */ |
| 336 default: |
| 337 return ""; |
| 338 } |
| 339 } |
| 340 |
| 341 // Return key and code of KeyboardEvent. |
| 342 // See: http://developer.chrome.com/extensions/input_ime.html |
| 343 void GetKeyAndCode(const ui::KeyEvent& event, |
| 344 std::string *key, |
| 345 std::string *code) { |
| 346 DCHECK(key); |
| 347 DCHECK(code); |
| 348 key->clear(); |
| 349 code->clear(); |
| 350 |
| 351 if (event.HasNativeEvent()) { |
| 352 uint32 ibus_keyval = 0; |
| 353 uint32 ibus_keycode = 0; |
| 354 IBusKeyEventFromKeyEvent(event, &ibus_keyval, &ibus_keycode); |
| 355 |
| 356 *key = chromeos::input_method::GetIBusKey(ibus_keyval); |
| 357 *code = chromeos::input_method::GetIBusKeyCode(ibus_keycode); |
| 358 |
| 359 } else { |
| 360 // Convert ui::KeyEvent to key |
| 361 const uint16 key_char16 = event.GetCharacter(); |
| 362 if (key_char16 != 0) { |
| 363 char16 key16[2]; |
| 364 key16[0] = key_char16; |
| 365 key16[1] = '\0'; |
| 366 *key = UTF16ToUTF8(key16); |
| 367 } |
| 368 |
| 369 // Convert ui::KeyEvent to keycode |
| 370 *code = GetIBusKeyCodeFromKeyboardCode(event.key_code()); |
| 371 } |
| 372 } |
| 373 |
123 } // namespace | 374 } // namespace |
124 | 375 |
125 namespace ui { | 376 namespace ui { |
126 | 377 |
127 // InputMethodIBus implementation ----------------------------------------- | 378 // InputMethodIBus implementation ----------------------------------------- |
128 InputMethodIBus::InputMethodIBus( | 379 InputMethodIBus::InputMethodIBus( |
129 internal::InputMethodDelegate* delegate) | 380 internal::InputMethodDelegate* delegate) |
130 : context_focused_(false), | 381 : context_focused_(false), |
131 composing_text_(false), | 382 composing_text_(false), |
132 composition_changed_(false), | 383 composition_changed_(false), |
(...skipping 28 matching lines...) Expand all Loading... |
161 InputMethodBase::OnBlur(); | 412 InputMethodBase::OnBlur(); |
162 UpdateContextFocusState(); | 413 UpdateContextFocusState(); |
163 } | 414 } |
164 | 415 |
165 bool InputMethodIBus::OnUntranslatedIMEMessage(const base::NativeEvent& event, | 416 bool InputMethodIBus::OnUntranslatedIMEMessage(const base::NativeEvent& event, |
166 NativeEventResult* result) { | 417 NativeEventResult* result) { |
167 return false; | 418 return false; |
168 } | 419 } |
169 | 420 |
170 void InputMethodIBus::ProcessKeyEventDone(uint32 id, | 421 void InputMethodIBus::ProcessKeyEventDone(uint32 id, |
171 XEvent* event, | 422 ui::KeyEvent* event, |
172 uint32 ibus_keyval, | |
173 uint32 ibus_keycode, | |
174 uint32 ibus_state, | |
175 bool is_handled) { | 423 bool is_handled) { |
176 DCHECK(event); | 424 DCHECK(event); |
177 std::set<uint32>::iterator it = pending_key_events_.find(id); | |
178 | 425 |
179 if (it == pending_key_events_.end()) | 426 if (pending_key_events_.find(id) == pending_key_events_.end()) |
180 return; // Abandoned key event. | 427 return; // Abandoned key event. |
181 | 428 |
182 if (event->type == KeyPress) { | 429 if (event->type() == ui::ET_KEY_PRESSED) { |
183 if (is_handled) { | 430 if (is_handled) { |
184 // IME event has a priority to be handled, so that character composer | 431 // IME event has a priority to be handled, so that character composer |
185 // should be reset. | 432 // should be reset. |
186 character_composer_.Reset(); | 433 character_composer_.Reset(); |
187 } else { | 434 } else { |
188 // If IME does not handle key event, passes keyevent to character composer | 435 // If IME does not handle key event, passes keyevent to character composer |
189 // to be able to compose complex characters. | 436 // to be able to compose complex characters. |
190 is_handled = ExecuteCharacterComposer(ibus_keyval, ibus_keycode, | 437 is_handled = ExecuteCharacterComposer(*event); |
191 ibus_state); | |
192 } | 438 } |
193 } | 439 } |
194 | 440 |
195 if (event->type == KeyPress || event->type == KeyRelease) | 441 if (event->type() == ui::ET_KEY_PRESSED || |
196 ProcessKeyEventPostIME(event, ibus_state, is_handled); | 442 event->type() == ui::ET_KEY_RELEASED) |
| 443 ProcessKeyEventPostIME(*event, is_handled); |
197 | 444 |
198 // Do not use |it| for erasing, ProcessKeyEventPostIME may change the | |
199 // |pending_key_events_|. | |
200 pending_key_events_.erase(id); | 445 pending_key_events_.erase(id); |
201 } | 446 } |
202 | 447 |
203 bool InputMethodIBus::DispatchKeyEvent(const base::NativeEvent& native_event) { | 448 bool InputMethodIBus::DispatchKeyEvent(const ui::KeyEvent& event) { |
204 DCHECK(native_event && (native_event->type == KeyPress || | 449 DCHECK(event.type() == ui::ET_KEY_PRESSED || |
205 native_event->type == KeyRelease)); | 450 event.type() == ui::ET_KEY_RELEASED); |
206 DCHECK(system_toplevel_window_focused()); | 451 DCHECK(system_toplevel_window_focused()); |
207 | 452 |
208 uint32 ibus_keyval = 0; | |
209 uint32 ibus_keycode = 0; | |
210 uint32 ibus_state = 0; | |
211 IBusKeyEventFromNativeKeyEvent( | |
212 native_event, | |
213 &ibus_keyval, &ibus_keycode, &ibus_state); | |
214 | |
215 // If |context_| is not usable, then we can only dispatch the key event as is. | 453 // If |context_| is not usable, then we can only dispatch the key event as is. |
216 // We also dispatch the key event directly if the current text input type is | 454 // We also dispatch the key event directly if the current text input type is |
217 // TEXT_INPUT_TYPE_PASSWORD, to bypass the input method. | 455 // TEXT_INPUT_TYPE_PASSWORD, to bypass the input method. |
218 // Note: We need to send the key event to ibus even if the |context_| is not | 456 // Note: We need to send the key event to ibus even if the |context_| is not |
219 // enabled, so that ibus can have a chance to enable the |context_|. | 457 // enabled, so that ibus can have a chance to enable the |context_|. |
220 if (!context_focused_ || !GetEngine() || | 458 if (!context_focused_ || !GetEngine() || |
221 GetTextInputType() == TEXT_INPUT_TYPE_PASSWORD ) { | 459 GetTextInputType() == TEXT_INPUT_TYPE_PASSWORD ) { |
222 if (native_event->type == KeyPress) { | 460 if (event.type() == ui::ET_KEY_PRESSED) { |
223 if (ExecuteCharacterComposer(ibus_keyval, ibus_keycode, ibus_state)) { | 461 // TODO(komatsu): Enable ExecuteCharacterComposer to work with |
224 // Treating as PostIME event if character composer handles key event and | 462 // with fabricated keyevents. |
225 // generates some IME event, | 463 if (ExecuteCharacterComposer(event)) { |
226 ProcessKeyEventPostIME(native_event, ibus_state, true); | 464 // Treating as PostIME event if character composer handles key |
| 465 // event and generates some IME event, |
| 466 ProcessKeyEventPostIME(event, true); // true == Handled. |
227 return true; | 467 return true; |
228 } | 468 } |
229 ProcessUnfilteredKeyPressEvent(native_event, ibus_state); | 469 ProcessUnfilteredKeyPressEvent(event); |
230 } else { | 470 } else { |
231 DispatchKeyEventPostIME(native_event); | 471 DispatchKeyEventPostIME(event); |
232 } | 472 } |
233 return true; | 473 return true; |
234 } | 474 } |
235 | 475 |
236 pending_key_events_.insert(current_keyevent_id_); | 476 pending_key_events_.insert(current_keyevent_id_); |
237 | 477 |
238 // Since |native_event| might be treated as XEvent whose size is bigger than | 478 std::string key; |
239 // XKeyEvent e.g. in CopyNativeEvent() in ui/events/event.cc, allocating | 479 std::string code; |
240 // |event| as XKeyEvent and casting it to XEvent is unsafe. crbug.com/151884 | 480 GetKeyAndCode(event, &key, &code); |
241 XEvent* event = new XEvent; | 481 |
242 *event = *native_event; | 482 LOG(ERROR) << "key: " << key; |
| 483 LOG(ERROR) << "code: " << code; |
| 484 |
| 485 ui::KeyEvent* copied_event = NULL; |
| 486 // TODO: Fix ui::KeyEvent itself. |
| 487 if (event.HasNativeEvent()) { |
| 488 copied_event = event.Copy(); |
| 489 } else { |
| 490 copied_event = new KeyEvent(event); |
| 491 } |
| 492 |
243 GetEngine()->ProcessKeyEvent( | 493 GetEngine()->ProcessKeyEvent( |
244 ibus_keyval, | 494 key, |
245 ibus_keycode, | 495 code, |
246 ibus_state, | 496 event.type() == ET_KEY_PRESSED, |
| 497 event.IsAltDown(), |
| 498 event.IsControlDown(), |
| 499 event.IsShiftDown(), |
| 500 event.IsCapsLockDown(), |
247 base::Bind(&InputMethodIBus::ProcessKeyEventDone, | 501 base::Bind(&InputMethodIBus::ProcessKeyEventDone, |
248 weak_ptr_factory_.GetWeakPtr(), | 502 weak_ptr_factory_.GetWeakPtr(), |
249 current_keyevent_id_, | 503 current_keyevent_id_, |
250 base::Owned(event), // Pass the ownership of |event|. | 504 // Pass the ownership of |copied_event|. |
251 ibus_keyval, | 505 base::Owned(copied_event))); |
252 ibus_keycode, | |
253 ibus_state)); | |
254 | 506 |
255 ++current_keyevent_id_; | 507 ++current_keyevent_id_; |
256 | 508 |
257 // We don't want to suppress the result generated by this key event, but it | 509 // We don't want to suppress the result generated by this key event, but it |
258 // may cause problem. See comment in ResetContext() method. | 510 // may cause problem. See comment in ResetContext() method. |
259 suppress_next_result_ = false; | 511 suppress_next_result_ = false; |
260 return true; | 512 return true; |
261 } | 513 } |
262 | 514 |
263 bool InputMethodIBus::DispatchFabricatedKeyEvent(const ui::KeyEvent& event) { | 515 bool InputMethodIBus::DispatchFabricatedKeyEvent(const ui::KeyEvent& event) { |
264 // TODO(bryeung): The fabricated events should also pass through IME. | 516 return DispatchKeyEvent(event); |
265 if (event.type() == ET_KEY_PRESSED) { | |
266 ProcessUnfilteredFabricatedKeyPressEvent( | |
267 ET_KEY_PRESSED, event.key_code(), event.flags()); | |
268 } else { | |
269 DispatchFabricatedKeyEventPostIME( | |
270 ET_KEY_RELEASED, | |
271 event.key_code(), | |
272 event.flags()); | |
273 } | |
274 return true; | |
275 } | 517 } |
276 | 518 |
277 void InputMethodIBus::OnTextInputTypeChanged(const TextInputClient* client) { | 519 void InputMethodIBus::OnTextInputTypeChanged(const TextInputClient* client) { |
278 if (IsTextInputClientFocused(client)) { | 520 if (IsTextInputClientFocused(client)) { |
279 ResetContext(); | 521 ResetContext(); |
280 UpdateContextFocusState(); | 522 UpdateContextFocusState(); |
281 if (previous_textinput_type_ != client->GetTextInputType()) | 523 if (previous_textinput_type_ != client->GetTextInputType()) |
282 OnInputMethodChanged(); | 524 OnInputMethodChanged(); |
283 previous_textinput_type_ = client->GetTextInputType(); | 525 previous_textinput_type_ = client->GetTextInputType(); |
284 } | 526 } |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
400 GetEngine()->FocusIn(UiToIbusTextInputType(current_text_input_type)); | 642 GetEngine()->FocusIn(UiToIbusTextInputType(current_text_input_type)); |
401 OnCaretBoundsChanged(GetTextInputClient()); | 643 OnCaretBoundsChanged(GetTextInputClient()); |
402 } else if (context_focused_ && | 644 } else if (context_focused_ && |
403 current_text_input_type != previous_textinput_type_) { | 645 current_text_input_type != previous_textinput_type_) { |
404 GetEngine()->FocusOut(); | 646 GetEngine()->FocusOut(); |
405 GetEngine()->FocusIn(UiToIbusTextInputType(current_text_input_type)); | 647 GetEngine()->FocusIn(UiToIbusTextInputType(current_text_input_type)); |
406 OnCaretBoundsChanged(GetTextInputClient()); | 648 OnCaretBoundsChanged(GetTextInputClient()); |
407 } | 649 } |
408 } | 650 } |
409 | 651 |
410 void InputMethodIBus::ProcessKeyEventPostIME( | 652 void InputMethodIBus::ProcessKeyEventPostIME(const ui::KeyEvent& event, |
411 const base::NativeEvent& native_event, | 653 bool handled) { |
412 uint32 ibus_state, | |
413 bool handled) { | |
414 TextInputClient* client = GetTextInputClient(); | 654 TextInputClient* client = GetTextInputClient(); |
415 | 655 |
416 if (!client) { | 656 if (!client) { |
417 // As ibus works asynchronously, there is a chance that the focused client | 657 // As ibus works asynchronously, there is a chance that the focused client |
418 // loses focus before this method gets called. | 658 // loses focus before this method gets called. |
419 DispatchKeyEventPostIME(native_event); | 659 DispatchKeyEventPostIME(event); |
420 return; | 660 return; |
421 } | 661 } |
422 | 662 |
423 if (native_event->type == KeyPress && handled) | 663 if (event.type() == ui::ET_KEY_PRESSED && handled) |
424 ProcessFilteredKeyPressEvent(native_event); | 664 ProcessFilteredKeyPressEvent(event); |
425 | 665 |
426 // In case the focus was changed by the key event. The |context_| should have | 666 // In case the focus was changed by the key event. The |context_| should have |
427 // been reset when the focused window changed. | 667 // been reset when the focused window changed. |
428 if (client != GetTextInputClient()) | 668 if (client != GetTextInputClient()) |
429 return; | 669 return; |
430 | 670 |
431 if (HasInputMethodResult()) | 671 if (HasInputMethodResult()) |
432 ProcessInputMethodResult(native_event, handled); | 672 ProcessInputMethodResult(event, handled); |
433 | 673 |
434 // In case the focus was changed when sending input method results to the | 674 // In case the focus was changed when sending input method results to the |
435 // focused window. | 675 // focused window. |
436 if (client != GetTextInputClient()) | 676 if (client != GetTextInputClient()) |
437 return; | 677 return; |
438 | 678 |
439 if (native_event->type == KeyPress && !handled) | 679 if (event.type() == ui::ET_KEY_PRESSED && !handled) |
440 ProcessUnfilteredKeyPressEvent(native_event, ibus_state); | 680 ProcessUnfilteredKeyPressEvent(event); |
441 else if (native_event->type == KeyRelease) | 681 else if (event.type() == ui::ET_KEY_RELEASED) |
442 DispatchKeyEventPostIME(native_event); | 682 DispatchKeyEventPostIME(event); |
443 } | 683 } |
444 | 684 |
445 void InputMethodIBus::IBusKeyEventFromNativeKeyEvent( | 685 void InputMethodIBus::ProcessFilteredKeyPressEvent(const ui::KeyEvent& event) { |
446 const base::NativeEvent& native_event, | 686 if (NeedInsertChar()) { |
447 uint32* ibus_keyval, | 687 DispatchKeyEventPostIME(event); |
448 uint32* ibus_keycode, | 688 } else { |
449 uint32* ibus_state) { | 689 const ui::KeyEvent fabricated_event(ET_KEY_PRESSED, |
450 DCHECK(native_event); // A fabricated event is not supported here. | 690 VKEY_PROCESSKEY, |
451 XKeyEvent* x_key = GetKeyEvent(native_event); | 691 event.flags(), |
452 | 692 false); // is_char |
453 // Yes, ibus uses X11 keysym. We cannot use XLookupKeysym(), which doesn't | 693 DispatchKeyEventPostIME(fabricated_event); |
454 // translate Shift and CapsLock states. | 694 } |
455 KeySym keysym = NoSymbol; | |
456 ::XLookupString(x_key, NULL, 0, &keysym, NULL); | |
457 *ibus_keyval = keysym; | |
458 *ibus_keycode = x_key->keycode; | |
459 *ibus_state = IBusStateFromXState(x_key->state); | |
460 if (native_event->type == KeyRelease) | |
461 *ibus_state |= kIBusReleaseMask; | |
462 } | |
463 | |
464 void InputMethodIBus::ProcessFilteredKeyPressEvent( | |
465 const base::NativeEvent& native_event) { | |
466 if (NeedInsertChar()) | |
467 DispatchKeyEventPostIME(native_event); | |
468 else | |
469 DispatchFabricatedKeyEventPostIME( | |
470 ET_KEY_PRESSED, | |
471 VKEY_PROCESSKEY, | |
472 EventFlagsFromXState(GetKeyEvent(native_event)->state)); | |
473 } | 695 } |
474 | 696 |
475 void InputMethodIBus::ProcessUnfilteredKeyPressEvent( | 697 void InputMethodIBus::ProcessUnfilteredKeyPressEvent( |
476 const base::NativeEvent& native_event, | 698 const ui::KeyEvent& event) { |
477 uint32 ibus_state) { | |
478 // For a fabricated event, ProcessUnfilteredFabricatedKeyPressEvent should be | |
479 // called instead. | |
480 DCHECK(native_event); | |
481 | |
482 TextInputClient* client = GetTextInputClient(); | 699 TextInputClient* client = GetTextInputClient(); |
483 DispatchKeyEventPostIME(native_event); | 700 DispatchKeyEventPostIME(event); // This may change the focus. |
484 | 701 |
485 // We shouldn't dispatch the character anymore if the key event dispatch | 702 // We shouldn't dispatch the character anymore if the key event dispatch |
486 // caused focus change. For example, in the following scenario, | 703 // caused focus change. For example, in the following scenario, |
487 // 1. visit a web page which has a <textarea>. | 704 // 1. visit a web page which has a <textarea>. |
488 // 2. click Omnibox. | 705 // 2. click Omnibox. |
489 // 3. enable Korean IME, press A, then press Tab to move the focus to the web | 706 // 3. enable Korean IME, press A, then press Tab to move the focus to the web |
490 // page. | 707 // page. |
491 // We should return here not to send the Tab key event to RWHV. | 708 // We should return here not to send the Tab key event to RWHV. |
492 if (client != GetTextInputClient()) | 709 if (client != GetTextInputClient()) |
493 return; | 710 return; |
494 | 711 |
495 const uint32 event_flags = EventFlagsFromXState(ibus_state); | 712 DCHECK_EQ(client, GetTextInputClient()); |
| 713 if (!client) |
| 714 return; |
496 | 715 |
497 // If a key event was not filtered by |context_| and |character_composer_|, | 716 // If a key event was not filtered by |context_| and |character_composer_|, |
498 // then it means the key event didn't generate any result text. So we need | 717 // then it means the key event didn't generate any result text. So we need |
499 // to send corresponding character to the focused text input client. | 718 // to send corresponding character to the focused text input client. |
500 client = GetTextInputClient(); | 719 uint16 ch = 0; |
| 720 const uint32 event_flags = event.flags(); |
| 721 // TODO(komatsu): The following logic could be simplified. |
| 722 if (event.HasNativeEvent()) { |
| 723 const base::NativeEvent& native_event = event.native_event(); |
501 | 724 |
502 uint16 ch = 0; | 725 if (!(event_flags & ui::EF_CONTROL_DOWN)) |
503 if (!(event_flags & ui::EF_CONTROL_DOWN)) | 726 ch = ui::GetCharacterFromXEvent(native_event); |
504 ch = ui::GetCharacterFromXEvent(native_event); | 727 if (!ch) { |
505 if (!ch) { | 728 ch = ui::GetCharacterFromKeyCode( |
506 ch = ui::GetCharacterFromKeyCode( | 729 ui::KeyboardCodeFromNative(native_event), event_flags); |
507 ui::KeyboardCodeFromNative(native_event), event_flags); | 730 } |
| 731 } else { |
| 732 ch = ui::GetCharacterFromKeyCode(event.key_code(), event_flags); |
508 } | 733 } |
509 | 734 |
510 if (client && ch) | 735 if (ch) |
511 client->InsertChar(ch, event_flags); | 736 client->InsertChar(ch, event_flags); |
512 } | 737 } |
513 | 738 |
514 void InputMethodIBus::ProcessUnfilteredFabricatedKeyPressEvent( | 739 void InputMethodIBus::ProcessInputMethodResult(const ui::KeyEvent& event, |
515 EventType type, | 740 bool handled) { |
516 KeyboardCode key_code, | |
517 int event_flags) { | |
518 TextInputClient* client = GetTextInputClient(); | |
519 DispatchFabricatedKeyEventPostIME(type, key_code, event_flags); | |
520 | |
521 if (client != GetTextInputClient()) | |
522 return; | |
523 | |
524 client = GetTextInputClient(); | |
525 const uint16 ch = ui::GetCharacterFromKeyCode(key_code, event_flags); | |
526 if (client && ch) | |
527 client->InsertChar(ch, event_flags); | |
528 } | |
529 | |
530 void InputMethodIBus::ProcessInputMethodResult( | |
531 const base::NativeEvent& native_event, | |
532 bool handled) { | |
533 TextInputClient* client = GetTextInputClient(); | 741 TextInputClient* client = GetTextInputClient(); |
534 DCHECK(client); | 742 DCHECK(client); |
535 | 743 |
536 if (result_text_.length()) { | 744 if (result_text_.length()) { |
537 if (handled && NeedInsertChar()) { | 745 if (handled && NeedInsertChar()) { |
538 const uint32 state = | |
539 EventFlagsFromXState(GetKeyEvent(native_event)->state); | |
540 for (string16::const_iterator i = result_text_.begin(); | 746 for (string16::const_iterator i = result_text_.begin(); |
541 i != result_text_.end(); ++i) { | 747 i != result_text_.end(); ++i) { |
542 client->InsertChar(*i, state); | 748 client->InsertChar(*i, event.flags()); |
543 } | 749 } |
544 } else { | 750 } else { |
545 client->InsertText(result_text_); | 751 client->InsertText(result_text_); |
546 composing_text_ = false; | 752 composing_text_ = false; |
547 } | 753 } |
548 } | 754 } |
549 | 755 |
550 if (composition_changed_ && !IsTextInputTypeNone()) { | 756 if (composition_changed_ && !IsTextInputTypeNone()) { |
551 if (composition_.text.length()) { | 757 if (composition_.text.length()) { |
552 composing_text_ = true; | 758 composing_text_ = true; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
611 | 817 |
612 const EventType event_type = | 818 const EventType event_type = |
613 (state & kIBusReleaseMask) ? ET_KEY_RELEASED : ET_KEY_PRESSED; | 819 (state & kIBusReleaseMask) ? ET_KEY_RELEASED : ET_KEY_PRESSED; |
614 const int event_flags = EventFlagsFromXState(state); | 820 const int event_flags = EventFlagsFromXState(state); |
615 | 821 |
616 // It is not clear when the input method will forward us a fake key event. | 822 // It is not clear when the input method will forward us a fake key event. |
617 // If there is a pending key event, then we may already received some input | 823 // If there is a pending key event, then we may already received some input |
618 // method results, so we dispatch this fake key event directly rather than | 824 // method results, so we dispatch this fake key event directly rather than |
619 // calling ProcessKeyEventPostIME(), which will clear pending input method | 825 // calling ProcessKeyEventPostIME(), which will clear pending input method |
620 // results. | 826 // results. |
| 827 const bool kIsChar = false; |
| 828 const ui::KeyEvent event(event_type, ui_key_code, event_flags, kIsChar); |
621 if (event_type == ET_KEY_PRESSED) { | 829 if (event_type == ET_KEY_PRESSED) { |
622 ProcessUnfilteredFabricatedKeyPressEvent(event_type, ui_key_code, | 830 ProcessUnfilteredKeyPressEvent(event); |
623 event_flags); | |
624 } else { | 831 } else { |
625 DispatchFabricatedKeyEventPostIME(event_type, ui_key_code, event_flags); | 832 DispatchKeyEventPostIME(event); |
626 } | 833 } |
627 } | 834 } |
628 | 835 |
629 void InputMethodIBus::ShowPreeditText() { | 836 void InputMethodIBus::ShowPreeditText() { |
630 if (suppress_next_result_ || IsTextInputTypeNone()) | 837 if (suppress_next_result_ || IsTextInputTypeNone()) |
631 return; | 838 return; |
632 | 839 |
633 composing_text_ = true; | 840 composing_text_ = true; |
634 } | 841 } |
635 | 842 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
693 | 900 |
694 void InputMethodIBus::DeleteSurroundingText(int32 offset, uint32 length) { | 901 void InputMethodIBus::DeleteSurroundingText(int32 offset, uint32 length) { |
695 if (!composition_.text.empty()) | 902 if (!composition_.text.empty()) |
696 return; // do nothing if there is ongoing composition. | 903 return; // do nothing if there is ongoing composition. |
697 if (offset < 0 && static_cast<uint32>(-1 * offset) != length) | 904 if (offset < 0 && static_cast<uint32>(-1 * offset) != length) |
698 return; // only preceding text can be deletable. | 905 return; // only preceding text can be deletable. |
699 if (GetTextInputClient()) | 906 if (GetTextInputClient()) |
700 GetTextInputClient()->ExtendSelectionAndDelete(length, 0U); | 907 GetTextInputClient()->ExtendSelectionAndDelete(length, 0U); |
701 } | 908 } |
702 | 909 |
703 bool InputMethodIBus::ExecuteCharacterComposer(uint32 ibus_keyval, | 910 bool InputMethodIBus::ExecuteCharacterComposer(const ui::KeyEvent& event) { |
704 uint32 ibus_keycode, | 911 // TODO(komatsu): Support fabricated events too. |
705 uint32 ibus_state) { | 912 if (!event.HasNativeEvent()) |
| 913 return false; |
| 914 |
| 915 uint32 ibus_keyval = 0; |
| 916 uint32 ibus_keycode = 0; |
| 917 IBusKeyEventFromKeyEvent(event, &ibus_keyval, &ibus_keycode); |
| 918 |
706 bool consumed = character_composer_.FilterKeyPress( | 919 bool consumed = character_composer_.FilterKeyPress( |
707 ibus_keyval, | 920 ibus_keyval, |
708 ibus_keycode, | 921 ibus_keycode, |
709 EventFlagsFromXState(ibus_state)); | 922 event.flags()); |
710 | 923 |
711 suppress_next_result_ = false; | 924 suppress_next_result_ = false; |
712 chromeos::IBusText preedit; | 925 chromeos::IBusText preedit; |
713 preedit.set_text( | 926 preedit.set_text( |
714 UTF16ToUTF8(character_composer_.preedit_string())); | 927 UTF16ToUTF8(character_composer_.preedit_string())); |
715 UpdatePreeditText(preedit, preedit.text().size(), | 928 UpdatePreeditText(preedit, preedit.text().size(), |
716 !preedit.text().empty()); | 929 !preedit.text().empty()); |
717 std::string commit_text = | 930 std::string commit_text = |
718 UTF16ToUTF8(character_composer_.composed_character()); | 931 UTF16ToUTF8(character_composer_.composed_character()); |
719 if (!commit_text.empty()) { | 932 if (!commit_text.empty()) { |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
860 // |surrounding_text| coordinates. | 1073 // |surrounding_text| coordinates. |
861 if (!GetEngine()) | 1074 if (!GetEngine()) |
862 return; | 1075 return; |
863 GetEngine()->SetSurroundingText( | 1076 GetEngine()->SetSurroundingText( |
864 UTF16ToUTF8(surrounding_text), | 1077 UTF16ToUTF8(surrounding_text), |
865 selection_range.start() - text_range.start(), | 1078 selection_range.start() - text_range.start(), |
866 selection_range.end() - text_range.start()); | 1079 selection_range.end() - text_range.start()); |
867 } | 1080 } |
868 | 1081 |
869 } // namespace ui | 1082 } // namespace ui |
OLD | NEW |