Add init interface with main_window as a parameter 82/128982/2
authorJi-hoon Lee <dalton.lee@samsung.com>
Wed, 10 May 2017 04:55:32 +0000 (13:55 +0900)
committerJihoon Kim <jihoon48.kim@samsung.com>
Fri, 2 Jun 2017 10:05:49 +0000 (10:05 +0000)
Since libscl-core creates input panel window automatically
by itself, it was not possible to create a window outside
of libscl-core and use it as main input panel window.
So added a new init interface that accepts window as a
parameter which will let libscl-core to use it as a main
input panel window. When NULL given or this new init function
is not called from outside, libscl-core will create input panel
window by itself when starts running, as before.

Change-Id: I001edc342f1090ed33018eab04e8a90e55d60d21

12 files changed:
src/sclconnection-isf.cpp
src/sclconnection-isf.h
src/sclconnection.cpp
src/sclconnection.h
src/sclcore.cpp
src/sclcore.h
src/sclcoreimpl.cpp
src/sclcoreimpl.h
src/sclcoreui-efl.cpp
src/sclcoreui-efl.h
src/sclcoreui.cpp
src/sclcoreui.h

index f343346..a322e50 100644 (file)
@@ -637,14 +637,6 @@ sclboolean CSCLConnectionISF::init()
 {
     LOGD("Enter\n");
 
-    CSCLCoreImpl *impl = CSCLCoreImpl::get_instance();
-    if (impl) {
-        sclchar *uuid = impl->get_uuid();
-        if (uuid) {
-            m_helper_info.uuid = uuid;
-        }
-    }
-
     if (!m_initialized) {
         m_helper_agent.signal_connect_exit(scim::slot(slot_exit));
         m_helper_agent.signal_connect_attach_input_context(scim::slot(slot_attach_input_context));
@@ -701,14 +693,6 @@ sclboolean CSCLConnectionISF::init()
         m_initialized = TRUE;
     }
 
-    if (_scim_config.null()) {
-        scim::ConfigPointer config_pointer = scim::ConfigBase::get(true, "socket");
-        if (config_pointer.null()) {
-            config_pointer = new scim::DummyConfig();
-        }
-        _scim_config = config_pointer;
-    }
-
     return TRUE;
 }
 
@@ -722,10 +706,39 @@ void CSCLConnectionISF::fini()
     m_initialized = FALSE;
 }
 
-void CSCLConnectionISF::open_connection(const sclchar *display)
+sclboolean CSCLConnectionISF::open_connection(const sclchar *display)
 {
-    if (m_initialized) {
-        m_helper_agent.open_connection(m_helper_info, display);
+    sclboolean ret = FALSE;
+    sclboolean has_window = FALSE;
+
+    CSCLCoreImpl *impl = CSCLCoreImpl::get_instance();
+    if (impl) {
+        sclchar *uuid = impl->get_uuid();
+        if (uuid) {
+            m_helper_info.uuid = uuid;
+        }
+
+        CSCLCoreUI *ui = impl->get_core_ui();
+        if (ui) {
+            if (ui->get_main_window() != SCLWINDOW_INVALID) {
+                has_window = TRUE;
+            }
+        }
+    }
+
+    /* We will not going to open a connection unless a keyboard window is prepared */
+    if (m_initialized && has_window) {
+        if (_scim_config.null()) {
+            LOGD("Creating socket config module");
+            scim::ConfigPointer config_pointer = scim::ConfigBase::get(true, "socket");
+            if (config_pointer.null()) {
+                LOGW("Config pointer is NULL, assigning a dummy config");
+                config_pointer = new scim::DummyConfig();
+            }
+            _scim_config = config_pointer;
+        }
+
+        m_helper_agent.open_connection(m_helper_info, display ? display : ":0");
         int fd = m_helper_agent.get_connection_number();
 
         if (fd >= 0) {
@@ -744,13 +757,21 @@ void CSCLConnectionISF::open_connection(const sclchar *display)
             props.push_back(prop);
             m_helper_agent.register_properties(props);
 #endif
-
             m_fd_handler = ecore_main_fd_handler_add(fd, ECORE_FD_READ, input_handler, &m_helper_agent, NULL, NULL);
+
+            ret = TRUE;
         }
+    } else {
+        if (!m_initialized) LOGW("Attempt to open a connection without initializing");
+        if (!has_window) LOGW("Attempt to open a connection without a valid window");
     }
+
+    return ret;
 }
-void CSCLConnectionISF::close_connection()
+
+sclboolean CSCLConnectionISF::close_connection()
 {
+    sclboolean ret = FALSE;
     if (m_initialized) {
         if (m_fd_handler) {
             ecore_main_fd_handler_del(m_fd_handler);
@@ -758,7 +779,21 @@ void CSCLConnectionISF::close_connection()
         }
         m_helper_agent.update_ise_exit();
         m_helper_agent.close_connection();
+
+        ret = TRUE;
+    } else {
+        LOGW("Attempt to close a connection without initializing");
     }
+    return ret;
+}
+
+sclboolean CSCLConnectionISF::is_connected()
+{
+    sclboolean ret = FALSE;
+    if (m_initialized) {
+        ret = m_helper_agent.is_connected();
+    }
+    return ret;
 }
 
 void CSCLConnectionISF::config_reload()
index b0621ab..7ea68ef 100644 (file)
@@ -44,8 +44,9 @@ public:
     virtual sclboolean init();
     virtual void fini();
 
-    virtual void open_connection(const sclchar *display);
-    virtual void close_connection();
+    virtual sclboolean open_connection(const sclchar *display);
+    virtual sclboolean close_connection();
+    virtual sclboolean is_connected();
 
     void config_reload();
     sclboolean config_read_int(const sclchar *name, sclint &value);
index 7694114..7001a33 100644 (file)
@@ -58,18 +58,31 @@ void CSCLConnection::fini()
     }
 }
 
