Home | History | Annotate | Download | only in ime
      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 
     21 namespace dbus {
     22 class ObjectPath;
     23 }
     24 namespace chromeos {
     25 namespace ibus {
     26 class IBusText;
     27 }  // namespace ibus
     28 }  // namespace chromeos
     29 
     30 namespace ui {
     31 
     32 // A ui::InputMethod implementation based on IBus.
     33 class 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