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 3// found in the LICENSE file. 4 5#ifndef UI_BASE_IME_INPUT_METHOD_IBUS_H_ 6#define UI_BASE_IME_INPUT_METHOD_IBUS_H_ 7 8#include <set> 9#include <string> 10 11#include "base/basictypes.h" 12#include "base/compiler_specific.h" 13#include "base/memory/scoped_ptr.h" 14#include "base/memory/weak_ptr.h" 15#include "chromeos/dbus/ibus/ibus_input_context_client.h" 16#include "chromeos/ime/ibus_daemon_controller.h" 17#include "ui/base/ime/character_composer.h" 18#include "ui/base/ime/composition_text.h" 19#include "ui/base/ime/input_method_base.h" 20 21namespace dbus { 22class ObjectPath; 23} 24namespace chromeos { 25namespace ibus { 26class IBusText; 27} // namespace ibus 28} // namespace chromeos 29 30namespace ui { 31 32// A ui::InputMethod implementation based on IBus. 33class UI_EXPORT InputMethodIBus 34 : public InputMethodBase, 35 public chromeos::IBusInputContextHandlerInterface, 36 public chromeos::IBusDaemonController::Observer { 37 public: 38 explicit InputMethodIBus(internal::InputMethodDelegate* delegate); 39 virtual ~InputMethodIBus(); 40 41 // Overridden from InputMethod: 42 virtual void OnFocus() OVERRIDE; 43 virtual void OnBlur() OVERRIDE; 44 virtual bool OnUntranslatedIMEMessage(const base::NativeEvent& event, 45 NativeEventResult* result) OVERRIDE; 46 virtual void Init(bool focused) OVERRIDE; 47 virtual bool DispatchKeyEvent( 48 const base::NativeEvent& native_key_event) OVERRIDE; 49 virtual bool DispatchFabricatedKeyEvent(const ui::KeyEvent& event) OVERRIDE; 50 virtual void OnTextInputTypeChanged(const TextInputClient* client) OVERRIDE; 51 virtual void OnCaretBoundsChanged(const TextInputClient* client) OVERRIDE; 52 virtual void CancelComposition(const TextInputClient* client) OVERRIDE; 53 virtual void OnInputLocaleChanged() OVERRIDE; 54 virtual std::string GetInputLocale() OVERRIDE; 55 virtual base::i18n::TextDirection GetInputTextDirection() OVERRIDE; 56 virtual bool IsActive() OVERRIDE; 57 virtual bool IsCandidatePopupOpen() const OVERRIDE; 58 59 protected: 60 // chromeos::IBusDaemonController::Observer overrides. 61 virtual void OnConnected() OVERRIDE; 62 virtual void OnDisconnected() OVERRIDE; 63 64 // Converts |text| into CompositionText. 65 void ExtractCompositionText(const chromeos::IBusText& text, 66 uint32 cursor_position, 67 CompositionText* out_composition) const; 68 69 // Process a key returned from the input method. 70 virtual void ProcessKeyEventPostIME(const base::NativeEvent& native_key_event, 71 uint32 ibus_state, 72 bool handled); 73 74 // Converts |native_event| to ibus representation. 75 virtual void IBusKeyEventFromNativeKeyEvent( 76 const base::NativeEvent& native_event, 77 uint32* ibus_keyval, 78 uint32* ibus_keycode, 79 uint32* ibus_state); 80 81 // Resets context and abandon all pending results and key events. 82 void ResetContext(); 83 84 private: 85 enum InputContextState { 86 // The input context is not working. 87 INPUT_CONTEXT_STOP, 88 // The input context is waiting for CreateInputContext reply from 89 // ibus-daemon. 90 INPUT_CONTEXT_WAIT_CREATE_INPUT_CONTEXT_RESPONSE, 91 // The input context is working and ready to communicate with ibus-daemon. 92 INPUT_CONTEXT_RUNNING, 93 }; 94 class PendingKeyEvent; 95 96 // Overridden from InputMethodBase: 97 virtual void OnWillChangeFocusedClient(TextInputClient* focused_before, 98 TextInputClient* focused) OVERRIDE; 99 virtual void OnDidChangeFocusedClient(TextInputClient* focused_before, 100 TextInputClient* focused) OVERRIDE; 101 102 // Creates context asynchronously. 103 void CreateContext(); 104 105 // Sets necessary signal handlers. 106 void SetUpSignalHandlers(); 107 108 // Destroys context. 109 void DestroyContext(); 110 111 // Asks the client to confirm current composition text. 112 void ConfirmCompositionText(); 113 114 // Checks the availability of focused text input client and update focus 115 // state. 116 void UpdateContextFocusState(); 117 118 // Processes a key event that was already filtered by the input method. 119 // A VKEY_PROCESSKEY may be dispatched to the focused View. 120 void ProcessFilteredKeyPressEvent(const base::NativeEvent& native_key_event); 121 122 // Processes a key event that was not filtered by the input method. 123 void ProcessUnfilteredKeyPressEvent(const base::NativeEvent& native_key_event, 124 uint32 ibus_state); 125 void ProcessUnfilteredFabricatedKeyPressEvent(EventType type, 126 KeyboardCode key_code, 127 int event_flags); 128 129 // Sends input method result caused by the given key event to the focused text 130 // input client. 131 void ProcessInputMethodResult(const base::NativeEvent& native_key_event, 132 bool filtered); 133 134 // Checks if the pending input method result needs inserting into the focused 135 // text input client as a single character. 136 bool NeedInsertChar() const; 137 138 // Checks if there is pending input method result. 139 bool HasInputMethodResult() const; 140 141 // Abandons all pending key events. It usually happends when we lose keyboard 142 // focus, the text input type is changed or we are destroyed. 143 void AbandonAllPendingKeyEvents(); 144 145 // Releases context focus and confirms the composition text. Then destroy 146 // object proxy. 147 void ResetInputContext(); 148 149 // Returns true if the connection to ibus-daemon is established. 150 bool IsConnected(); 151 152 // Returns true if the input context is ready to use. 153 bool IsContextReady(); 154 155 // Passes keyevent and executes character composition if necessary. Returns 156 // true if character composer comsumes key event. 157 bool ExecuteCharacterComposer(uint32 ibus_keyval, 158 uint32 ibus_keycode, 159 uint32 ibus_state); 160 161 // chromeos::IBusInputContextHandlerInterface overrides: 162 virtual void CommitText(const chromeos::IBusText& text) OVERRIDE; 163 virtual void ForwardKeyEvent(uint32 keyval, 164 uint32 keycode, 165 uint32 state) OVERRIDE; 166 virtual void ShowPreeditText() OVERRIDE; 167 virtual void HidePreeditText() OVERRIDE; 168 virtual void UpdatePreeditText(const chromeos::IBusText& text, 169 uint32 cursor_pos, 170 bool visible) OVERRIDE; 171 virtual void DeleteSurroundingText(int32 offset, uint32 length) OVERRIDE; 172 173 void CreateInputContextDone(const dbus::ObjectPath& object_path); 174 void CreateInputContextFail(); 175 void ProcessKeyEventDone(uint32 id, XEvent* xevent, 176 uint32 ibus_keyval, uint32 ibus_keycode, 177 uint32 ibus_state, bool is_handled); 178 179 // All pending key events. Note: we do not own these object, we just save 180 // pointers to these object so that we can abandon them when necessary. 181 // They will be deleted in ProcessKeyEventDone(). 182 std::set<uint32> pending_key_events_; 183 184 // Represents input context's state. 185 InputContextState input_context_state_; 186 187 // The count of CreateInputContext message failure. 188 int create_input_context_fail_count_; 189 190 // Pending composition text generated by the current pending key event. 191 // It'll be sent to the focused text input client as soon as we receive the 192 // processing result of the pending key event. 193 CompositionText composition_; 194 195 // Pending result text generated by the current pending key event. 196 // It'll be sent to the focused text input client as soon as we receive the 197 // processing result of the pending key event. 198 string16 result_text_; 199 200 string16 previous_surrounding_text_; 201 ui::Range previous_selection_range_; 202 203 // Indicates if input context is focused or not. 204 bool context_focused_; 205 206 // Indicates if there is an ongoing composition text. 207 bool composing_text_; 208 209 // Indicates if the composition text is changed or deleted. 210 bool composition_changed_; 211 212 // If it's true then all input method result received before the next key 213 // event will be discarded. 214 bool suppress_next_result_; 215 216 // The latest id of key event. 217 uint32 current_keyevent_id_; 218 219 // An object to compose a character from a sequence of key presses 220 // including dead key etc. 221 CharacterComposer character_composer_; 222 223 // Used for making callbacks. 224 base::WeakPtrFactory<InputMethodIBus> weak_ptr_factory_; 225 226 DISALLOW_COPY_AND_ASSIGN(InputMethodIBus); 227}; 228 229} // namespace ui 230 231#endif // UI_BASE_IME_INPUT_METHOD_IBUS_H_ 232