| OLD | NEW |
| 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 "views/ime/input_method_ibus.h" | 5 #include "views/ime/input_method_ibus.h" |
| 6 | 6 |
| 7 #include <ibus.h> | 7 #include <ibus.h> |
| 8 #if defined(TOUCH_UI) | 8 #if defined(TOUCH_UI) |
| 9 #include <X11/Xlib.h> | 9 #include <X11/Xlib.h> |
| 10 #include <X11/Xutil.h> | 10 #include <X11/Xutil.h> |
| 11 #endif | 11 #endif |
| 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/command_line.h" | 18 #include "base/command_line.h" |
| 19 #include "base/basictypes.h" | 19 #include "base/basictypes.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/string_util.h" | 22 #include "base/string_util.h" |
| 23 #include "base/third_party/icu/icu_utf.h" | 23 #include "base/third_party/icu/icu_utf.h" |
| 24 #include "base/utf_string_conversions.h" | 24 #include "base/utf_string_conversions.h" |
| 25 #include "ui/base/keycodes/keyboard_codes.h" | 25 #include "ui/base/keycodes/keyboard_codes.h" |
| 26 #include "ui/gfx/point.h" |
| 27 #include "ui/gfx/rect.h" |
| 26 #include "views/events/event.h" | 28 #include "views/events/event.h" |
| 27 #include "views/widget/widget.h" | 29 #include "views/widget/widget.h" |
| 28 | 30 |
| 29 #if defined(USE_AURA) || defined(TOUCH_UI) | 31 #if defined(USE_AURA) || defined(TOUCH_UI) |
| 30 #include "ui/base/keycodes/keyboard_code_conversion_x.h" | 32 #include "ui/base/keycodes/keyboard_code_conversion_x.h" |
| 31 #elif defined(TOOLKIT_USES_GTK) | 33 #elif defined(TOOLKIT_USES_GTK) |
| 32 #include "ui/base/keycodes/keyboard_code_conversion_gtk.h" | 34 #include "ui/base/keycodes/keyboard_code_conversion_gtk.h" |
| 33 #endif | 35 #endif |
| 34 | 36 |
| 35 namespace { | 37 namespace { |
| 36 | 38 |
| 37 // A global flag to switch the InputMethod implementation to InputMethodIBus | 39 // A global flag to switch the InputMethod implementation to InputMethodIBus |
| 38 bool inputmethod_ibus_enabled = false; | 40 bool inputmethod_ibus_enabled = false; |
| 39 | 41 |
| 40 // Converts ibus key state flags to Views event flags. | 42 // Converts ibus key state flags to event flags. |
| 41 int ViewsFlagsFromIBusState(guint32 state) { | 43 int EventFlagsFromIBusState(guint32 state) { |
| 42 return (state & IBUS_LOCK_MASK ? ui::EF_CAPS_LOCK_DOWN : 0) | | 44 return (state & IBUS_LOCK_MASK ? ui::EF_CAPS_LOCK_DOWN : 0) | |
| 43 (state & IBUS_CONTROL_MASK ? ui::EF_CONTROL_DOWN : 0) | | 45 (state & IBUS_CONTROL_MASK ? ui::EF_CONTROL_DOWN : 0) | |
| 44 (state & IBUS_SHIFT_MASK ? ui::EF_SHIFT_DOWN : 0) | | 46 (state & IBUS_SHIFT_MASK ? ui::EF_SHIFT_DOWN : 0) | |
| 45 (state & IBUS_MOD1_MASK ? ui::EF_ALT_DOWN : 0) | | 47 (state & IBUS_MOD1_MASK ? ui::EF_ALT_DOWN : 0) | |
| 46 (state & IBUS_BUTTON1_MASK ? ui::EF_LEFT_BUTTON_DOWN : 0) | | 48 (state & IBUS_BUTTON1_MASK ? ui::EF_LEFT_BUTTON_DOWN : 0) | |
| 47 (state & IBUS_BUTTON2_MASK ? ui::EF_MIDDLE_BUTTON_DOWN : 0) | | 49 (state & IBUS_BUTTON2_MASK ? ui::EF_MIDDLE_BUTTON_DOWN : 0) | |
| 48 (state & IBUS_BUTTON3_MASK ? ui::EF_RIGHT_BUTTON_DOWN : 0); | 50 (state & IBUS_BUTTON3_MASK ? ui::EF_RIGHT_BUTTON_DOWN : 0); |
| 49 } | 51 } |
| 50 | 52 |
| 51 // Converts Views event flags to ibus key state flags. | 53 // Converts event flags to ibus key state flags. |
| 52 guint32 IBusStateFromViewsFlags(int flags) { | 54 guint32 IBusStateFromEventFlags(int flags) { |
| 53 return (flags & ui::EF_CAPS_LOCK_DOWN ? IBUS_LOCK_MASK : 0) | | 55 return (flags & ui::EF_CAPS_LOCK_DOWN ? IBUS_LOCK_MASK : 0) | |
| 54 (flags & ui::EF_CONTROL_DOWN ? IBUS_CONTROL_MASK : 0) | | 56 (flags & ui::EF_CONTROL_DOWN ? IBUS_CONTROL_MASK : 0) | |
| 55 (flags & ui::EF_SHIFT_DOWN ? IBUS_SHIFT_MASK : 0) | | 57 (flags & ui::EF_SHIFT_DOWN ? IBUS_SHIFT_MASK : 0) | |
| 56 (flags & ui::EF_ALT_DOWN ? IBUS_MOD1_MASK : 0) | | 58 (flags & ui::EF_ALT_DOWN ? IBUS_MOD1_MASK : 0) | |
| 57 (flags & ui::EF_LEFT_BUTTON_DOWN ? IBUS_BUTTON1_MASK : 0) | | 59 (flags & ui::EF_LEFT_BUTTON_DOWN ? IBUS_BUTTON1_MASK : 0) | |
| 58 (flags & ui::EF_MIDDLE_BUTTON_DOWN ? IBUS_BUTTON2_MASK : 0) | | 60 (flags & ui::EF_MIDDLE_BUTTON_DOWN ? IBUS_BUTTON2_MASK : 0) | |
| 59 (flags & ui::EF_RIGHT_BUTTON_DOWN ? IBUS_BUTTON3_MASK : 0); | 61 (flags & ui::EF_RIGHT_BUTTON_DOWN ? IBUS_BUTTON3_MASK : 0); |
| 60 } | 62 } |
| 61 | 63 |
| 62 void IBusKeyEventFromViewsKeyEvent(const views::KeyEvent& key, | 64 void IBusKeyEventFromViewsKeyEvent(const views::KeyEvent& key, |
| (...skipping 24 matching lines...) Expand all Loading... |
| 87 GdkEventKey* gdk_key = reinterpret_cast<GdkEventKey*>(key.gdk_event()); | 89 GdkEventKey* gdk_key = reinterpret_cast<GdkEventKey*>(key.gdk_event()); |
| 88 *ibus_keyval = gdk_key->keyval; | 90 *ibus_keyval = gdk_key->keyval; |
| 89 *ibus_keycode = gdk_key->hardware_keycode; | 91 *ibus_keycode = gdk_key->hardware_keycode; |
| 90 } else { | 92 } else { |
| 91 *ibus_keyval = ui::GdkKeyCodeForWindowsKeyCode( | 93 *ibus_keyval = ui::GdkKeyCodeForWindowsKeyCode( |
| 92 key.key_code(), key.IsShiftDown() ^ key.IsCapsLockDown()); | 94 key.key_code(), key.IsShiftDown() ^ key.IsCapsLockDown()); |
| 93 *ibus_keycode = 0; | 95 *ibus_keycode = 0; |
| 94 } | 96 } |
| 95 #endif | 97 #endif |
| 96 | 98 |
| 97 *ibus_state = IBusStateFromViewsFlags(key.flags()); | 99 *ibus_state = IBusStateFromEventFlags(key.flags()); |
| 98 if (key.type() == ui::ET_KEY_RELEASED) | 100 if (key.type() == ui::ET_KEY_RELEASED) |
| 99 *ibus_state |= IBUS_RELEASE_MASK; | 101 *ibus_state |= IBUS_RELEASE_MASK; |
| 100 } | 102 } |
| 101 | 103 |
| 102 void ExtractCompositionTextFromIBusPreedit(IBusText* text, | 104 void ExtractCompositionTextFromIBusPreedit(IBusText* text, |
| 103 guint cursor_position, | 105 guint cursor_position, |
| 104 ui::CompositionText* composition) { | 106 ui::CompositionText* composition) { |
| 105 composition->Clear(); | 107 composition->Clear(); |
| 106 composition->text = UTF8ToUTF16(text->text); | 108 composition->text = UTF8ToUTF16(text->text); |
| 107 | 109 |
| (...skipping 585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 693 // then it means the key event didn't generate any result text. So we need | 695 // then it means the key event didn't generate any result text. So we need |
| 694 // to send corresponding character to the focused text input client. | 696 // to send corresponding character to the focused text input client. |
| 695 | 697 |
| 696 ui::TextInputClient* client = GetTextInputClient(); | 698 ui::TextInputClient* client = GetTextInputClient(); |
| 697 char16 ch = key.GetCharacter(); | 699 char16 ch = key.GetCharacter(); |
| 698 if (ch && client) | 700 if (ch && client) |
| 699 client->InsertChar(ch, key.flags()); | 701 client->InsertChar(ch, key.flags()); |
| 700 } | 702 } |
| 701 | 703 |
| 702 void InputMethodIBus::ProcessInputMethodResult(const KeyEvent& key, | 704 void InputMethodIBus::ProcessInputMethodResult(const KeyEvent& key, |
| 703 bool filtered) { | 705 bool handled) { |
| 704 ui::TextInputClient* client = GetTextInputClient(); | 706 ui::TextInputClient* client = GetTextInputClient(); |
| 705 DCHECK(client); | 707 DCHECK(client); |
| 706 | 708 |
| 707 if (result_text_.length()) { | 709 if (result_text_.length()) { |
| 708 if (filtered && NeedInsertChar()) { | 710 if (handled && NeedInsertChar()) { |
| 709 for (string16::const_iterator i = result_text_.begin(); | 711 for (string16::const_iterator i = result_text_.begin(); |
| 710 i != result_text_.end(); ++i) { | 712 i != result_text_.end(); ++i) { |
| 711 client->InsertChar(*i, key.flags()); | 713 client->InsertChar(*i, key.flags()); |
| 712 } | 714 } |
| 713 } else { | 715 } else { |
| 714 client->InsertText(result_text_); | 716 client->InsertText(result_text_); |
| 715 composing_text_ = false; | 717 composing_text_ = false; |
| 716 } | 718 } |
| 717 } | 719 } |
| 718 | 720 |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 801 key_code = ui::KeyboardCodeFromXKeysym(keyval); | 803 key_code = ui::KeyboardCodeFromXKeysym(keyval); |
| 802 #elif defined(TOOLKIT_USES_GTK) | 804 #elif defined(TOOLKIT_USES_GTK) |
| 803 key_code = ui::WindowsKeyCodeForGdkKeyCode(keyval); | 805 key_code = ui::WindowsKeyCodeForGdkKeyCode(keyval); |
| 804 #endif | 806 #endif |
| 805 | 807 |
| 806 if (!key_code) | 808 if (!key_code) |
| 807 return; | 809 return; |
| 808 | 810 |
| 809 KeyEvent key(state & IBUS_RELEASE_MASK ? | 811 KeyEvent key(state & IBUS_RELEASE_MASK ? |
| 810 ui::ET_KEY_RELEASED : ui::ET_KEY_PRESSED, | 812 ui::ET_KEY_RELEASED : ui::ET_KEY_PRESSED, |
| 811 key_code, ViewsFlagsFromIBusState(state)); | 813 key_code, EventFlagsFromIBusState(state)); |
| 812 | 814 |
| 813 // It is not clear when the input method will forward us a fake key event. | 815 // It is not clear when the input method will forward us a fake key event. |
| 814 // If there is a pending key event, then we may already received some input | 816 // If there is a pending key event, then we may already received some input |
| 815 // method results, so we dispatch this fake key event directly rather than | 817 // method results, so we dispatch this fake key event directly rather than |
| 816 // calling ProcessKeyEventPostIME(), which will clear pending input method | 818 // calling ProcessKeyEventPostIME(), which will clear pending input method |
| 817 // results. | 819 // results. |
| 818 if (key.type() == ui::ET_KEY_PRESSED) | 820 if (key.type() == ui::ET_KEY_PRESSED) |
| 819 ProcessUnfilteredKeyPressEvent(key, keyval); | 821 ProcessUnfilteredKeyPressEvent(key, keyval); |
| 820 else | 822 else |
| 821 DispatchKeyEventPostIME(key); | 823 DispatchKeyEventPostIME(key); |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 950 DCHECK_EQ(GetIBus(), bus); | 952 DCHECK_EQ(GetIBus(), bus); |
| 951 DCHECK(data); | 953 DCHECK(data); |
| 952 IBusInputContext* ic = | 954 IBusInputContext* ic = |
| 953 ibus_bus_create_input_context_async_finish(bus, res, NULL); | 955 ibus_bus_create_input_context_async_finish(bus, res, NULL); |
| 954 if (ic) | 956 if (ic) |
| 955 data->StoreOrAbandonInputContext(ic); | 957 data->StoreOrAbandonInputContext(ic); |
| 956 delete data; | 958 delete data; |
| 957 } | 959 } |
| 958 | 960 |
| 959 } // namespace views | 961 } // namespace views |
| OLD | NEW |