-void CSCLConnection::open_connection(const sclchar *display)
+sclboolean CSCLConnection::open_connection(const sclchar *display)
 {
+    sclboolean ret = FALSE;
     if (m_impl) {
-        m_impl->open_connection(display);
+        ret = m_impl->open_connection(display);
     }
+    return ret;
 }
 
-void CSCLConnection::close_connection()
+sclboolean CSCLConnection::close_connection()
 {
+    sclboolean ret = FALSE;
     if (m_impl) {
-        m_impl->close_connection();
+        ret = m_impl->close_connection();
     }
+    return ret;
+}
+
+sclboolean CSCLConnection::is_connected()
+{
+    sclboolean ret = FALSE;
+    if (m_impl) {
+        ret = m_impl->is_connected();
+    }
+    return ret;
 }
 
 void CSCLConnection::config_reload()
index 302583b..a4f24d0 100644 (file)
@@ -44,8 +44,9 @@ public:
     virtual sclboolean init();
     virtual void fini();
 
-    virtual void open_connection(const sclchar *display);
-    virtual void close_connection();
+    virtual sclboolean open_connection(const sclchar *display);
+    virtual sclboolean close_connection();
+    virtual sclboolean is_connected();
 
     virtual void config_reload();
     virtual sclboolean config_read_int(const sclchar *name, sclint &value);
index c543dcd..24dfc73 100644 (file)
@@ -34,6 +34,20 @@ CSCLCore::~CSCLCore()
     m_impl = NULL;
 }
 
