OLD | NEW |
---|---|
(Empty) | |
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 "chromeos/dbus/ibus/ibus_input_context_client.h" | |
6 | |
7 #include <string> | |
8 #include "base/bind.h" | |
9 #include "base/callback.h" | |
10 #include "chromeos/dbus/ibus/ibus_constants.h" | |
11 #include "chromeos/dbus/ibus/ibus_text.h" | |
12 #include "dbus/bus.h" | |
13 #include "dbus/message.h" | |
14 #include "dbus/object_path.h" | |
15 #include "dbus/object_proxy.h" | |
16 | |
17 namespace chromeos { | |
18 | |
19 // TODO(nona): Remove after complete libibus removal. | |
20 using chromeos::ibus::IBusText; | |
21 | |
22 namespace { | |
23 const char kIBusInputContextInterface[] = "org.freedesktop.IBus.InputContext"; | |
24 | |
25 // Signal names. | |
26 const char kCommitTextSignal[] = "CommitText"; | |
27 const char kForwardKeyEventSignal[] = "ForwardKeyEvent"; | |
28 const char kHidePreeditTextSignal[] = "HidePreeditText"; | |
29 const char kShowPreeditTextSignal[] = "ShowPreeditText"; | |
30 const char kUpdatePreeditTextSignal[] = "UpdatePreeditText"; | |
31 | |
32 // Method names. | |
33 const char kFocusInMethod[] = "FocusIn"; | |
34 const char kFocusOutMethod[] = "FocusOut"; | |
35 const char kResetMethod[] = "Reset"; | |
36 const char kSetCapabilitiesMethod[] = "SetCapabilities"; | |
37 const char kSetCursorLocationMethod[] = "SetCursorLocation"; | |
38 const char kProcessKeyEventMethod[] = "ProcessKeyEvent"; | |
39 | |
40 // The IBusInputContextClient implementation. | |
41 class IBusInputContextClientImpl : public IBusInputContextClient { | |
42 public: | |
43 IBusInputContextClientImpl() | |
44 : proxy_(NULL), | |
45 weak_ptr_factory_(this) { | |
46 } | |
47 | |
48 virtual ~IBusInputContextClientImpl() {} | |
49 | |
50 public: | |
51 // IBusInputContextClient override. | |
52 virtual void Initialize(dbus::Bus* bus, | |
53 const dbus::ObjectPath& object_path) OVERRIDE { | |
54 if (proxy_ != NULL) { | |
55 LOG(ERROR) << "IBusInputContextClient is already initialized."; | |
56 return; | |
57 } | |
58 proxy_ = bus->GetObjectProxy(kIBusServiceName, object_path); | |
59 | |
60 ConnectSignals(); | |
61 } | |
62 | |
63 // IBusInputContextClient override. | |
64 virtual void ResetObjectProxy() OVERRIDE { | |
65 // Do not delete proxy here, proxy object is managed by dbus::Bus object. | |
66 proxy_ = NULL; | |
67 } | |
68 | |
69 // IBusInputContextClient override. | |
70 virtual bool IsConnected() const OVERRIDE { | |
71 return proxy_ != NULL; | |
72 } | |
73 | |
74 // IBusInputContextClient override. | |
75 virtual void SetCommitTextHandler( | |
76 const CommitTextHandler& commit_text_handler) OVERRIDE { | |
77 DCHECK(!commit_text_handler.is_null()); | |
78 commit_text_handler_ = commit_text_handler; | |
79 } | |
80 | |
81 // IBusInputContextClient override. | |
82 virtual void SetForwardKeyEventHandler( | |
83 const ForwardKeyEventHandler& forward_key_event_handler) OVERRIDE { | |
84 DCHECK(!forward_key_event_handler.is_null()); | |
85 forward_key_event_handler_ = forward_key_event_handler; | |
86 } | |
87 | |
88 // IBusInputContextClient override. | |
89 virtual void SetUpdatePreeditTextHandler( | |
90 const UpdatePreeditTextHandler& update_preedit_text_handler) OVERRIDE { | |
91 DCHECK(!update_preedit_text_handler.is_null()); | |
92 update_preedit_text_handler_ = update_preedit_text_handler; | |
93 } | |
94 | |
95 // IBusInputContextClient override. | |
96 virtual void SetShowPreeditTextHandler( | |
97 const ShowPreeditTextHandler& show_preedit_text_handler) OVERRIDE { | |
98 DCHECK(!show_preedit_text_handler.is_null()); | |
99 show_preedit_text_handler_ = show_preedit_text_handler; | |
100 } | |
101 | |
102 // IBusInputContextClient override. | |
103 virtual void SetHidePreeditTextHandler( | |
104 const HidePreeditTextHandler& hide_preedit_text_handler) OVERRIDE { | |
105 DCHECK(!hide_preedit_text_handler.is_null()); | |
106 hide_preedit_text_handler_ = hide_preedit_text_handler; | |
107 } | |
108 | |
109 // IBusInputContextClient override. | |
110 virtual void UnsetCommitTextHandler() OVERRIDE { | |
111 commit_text_handler_.Reset(); | |
112 } | |
113 | |
114 // IBusInputContextClient override. | |
115 virtual void UnsetForwardKeyEventHandler() OVERRIDE { | |
116 forward_key_event_handler_.Reset(); | |
117 } | |
118 | |
119 // IBusInputContextClient override. | |
120 virtual void UnsetUpdatePreeditTextHandler() OVERRIDE { | |
121 update_preedit_text_handler_.Reset(); | |
122 } | |
123 | |
124 // IBusInputContextClient override. | |
125 virtual void UnsetShowPreeditTextHandler() OVERRIDE { | |
126 show_preedit_text_handler_.Reset(); | |
127 } | |
128 | |
129 // IBusInputContextClient override. | |
130 virtual void UnsetHidePreeditTextHandler() OVERRIDE { | |
131 hide_preedit_text_handler_.Reset(); | |
132 } | |
133 | |
134 // IBusInputContextClient override. | |
135 virtual void SetCapabilities(uint32 capabilities) OVERRIDE { | |
136 dbus::MethodCall method_call(kIBusInputContextInterface, | |
137 kSetCapabilitiesMethod); | |
138 dbus::MessageWriter writer(&method_call); | |
139 writer.AppendUint32(capabilities); | |
140 proxy_->CallMethod(&method_call, | |
141 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
142 base::Bind(&IBusInputContextClientImpl::DefaultCallback, | |
143 kSetCapabilitiesMethod)); | |
144 } | |
145 | |
146 // IBusInputContextClient override. | |
147 virtual void FocusIn() OVERRIDE { | |
148 dbus::MethodCall method_call(kIBusInputContextInterface, kFocusInMethod); | |
149 proxy_->CallMethod(&method_call, | |
150 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
151 base::Bind(&IBusInputContextClientImpl::DefaultCallback, | |
152 kFocusInMethod)); | |
153 } | |
154 | |
155 // IBusInputContextClient override. | |
156 virtual void FocusOut() OVERRIDE { | |
157 dbus::MethodCall method_call(kIBusInputContextInterface, kFocusOutMethod); | |
158 proxy_->CallMethod(&method_call, | |
159 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
160 base::Bind(&IBusInputContextClientImpl::DefaultCallback, | |
161 kFocusOutMethod)); | |
162 } | |
163 | |
164 // IBusInputContextClient override. | |
165 virtual void Reset() OVERRIDE { | |
166 dbus::MethodCall method_call(kIBusInputContextInterface, kResetMethod); | |
167 proxy_->CallMethod(&method_call, | |
168 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
169 base::Bind(&IBusInputContextClientImpl::DefaultCallback, | |
170 kResetMethod)); | |
171 } | |
172 | |
173 // IBusInputContextClient override. | |
174 virtual void SetCursorLocation(int32 x, int32 y, int32 w, int32 h) OVERRIDE { | |
satorux1
2012/05/22 21:41:00
w -> width, h -> height...
Seigo Nonaka
2012/05/22 22:10:00
Done.
| |
175 dbus::MethodCall method_call(kIBusInputContextInterface, | |
176 kSetCursorLocationMethod); | |
177 dbus::MessageWriter writer(&method_call); | |
178 writer.AppendInt32(x); | |
179 writer.AppendInt32(y); | |
180 writer.AppendInt32(w); | |
181 writer.AppendInt32(h); | |
182 proxy_->CallMethod(&method_call, | |
183 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
184 base::Bind(&IBusInputContextClientImpl::DefaultCallback, | |
185 kSetCursorLocationMethod)); | |
186 } | |
187 | |
188 // IBusInputContextClient override. | |
189 virtual void ProcessKeyEvent( | |
190 uint32 keyval, | |
191 uint32 keycode, | |
192 uint32 state, | |
193 const ProcessKeyEventCallback& callback) OVERRIDE { | |
194 dbus::MethodCall method_call(kIBusInputContextInterface, | |
195 kProcessKeyEventMethod); | |
196 dbus::MessageWriter writer(&method_call); | |
197 writer.AppendUint32(keyval); | |
198 writer.AppendUint32(keycode); | |
199 writer.AppendUint32(state); | |
200 proxy_->CallMethod( | |
201 &method_call, | |
202 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
203 base::Bind(&IBusInputContextClientImpl::OnProcessKeyEvent, | |
204 callback)); | |
205 } | |
206 | |
207 private: | |
208 // Handles no response method call reply. | |
209 static void DefaultCallback(const std::string& method_name, | |
210 dbus::Response* response) { | |
211 if (!response) { | |
212 LOG(ERROR) << "Failed to call method: " << method_name; | |
213 return; | |
214 } | |
215 } | |
216 | |
217 // Handles ProcessKeyEvent method call reply. | |
218 static void OnProcessKeyEvent(const ProcessKeyEventCallback& callback, | |
219 dbus::Response* response) { | |
220 if (!response) { | |
221 LOG(ERROR) << "Cannot get input context: " << response->ToString(); | |
222 return; | |
223 } | |
224 dbus::MessageReader reader(response); | |
225 bool is_keyevent_used; | |
226 if (!reader.PopBool(&is_keyevent_used)) { | |
227 // The IBus message structure may be changed. | |
228 LOG(ERROR) << "Invalid response: " << response->ToString(); | |
229 return; | |
230 } | |
231 DCHECK(!callback.is_null()); | |
232 callback.Run(is_keyevent_used); | |
233 } | |
234 | |
235 // Handles CommitText signal. | |
236 void OnCommitText(dbus::Signal* signal) { | |
237 if (commit_text_handler_.is_null()) | |
238 return; | |
239 dbus::MessageReader reader(signal); | |
240 IBusText ibus_text; | |
241 if (!PopIBusText(&reader, &ibus_text)) { | |
242 // The IBus message structure may be changed. | |
243 LOG(ERROR) << "Invalid signal: " << signal->ToString(); | |
244 return; | |
245 } | |
246 commit_text_handler_.Run(ibus_text); | |
247 } | |
248 | |
249 // Handles ForwardKeyEvetn signal. | |
250 void OnForwardKeyEvent(dbus::Signal* signal) { | |
251 if (forward_key_event_handler_.is_null()) | |
252 return; | |
253 dbus::MessageReader reader(signal); | |
254 uint32 keyval = 0; | |
255 uint32 keycode = 0; | |
256 uint32 state = 0; | |
257 if (!reader.PopUint32(&keyval) || | |
258 !reader.PopUint32(&keycode) || | |
259 !reader.PopUint32(&state)) { | |
260 // The IBus message structure may be changed. | |
261 LOG(ERROR) << "Invalid signal: " << signal->ToString(); | |
262 return; | |
263 } | |
264 forward_key_event_handler_.Run(keyval, keycode, state); | |
265 } | |
266 | |
267 // Handles UpdatePreeditText signal. | |
268 void OnUpdatePreeditText(dbus::Signal* signal) { | |
269 if (update_preedit_text_handler_.is_null()) | |
270 return; | |
271 dbus::MessageReader reader(signal); | |
272 IBusText ibus_text; | |
273 uint32 cursor_pos = 0; | |
274 bool visible = true; | |
275 if (!PopIBusText(&reader, &ibus_text) || | |
276 !reader.PopUint32(&cursor_pos) || | |
277 !reader.PopBool(&visible)) { | |
278 // The IBus message structure may be changed. | |
279 LOG(ERROR) << "Invalid signal: " << signal->ToString(); | |
280 return; | |
281 } | |
282 update_preedit_text_handler_.Run(ibus_text, cursor_pos, visible); | |
283 } | |
284 | |
285 // Handles ShowPreeditText signal. | |
286 void OnShowPreeditText(dbus::Signal* signal) { | |
287 if (!show_preedit_text_handler_.is_null()) | |
288 show_preedit_text_handler_.Run(); | |
289 } | |
290 | |
291 // Handles HidePreeditText signal. | |
292 void OnHidePreeditText(dbus::Signal* signal) { | |
293 if (!hide_preedit_text_handler_.is_null()) | |
294 hide_preedit_text_handler_.Run(); | |
295 } | |
296 | |
297 // Connects signals to signal handlers. | |
298 void ConnectSignals() { | |
299 proxy_->ConnectToSignal( | |
300 kIBusInputContextInterface, | |
301 kCommitTextSignal, | |
302 base::Bind(&IBusInputContextClientImpl::OnCommitText, | |
303 weak_ptr_factory_.GetWeakPtr()), | |
304 base::Bind(&IBusInputContextClientImpl::OnSignalConnected, | |
305 weak_ptr_factory_.GetWeakPtr())); | |
306 | |
307 proxy_->ConnectToSignal( | |
308 kIBusInputContextInterface, | |
309 kForwardKeyEventSignal, | |
310 base::Bind(&IBusInputContextClientImpl::OnForwardKeyEvent, | |
311 weak_ptr_factory_.GetWeakPtr()), | |
312 base::Bind(&IBusInputContextClientImpl::OnSignalConnected, | |
313 weak_ptr_factory_.GetWeakPtr())); | |
314 | |
315 proxy_->ConnectToSignal( | |
316 kIBusInputContextInterface, | |
317 kUpdatePreeditTextSignal, | |
318 base::Bind(&IBusInputContextClientImpl::OnUpdatePreeditText, | |
319 weak_ptr_factory_.GetWeakPtr()), | |
320 base::Bind(&IBusInputContextClientImpl::OnSignalConnected, | |
321 weak_ptr_factory_.GetWeakPtr())); | |
322 | |
323 proxy_->ConnectToSignal( | |
324 kIBusInputContextInterface, | |
325 kShowPreeditTextSignal, | |
326 base::Bind(&IBusInputContextClientImpl::OnShowPreeditText, | |
327 weak_ptr_factory_.GetWeakPtr()), | |
328 base::Bind(&IBusInputContextClientImpl::OnSignalConnected, | |
329 weak_ptr_factory_.GetWeakPtr())); | |
330 | |
331 proxy_->ConnectToSignal( | |
332 kIBusInputContextInterface, | |
333 kHidePreeditTextSignal, | |
334 base::Bind(&IBusInputContextClientImpl::OnHidePreeditText, | |
335 weak_ptr_factory_.GetWeakPtr()), | |
336 base::Bind(&IBusInputContextClientImpl::OnSignalConnected, | |
337 weak_ptr_factory_.GetWeakPtr())); | |
338 } | |
339 | |
340 // Handles the result of signal connection setup. | |
341 void OnSignalConnected(const std::string& interface, | |
342 const std::string& signal, | |
343 bool succeeded) { | |
344 LOG_IF(ERROR, !succeeded) << "Connect to " << interface << " " | |
345 << signal << " failed."; | |
346 } | |
347 | |
348 dbus::ObjectProxy* proxy_; | |
349 | |
350 // Signal handlers. | |
351 CommitTextHandler commit_text_handler_; | |
352 ForwardKeyEventHandler forward_key_event_handler_; | |
353 HidePreeditTextHandler hide_preedit_text_handler_; | |
354 ShowPreeditTextHandler show_preedit_text_handler_; | |
355 UpdatePreeditTextHandler update_preedit_text_handler_; | |
356 | |
357 base::WeakPtrFactory<IBusInputContextClientImpl> weak_ptr_factory_; | |
358 | |
359 DISALLOW_COPY_AND_ASSIGN(IBusInputContextClientImpl); | |
360 }; | |
361 | |
362 // A stub implementation of IBusInputContextClient. | |
363 class IBusInputContextClientStubImpl : public IBusInputContextClient { | |
364 public: | |
365 IBusInputContextClientStubImpl() {} | |
366 | |
367 virtual ~IBusInputContextClientStubImpl() {} | |
368 | |
369 public: | |
370 // IBusInputContextClient override. | |
371 virtual void Initialize(dbus::Bus* bus, | |
372 const dbus::ObjectPath& object_path) OVERRIDE {} | |
373 // IBusInputContextClient override. | |
374 virtual void ResetObjectProxy() OVERRIDE {} | |
375 // IBusInputContextClient override. | |
376 virtual bool IsConnected() const OVERRIDE { | |
377 return true; | |
378 } | |
379 // IBusInputContextClient overrides. | |
380 virtual void SetCommitTextHandler( | |
381 const CommitTextHandler& commit_text_handler) OVERRIDE {} | |
382 virtual void SetForwardKeyEventHandler( | |
383 const ForwardKeyEventHandler& forward_key_event_handler) OVERRIDE {} | |
384 virtual void SetUpdatePreeditTextHandler( | |
385 const UpdatePreeditTextHandler& update_preedit_text_handler) OVERRIDE {} | |
386 virtual void SetShowPreeditTextHandler( | |
387 const ShowPreeditTextHandler& show_preedit_text_handler) OVERRIDE {} | |
388 virtual void SetHidePreeditTextHandler( | |
389 const HidePreeditTextHandler& hide_preedit_text_handler) OVERRIDE {} | |
390 virtual void UnsetCommitTextHandler() OVERRIDE {} | |
391 virtual void UnsetForwardKeyEventHandler() OVERRIDE {} | |
392 virtual void UnsetUpdatePreeditTextHandler() OVERRIDE {} | |
393 virtual void UnsetShowPreeditTextHandler() OVERRIDE {} | |
394 virtual void UnsetHidePreeditTextHandler() OVERRIDE {} | |
395 virtual void SetCapabilities(uint32 capability) OVERRIDE {} | |
396 virtual void FocusIn() OVERRIDE {} | |
397 virtual void FocusOut() OVERRIDE {} | |
398 virtual void Reset() OVERRIDE {} | |
399 virtual void SetCursorLocation(int32 x, int32 y, int32 w, int32 h) OVERRIDE {} | |
400 virtual void ProcessKeyEvent( | |
401 uint32 keyval, | |
402 uint32 keycode, | |
403 uint32 state, | |
404 const ProcessKeyEventCallback& callback) OVERRIDE { | |
405 callback.Run(false); | |
406 } | |
407 | |
408 private: | |
409 DISALLOW_COPY_AND_ASSIGN(IBusInputContextClientStubImpl); | |
410 }; | |
411 | |
412 } // namespace | |
413 | |
414 /////////////////////////////////////////////////////////////////////////////// | |
415 // IBusInputContextClient | |
416 | |
417 IBusInputContextClient::IBusInputContextClient() {} | |
418 | |
419 IBusInputContextClient::~IBusInputContextClient() {} | |
420 | |
421 // static | |
422 IBusInputContextClient* IBusInputContextClient::Create( | |
423 DBusClientImplementationType type) { | |
424 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) { | |
425 return new IBusInputContextClientImpl(); | |
426 } | |
427 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type); | |
428 return new IBusInputContextClientStubImpl(); | |
429 } | |
430 } // namespace chromeos | |
OLD | NEW |