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 #include "ui/base/ime/fake_input_method.h" 6 7 #include "base/logging.h" 8 #include "base/strings/string16.h" 9 #include "ui/base/events/event.h" 10 #include "ui/base/events/event_constants.h" 11 #include "ui/base/events/event_utils.h" 12 #include "ui/base/glib/glib_integers.h" 13 #include "ui/base/ime/input_method_delegate.h" 14 #include "ui/base/ime/text_input_client.h" 15 #include "ui/base/keycodes/keyboard_code_conversion.h" 16 17 #if defined(USE_X11) 18 #include <X11/X.h> 19 #include <X11/Xlib.h> 20 #include <X11/Xutil.h> 21 #include "ui/base/keycodes/keyboard_code_conversion_x.h" 22 #endif 23 24 namespace { 25 26 #if defined(USE_X11) 27 uint32 EventFlagsFromXFlags(unsigned int flags) { 28 return (flags & LockMask ? ui::EF_CAPS_LOCK_DOWN : 0U) | 29 (flags & ControlMask ? ui::EF_CONTROL_DOWN : 0U) | 30 (flags & ShiftMask ? ui::EF_SHIFT_DOWN : 0U) | 31 (flags & Mod1Mask ? ui::EF_ALT_DOWN : 0U); 32 } 33 #endif 34 35 } // namespace 36 37 namespace ui { 38 39 FakeInputMethod::FakeInputMethod(internal::InputMethodDelegate* delegate) 40 : delegate_(NULL), 41 text_input_client_(NULL) { 42 SetDelegate(delegate); 43 } 44 45 FakeInputMethod::~FakeInputMethod() { 46 } 47 48 void FakeInputMethod::SetDelegate(internal::InputMethodDelegate* delegate) { 49 delegate_ = delegate; 50 } 51 52 void FakeInputMethod::SetFocusedTextInputClient(TextInputClient* client) { 53 text_input_client_ = client; 54 FOR_EACH_OBSERVER(InputMethodObserver, observers_, 55 OnTextInputStateChanged(client)); 56 } 57 58 TextInputClient* FakeInputMethod::GetTextInputClient() const { 59 return text_input_client_; 60 } 61 62 bool FakeInputMethod::DispatchKeyEvent(const base::NativeEvent& native_event) { 63 bool handled = false; 64 #if defined(OS_WIN) 65 if (native_event.message == WM_CHAR) { 66 if (text_input_client_) { 67 text_input_client_->InsertChar(ui::KeyboardCodeFromNative(native_event), 68 ui::EventFlagsFromNative(native_event)); 69 handled = true; 70 } 71 } else { 72 handled = delegate_->DispatchKeyEventPostIME(native_event); 73 } 74 #elif defined(USE_X11) 75 DCHECK(native_event); 76 if (native_event->type == KeyRelease) { 77 // On key release, just dispatch it. 78 handled = delegate_->DispatchKeyEventPostIME(native_event); 79 } else { 80 const uint32 state = EventFlagsFromXFlags(native_event->xkey.state); 81 // Send a RawKeyDown event first, 82 handled = delegate_->DispatchKeyEventPostIME(native_event); 83 if (text_input_client_) { 84 // then send a Char event via ui::TextInputClient. 85 const KeyboardCode key_code = ui::KeyboardCodeFromNative(native_event); 86 uint16 ch = 0; 87 if (!(state & ui::EF_CONTROL_DOWN)) 88 ch = ui::GetCharacterFromXEvent(native_event); 89 if (!ch) 90 ch = ui::GetCharacterFromKeyCode(key_code, state); 91 if (ch) 92 text_input_client_->InsertChar(ch, state); 93 } 94 } 95 #else 96 // TODO(yusukes): Support other platforms. Call InsertChar() when necessary. 97 handled = delegate_->DispatchKeyEventPostIME(native_event); 98 #endif 99 return handled; 100 } 101 102 bool FakeInputMethod::DispatchFabricatedKeyEvent(const ui::KeyEvent& event) { 103 bool handled = delegate_->DispatchFabricatedKeyEventPostIME( 104 event.type(), event.key_code(), event.flags()); 105 if (event.type() == ET_KEY_PRESSED && text_input_client_) { 106 uint16 ch = event.GetCharacter(); 107 if (ch) 108 text_input_client_->InsertChar(ch, event.flags()); 109 } 110 return handled; 111 } 112 113 void FakeInputMethod::Init(bool focused) {} 114 void FakeInputMethod::OnFocus() {} 115 void FakeInputMethod::OnBlur() {} 116 bool FakeInputMethod::OnUntranslatedIMEMessage(const base::NativeEvent& event, 117 NativeEventResult* result) { 118 return false; 119 } 120 void FakeInputMethod::OnTextInputTypeChanged(const TextInputClient* client) { 121 FOR_EACH_OBSERVER(InputMethodObserver, observers_, 122 OnTextInputStateChanged(client)); 123 } 124 void FakeInputMethod::OnCaretBoundsChanged(const TextInputClient* client) {} 125 void FakeInputMethod::CancelComposition(const TextInputClient* client) {} 126 void FakeInputMethod::OnInputLocaleChanged() {} 127 128 std::string FakeInputMethod::GetInputLocale() { 129 return ""; 130 } 131 132 base::i18n::TextDirection FakeInputMethod::GetInputTextDirection() { 133 return base::i18n::UNKNOWN_DIRECTION; 134 } 135 136 bool FakeInputMethod::IsActive() { 137 return true; 138 } 139 140 bool FakeInputMethod::IsCandidatePopupOpen() const { 141 return false; 142 } 143 144 ui::TextInputType FakeInputMethod::GetTextInputType() const { 145 return ui::TEXT_INPUT_TYPE_NONE; 146 } 147 148 bool FakeInputMethod::CanComposeInline() const { 149 return true; 150 } 151 152 void FakeInputMethod::AddObserver(InputMethodObserver* observer) { 153 observers_.AddObserver(observer); 154 } 155 156 void FakeInputMethod::RemoveObserver(InputMethodObserver* observer) { 157 observers_.RemoveObserver(observer); 158 } 159 160 } // namespace ui 161