+void CSCLCore::init(sclwindow main_window)
+{
+    if (m_impl) {
+        m_impl->init(main_window);
+    }
+}
+
+void CSCLCore::fini()
+{
+    if (m_impl) {
+        m_impl->fini();
+    }
+}
+
 void CSCLCore::run()
 {
     if (m_impl) {
index 383c1f5..9a549bc 100644 (file)
@@ -45,6 +45,21 @@ public:
     CSCLCore(ISCLCoreEventCallback *callback);
     ~CSCLCore();
 
+    /**
+     * @brief Request SCLCore to initialize.
+     * @param[in] main_window The main window of IME application.
+     *            if NULL, a new main window will be created internally on execution.
+     */
+    void init(sclwindow main_window);
+
+    /**
+    * @brief Request SCLCore to finalize.
+    */
+    void fini();
+
+    /**
+     * @brief Request SCLCore to start execution.
+     */
     void run();
 
     /**
index 468078e..d26cc4f 100644 (file)
@@ -26,10 +26,15 @@ CSCLCoreImpl::CSCLCoreImpl()
     m_event_callback = NULL;
     m_display = NULL;
     m_uuid = NULL;
+
+    m_initialized = FALSE;
 }
 
 CSCLCoreImpl::~CSCLCoreImpl()
 {
+    if (m_initialized) {
+        fini();
+    }
     if (m_display) {
         free(m_display);
         m_display = NULL;
@@ -47,16 +52,18 @@ CSCLCoreImpl::get_instance()
     return &instance;
 }
 
-void CSCLCoreImpl::init(const sclchar *display)
+void CSCLCoreImpl::init(sclwindow main_window)
 {
-    m_connection.init();
-    m_core_ui.init();
+    m_core_ui.init(main_window);
 
-    m_connection.open_connection(display);
+    m_connection.init();
+    m_connection.open_connection(m_display);
 
     if (m_event_callback) {
         m_event_callback->on_init();
     }
+
+    m_initialized = TRUE;
 }
 
 void CSCLCoreImpl::fini()
@@ -69,6 +76,8 @@ void CSCLCoreImpl::fini()
 
     m_core_ui.fini();
     m_connection.fini();
+
+    m_initialized = FALSE;
 }
 
 void CSCLCoreImpl::set_core_event_callback(ISCLCoreEventCallback *callback)
@@ -97,6 +106,11 @@ sclchar* CSCLCoreImpl::get_uuid()
     return m_uuid;
 }
 
+sclchar* CSCLCoreImpl::get_display()
+{
+    return m_display;
+}
+
 void CSCLCoreImpl::config_reload()
 {
     m_connection.config_reload();
@@ -274,9 +288,6 @@ void CSCLCoreImpl::get_keyboard_ise(const sclchar *uuid)
 
 void CSCLCoreImpl::on_run(const sclchar *uuid, const sclchar *display)
 {
-    m_core_ui.init();
-    m_connection.init();
-
     LOGD("uuid : '%s', display : '%s'\n", uuid, display);
 
     if (uuid && strlen(uuid) > 0) {
@@ -302,8 +313,9 @@ void CSCLCoreImpl::on_run(const sclchar *uuid, const sclchar *display)
 
 void CSCLCoreImpl::run()
 {
-    m_core_ui.init();
-    m_connection.init();
+    if (!m_initialized) {
+        init(NULL);
+    }
 
     if (!m_uuid) {
         char *appid = NULL;
@@ -324,9 +336,6 @@ void CSCLCoreImpl::run()
     }
 
     m_core_ui.run(m_display);
-
-    m_connection.fini();
-    m_core_ui.fini();
 }
 
 sclwindow CSCLCoreImpl::get_main_window()
index 6145699..8890b42 100644 (file)
@@ -39,7 +39,7 @@ public:
     ~CSCLCoreImpl();
     static CSCLCoreImpl* get_instance();
 
-    void init(const sclchar *display);
+    void init(sclwindow main_window);
     void fini();
 
     void on_run(const sclchar *uuid, const sclchar *display);
@@ -51,6 +51,7 @@ public:
     CSCLCoreUI* get_core_ui();
     CSCLConnection* get_connection();
     sclchar* get_uuid();
+    sclchar* get_display();
 
     void config_reload();
     sclboolean config_read_int(const sclchar *name, sclint &value);
@@ -112,6 +113,8 @@ private:
     CSCLConnection m_connection;
     CSCLCoreUI m_core_ui;
     sclchar *m_uuid;
+
+    sclboolean m_initialized;
 };
 
 }
index 8f3a315..c327d95 100644 (file)
@@ -69,6 +69,227 @@ static void delete_render_pre_timer()
 
 using namespace scl;
 
+CoreUIEFLCallback::CoreUIEFLCallback()
+{
+    app_callback = NULL;
+    initialized = FALSE;
+    main_window = NULL;
+}
+
+void CoreUIEFLCallback::on_init()
+{
+    /* Make sure the on_init() handler gets called when main_window is available */
+    if (!initialized && main_window) {
+        if (app_callback) app_callback->on_init();
+        initialized = TRUE;
+    }
+}
+void CoreUIEFLCallback::on_run(int argc, char **argv)
+{
+    if (app_callback) app_callback->on_run(argc, argv);
+}
+void CoreUIEFLCallback::on_exit()
+{
+    /* Make sure the on_exit() handler gets called only once */
+    if (initialized) {
+        if (app_callback) app_callback->on_exit();
+        initialized = FALSE;
+    }
+}
+void CoreUIEFLCallback::on_attach_input_context(sclint ic, const sclchar *ic_uuid)
+{
+    if (app_callback) app_callback->on_attach_input_context(ic, ic_uuid);
+}
+void CoreUIEFLCallback::on_detach_input_context(sclint ic, const sclchar *ic_uuid)
+{
+    if (app_callback) app_callback->on_detach_input_context(ic, ic_uuid);
+}
+void CoreUIEFLCallback::on_reload_config(sclint ic, const sclchar *ic_uuid)
+{
+    if (app_callback) app_callback->on_reload_config(ic, ic_uuid);
+}
+void CoreUIEFLCallback::on_update_spot_location(sclint ic, const sclchar *ic_uuid, sclint x, sclint y)
+{
+    if (app_callback) app_callback->on_update_spot_location(ic, ic_uuid, x, y);
+}
+void CoreUIEFLCallback::on_update_cursor_position(sclint ic, const sclchar *ic_uuid, sclint cursor_pos)
+{
+    if (app_callback) app_callback->on_update_cursor_position(ic, ic_uuid, cursor_pos);
+}
+void CoreUIEFLCallback::on_update_surrounding_text(sclint ic, const sclchar *text, sclint cursor)
+{
+    if (app_callback) app_callback->on_update_surrounding_text(ic, text, cursor);
+}
+void CoreUIEFLCallback::on_focus_out(sclint ic, const sclchar *ic_uuid)
+{
+    if (app_callback) app_callback->on_focus_out(ic, ic_uuid);
+}
+void CoreUIEFLCallback::on_focus_in(sclint ic, const sclchar *ic_uuid)
+{
+    if (app_callback) app_callback->on_focus_in(ic, ic_uuid);
+}
+void CoreUIEFLCallback::on_ise_show(sclint ic, const int degree, Ise_Context &context)
+{
+    if (app_callback) app_callback->on_ise_show(ic, degree, context);
+}
+void CoreUIEFLCallback::on_ise_hide(sclint ic, const sclchar *ic_uuid)
+{
+    if (app_callback) app_callback->on_ise_hide(ic, ic_uuid);
+}
+void CoreUIEFLCallback::on_get_geometry(sclu32 *pos_x, sclu32 *pos_y, sclu32 *width, sclu32 *height)
+{
+    if (app_callback) app_callback->on_get_geometry(pos_x, pos_y, width, height);
+}
+void CoreUIEFLCallback::on_set_mode(sclu32 mode)
+{
+    if (app_callback) app_callback->on_set_mode(mode);
+}
+void CoreUIEFLCallback::on_set_language(sclu32 language)
+{
+    if (app_callback) app_callback->on_set_language(language);
+}
+void CoreUIEFLCallback::on_set_imdata(sclchar *buf, sclu32 len)
+{
+    if (app_callback) app_callback->on_set_imdata(buf, len);
+}
+void CoreUIEFLCallback::on_get_imdata(sclchar **buf, sclu32 *len)
+{
+    if (app_callback) app_callback->on_get_imdata(buf, len);
+}
+void CoreUIEFLCallback::on_get_language_locale(sclint ic, sclchar **locale)
+{
+    if (app_callback) app_callback->on_get_language_locale(ic, locale);
+}
+void CoreUIEFLCallback::on_set_return_key_type(sclu32 type)
+{
+    if (app_callback) app_callback->on_set_return_key_type(type);
+}
+void CoreUIEFLCallback::on_get_return_key_type(sclu32 *type)
+{
+    if (app_callback) app_callback->on_get_return_key_type(type);
+}
+void CoreUIEFLCallback::on_set_return_key_disable(sclu32 disabled)
+{
+    if (app_callback) app_callback->on_set_return_key_disable(disabled);
+}
+void CoreUIEFLCallback::on_get_return_key_disable(sclu32 *disabled)
+{
+    if (app_callback) app_callback->on_get_return_key_disable(disabled);
+}
+void CoreUIEFLCallback::on_set_layout(sclu32 layout)
+{
+    if (app_callback) app_callback->on_set_layout(layout);
+}
+void CoreUIEFLCallback::on_get_layout(sclu32 *layout)
+{
+    if (app_callback) app_callback->on_get_layout(layout);
+}
+void CoreUIEFLCallback::on_set_caps_mode(sclu32 mode)
+{
+    if (app_callback) app_callback->on_set_caps_mode(mode);
+}
+void CoreUIEFLCallback::on_reset_input_context(sclint ic, const sclchar *uuid)
+{
+    if (app_callback) app_callback->on_reset_input_context(ic, uuid);
+}
+void CoreUIEFLCallback::on_update_candidate_geometry(sclint ic, const sclchar *uuid, sclu32 pos_x, sclu32 pos_y, sclu32 width, sclu32 height)
+{
+    if (app_callback) app_callback->on_update_candidate_geometry(ic, uuid, pos_x, pos_y, width, height);
+}
+void CoreUIEFLCallback::on_update_keyboard_ise(sclint ic, const sclchar *uuid, const sclchar *ise_name, const sclchar *ise_uuid)
+{
+    if (app_callback) app_callback->on_update_keyboard_ise(ic, uuid, ise_name, ise_uuid);
+}
+void CoreUIEFLCallback::on_candidate_more_window_show(sclint ic, const sclchar *uuid)
+{
+    if (app_callback) app_callback->on_candidate_more_window_show(ic, uuid);
+}
+void CoreUIEFLCallback::on_candidate_more_window_hide(sclint ic, const sclchar *uuid)
+{
+    if (app_callback) app_callback->on_candidate_more_window_hide(ic, uuid);
+}
+void CoreUIEFLCallback::on_select_aux(sclint ic, const sclchar *uuid, sclint index)
+{
+    if (app_callback) app_callback->on_select_aux(ic, uuid, index);
+}
+void CoreUIEFLCallback::on_select_candidate(sclint ic, const sclchar *uuid, sclint index)
+{
+    if (app_callback) app_callback->on_select_candidate(ic, uuid, index);
+}
+void CoreUIEFLCallback::on_candidate_table_page_up(sclint ic, const sclchar *uuid)
+{
+    if (app_callback) app_callback->on_candidate_table_page_up(ic, uuid);
+}
+void CoreUIEFLCallback::on_candidate_table_page_down(sclint ic, const sclchar *uuid)
+{
+    if (app_callback) app_callback->on_candidate_table_page_down(ic, uuid);
+}
+void CoreUIEFLCallback::on_update_lookup_table(SclCandidateTable& table)
+{
+    if (app_callback) app_callback->on_update_lookup_table(table);
+}
+void CoreUIEFLCallback::on_update_candidate_table_page_size(sclint ic, const sclchar *uuid, sclint page_size)
+{
+    if (app_callback) app_callback->on_update_candidate_table_page_size(ic, uuid, page_size);
+}
+void CoreUIEFLCallback::on_select_associate(sclint ic, const sclchar *uuid, sclint index)
+{
+    if (app_callback) app_callback->on_select_associate(ic, uuid, index);
+}
+void CoreUIEFLCallback::on_associate_table_page_up(sclint ic, const sclchar *uuid)
+{
+    if (app_callback) app_callback->on_associate_table_page_up(ic, uuid);
+}
+void CoreUIEFLCallback::on_associate_table_page_down(sclint ic, const sclchar *uuid)
+{
+    if (app_callback) app_callback->on_associate_table_page_down(ic, uuid);
+}
+void CoreUIEFLCallback::on_update_associate_table_page_size(sclint ic, const sclchar *uuid, sclint page_size)
+{
+    if (app_callback) app_callback->on_update_associate_table_page_size(ic, uuid, page_size);
+}
+void CoreUIEFLCallback::on_process_key_event(scim::KeyEvent &key, sclu32 *ret)
+{
+    if (app_callback) app_callback->on_process_key_event(key, ret);
+}
+void CoreUIEFLCallback::on_set_display_language(const sclchar *language)
+{
+    if (app_callback) app_callback->on_set_display_language(language);
+}
+void CoreUIEFLCallback::on_set_rotation_degree(sclint degree)
+{
+    if (app_callback) app_callback->on_set_rotation_degree(degree);
+}
+void CoreUIEFLCallback::on_set_accessibility_state(sclboolean state)
+{
+    if (app_callback) app_callback->on_set_accessibility_state(state);
+}
+void CoreUIEFLCallback::on_create_option_window(sclwindow window, SCLOptionWindowType type)
+{
+    if (app_callback) app_callback->on_create_option_window(window, type);
+}
+void CoreUIEFLCallback::on_destroy_option_window(sclwindow window)
+{
+    if (app_callback) app_callback->on_destroy_option_window(window);
+}
+void CoreUIEFLCallback::on_check_option_window_availability(sclboolean *avail)
+{
+    if (app_callback) app_callback->on_check_option_window_availability(avail);
+    else if (avail) *avail = FALSE;
+}
+void CoreUIEFLCallback::on_candidate_show(sclint ic, const sclchar *ic_uuid)
+{
+    if (app_callback) app_callback->on_candidate_show(ic, ic_uuid);
+}
+void CoreUIEFLCallback::on_candidate_hide(sclint ic, const sclchar *ic_uuid)
+{
+    if (app_callback) app_callback->on_candidate_hide(ic, ic_uuid);
+}
+void CoreUIEFLCallback::on_process_input_device_event(sclu32 &type, sclchar *data, size_t &len, sclu32 *ret)
+{
+    if (app_callback) app_callback->on_process_input_device_event(type, data, len, ret);
+}
+
 CSCLCoreUIEFL::CSCLCoreUIEFL()
 {
     m_initialized = FALSE;
@@ -85,11 +306,165 @@ CSCLCoreUIEFL::~CSCLCoreUIEFL()
 {
 }
 
-sclboolean CSCLCoreUIEFL::init()
+#ifdef WAYLAND
+static bool
+_wayland_setup(struct WaylandKeyboard *wlkb, Evas_Object *main_window)
+{
+    Eina_Inlist *globals;
+    struct wl_registry *registry;
+    Ecore_Wl_Global *global;
+
+    if (!(registry = ecore_wl_registry_get()))
+        return false;
+
+    if (!(globals = ecore_wl_globals_get()))
+        return false;
+
+    EINA_INLIST_FOREACH(globals, global)
+    {
+        if (strcmp(global->interface, "wl_input_panel") == 0)
+            wlkb->ip = (wl_input_panel *)wl_registry_bind(registry, global->id, &wl_input_panel_interface, 1);
+        else if (strcmp(global->interface, "wl_output") == 0)
+            wlkb->output = (wl_output *)wl_registry_bind(registry, global->id, &wl_output_interface, 1);
+    }
+
+    if (!wlkb->ip) {
+        LOGW("Can't get wayland input panel interface\n");
+        return false;
+    }
+
+    if (!wlkb->output) {
+        LOGW("Can't get wayland output interface\n");
+        return false;
+    }
+
+    wlkb->ee = ecore_evas_ecore_evas_get(evas_object_evas_get(main_window));
+    if (!wlkb->ee) {
+        LOGW("ERROR: Unable to create Ecore_Evas object\n");
+        return false;
+    }
+
+    /* Set input panel surface */
+    LOGD("Setting up input panel\n");
+    wlkb->wl_win = ecore_evas_wayland_window_get(wlkb->ee);
+    if (!wlkb->wl_win) {
+        LOGW("Couldn't get wayland window\n");
+        return false;
+    }
+
+    ecore_wl_window_type_set(wlkb->wl_win, ECORE_WL_WINDOW_TYPE_NONE);
+    wlkb->surface = ecore_wl_window_surface_create(wlkb->wl_win);
+    if (!wlkb->surface) {
+        LOGW("Couldn't create surface\n");
+        return false;
+    }
+
+    wlkb->ips = wl_input_panel_get_input_panel_surface(wlkb->ip, wlkb->surface);
+    if (!wlkb->ips) {
+        LOGW("Couldn't get input panel surface\n");
+        return false;
+    }
+
+    wl_input_panel_surface_set_toplevel(wlkb->ips, wlkb->output, WL_INPUT_PANEL_SURFACE_POSITION_CENTER_BOTTOM);
+
+    return true;
+}
+
+static Eina_Bool
+check_evas_engine(struct WaylandKeyboard *wlkb)
+{
+    Eina_Bool ret = EINA_FALSE;
+    const char *env = getenv("ECORE_EVAS_ENGINE");
+
+    if (!env) {
+        if (ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_WAYLAND_SHM)) {
+            env = "wayland_shm";
+        } else if (ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_WAYLAND_EGL)) {
+            env = "wayland_egl";
+        } else {
+            LOGW("ERROR: Ecore_Evas does must be compiled with support for Wayland engines\n");
+            goto err;
+        }
+    } else if (strcmp(env, "wayland_shm") != 0 && strcmp(env, "wayland_egl") != 0) {
+        LOGW("ERROR: ECORE_EVAS_ENGINE must be set to either 'wayland_shm' or 'wayland_egl'\n");
+        goto err;
+    }
+
+    wlkb->ee_engine = env;
+    ret = EINA_TRUE;
+
+err:
+    return ret;
+}
+#endif
+
+sclboolean CSCLCoreUIEFL::prepare(sclwindow main_window)
+{
+#ifdef WAYLAND
+    if (!check_evas_engine(&wlkb)) {
+        LOGW("_wlkb_check_evas_engine error!\n");
+        return FALSE;
+    }
+    LOGD("Selected engine: '%s'\n", wlkb.ee_engine);
+#endif
+
+    elm_config_accel_preference_set("3d");
+    elm_policy_set(ELM_POLICY_THROTTLE, ELM_POLICY_THROTTLE_NEVER);
+
+    if (!main_window) {
+        Evas_Object *window = elm_win_add(NULL, m_appid, ELM_WIN_UTILITY);
+        if (!window) {
+            LOGE("Failed to create main window\n");
+            return FALSE;
+        }
+        main_window = SCL_WINDOW_CAST(window);
+    }
+
+    m_main_window = main_window;
+    m_event_callback.main_window = main_window;
+
+    Evas_Object *evas_object = NATIVE_WINDOW_CAST(main_window);
+
+#ifdef WAYLAND
+    if (!_wayland_setup(&wlkb, evas_object)) {
+        LOGW("ERROR: Unable to setup input panel.\n");
+        return FALSE;
+    }
+#endif
+
+    elm_win_borderless_set(evas_object, EINA_TRUE);
+    elm_win_keyboard_win_set(evas_object, EINA_TRUE);
+    elm_win_autodel_set(evas_object, EINA_TRUE);
+    elm_win_title_set(evas_object, m_appid);
+    elm_win_prop_focus_skip_set(evas_object, EINA_TRUE);
+    int rots[] = { 0, 90, 180, 270 };
+    elm_win_wm_rotation_available_rotations_set(evas_object, rots, (sizeof(rots) / sizeof(int)));
+
+#ifndef WAYLAND
+    unsigned int set = 1;
+    ecore_x_window_prop_card32_set(elm_win_xwindow_get(evas_object),
+        ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED,
+        &set, 1);
+
+    ecore_x_icccm_name_class_set(elm_win_xwindow_get(evas_object), "Virtual Keyboard", "ISF");
+#endif
+    LOGD("prepare finished");
+
+    return TRUE;
+}
+
+sclboolean CSCLCoreUIEFL::init(sclwindow main_window)
 {
     m_initialized = TRUE;
     m_rotation_degree = -1;
 
+    /* We need to intercept default event callback handlers */
+    CSCLCoreImpl *impl = CSCLCoreImpl::get_instance();
+    if (impl) {
+        m_event_callback.app_callback = impl->get_core_event_callback();
+        impl->set_core_event_callback(&m_event_callback);
+    }
+
     for (int loop = 0;loop < OPTION_WINDOW_TYPE_MAX;loop++) {
         m_option_window_info[loop].window = SCLWINDOW_INVALID;
     }
@@ -98,6 +473,10 @@ sclboolean CSCLCoreUIEFL::init()
     g_websocket.init();
 #endif
 
+    if (main_window) {
+        prepare(main_window);
+    }
+
     return TRUE;
 }
 
