Send module name of keyboard Engine
[platform/core/uifw/ise-default.git] / src / ise-dbus.cpp
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <dlog.h>
18 #include <inputmethod.h>
19 #include <inputmethod_internal.h>
20 #include <pkgmgr-info.h>
21
22 #include "ise-dbus.h"
23
24 #ifdef LOG_TAG
25 #undef LOG_TAG
26 #endif
27 #define LOG_TAG "ISE_DEFAULT"
28
29 static bool is_server_started = false;
30 static engine_loader_dbus_info_s *dbus_info = NULL;
31
32 static void _server_appeared_cb(GDBusConnection *connection, const gchar *name, const gchar *name_owner, gpointer user_data)
33 {
34     LOGD("name : %s, name_owner : %s", name, name_owner);
35 }
36
37 static void _server_vanished_cb(GDBusConnection *connection, const gchar *name, gpointer user_data)
38 {
39     LOGD("name : %s", name);
40 }
41
42 static bool _dbus_init()
43 {
44     GError *error = NULL;
45     int watch_id = 0;
46
47     if (dbus_info->gdbus_connection == NULL) {
48         GDBusConnection *conn = NULL;
49         conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
50         if (conn == NULL) {
51             if (error != NULL) {
52                 LOGE("g_bus_get_sync error message = %s", error->message);
53                 g_error_free(error);
54             }
55             return false;
56         }
57         dbus_info->gdbus_connection = conn;
58     }
59
60     LOGD("Connected bus name : %s", g_dbus_connection_get_unique_name(dbus_info->gdbus_connection));
61     watch_id = g_bus_watch_name(G_BUS_TYPE_SYSTEM,
62                                 ENGINE_LOADER_DBUS_NAME,
63                                 G_BUS_NAME_WATCHER_FLAGS_NONE,
64                                 _server_appeared_cb,
65                                 _server_vanished_cb,
66                                 NULL, NULL);
67
68     if (watch_id == 0) {
69         LOGE("Failed to get identifier");
70         return false;
71     }
72
73     return true;
74 }
75
76 static void _handle_engine_loader_cb(GDBusConnection *connection,
77                                      const gchar *sender_name,
78                                      const gchar *object_path,
79                                      const gchar *interface_name,
80                                      const gchar *signal_name,
81                                      GVariant *parameters,
82                                      gpointer user_data)
83 {
84     LOGD("own_name : %s, signal_name : %s", g_dbus_connection_get_unique_name(connection), signal_name);
85
86     if (g_strcmp0(signal_name, "show_preedit_string") == 0) {
87         int ret = ime_show_preedit_string();
88         if (ret != IME_ERROR_NONE)
89             LOGE("ime_show_preedit_string() failed");
90     } else if (g_strcmp0(signal_name, "update_preedit_string") == 0) {
91         GVariantIter *attr_iter = NULL;
92         GVariant *iter_body;
93         char *preedit_string = NULL;
94         unsigned int start;
95         unsigned int length;
96         unsigned int type;
97         unsigned int value;
98         Eina_List *list = NULL;
99             ime_preedit_attribute *attr;
100
101         g_variant_get(parameters, "(a(v)&s)", &attr_iter, &preedit_string);
102         if (!attr_iter || !preedit_string)
103             LOGE("Failed to get variant");
104
105         while (g_variant_iter_loop (attr_iter, "(v)", &iter_body)) {
106             g_variant_get(iter_body, "(uuuu)", &start, &length, &type, &value);
107             attr = (ime_preedit_attribute *)calloc(1, sizeof(ime_preedit_attribute));
108             attr->start = start;
109             attr->length = length;
110             attr->type = (ime_attribute_type)type;
111             attr->value = value;
112             list = eina_list_append(list, attr);
113         }
114
115         int ret = ime_update_preedit_string(preedit_string, list);
116         if (ret != IME_ERROR_NONE) {
117             EINA_LIST_FREE(list, attr)
118                 free(attr);
119         }
120     } else if (g_strcmp0(signal_name, "hide_preedit_string") == 0) {
121         int ret = ime_hide_preedit_string();
122         if (ret != IME_ERROR_NONE)
123             LOGE("ime_hide_preedit_string() failed");
124     } else if (g_strcmp0(signal_name, "commit_string") == 0) {
125         char *commit_string = NULL;
126         g_variant_get(parameters, "(&s)", &commit_string);
127         if (!commit_string)
128             LOGE("Failed to get variant");
129
130         int ret = ime_commit_string(commit_string);
131         if (ret != IME_ERROR_NONE)
132             LOGE("ime_commit_string() failed");
133     } else if (g_strcmp0(signal_name, "forward_key_event") == 0) {
134         GVariantIter *key_event_iter = NULL;
135         GVariant *value = NULL;
136         gchar *key = NULL;
137         scim::KeyEvent key_event;
138         char *dev_name = NULL;
139
140         g_variant_get(parameters, "(a{sv}&s)", &key_event_iter, &dev_name);
141         if (!key_event_iter)
142             LOGD("Failed to get iter");
143
144         key_event.dev_name = std::string(dev_name);
145         while (g_variant_iter_loop (key_event_iter, "{sv}", &key, &value)) {
146             if (g_strcmp0(key, "key_code") == 0)
147                 key_event.code = g_variant_get_uint32(value);
148             else if (g_strcmp0(key, "key_mask") == 0)
149                 key_event.mask = g_variant_get_uint16(value);
150             else if (g_strcmp0(key, "key_layout") == 0)
151                 key_event.layout = g_variant_get_uint16(value);
152             else if (g_strcmp0(key, "key_dev_class") == 0)
153                 key_event.dev_class = g_variant_get_uint16(value);
154             else if (g_strcmp0(key, "key_dev_subclass") == 0)
155                 key_event.dev_subclass = g_variant_get_uint16(value);
156         }
157
158         if (key)
159             g_free(key);
160
161         if (value)
162             g_variant_unref(value);
163
164         int ret = ime_send_key_event((ime_key_code_e)key_event.code, (ime_key_mask_e)key_event.mask, true);
165         if (ret != IME_ERROR_NONE)
166             LOGE("ime_send_key_event() failed");
167     } else if (g_strcmp0(signal_name, "delete_surrounding_text") == 0) {
168         int offset, len;
169         g_variant_get(parameters, "(ii)", &offset, &len);
170
171         int ret = ime_delete_surrounding_text(offset, len);
172         if (ret != IME_ERROR_NONE)
173             LOGE("ime_delete_surrounding_text() failed");
174     } else if (g_strcmp0(signal_name, "set_selection") == 0) {
175         int start, end;
176         g_variant_get(parameters, "(ii)", &start, &end);
177
178         int ret = ime_set_selection(start, end);
179         if (ret != IME_ERROR_NONE)
180             LOGE("ime_set_selection() failed");
181     } else if (g_strcmp0(signal_name, "send_private_command") == 0) {
182         char *private_command = NULL;
183         g_variant_get(parameters, "(&s)", &private_command);
184         if (!private_command)
185             LOGE("Failed to get variant");
186
187         int ret = ime_send_private_command(private_command);
188         if (ret != IME_ERROR_NONE)
189             LOGE("ime_send_private_command() failed");
190     } else if (g_strcmp0(signal_name, "show_aux_string") == 0) {
191         int ret = ime_show_aux_string();
192         if (ret != IME_ERROR_NONE)
193             LOGE("ime_show_aux_string() failed");
194     } else if (g_strcmp0(signal_name, "show_lookup_table") == 0) {
195         int ret = ime_show_lookup_table();
196         if (ret != IME_ERROR_NONE)
197             LOGE("ime_show_lookup_table() failed");
198     } else if (g_strcmp0(signal_name, "hide_aux_string") == 0) {
199         int ret = ime_hide_aux_string();
200         if (ret != IME_ERROR_NONE)
201             LOGE("ime_hide_aux_string() failed");
202     } else if (g_strcmp0(signal_name, "hide_lookup_table") == 0) {
203         int ret = ime_hide_lookup_table();
204         if (ret != IME_ERROR_NONE)
205             LOGE("ime_hide_lookup_table() failed");
206     } else if (g_strcmp0(signal_name, "update_preedit_caret") == 0) {
207         int caret;
208         g_variant_get(parameters, "(i)", &caret);
209
210         int ret = ime_update_preedit_caret(caret);
211         if (ret != IME_ERROR_NONE)
212             LOGE("ime_update_preedit_caret() failed");
213     } else if (g_strcmp0(signal_name, "update_preedit_string_with_commit") == 0) {
214         GVariantIter *attr_iter = NULL;
215         GVariant *iter_body;
216         char *preedit_string = NULL;
217         char *commit_string = NULL;
218         int caret;
219         unsigned int start;
220         unsigned int length;
221         unsigned int type;
222         unsigned int value;
223         scim::AttributeList attr;
224
225         g_variant_get(parameters, "(a(v)&s&si)", &attr_iter, &preedit_string, &commit_string, &caret);
226         if (!attr_iter || !preedit_string || !commit_string)
227             LOGE("Failed to get variant");
228
229         while (g_variant_iter_loop (attr_iter, "(v)", &iter_body)) {
230             g_variant_get(iter_body, "(uuuu)", &start, &length, &type, &value);
231             attr.push_back(scim::Attribute(start, length, (scim::AttributeType)type, value));
232         }
233
234         int ret = ime_update_preedit_string_with_commit(preedit_string, commit_string, attr, caret);
235         if (ret != IME_ERROR_NONE)
236             LOGE("ime_update_preedit_string_with_commit() failed");
237     } else if (g_strcmp0(signal_name, "update_aux_string") == 0) {
238         GVariantIter *attr_iter = NULL;
239         GVariant *iter_body;
240         char *aux_string = NULL;
241         unsigned int start;
242         unsigned int length;
243         unsigned int type;
244         unsigned int value;
245         scim::AttributeList attr;
246
247         g_variant_get(parameters, "(a(v)&s)", &attr_iter, &aux_string);
248         if (!attr_iter || !aux_string)
249             LOGE("Failed to get variant");
250
251         while (g_variant_iter_loop (attr_iter, "(v)", &iter_body)) {
252             g_variant_get(iter_body, "(uuuu)", &start, &length, &type, &value);
253             attr.push_back(scim::Attribute(start, length, (scim::AttributeType)type, value));
254         }
255
256         int ret = ime_update_aux_string(aux_string);
257         if (ret != IME_ERROR_NONE)
258             LOGE("ime_update_aux_string() failed");
259     } else if (g_strcmp0(signal_name, "recapture_string") == 0) {
260         GVariantIter *attr_iter = NULL;
261         GVariant *iter_body;
262         char *preedit_string = NULL;
263         char *commit_string = NULL;
264         int offset, len;
265         unsigned int start;
266         unsigned int length;
267         unsigned int type;
268         unsigned int value;
269         scim::AttributeList attr;
270
271         g_variant_get(parameters, "(a(v)&s&sii)", &attr_iter, &preedit_string, &commit_string, &offset, &len);
272         if (!attr_iter || !preedit_string || !commit_string)
273             LOGE("Failed to get variant");
274
275         while (g_variant_iter_loop (attr_iter, "(v)", &iter_body)) {
276             g_variant_get(iter_body, "(uuuu)", &start, &length, &type, &value);
277             attr.push_back(scim::Attribute(start, length, (scim::AttributeType)type, value));
278         }
279
280         int ret = ime_recapture_string(offset, len, preedit_string, commit_string, attr);
281         if (ret != IME_ERROR_NONE)
282             LOGE("ime_recapture_string() failed");
283     } else if (g_strcmp0(signal_name, "update_lookup_table") == 0) {
284         GVariantIter *attr_iter = NULL;
285         GVariantIter *candidate_iter = NULL;
286         GVariant *attrs_iter_body;
287         GVariant *candidate_iter_body;
288         scim::CommonLookupTable lookup_table;
289         scim::AttributeList attr_list;
290         char *candidate_text = NULL;
291         int idx = 0;
292         int page_size;
293         int cursor_pos;
294
295         g_variant_get(parameters, "(a(a(v))a(v)ii)", &attr_iter, &candidate_iter, &page_size, &cursor_pos);
296         if (!attr_iter || !candidate_iter)
297             LOGE("Failed to get variant");
298
299         lookup_table.set_page_size(page_size);
300         lookup_table.set_cursor_pos(cursor_pos);
301
302         while (g_variant_iter_loop (candidate_iter, "(v)", &candidate_iter_body)) {
303             g_variant_get(candidate_iter_body, "(&s)", &candidate_text);
304             lookup_table.append_candidate(scim::utf8_mbstowcs ((const char*)candidate_text));
305         }
306
307         while (g_variant_iter_loop (attr_iter, "(a(v))", &attrs_iter_body)) {
308             GVariantIter *innter_iter = NULL;
309             GVariant *iner_body;
310             g_variant_get(attrs_iter_body, "(a(v))", &innter_iter);
311             while (g_variant_iter_loop (innter_iter, "(v)", &iner_body)) {
312                 int start, length, type, value;
313                 g_variant_get(iner_body, "(uuuu)", &start, &length, &type, &value);
314
315                 if (start == 0 && length == 0 && type == 0 && value == 0)
316                     break;
317                 else
318                     attr_list.push_back(scim::Attribute(start, length, (scim::AttributeType)type, value));
319             }
320
321             if (!attr_list.empty())
322                 lookup_table.add_attributes(idx++, attr_list);
323             attr_list.clear();
324         }
325
326         int ret = ime_update_lookup_table(lookup_table);
327         if (ret != IME_ERROR_NONE)
328             LOGE("ime_update_lookup_table() failed");
329     } else if (g_strcmp0(signal_name, "register_properties") == 0) {
330         GVariantIter *list_iter = NULL;
331         GVariant *iter_body;
332         scim::PropertyList property_list;
333         scim::Property property;
334         char *key = NULL;
335         char *label = NULL;
336         char *icon = NULL;
337         char *tip = NULL;
338
339         g_variant_get(parameters, "(a(v))", &list_iter);
340         if (!list_iter)
341             LOGE("Failed to get variant");
342
343         while (g_variant_iter_loop (list_iter, "(v)", &iter_body)) {
344             g_variant_get(iter_body, "(&s&s&s&s)", &key, &label, &icon, &tip);
345             property.set_key(scim::String(key));
346             property.set_label(scim::String(label));
347             property.set_icon(scim::String(icon));
348             property.set_tip(scim::String(tip));
349             property_list.push_back(property);
350         }
351
352         int ret = ime_register_properties(property_list);
353         if (ret != IME_ERROR_NONE)
354             LOGE("ime_register_properties() failed");
355     } else if (g_strcmp0(signal_name, "update_property") == 0) {
356         char *key = NULL;
357         char *label = NULL;
358         char *icon = NULL;
359         char *tip = NULL;
360         scim::Property property;
361
362         g_variant_get(parameters, "(&s&s&s&s)", &key, &label, &icon, &tip);
363
364         property.set_key(scim::String(key));
365         property.set_label(scim::String(label));
366         property.set_icon(scim::String(icon));
367         property.set_tip(scim::String(tip));
368
369         int ret = ime_update_property(property);
370         if (ret != IME_ERROR_NONE)
371             LOGE("ime_update_property() failed");
372     } else if (g_strcmp0(signal_name, "expand_candidate") == 0) {
373         int ret = ime_expand_candidate();
374         if (ret != IME_ERROR_NONE)
375             LOGE("ime_expand_candidate() failed");
376     } else if (g_strcmp0(signal_name, "contract_candidate") == 0) {
377         int ret = ime_contract_candidate();
378         if (ret != IME_ERROR_NONE)
379             LOGE("ime_contract_candidate() failed");
380     } else if (g_strcmp0(signal_name, "set_candidate_style") == 0) {
381         int port_line, mode;
382         g_variant_get(parameters, "(ii)", &port_line, &mode);
383
384         int ret = ime_set_candidate_style((scim::ISF_CANDIDATE_PORTRAIT_LINE_T)port_line, (scim::ISF_CANDIDATE_MODE_T)mode);
385         if (ret != IME_ERROR_NONE)
386             LOGE("ime_set_candidate_style() failed");
387     }
388 }
389
390 static bool _dbus_signal_init()
391 {
392     if (dbus_info->monitor_id == 0) {
393         int id = g_dbus_connection_signal_subscribe(dbus_info->gdbus_connection,
394                                                     ENGINE_LOADER_DBUS_NAME,
395                                                     ENGINE_LOADER_ISE_INTERFACE_NAME,
396                                                     NULL,
397                                                     ENGINE_LOADER_OBJECT_PATH,
398                                                     NULL,
399                                                     G_DBUS_SIGNAL_FLAGS_NONE,
400                                                     _handle_engine_loader_cb,
401                                                     dbus_info->user_data,
402                                                     NULL);
403
404         if (id == 0) {
405             LOGE("g_dbus_connection_signal_subscribe() failed");
406             return false;
407         } else
408             dbus_info->monitor_id = id;
409     }
410
411     return true;
412 }
413
414 static GDBusMessage *_get_gbus_message(GVariant *body, const char *cmd)
415 {
416     GDBusMessage *message = NULL;
417     message = g_dbus_message_new_method_call(
418         ENGINE_LOADER_DBUS_NAME,
419         ENGINE_LOADER_OBJECT_PATH,
420         ENGINE_LOADER_INTERFACE_NAME,
421         cmd);
422
423     if (!message) {
424         LOGE("Failed to create a new gdbus message");
425         if (body)
426             g_variant_unref(body);
427         return NULL;
428     }
429
430     if (body != NULL)
431         g_dbus_message_set_body(message, body);
432
433     return message;
434 }
435
436 static bool _send_gdbus_sync_message(GDBusConnection *gdbus_connection, GDBusMessage *msg, GDBusMessage **reply, const char *cmd)
437 {
438     GError *err = NULL;
439
440     *reply = g_dbus_connection_send_message_with_reply_sync(
441             gdbus_connection,
442             msg,
443             G_DBUS_SEND_MESSAGE_FLAGS_NONE,
444             -1,
445             NULL,
446             NULL,
447             &err);
448
449     if (!*reply) {
450         if (err != NULL) {
451             LOGE("Error occurred when sending message(%s) : %s", cmd, err->message);
452             g_error_free(err);
453         }
454         return false;
455     }
456
457     if (g_dbus_message_to_gerror(*reply, &err)) {
458         LOGE("error message = %s, code = %d", err->message, err->code);
459         g_error_free(err);
460         return false;
461     }
462
463     LOGD("Send a message to server(cmd : %s)", cmd);
464     return true;
465 }
466
467 static bool _send_sync_message(GDBusConnection *gdbus_connection, GVariant *body, GDBusMessage **reply, const char *cmd)
468 {
469     bool ret = false;
470     GDBusMessage *msg = NULL;
471
472     msg = _get_gbus_message(body, cmd);
473     if (msg == NULL)
474         return false;
475
476     ret = _send_gdbus_sync_message(gdbus_connection, msg, reply, cmd);
477
478     if (msg)
479         g_object_unref(msg);
480
481     return ret;
482 }
483
484 static bool _send_async_message(GDBusConnection *gdbus_connection, GVariant *body, const char *cmd)
485 {
486     GDBusMessage *msg = NULL;
487     GError *err = NULL;
488
489     msg = _get_gbus_message(body, cmd);
490     if (msg == NULL)
491         return false;
492
493     g_dbus_connection_send_message(gdbus_connection, msg, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &err);
494
495     if (msg)
496         g_object_unref(msg);
497
498     if (err != NULL) {
499         LOGE("Error occurred when sending message(%s) : %s", cmd, err->message);
500         g_error_free(err);
501         return false;
502     }
503
504     return true;
505 }
506
507 static bool _monitor_register(GDBusConnection *gdbus_connection)
508 {
509     bool ret = false;
510     GDBusMessage *reply = NULL;
511     GVariant *reply_body = NULL;
512
513     ret = _send_sync_message(gdbus_connection, g_variant_new("()"), &reply, "loader_service_register");
514     if (!ret) {
515         LOGE("_send_sync_message() failed");
516         return false;
517     }
518
519     reply_body = g_dbus_message_get_body(reply);
520     g_variant_get(reply_body, "(i)", dbus_info->server_watcher_id);
521
522     if (reply)
523         g_object_unref(reply);
524
525     is_server_started = true;
526
527     return true;
528 }
529
530 static void _on_name_appeared(GDBusConnection *connection,
531         const gchar     *name,
532         const gchar     *name_owner,
533         gpointer         user_data)
534 {
535     if (!is_server_started) {
536         dbus_info->server_watcher_id = (int)user_data;
537         _monitor_register(connection);
538     }
539 }
540
541 static void _on_name_vanished(GDBusConnection *connection,
542         const gchar     *name,
543         gpointer         user_data)
544 {
545     is_server_started = false;
546 }
547
548 bool engine_loader_dbus_init(void *data)
549 {
550     bool ret;
551     dbus_info = (engine_loader_dbus_info_s*)calloc(1, sizeof(engine_loader_dbus_info_s));
552     if (dbus_info == NULL) {
553         LOGE("Failed to allocate memory");
554         return false;
555     }
556
557     dbus_info->user_data = data;
558
559     ret = _dbus_init();
560     if (!ret) {
561         LOGE("_dbus_init() failed : %d", ret);
562         goto cleanup;
563     }
564
565     ret = _dbus_signal_init();
566     if (!ret) {
567         LOGE("_dbus_signal_init() failed : %d", ret);
568         goto cleanup;
569     }
570
571     ret = _monitor_register(dbus_info->gdbus_connection);
572     if (!ret) {
573         LOGE("_monitor_register() failed : %d", ret);
574         goto cleanup;
575     }
576
577     if (dbus_info->server_monitor_id == 0) {
578         dbus_info->server_monitor_id = g_bus_watch_name_on_connection(
579                 dbus_info->gdbus_connection,
580                 ENGINE_LOADER_DBUS_NAME,
581                 G_BUS_NAME_WATCHER_FLAGS_NONE,
582                 _on_name_appeared,
583                 _on_name_vanished,
584                 (void *)dbus_info->server_watcher_id,
585                 NULL);
586
587         if (dbus_info->server_monitor_id == 0) {
588             g_dbus_connection_signal_unsubscribe(dbus_info->gdbus_connection, dbus_info->monitor_id);
589             dbus_info->monitor_id = 0;
590             LOGE("Failed to get identifier");
591             ret = false;
592             goto cleanup;
593         }
594     }
595
596     return true;
597
598 cleanup:
599     if (dbus_info->gdbus_connection)
600         g_object_unref(dbus_info->gdbus_connection);
601
602     free(dbus_info);
603     dbus_info = NULL;
604
605     return ret;
606 }
607
608 bool engine_loader_dbus_shutdown()
609 {
610     bool ret;
611
612     if (dbus_info->server_watcher_id) {
613         ret = _send_async_message(dbus_info->gdbus_connection, g_variant_new("(i)", dbus_info->server_watcher_id), "loader_service_unregister");
614         if (!ret) {
615             LOGE("Failed to unregister client");
616             return ret;
617         }
618     }
619
620     if (dbus_info->server_monitor_id)
621         g_bus_unwatch_name(dbus_info->server_monitor_id);
622
623     if (dbus_info->monitor_id)
624         g_dbus_connection_signal_unsubscribe(dbus_info->gdbus_connection, dbus_info->monitor_id);
625
626     free(dbus_info);
627     dbus_info = NULL;
628
629     return true;
630 }
631
632 void engine_loader_set_imengine(const char *engine_id, const char *module_name)
633 {
634     GDBusMessage *reply = NULL;
635     GVariant *reply_body = NULL;
636     bool result = false;
637
638     if (_send_sync_message(dbus_info->gdbus_connection, g_variant_new("(ss)", engine_id, module_name), &reply, "set_imengine")) {
639         reply_body = g_dbus_message_get_body(reply);
640         g_variant_get(reply_body, "(b)", &result);
641     }
642
643     if (!result)
644         LOGE("Failed to set imengine");
645
646     if (reply_body)
647         g_variant_unref(reply_body);
648 }
649
650 void engine_loader_flush_imengine()
651 {
652     if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("()"), "flush_imengine"))
653         LOGE("Failed to flush imengine");
654 }
655
656 void engine_loader_reset_imengine()
657 {
658     if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("()"), "reset_imengine"))
659         LOGE("Failed to reset imengine");
660 }
661
662 void engine_loader_send_imengine_event(int command, uint32_t value)
663 {
664     if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("(iu)", command, value), "send_imengine_event"))
665         LOGE("Failed to send imengine event");
666 }
667
668 bool engine_loader_process_key_event(scim::KeyEvent& key)
669 {
670     bool result = false;
671     GDBusMessage *reply = NULL;
672     GVariant *reply_body = NULL;
673     GVariantBuilder *key_event_builder = NULL;
674
675     key_event_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
676     g_variant_builder_add(key_event_builder, "{sv}", "key_code", g_variant_new_uint32(key.code));
677     g_variant_builder_add(key_event_builder, "{sv}", "key_mask", g_variant_new_uint16(key.mask));
678     g_variant_builder_add(key_event_builder, "{sv}", "key_layout", g_variant_new_uint16(key.layout));
679     g_variant_builder_add(key_event_builder, "{sv}", "key_dev_class", g_variant_new_uint16(key.dev_class));
680     g_variant_builder_add(key_event_builder, "{sv}", "key_dev_subclass", g_variant_new_uint16(key.dev_subclass));
681
682     if (_send_sync_message(dbus_info->gdbus_connection, g_variant_new("(a{sv}s)", key_event_builder, key.dev_name.c_str()), &reply, "process_key_event")) {
683         reply_body = g_dbus_message_get_body(reply);
684         g_variant_get(reply_body, "(b)", &result);
685     }
686
687     g_variant_builder_unref(key_event_builder);
688
689     if (reply_body)
690         g_variant_unref(reply_body);
691
692     return result;
693 }
694
695 void engine_loader_focus_in()
696 {
697     if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("()"), "focus_in"))
698         LOGE("Failed to send focus_in event");
699 }
700
701 void engine_loader_focus_out()
702 {
703     if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("()"), "focus_out"))
704         LOGE("Failed to send focus_out event");
705 }
706
707 void engine_loader_update_cursor_position(int cursor_pos)
708 {
709     if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("(i)", cursor_pos), "update_cursor_position"))
710         LOGE("Failed to update cursor position");
711 }
712
713 void engine_loader_set_autocapital_type(uint32_t type)
714 {
715     if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("(u)", type), "set_autocapital_type"))
716         LOGE("Failed to send autocapital type");
717 }
718
719 void engine_loader_set_prediction_allow(uint32_t prediction_allow)
720 {
721     if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("(u)", prediction_allow), "set_prediction_allow"))
722         LOGE("Failed to send prediction allow");
723 }
724
725 void engine_loader_reset_input_context()
726 {
727     if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("()"), "reset_input_context"))
728         LOGE("Failed to reset input context");
729 }
730
731 void engine_loader_set_layout(uint32_t layout)
732 {
733     if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("(u)", layout), "set_layout"))
734         LOGE("Failed to set layout");
735 }
736
737 void engine_loader_set_imdata(const char *imdata, uint32_t len)
738 {
739     if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("(su)", imdata, len), "set_imdata"))
740         LOGE("Failed to set imdata");
741 }
742
743 void engine_loader_set_input_hint(uint32_t input_hint)
744 {
745     if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("(u)", input_hint), "set_input_hint"))
746         LOGE("Failed to set input hint");
747 }
748
749 void engine_loader_update_bidi_direction(uint32_t direction)
750 {
751     if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("(u)", direction), "update_bidi_direction"))
752         LOGE("Failed to update bidi direction");
753 }
754
755 void engine_loader_trigger_property(const char *property)
756 {
757     if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("(s)", property), "trigger_property"))
758         LOGE("Failed to send trigger property");
759 }
760
761 void engine_loader_show_candidate_more_window()
762 {
763     if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("()"), "show_candidate_more_window"))
764         LOGE("Failed to show candidate more window");
765 }
766
767 void engine_loader_hide_candidate_more_window()
768 {
769     if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("()"), "hide_candidate_more_window"))
770         LOGE("Failed to hide candidate more window");
771 }
772
773 void engine_loader_select_aux(uint32_t item)
774 {
775     if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("(u)", item), "select_aux"))
776         LOGE("Failed to select aux");
777 }
778
779 void engine_loader_select_candidate(uint32_t item)
780 {
781     if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("(u)", item), "select_candidate"))
782         LOGE("Failed to select candidate");
783 }
784
785 void engine_loader_candidate_table_page_up()
786 {
787     if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("()"), "candidate_table_page_up"))
788         LOGE("Failed to page up the candidate table");
789 }
790
791 void engine_loader_candidate_table_page_down()
792 {
793     if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("()"), "candidate_table_page_down"))
794         LOGE("Failed to page down the candidate table");
795 }
796
797 void engine_loader_change_candidate_page_size(uint32_t size)
798 {
799     if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("(u)", size), "change_candidate_page_size"))
800         LOGE("Failed to change candidate page size");
801 }
802
803 void engine_loader_set_candidate_item_layout(std::vector<uint32_t> item)
804 {
805     bool result = false;
806     GDBusMessage *reply = NULL;
807     GVariant *reply_body = NULL;
808     GVariantBuilder *item_builder = NULL;
809     GVariant *body = NULL;
810     std::vector<uint32_t>::iterator it;
811
812     item_builder = g_variant_builder_new(G_VARIANT_TYPE("a(v)"));
813     for (it = item.begin(); it != item.end(); ++it) {
814         body = g_variant_new("(u)", *it);
815         g_variant_builder_add(item_builder, "(v)", body);
816     }
817
818     if (_send_sync_message(dbus_info->gdbus_connection, g_variant_new("(a(v))", item_builder), &reply, "set_candidate_item_layout")) {
819         reply_body = g_dbus_message_get_body(reply);
820         g_variant_get(reply_body, "(b)", &result);
821     }
822
823     if (!result)
824         LOGE("Failed to set candidate item layout");
825
826     g_variant_builder_unref(item_builder);
827
828     if (reply_body)
829         g_variant_unref(reply_body);
830 }
831
832 void engine_loader_change_candidate_number(uint32_t page_num)
833 {
834     if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("(u)", page_num), "change_candidate_number"))
835         LOGE("Failed to change candidate number");
836 }
837
838 void engine_loader_long_press_candidate_item(uint32_t index)
839 {
840     if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("(u)", index), "long_press_candidate_item"))
841         LOGE("Failed to send long pressed item");
842 }