--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dlog.h>
+#include <inputmethod.h>
+#include <inputmethod_internal.h>
+
+#include "ise-dbus.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "ISE_DEFAULT"
+
+static bool is_server_started = false;
+static engine_loader_dbus_info_s *dbus_info = NULL;
+
+static void _server_appeared_cb(GDBusConnection *connection, const gchar *name, const gchar *name_owner, gpointer user_data)
+{
+ LOGD("name : %s, name_owner : %s", name, name_owner);
+}
+
+static void _server_vanished_cb(GDBusConnection *connection, const gchar *name, gpointer user_data)
+{
+ LOGD("name : %s", name);
+}
+
+static bool _dbus_init()
+{
+ GError *error = NULL;
+ int watch_id = 0;
+
+ if (dbus_info->gdbus_connection == NULL) {
+ GDBusConnection *conn = NULL;
+ conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+ if (conn == NULL) {
+ if (error != NULL) {
+ LOGE("g_bus_get_sync error message = %s", error->message);
+ g_error_free(error);
+ }
+ return false;
+ }
+ dbus_info->gdbus_connection = conn;
+ }
+
+ LOGD("Connected bus name : %s", g_dbus_connection_get_unique_name(dbus_info->gdbus_connection));
+ watch_id = g_bus_watch_name(G_BUS_TYPE_SYSTEM,
+ ENGINE_LOADER_DBUS_NAME,
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
+ _server_appeared_cb,
+ _server_vanished_cb,
+ NULL, NULL);
+
+ if (watch_id == 0) {
+ LOGE("Failed to get identifier");
+ return false;
+ }
+
+ return true;
+}
+
+static void _handle_engine_loader_cb(GDBusConnection *connection,
+ const gchar *sender_name,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *signal_name,
+ GVariant *parameters,
+ gpointer user_data)
+{
+ LOGD("own_name : %s, signal_name : %s", g_dbus_connection_get_unique_name(connection), signal_name);
+
+ if (g_strcmp0(signal_name, "show_preedit_string") == 0) {
+ int ret = ime_show_preedit_string();
+ if (ret != IME_ERROR_NONE)
+ LOGE("ime_show_preedit_string() failed");
+ } else if (g_strcmp0(signal_name, "update_preedit_string") == 0) {
+ GVariantIter *attr_iter = NULL;
+ GVariant *iter_body;
+ char *preedit_string = NULL;
+ unsigned int start;
+ unsigned int length;
+ unsigned int type;
+ unsigned int value;
+ Eina_List *list = NULL;
+ ime_preedit_attribute *attr;
+
+ g_variant_get(parameters, "(a(v)&s)", &attr_iter, &preedit_string);
+ if (!attr_iter || !preedit_string)
+ LOGE("Failed to get variant");
+
+ while (g_variant_iter_loop (attr_iter, "(v)", &iter_body)) {
+ g_variant_get(iter_body, "(uuuu)", &start, &length, &type, &value);
+ attr = (ime_preedit_attribute *)calloc(1, sizeof(ime_preedit_attribute));
+ attr->start = start;
+ attr->length = length;
+ attr->type = (ime_attribute_type)type;
+ attr->value = value;
+ list = eina_list_append(list, attr);
+ }
+
+ int ret = ime_update_preedit_string(preedit_string, list);
+ if (ret != IME_ERROR_NONE) {
+ EINA_LIST_FREE(list, attr)
+ free(attr);
+ }
+ } else if (g_strcmp0(signal_name, "hide_preedit_string") == 0) {
+ int ret = ime_hide_preedit_string();
+ if (ret != IME_ERROR_NONE)
+ LOGE("ime_hide_preedit_string() failed");
+ } else if (g_strcmp0(signal_name, "commit_string") == 0) {
+ char *commit_string = NULL;
+ g_variant_get(parameters, "(&s)", &commit_string);
+ if (!commit_string)
+ LOGE("Failed to get variant");
+
+ int ret = ime_commit_string(commit_string);
+ if (ret != IME_ERROR_NONE)
+ LOGE("ime_commit_string() failed");
+ } else if (g_strcmp0(signal_name, "forward_key_event") == 0) {
+ GVariantIter *key_event_iter = NULL;
+ GVariant *value = NULL;
+ gchar *key = NULL;
+ scim::KeyEvent key_event;
+ char *dev_name = NULL;
+
+ g_variant_get(parameters, "(a{sv}&s)", &key_event_iter, &dev_name);
+ if (!key_event_iter)
+ LOGD("Failed to get iter");
+
+ key_event.dev_name = std::string(dev_name);
+ while (g_variant_iter_loop (key_event_iter, "{sv}", &key, &value)) {
+ if (g_strcmp0(key, "key_code") == 0)
+ key_event.code = g_variant_get_uint32(value);
+ else if (g_strcmp0(key, "key_mask") == 0)
+ key_event.mask = g_variant_get_uint16(value);
+ else if (g_strcmp0(key, "key_layout") == 0)
+ key_event.layout = g_variant_get_uint16(value);
+ else if (g_strcmp0(key, "key_dev_class") == 0)
+ key_event.dev_class = g_variant_get_uint16(value);
+ else if (g_strcmp0(key, "key_dev_subclass") == 0)
+ key_event.dev_subclass = g_variant_get_uint16(value);
+ }
+
+ if (key)
+ g_free(key);
+
+ if (value)
+ g_variant_unref(value);
+
+ int ret = ime_send_key_event((ime_key_code_e)key_event.code, (ime_key_mask_e)key_event.mask, true);
+ if (ret != IME_ERROR_NONE)
+ LOGE("ime_send_key_event() failed");
+ } else if (g_strcmp0(signal_name, "delete_surrounding_text") == 0) {
+ int offset, len;
+ g_variant_get(parameters, "(ii)", &offset, &len);
+
+ int ret = ime_delete_surrounding_text(offset, len);
+ if (ret != IME_ERROR_NONE)
+ LOGE("ime_delete_surrounding_text() failed");
+ } else if (g_strcmp0(signal_name, "set_selection") == 0) {
+ int start, end;
+ g_variant_get(parameters, "(ii)", &start, &end);
+
+ int ret = ime_set_selection(start, end);
+ if (ret != IME_ERROR_NONE)
+ LOGE("ime_set_selection() failed");
+ } else if (g_strcmp0(signal_name, "send_private_command") == 0) {
+ char *private_command = NULL;
+ g_variant_get(parameters, "(&s)", &private_command);
+ if (!private_command)
+ LOGE("Failed to get variant");
+
+ int ret = ime_send_private_command(private_command);
+ if (ret != IME_ERROR_NONE)
+ LOGE("ime_send_private_command() failed");
+ } else if (g_strcmp0(signal_name, "show_aux_string") == 0) {
+ int ret = ime_show_aux_string();
+ if (ret != IME_ERROR_NONE)
+ LOGE("ime_show_aux_string() failed");
+ } else if (g_strcmp0(signal_name, "show_lookup_table") == 0) {
+ int ret = ime_show_lookup_table();
+ if (ret != IME_ERROR_NONE)
+ LOGE("ime_show_lookup_table() failed");
+ } else if (g_strcmp0(signal_name, "hide_aux_string") == 0) {
+ int ret = ime_hide_aux_string();
+ if (ret != IME_ERROR_NONE)
+ LOGE("ime_hide_aux_string() failed");
+ } else if (g_strcmp0(signal_name, "hide_lookup_table") == 0) {
+ int ret = ime_hide_lookup_table();
+ if (ret != IME_ERROR_NONE)
+ LOGE("ime_hide_lookup_table() failed");
+ } else if (g_strcmp0(signal_name, "update_preedit_caret") == 0) {
+ int caret;
+ g_variant_get(parameters, "(i)", &caret);
+
+ int ret = ime_update_preedit_caret(caret);
+ if (ret != IME_ERROR_NONE)
+ LOGE("ime_update_preedit_caret() failed");
+ } else if (g_strcmp0(signal_name, "update_preedit_string_with_commit") == 0) {
+ GVariantIter *attr_iter = NULL;
+ GVariant *iter_body;
+ char *preedit_string = NULL;
+ char *commit_string = NULL;
+ int caret;
+ unsigned int start;
+ unsigned int length;
+ unsigned int type;
+ unsigned int value;
+ scim::AttributeList attr;
+
+ g_variant_get(parameters, "(a(v)&s&si)", &attr_iter, &preedit_string, &commit_string, &caret);
+ if (!attr_iter || !preedit_string || !commit_string)
+ LOGE("Failed to get variant");
+
+ while (g_variant_iter_loop (attr_iter, "(v)", &iter_body)) {
+ g_variant_get(iter_body, "(uuuu)", &start, &length, &type, &value);
+ attr.push_back(scim::Attribute(start, length, (scim::AttributeType)type, value));
+ }
+
+ int ret = ime_update_preedit_string_with_commit(preedit_string, commit_string, attr, caret);
+ if (ret != IME_ERROR_NONE)
+ LOGE("ime_update_preedit_string_with_commit() failed");
+ } else if (g_strcmp0(signal_name, "update_aux_string") == 0) {
+ GVariantIter *attr_iter = NULL;
+ GVariant *iter_body;
+ char *aux_string = NULL;
+ unsigned int start;
+ unsigned int length;
+ unsigned int type;
+ unsigned int value;
+ scim::AttributeList attr;
+
+ g_variant_get(parameters, "(a(v)&s)", &attr_iter, &aux_string);
+ if (!attr_iter || !aux_string)
+ LOGE("Failed to get variant");
+
+ while (g_variant_iter_loop (attr_iter, "(v)", &iter_body)) {
+ g_variant_get(iter_body, "(uuuu)", &start, &length, &type, &value);
+ attr.push_back(scim::Attribute(start, length, (scim::AttributeType)type, value));
+ }
+
+ int ret = ime_update_aux_string(aux_string);
+ if (ret != IME_ERROR_NONE)
+ LOGE("ime_update_aux_string() failed");
+ } else if (g_strcmp0(signal_name, "recapture_string") == 0) {
+ GVariantIter *attr_iter = NULL;
+ GVariant *iter_body;
+ char *preedit_string = NULL;
+ char *commit_string = NULL;
+ int offset, len;
+ unsigned int start;
+ unsigned int length;
+ unsigned int type;
+ unsigned int value;
+ scim::AttributeList attr;
+
+ g_variant_get(parameters, "(a(v)&s&sii)", &attr_iter, &preedit_string, &commit_string, &offset, &len);
+ if (!attr_iter || !preedit_string || !commit_string)
+ LOGE("Failed to get variant");
+
+ while (g_variant_iter_loop (attr_iter, "(v)", &iter_body)) {
+ g_variant_get(iter_body, "(uuuu)", &start, &length, &type, &value);
+ attr.push_back(scim::Attribute(start, length, (scim::AttributeType)type, value));
+ }
+
+ int ret = ime_recapture_string(offset, len, preedit_string, commit_string, attr);
+ if (ret != IME_ERROR_NONE)
+ LOGE("ime_recapture_string() failed");
+ } else if (g_strcmp0(signal_name, "update_lookup_table") == 0) {
+ GVariantIter *attr_iter = NULL;
+ GVariantIter *candidate_iter = NULL;
+ GVariant *attrs_iter_body;
+ GVariant *candidate_iter_body;
+ scim::CommonLookupTable lookup_table;
+ scim::AttributeList attr_list;
+ char *candidate_text = NULL;
+ int idx = 0;
+ int page_size;
+ int cursor_pos;
+
+ g_variant_get(parameters, "(a(a(v))a(v)ii)", &attr_iter, &candidate_iter, &page_size, &cursor_pos);
+ if (!attr_iter || !candidate_iter)
+ LOGE("Failed to get variant");
+
+ lookup_table.set_page_size(page_size);
+ lookup_table.set_cursor_pos(cursor_pos);
+
+ while (g_variant_iter_loop (candidate_iter, "(v)", &candidate_iter_body)) {
+ g_variant_get(candidate_iter_body, "(&s)", &candidate_text);
+ lookup_table.append_candidate(scim::utf8_mbstowcs ((const char*)candidate_text));
+ }
+
+ while (g_variant_iter_loop (attr_iter, "(a(v))", &attrs_iter_body)) {
+ GVariantIter *innter_iter = NULL;
+ GVariant *iner_body;
+ g_variant_get(attrs_iter_body, "(a(v))", &innter_iter);
+ while (g_variant_iter_loop (innter_iter, "(v)", &iner_body)) {
+ int start, length, type, value;
+ g_variant_get(iner_body, "(uuuu)", &start, &length, &type, &value);
+
+ if (start == 0 && length == 0 && type == 0 && value == 0)
+ break;
+ else
+ attr_list.push_back(scim::Attribute(start, length, (scim::AttributeType)type, value));
+ }
+
+ if (!attr_list.empty())
+ lookup_table.add_attributes(idx++, attr_list);
+ attr_list.clear();
+ }
+
+ int ret = ime_update_lookup_table(lookup_table);
+ if (ret != IME_ERROR_NONE)
+ LOGE("ime_update_lookup_table() failed");
+ } else if (g_strcmp0(signal_name, "register_properties") == 0) {
+ GVariantIter *list_iter = NULL;
+ GVariant *iter_body;
+ scim::PropertyList property_list;
+ scim::Property property;
+ char *key = NULL;
+ char *label = NULL;
+ char *icon = NULL;
+ char *tip = NULL;
+
+ g_variant_get(parameters, "(a(v))", &list_iter);
+ if (!list_iter)
+ LOGE("Failed to get variant");
+
+ while (g_variant_iter_loop (list_iter, "(v)", &iter_body)) {
+ g_variant_get(iter_body, "(&s&s&s&s)", &key, &label, &icon, &tip);
+ property.set_key(scim::String(key));
+ property.set_label(scim::String(label));
+ property.set_icon(scim::String(icon));
+ property.set_tip(scim::String(tip));
+ property_list.push_back(property);
+ }
+
+ int ret = ime_register_properties(property_list);
+ if (ret != IME_ERROR_NONE)
+ LOGE("ime_register_properties() failed");
+ } else if (g_strcmp0(signal_name, "update_property") == 0) {
+ char *key = NULL;
+ char *label = NULL;
+ char *icon = NULL;
+ char *tip = NULL;
+ scim::Property property;
+
+ g_variant_get(parameters, "(&s&s&s&s)", &key, &label, &icon, &tip);
+
+ property.set_key(scim::String(key));
+ property.set_label(scim::String(label));
+ property.set_icon(scim::String(icon));
+ property.set_tip(scim::String(tip));
+
+ int ret = ime_update_property(property);
+ if (ret != IME_ERROR_NONE)
+ LOGE("ime_update_property() failed");
+ } else if (g_strcmp0(signal_name, "expand_candidate") == 0) {
+ int ret = ime_expand_candidate();
+ if (ret != IME_ERROR_NONE)
+ LOGE("ime_expand_candidate() failed");
+ } else if (g_strcmp0(signal_name, "contract_candidate") == 0) {
+ int ret = ime_contract_candidate();
+ if (ret != IME_ERROR_NONE)
+ LOGE("ime_contract_candidate() failed");
+ } else if (g_strcmp0(signal_name, "set_candidate_style") == 0) {
+ int port_line, mode;
+ g_variant_get(parameters, "(ii)", &port_line, &mode);
+
+ int ret = ime_set_candidate_style((scim::ISF_CANDIDATE_PORTRAIT_LINE_T)port_line, (scim::ISF_CANDIDATE_MODE_T)mode);
+ if (ret != IME_ERROR_NONE)
+ LOGE("ime_set_candidate_style() failed");
+ }
+}
+
+static bool _dbus_signal_init()
+{
+ if (dbus_info->monitor_id == 0) {
+ int id = g_dbus_connection_signal_subscribe(dbus_info->gdbus_connection,
+ ENGINE_LOADER_DBUS_NAME,
+ ENGINE_LOADER_ISE_INTERFACE_NAME,
+ NULL,
+ ENGINE_LOADER_OBJECT_PATH,
+ NULL,
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ _handle_engine_loader_cb,
+ dbus_info->user_data,
+ NULL);
+
+ if (id == 0) {
+ LOGE("g_dbus_connection_signal_subscribe() failed");
+ return false;
+ } else
+ dbus_info->monitor_id = id;
+ }
+
+ return true;
+}
+
+static GDBusMessage *_get_gbus_message(GVariant *body, const char *cmd)
+{
+ GDBusMessage *message = NULL;
+ message = g_dbus_message_new_method_call(
+ ENGINE_LOADER_DBUS_NAME,
+ ENGINE_LOADER_OBJECT_PATH,
+ ENGINE_LOADER_INTERFACE_NAME,
+ cmd);
+
+ if (!message) {
+ LOGE("Failed to create a new gdbus message");
+ if (body)
+ g_variant_unref(body);
+ return NULL;
+ }
+
+ if (body != NULL)
+ g_dbus_message_set_body(message, body);
+
+ return message;
+}
+
+static bool _send_gdbus_sync_message(GDBusConnection *gdbus_connection, GDBusMessage *msg, GDBusMessage **reply, const char *cmd)
+{
+ GError *err = NULL;
+
+ *reply = g_dbus_connection_send_message_with_reply_sync(
+ gdbus_connection,
+ msg,
+ G_DBUS_SEND_MESSAGE_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ &err);
+
+ if (!*reply) {
+ if (err != NULL) {
+ LOGE("Error occurred when sending message(%s) : %s", cmd, err->message);
+ g_error_free(err);
+ }
+ return false;
+ }
+
+ if (g_dbus_message_to_gerror(*reply, &err)) {
+ LOGE("error message = %s, code = %d", err->message, err->code);
+ g_error_free(err);
+ return false;
+ }
+
+ LOGD("Send a message to server(cmd : %s)", cmd);
+ return true;
+}
+
+static bool _send_sync_message(GDBusConnection *gdbus_connection, GVariant *body, GDBusMessage **reply, const char *cmd)
+{
+ bool ret = false;
+ GDBusMessage *msg = NULL;
+
+ msg = _get_gbus_message(body, cmd);
+ if (msg == NULL)
+ return false;
+
+ ret = _send_gdbus_sync_message(gdbus_connection, msg, reply, cmd);
+
+ if (msg)
+ g_object_unref(msg);
+
+ return ret;
+}
+
+static bool _send_async_message(GDBusConnection *gdbus_connection, GVariant *body, const char *cmd)
+{
+ GDBusMessage *msg = NULL;
+ GError *err = NULL;
+
+ msg = _get_gbus_message(body, cmd);
+ if (msg == NULL)
+ return false;
+
+ g_dbus_connection_send_message(gdbus_connection, msg, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &err);
+
+ if (msg)
+ g_object_unref(msg);
+
+ if (err != NULL) {
+ LOGE("Error occurred when sending message(%s) : %s", cmd, err->message);
+ g_error_free(err);
+ return false;
+ }
+
+ return true;
+}
+
+static bool _monitor_register(GDBusConnection *gdbus_connection)
+{
+ bool ret = false;
+ GDBusMessage *reply = NULL;
+ GVariant *reply_body = NULL;
+
+ ret = _send_sync_message(gdbus_connection, g_variant_new("()"), &reply, "loader_service_register");
+ if (!ret) {
+ LOGE("_send_sync_message() failed");
+ return false;
+ }
+
+ reply_body = g_dbus_message_get_body(reply);
+ g_variant_get(reply_body, "(i)", dbus_info->server_watcher_id);
+
+ if (reply)
+ g_object_unref(reply);
+
+ is_server_started = true;
+
+ return true;
+}
+
+static void _on_name_appeared(GDBusConnection *connection,
+ const gchar *name,
+ const gchar *name_owner,
+ gpointer user_data)
+{
+ if (!is_server_started) {
+ dbus_info->server_watcher_id = (int)user_data;
+ _monitor_register(connection);
+ }
+}
+
+static void _on_name_vanished(GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
+{
+ is_server_started = false;
+}
+
+bool engine_loader_dbus_init(void *data)
+{
+ bool ret;
+ dbus_info = (engine_loader_dbus_info_s*)calloc(1, sizeof(engine_loader_dbus_info_s));
+ if (dbus_info == NULL) {
+ LOGE("Failed to allocate memory");
+ return false;
+ }
+
+ dbus_info->user_data = data;
+
+ ret = _dbus_init();
+ if (!ret) {
+ LOGE("_dbus_init() failed : %d", ret);
+ goto cleanup;
+ }
+
+ ret = _dbus_signal_init();
+ if (!ret) {
+ LOGE("_dbus_signal_init() failed : %d", ret);
+ goto cleanup;
+ }
+
+ ret = _monitor_register(dbus_info->gdbus_connection);
+ if (!ret) {
+ LOGE("_monitor_register() failed : %d", ret);
+ goto cleanup;
+ }
+
+ if (dbus_info->server_monitor_id == 0) {
+ dbus_info->server_monitor_id = g_bus_watch_name_on_connection(
+ dbus_info->gdbus_connection,
+ ENGINE_LOADER_DBUS_NAME,
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
+ _on_name_appeared,
+ _on_name_vanished,
+ (void *)dbus_info->server_watcher_id,
+ NULL);
+
+ if (dbus_info->server_monitor_id == 0) {
+ g_dbus_connection_signal_unsubscribe(dbus_info->gdbus_connection, dbus_info->monitor_id);
+ dbus_info->monitor_id = 0;
+ LOGE("Failed to get identifier");
+ ret = false;
+ goto cleanup;
+ }
+ }
+
+ return true;
+
+cleanup:
+ if (dbus_info->gdbus_connection)
+ g_object_unref(dbus_info->gdbus_connection);
+
+ free(dbus_info);
+ dbus_info = NULL;
+
+ return ret;
+}
+
+bool engine_loader_dbus_shutdown()
+{
+ bool ret;
+
+ if (dbus_info->server_watcher_id) {
+ ret = _send_async_message(dbus_info->gdbus_connection, g_variant_new("(i)", dbus_info->server_watcher_id), "loader_service_unregister");
+ if (!ret) {
+ LOGE("Failed to unregister client");
+ return ret;
+ }
+ }
+
+ if (dbus_info->server_monitor_id)
+ g_bus_unwatch_name(dbus_info->server_monitor_id);
+
+ if (dbus_info->monitor_id)
+ g_dbus_connection_signal_unsubscribe(dbus_info->gdbus_connection, dbus_info->monitor_id);
+
+ free(dbus_info);
+ dbus_info = NULL;
+
+ return true;
+}
+
+void engine_loader_set_imengine(const char *engine_id)
+{
+ GDBusMessage *reply = NULL;
+ GVariant *reply_body = NULL;
+ bool result;
+
+ if (_send_sync_message(dbus_info->gdbus_connection, g_variant_new("(s)", engine_id), &reply, "set_imengine")) {
+ reply_body = g_dbus_message_get_body(reply);
+ g_variant_get(reply_body, "(b)", &result);
+ }
+
+ if (!result)
+ LOGE("Failed to set imengine");
+
+ if (reply_body)
+ g_variant_unref(reply_body);
+}
+
+void engine_loader_flush_imengine()
+{
+ if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("()"), "flush_imengine"))
+ LOGE("Failed to flush imengine");
+}
+
+void engine_loader_reset_imengine()
+{
+ if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("()"), "reset_imengine"))
+ LOGE("Failed to reset imengine");
+}
+
+void engine_loader_send_imengine_event(int command, uint32_t value)
+{
+ if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("(iu)", command, value), "send_imengine_event"))
+ LOGE("Failed to send imengine event");
+}
+
+bool engine_loader_process_key_event(scim::KeyEvent& key)
+{
+ bool result;
+ GDBusMessage *reply = NULL;
+ GVariant *reply_body = NULL;
+ GVariantBuilder *key_event_builder = NULL;
+
+ key_event_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+ g_variant_builder_add(key_event_builder, "{sv}", "key_code", g_variant_new_uint32(key.code));
+ g_variant_builder_add(key_event_builder, "{sv}", "key_mask", g_variant_new_uint16(key.mask));
+ g_variant_builder_add(key_event_builder, "{sv}", "key_layout", g_variant_new_uint16(key.layout));
+ g_variant_builder_add(key_event_builder, "{sv}", "key_dev_class", g_variant_new_uint16(key.dev_class));
+ g_variant_builder_add(key_event_builder, "{sv}", "key_dev_subclass", g_variant_new_uint16(key.dev_subclass));
+
+ 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")) {
+ reply_body = g_dbus_message_get_body(reply);
+ g_variant_get(reply_body, "(b)", &result);
+ }
+
+ g_variant_builder_unref(key_event_builder);
+
+ if (reply_body)
+ g_variant_unref(reply_body);
+
+ return result;
+}
+
+void engine_loader_focus_in()
+{
+ if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("()"), "focus_in"))
+ LOGE("Failed to send focus_in event");
+}
+
+void engine_loader_focus_out()
+{
+ if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("()"), "focus_out"))
+ LOGE("Failed to send focus_out event");
+}
+
+void engine_loader_update_cursor_position(int cursor_pos)
+{
+ if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("(i)", cursor_pos), "update_cursor_position"))
+ LOGE("Failed to update cursor position");
+}
+
+void engine_loader_set_autocapital_type(uint32_t type)
+{
+ if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("(u)", type), "set_autocapital_type"))
+ LOGE("Failed to send autocapital type");
+}
+
+void engine_loader_set_prediction_allow(uint32_t prediction_allow)
+{
+ if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("(u)", prediction_allow), "set_prediction_allow"))
+ LOGE("Failed to send prediction allow");
+}
+
+void engine_loader_reset_input_context()
+{
+ if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("()"), "reset_input_context"))
+ LOGE("Failed to reset input context");
+}
+
+void engine_loader_set_layout(uint32_t layout)
+{
+ if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("(u)", layout), "set_layout"))
+ LOGE("Failed to set layout");
+}
+
+void engine_loader_set_imdata(const char *imdata, uint32_t len)
+{
+ if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("(su)", imdata, len), "set_imdata"))
+ LOGE("Failed to set imdata");
+}
+
+void engine_loader_set_input_hint(uint32_t input_hint)
+{
+ if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("(u)", input_hint), "set_input_hint"))
+ LOGE("Failed to set input hint");
+}
+
+void engine_loader_update_bidi_direction(uint32_t direction)
+{
+ if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("(u)", direction), "update_bidi_direction"))
+ LOGE("Failed to update bidi direction");
+}
+
+void engine_loader_trigger_property(const char *property)
+{
+ if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("(s)", property), "trigger_property"))
+ LOGE("Failed to send trigger property");
+}
+
+void engine_loader_show_candidate_more_window()
+{
+ if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("()"), "show_candidate_more_window"))
+ LOGE("Failed to show candidate more window");
+}
+
+void engine_loader_hide_candidate_more_window()
+{
+ if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("()"), "hide_candidate_more_window"))
+ LOGE("Failed to hide candidate more window");
+}
+
+void engine_loader_select_aux(uint32_t item)
+{
+ if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("(u)", item), "select_aux"))
+ LOGE("Failed to select aux");
+}
+
+void engine_loader_select_candidate(uint32_t item)
+{
+ if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("(u)", item), "select_candidate"))
+ LOGE("Failed to select candidate");
+}
+
+void engine_loader_candidate_table_page_up()
+{
+ if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("()"), "candidate_table_page_up"))
+ LOGE("Failed to page up the candidate table");
+}
+
+void engine_loader_candidate_table_page_down()
+{
+ if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("()"), "candidate_table_page_down"))
+ LOGE("Failed to page down the candidate table");
+}
+
+void engine_loader_change_candidate_page_size(uint32_t size)
+{
+ if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("(u)", size), "change_candidate_page_size"))
+ LOGE("Failed to change candidate page size");
+}
+
+void engine_loader_set_candidate_item_layout(std::vector<uint32_t> item)
+{
+ bool result = false;
+ GDBusMessage *reply = NULL;
+ GVariant *reply_body = NULL;
+ GVariantBuilder *item_builder = NULL;
+ GVariant *body = NULL;
+ std::vector<uint32_t>::iterator it;
+
+ item_builder = g_variant_builder_new(G_VARIANT_TYPE("a(v)"));
+ for (it = item.begin(); it != item.end(); ++it) {
+ body = g_variant_new("(u)", *it);
+ g_variant_builder_add(item_builder, "(v)", body);
+ }
+
+ if (_send_sync_message(dbus_info->gdbus_connection, g_variant_new("(a(v))", item_builder), &reply, "set_candidate_item_layout")) {
+ reply_body = g_dbus_message_get_body(reply);
+ g_variant_get(reply_body, "(b)", &result);
+ }
+
+ if (!result)
+ LOGE("Failed to set candidate item layout");
+
+ g_variant_builder_unref(item_builder);
+
+ if (reply_body)
+ g_variant_unref(reply_body);
+}
+
+void engine_loader_change_candidate_number(uint32_t page_num)
+{
+ if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("(u)", page_num), "change_candidate_number"))
+ LOGE("Failed to change candidate number");
+}
+
+void engine_loader_long_press_candidate_item(uint32_t index)
+{
+ if (!_send_async_message(dbus_info->gdbus_connection, g_variant_new("(u)", index), "long_press_candidate_item"))
+ LOGE("Failed to send long pressed item");
+}
\ No newline at end of file
#include "modeindicator.h"
#include "w-input-smartreply.h"
#include "ise-floating-mode.h"
+#include "ise-dbus.h"
#define EDJ_FILE RESDIR"/edje/mobile/customised_ctxpopup.edj"
} else if (multidesc.index < (int)g_smartreply_size + 1) {
ise_send_string(g_softcandidate_string[multidesc.index].c_str());
} else {
- ime_select_candidate(multidesc.index - g_smartreply_size - 1);
+ engine_loader_select_candidate(multidesc.index - g_smartreply_size - 1);
}
} else {
if (multidesc.index < (int)g_smartreply_size)
ise_send_string(g_softcandidate_string[multidesc.index].c_str());
else
- ime_select_candidate(multidesc.index - g_smartreply_size);
+ engine_loader_select_candidate(multidesc.index - g_smartreply_size);
}
break;
case MultiEventDesc::CANDIDATE_MORE_VIEW_SHOW:
g_ui->set_shift_state(mode ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF);
g_ui->set_autocapital_shift_state(!mode);
- ime_send_imengine_event(mode ? MVK_Shift_On : MVK_Shift_Off, 0);
+ engine_loader_send_imengine_event(mode ? MVK_Shift_On : MVK_Shift_Off, 0);
}
}
}
LANGUAGE_INFO *info = _language_manager.get_language_info(cur_lang);
if (info) {
if (info->accepts_caps_mode) {
- ime_send_imengine_event(MVK_Shift_Enable, 0);
+ engine_loader_send_imengine_event(MVK_Shift_Enable, 0);
set_caps_mode(g_keyboard_state.caps_mode);
} else {
- ime_send_imengine_event(MVK_Shift_Disable, 0);
+ engine_loader_send_imengine_event(MVK_Shift_Disable, 0);
g_ui->set_shift_state(SCL_SHIFT_STATE_OFF);
}
}
if (info->accepts_caps_mode) {
LOGD("shift state: %d\n", desc->shift_state);
if (desc->shift_state == SCL_SHIFT_STATE_OFF) {
- ime_send_imengine_event(MVK_Shift_Off, 0);
+ engine_loader_send_imengine_event(MVK_Shift_Off, 0);
} else if (desc->shift_state == SCL_SHIFT_STATE_ON) {
- ime_send_imengine_event(MVK_Shift_On, 0);
+ engine_loader_send_imengine_event(MVK_Shift_On, 0);
} else if (desc->shift_state == SCL_SHIFT_STATE_LOCK) {
- ime_send_imengine_event(MVK_Shift_Lock, 0);
+ engine_loader_send_imengine_event(MVK_Shift_Lock, 0);
}
ret = SCL_EVENT_PASS_ON;
}
} else if (strncmp(event_desc.key_value, caps_lock, strlen(caps_lock)) == 0) {
if (g_ui->get_shift_state() != SCL_SHIFT_STATE_LOCK) {
g_ui->set_shift_state(SCL_SHIFT_STATE_LOCK);
- ime_send_imengine_event(MVK_Shift_Lock, 0);
+ engine_loader_send_imengine_event(MVK_Shift_Lock, 0);
} else {
g_ui->set_shift_state(SCL_SHIFT_STATE_OFF);
- ime_send_imengine_event(MVK_Shift_Off, 0);
+ engine_loader_send_imengine_event(MVK_Shift_Off, 0);
}
//g_need_send_shift_event = TRUE;
} else if (strncmp(event_desc.key_value, delete_all, strlen(delete_all)) == 0) {
g_keyboard_state.layout == ISE_LAYOUT_STYLE_IP ||
g_keyboard_state.layout == ISE_LAYOUT_STYLE_MONTH ||
g_keyboard_state.layout == ISE_LAYOUT_STYLE_NUMBERONLY) {
- ime_set_imengine(DEFAULT_KEYBOARD_ISE_UUID);
+ engine_loader_set_imengine(DEFAULT_KEYBOARD_ISE_UUID);
}
}
static void ime_app_create_cb(void *user_data)
{
+ if (!engine_loader_dbus_init(NULL))
+ LOGE("Failed to initialize dbus");
+
#if !(DEFER_ISE_CREATION)
ise_create();
#endif
ise_hide();
ise_destroy();
+ if (!engine_loader_dbus_shutdown())
+ LOGE("Failed to finalize dbus");
+
#ifdef HAVE_CBHM
cbhm_close_service(cbhm_handle);
cbhm_handle = NULL;
iseContext.return_key_disabled = return_key_state;
+ engine_loader_set_input_hint((uint32_t)iseContext.input_hint);
+ engine_loader_update_bidi_direction((uint32_t)iseContext.bidi_direction);
+
g_ic = ic;
g_autofill_hint = iseContext.input_hint & ECORE_IMF_INPUT_HINT_AUTOFILL_MASK;
static void ime_app_input_context_reset_cb(void *user_data)
{
ise_reset_input_context();
+ engine_loader_reset_input_context();
}
static void ime_app_cursor_position_updated_cb(int cursor_pos, void *user_data)
{
LOGD("cursor position : %d\n", cursor_pos);
ise_update_cursor_position(cursor_pos);
+ engine_loader_update_cursor_position(cursor_pos);
}
static void ime_app_language_requested_cb(void *user_data, char **lang_code)
g_candidate->hide();
}
}
+
+ engine_loader_focus_in();
}
static void ime_app_focus_out_cb(int context_id, void *user_data)
g_smartreply_strings.clear();
g_lookup_table_strings.clear();
g_softcandidate_string.clear();
+
+ engine_loader_focus_out();
}
static void ime_app_layout_set_cb(Ecore_IMF_Input_Panel_Layout layout, void *user_data)
}
if (g_keyboard_state.visible_state)
ise_show(g_keyboard_state.ic);
+
+ engine_loader_set_layout(static_cast<uint32_t>(layout));
}
static void ime_app_rotation_degree_changed_cb(int degree, void *user_data)
g_imdata_state = 0;
size_t _len = data_length;
set_ise_imdata((sclchar *)data, _len);
+ engine_loader_set_imdata((const char*)data, (uint32_t)data_length);
}
static bool ime_app_process_key_event_cb(ime_key_code_e keycode, ime_key_mask_e keymask, ime_device_info_h dev_info, void *user_data)
return ret;
}
+static bool ime_app_process_key_event_with_imengine_cb(scim::KeyEvent &key, void *user_data)
+{
+ bool ret = false;
+ ret = engine_loader_process_key_event(key);
+
+ return ret;
+}
+
static void ime_app_caps_mode_changed_cb(int mode, void *user_data)
{
ise_set_caps_mode(mode);
g_resource_id = string(value ? value : "");
}
+static void ime_app_autocapital_type_set_cb(uint32_t type, void *user_data)
+{
+ LOGD("autocapital type : %u\n", type);
+ engine_loader_set_autocapital_type(type);
+}
+
+static void ime_app_prediction_allow_set_cb(uint32_t prediction_allow, void *user_data)
+{
+ LOGD("prediction allow : %u\n", prediction_allow);
+ engine_loader_set_prediction_allow(prediction_allow);
+}
+
+static void ime_app_trigger_property_set_cb(const char *property, void *user_data)
+{
+ LOGD("trigger property : %s\n", property);
+ engine_loader_trigger_property(property);
+}
+
+static void ime_app_candidate_more_window_show_cb(void *user_data)
+{
+ LOGD("");
+ engine_loader_show_candidate_more_window();
+}
+
+static void ime_app_candidate_more_window_hide_cb(void *user_data)
+{
+ LOGD("");
+ engine_loader_hide_candidate_more_window();
+}
+
+static void ime_app_aux_select_cb(uint32_t item, void *user_data)
+{
+ LOGD("aux select : %u\n", item);
+ engine_loader_select_aux(item);
+}
+
+static void ime_app_candidate_select_cb(uint32_t item, void *user_data)
+{
+ LOGD("candidate select : %u\n", item);
+ engine_loader_select_candidate(item);
+}
+
+static void ime_app_candidate_table_page_up_cb(void *user_data)
+{
+ LOGD("");
+ engine_loader_candidate_table_page_up();
+}
+
+static void ime_app_candidate_table_page_down_cb(void *user_data)
+{
+ LOGD("");
+ engine_loader_candidate_table_page_down();
+}
+
+static void ime_app_candidate_table_page_size_chaned_cb(uint32_t size, void *user_data)
+{
+ LOGD("candidate page size : %u\n", size);
+ engine_loader_change_candidate_page_size(size);
+}
+
+static void ime_app_candidate_item_layout_set_cb(vector<uint32_t> item, void *user_data)
+{
+ LOGD("item layout size : %d", item.size());
+ engine_loader_set_candidate_item_layout(item);
+}
+
+static void ime_app_displayed_candidate_number_chaned_cb(uint32_t page_num, void *user_data)
+{
+ LOGD("candidate number changed : %u\n", page_num);
+ engine_loader_change_candidate_number(page_num);
+}
+
+static void ime_app_candidate_item_long_pressed_cb(uint32_t index, void *user_data)
+{
+ LOGD("candidate item : %u\n", index);
+ engine_loader_long_press_candidate_item(index);
+}
+
#ifdef __cplusplus
extern "C"{
#endif
ime_event_set_language_set_cb(ime_app_language_set_cb, NULL);
ime_event_set_imdata_set_cb(ime_app_imdata_set_cb, NULL);
ime_event_set_process_key_event_cb(ime_app_process_key_event_cb, NULL);
+ ime_event_set_process_key_event_with_imengine_cb(ime_app_process_key_event_with_imengine_cb, NULL);
ime_event_set_candidate_show_cb(ime_app_candidate_show_cb, NULL);
ime_event_set_candidate_hide_cb(ime_app_candidate_hide_cb, NULL);
ime_event_set_mime_type_set_request_cb(ime_app_mime_type_set_request_cb, NULL);
ime_event_set_prediction_hint_data_set_cb(ime_app_prediction_hint_data_set_cb, NULL);
+ ime_event_set_autocapital_type_set_cb(ime_app_autocapital_type_set_cb, NULL);
+ ime_event_set_prediction_allow_set_cb(ime_app_prediction_allow_set_cb, NULL);
+ ime_event_set_trigger_property_set_cb(ime_app_trigger_property_set_cb, NULL);
+ ime_event_set_candidate_more_window_show_cb(ime_app_candidate_more_window_show_cb, NULL);
+ ime_event_set_candidate_more_window_hide_cb(ime_app_candidate_more_window_hide_cb, NULL);
+ ime_event_set_aux_select_cb(ime_app_aux_select_cb, NULL);
+ ime_event_set_candidate_select_cb(ime_app_candidate_select_cb, NULL);
+ ime_event_set_candidate_table_page_up_cb(ime_app_candidate_table_page_up_cb, NULL);
+ ime_event_set_candidate_table_page_down_cb(ime_app_candidate_table_page_down_cb, NULL);
+ ime_event_set_candidate_table_page_size_chaned_cb(ime_app_candidate_table_page_size_chaned_cb, NULL);
+ ime_event_set_candidate_item_layout_set_cb(ime_app_candidate_item_layout_set_cb, NULL);
+ ime_event_set_displayed_candidate_number_chaned_cb(ime_app_displayed_candidate_number_chaned_cb, NULL);
+ ime_event_set_candidate_item_long_pressed_cb(ime_app_candidate_item_long_pressed_cb, NULL);
+
#if DEFER_ISE_CREATION
ime_set_window_creation_defer_flag(TRUE);
#endif