@@ -315,143 +694,11 @@ static void signal_handler(int sig) {
     elm_exit();
 }
 
-#ifdef WAYLAND
-static bool
-_wayland_setup(struct WaylandKeyboard *wlkb, Evas_Object *main_window)
-{
-    Eina_Inlist *globals;
-    struct wl_registry *registry;
-    Ecore_Wl_Global *global;
-
-    if (!(registry = ecore_wl_registry_get()))
-        return false;
-
-    if (!(globals = ecore_wl_globals_get()))
-        return false;
-
-    EINA_INLIST_FOREACH(globals, global)
-    {
-        if (strcmp(global->interface, "wl_input_panel") == 0)
-            wlkb->ip = (wl_input_panel *)wl_registry_bind(registry, global->id, &wl_input_panel_interface, 1);
-        else if (strcmp(global->interface, "wl_output") == 0)
-            wlkb->output = (wl_output *)wl_registry_bind(registry, global->id, &wl_output_interface, 1);
-    }
-
-    if (!wlkb->ip) {
-        LOGW("Can't get wayland input panel interface\n");
-        return false;
-    }
-
-    if (!wlkb->output) {
-        LOGW("Can't get wayland output interface\n");
-        return false;
-    }
-
-    wlkb->ee = ecore_evas_ecore_evas_get(evas_object_evas_get(main_window));
-    if (!wlkb->ee) {
-        LOGW("ERROR: Unable to create Ecore_Evas object\n");
-        return false;
-    }
-
-    /* Set input panel surface */
-    LOGD("Setting up input panel\n");
-    wlkb->wl_win = ecore_evas_wayland_window_get(wlkb->ee);
-    if (!wlkb->wl_win) {
-        LOGW("Couldn't get wayland window\n");
-        return false;
-    }
-
-    ecore_wl_window_type_set(wlkb->wl_win, ECORE_WL_WINDOW_TYPE_NONE);
-    wlkb->surface = ecore_wl_window_surface_create(wlkb->wl_win);
-    if (!wlkb->surface) {
-        LOGW("Couldn't create surface\n");
-        return false;
-    }
-
-    wlkb->ips = wl_input_panel_get_input_panel_surface(wlkb->ip, wlkb->surface);
-    if (!wlkb->ips) {
-        LOGW("Couldn't get input panel surface\n");
-        return false;
-    }
-
-    wl_input_panel_surface_set_toplevel(wlkb->ips, wlkb->output, WL_INPUT_PANEL_SURFACE_POSITION_CENTER_BOTTOM);
-
-    return true;
-}
-
-static Eina_Bool
-check_evas_engine(struct WaylandKeyboard *wlkb)
-{
-    Eina_Bool ret = EINA_FALSE;
-    const char *env = getenv("ECORE_EVAS_ENGINE");
-
-    if (!env) {
-        if (ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_WAYLAND_SHM)) {
-            env = "wayland_shm";
-        } else if (ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_WAYLAND_EGL)) {
-            env = "wayland_egl";
-        } else {
-            LOGW("ERROR: Ecore_Evas does must be compiled with support for Wayland engines\n");
-            goto err;
-        }
-    } else if (strcmp(env, "wayland_shm") != 0 && strcmp(env, "wayland_egl") != 0) {
-        LOGW("ERROR: ECORE_EVAS_ENGINE must be set to either 'wayland_shm' or 'wayland_egl'\n");
-        goto err;
-    }
-
-    wlkb->ee_engine = env;
-    ret = EINA_TRUE;
-
-err:
-    return ret;
-}
-#endif
-
 int CSCLCoreUIEFL::create(void *data)
 {
-#ifdef WAYLAND
-    if (!check_evas_engine(&wlkb)) {
-        LOGW("_wlkb_check_evas_engine error!\n");
-        return -1;
-    }
-    LOGD("Selected engine: '%s'\n", wlkb.ee_engine);
-#endif
-
-    elm_config_accel_preference_set("3d");
-    elm_policy_set(ELM_POLICY_THROTTLE, ELM_POLICY_THROTTLE_NEVER);
-
-    Evas_Object *main_window = elm_win_add(NULL, m_appid, ELM_WIN_UTILITY);
-    if (!main_window) {
-        LOGE("Failed to create main window\n");
-        return -1;
-    }
-
-    m_main_window = SCL_WINDOW_CAST(main_window);
-
-#ifdef WAYLAND
-    if (!_wayland_setup(&wlkb, main_window)) {
-        LOGW("ERROR: Unable to setup input panel.\n");
-        appcore_efl_fini();
-        return -1;
+    if (m_main_window == NULL) {
+        prepare(NULL);
     }
-#endif
-
-    elm_win_borderless_set(main_window, EINA_TRUE);
-    elm_win_keyboard_win_set(main_window, EINA_TRUE);
-    elm_win_autodel_set(main_window, EINA_TRUE);
-    elm_win_title_set(main_window, m_appid);
-    elm_win_prop_focus_skip_set(main_window, EINA_TRUE);
-    int rots[] = { 0, 90, 180, 270 };
-    elm_win_wm_rotation_available_rotations_set(main_window, rots, (sizeof(rots) / sizeof(int)));
-
-#ifndef WAYLAND
-    unsigned int set = 1;
-    ecore_x_window_prop_card32_set(elm_win_xwindow_get(main_window),
-        ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED,
-        &set, 1);
-
-    ecore_x_icccm_name_class_set(elm_win_xwindow_get(main_window), "Virtual Keyboard", "ISF");
-#endif
 
     appcore_set_event_callback(APPCORE_EVENT_LANG_CHANGE, language_changed_cb, NULL);
 
@@ -461,11 +708,8 @@ int CSCLCoreUIEFL::create(void *data)
     language_changed_cb(NULL, NULL);
     accessibility_changed_cb(NULL, NULL);
 
-    CSCLCoreImpl *impl = CSCLCoreImpl::get_instance();
-    if (impl)
-        impl->init(m_display);
-
 #ifdef WAYLAND
+    Evas_Object *main_window = NATIVE_WINDOW_CAST(m_main_window);
     evas_object_smart_callback_add(main_window, "wm,rotation,changed", win_rotation_changed_cb, NULL);
 #else
     Ecore_Event_Handler *XClientMsgHandler =
@@ -481,14 +725,28 @@ int CSCLCoreUIEFL::create(void *data)
     evas_object_show(main_window);
 #endif
 
+    CSCLCoreImpl *impl = CSCLCoreImpl::get_instance();
+    if (impl) {
+        CSCLConnection* connection = impl->get_connection();
+        if (connection) {
+            if (!connection->is_connected()) {
+                connection->open_connection(impl->get_display());
+            }
+        }
+    }
+
+    /* Invoke on_init() here if it was not initialized yet */
+    m_event_callback.on_init();
+
     return 0;
 }
 
 int CSCLCoreUIEFL::terminate(void *data)
 {
     CSCLCoreImpl *impl = CSCLCoreImpl::get_instance();
-    if (impl)
+    if (impl) {
         impl->fini();
+    }
 
     appcore_set_event_callback(APPCORE_EVENT_LANG_CHANGE, NULL, NULL);
 
index d12477b..b06461a 100644 (file)
@@ -35,6 +35,71 @@ typedef struct {
     sclwindow window;
 } OptionWindowInfo;
 
+struct CoreUIEFLCallback : public ISCLCoreEventCallback {
+    CoreUIEFLCallback();
+
+    virtual void on_init();
+    virtual void on_run(int argc, char **argv);
+    virtual void on_exit();
+    virtual void on_attach_input_context(sclint ic, const sclchar *ic_uuid);
+    virtual void on_detach_input_context(sclint ic, const sclchar *ic_uuid);
+    virtual void on_reload_config(sclint ic, const sclchar *ic_uuid);
+    virtual void on_update_spot_location(sclint ic, const sclchar *ic_uuid, sclint x, sclint y);
+    virtual void on_update_cursor_position(sclint ic, const sclchar *ic_uuid, sclint cursor_pos);
+    virtual void on_update_surrounding_text(sclint ic, const sclchar *text, sclint cursor);
+    virtual void on_focus_out(sclint ic, const sclchar *ic_uuid);
+    virtual void on_focus_in(sclint ic, const sclchar *ic_uuid);
+    virtual void on_ise_show(sclint ic, const int degree, Ise_Context &context);
+    virtual void on_ise_hide(sclint ic, const sclchar *ic_uuid);
+    virtual void on_get_geometry(sclu32 *pos_x, sclu32 *pos_y, sclu32 *width, sclu32 *height);
+    virtual void on_set_mode(sclu32 mode);
+    virtual void on_set_language(sclu32 language);
+    virtual void on_set_imdata(sclchar *buf, sclu32 len);
+    virtual void on_get_imdata(sclchar **buf, sclu32 *len);
+    virtual void on_get_language_locale(sclint ic, sclchar **locale);
+    virtual void on_set_return_key_type(sclu32 type);
+    virtual void on_get_return_key_type(sclu32 *type);
+    virtual void on_set_return_key_disable(sclu32 disabled);
+    virtual void on_get_return_key_disable(sclu32 *disabled);
+    virtual void on_set_layout(sclu32 layout);
+    virtual void on_get_layout(sclu32 *layout);
+    virtual void on_set_caps_mode(sclu32 mode);
+    virtual void on_reset_input_context(sclint ic, const sclchar *uuid);
+    virtual void on_update_candidate_geometry(sclint ic, const sclchar *uuid, sclu32 pos_x, sclu32 pos_y, sclu32 width, sclu32 height);
+    virtual void on_update_keyboard_ise(sclint ic, const sclchar *uuid, const sclchar *ise_name, const sclchar *ise_uuid);
+    virtual void on_candidate_more_window_show(sclint ic, const sclchar *uuid);
+    virtual void on_candidate_more_window_hide(sclint ic, const sclchar *uuid);
+    virtual void on_select_aux(sclint ic, const sclchar *uuid, sclint index);
+    virtual void on_select_candidate(sclint ic, const sclchar *uuid, sclint index);
+    virtual void on_candidate_table_page_up(sclint ic, const sclchar *uuid);
+    virtual void on_candidate_table_page_down(sclint ic, const sclchar *uuid);
+    virtual void on_update_lookup_table(SclCandidateTable& table);
+    virtual void on_update_candidate_table_page_size(sclint ic, const sclchar *uuid, sclint page_size);
+    virtual void on_select_associate(sclint ic, const sclchar *uuid, sclint index);
+    virtual void on_associate_table_page_up(sclint ic, const sclchar *uuid);
+    virtual void on_associate_table_page_down(sclint ic, const sclchar *uuid);
+    virtual void on_update_associate_table_page_size(sclint ic, const sclchar *uuid, sclint page_size);
+    virtual void on_process_key_event(scim::KeyEvent &key, sclu32 *ret);
+
+    virtual void on_set_display_language(const sclchar *language);
+    virtual void on_set_rotation_degree(sclint degree);
+    virtual void on_set_accessibility_state(sclboolean state);
+
+    virtual void on_create_option_window(sclwindow window, SCLOptionWindowType type);
+    virtual void on_destroy_option_window(sclwindow window);
+    virtual void on_check_option_window_availability(sclboolean *avail);
+
+    virtual void on_candidate_show(sclint ic, const sclchar *ic_uuid);
+    virtual void on_candidate_hide(sclint ic, const sclchar *ic_uuid);
+
+    /* Added in callback interface version 1.1 */
+    virtual void on_process_input_device_event(sclu32 &type, sclchar *data, size_t &len, sclu32 *ret);
+
+    ISCLCoreEventCallback *app_callback;
+    sclboolean initialized;
+    sclwindow main_window;
+};
+
 class CSCLCoreUIEFL : public CSCLCoreUI
 {
 public:
@@ -44,7 +109,7 @@ public:
     int create(void *data);
     int terminate(void *data);
 
-    virtual sclboolean init();
+    virtual sclboolean init(sclwindow main_window);
     virtual void fini();
 
     virtual void run(const sclchar *display);
@@ -59,6 +124,9 @@ public:
     void set_screen_rotation_degree(int degree);
 
     void process_keyboard_ui_state_change(KEYBOARD_UI_STATE state);
+protected:
+    virtual sclboolean prepare(sclwindow main_window);
+
 private:
     sclboolean m_initialized;
 
@@ -68,6 +136,8 @@ private:
     const sclchar *m_display;
 
     OptionWindowInfo m_option_window_info[OPTION_WINDOW_TYPE_MAX];
+
+    CoreUIEFLCallback m_event_callback;
 };
 
 }
index 500868c..0200314 100644 (file)
@@ -38,14 +38,14 @@ std::string CSCLCoreUI::get_backend_indentifier()
     return m_backend_identifier;
 }
 
-sclboolean CSCLCoreUI::init()
+sclboolean CSCLCoreUI::init(sclwindow main_window)
 {
     sclboolean ret = FALSE;
     if (m_impl == NULL) {
         /* There could be other backend implementations.. */
         m_impl = new CSCLCoreUIEFL;
         if (m_impl) {
-            ret = m_impl->init();
+            ret = m_impl->init(main_window);
         }
     }
     return ret;
index 12abdf1..a55a1e1 100644 (file)
@@ -48,7 +48,7 @@ public:
 
     std::string get_backend_indentifier();
 
-    virtual sclboolean init();
+    virtual sclboolean init(sclwindow main_window);
     virtual void fini();
 
     virtual void run(const sclchar *display);