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