Add new APIs for setting/getting cursor position in Remote Input 74/272774/2
authorInHong Han <inhong1.han@samsung.com>
Thu, 24 Mar 2022 06:19:32 +0000 (15:19 +0900)
committerInHong Han <inhong1.han@samsung.com>
Thu, 24 Mar 2022 06:58:01 +0000 (15:58 +0900)
Change-Id: I1805415433b1cf5c2d1fbe551057edaa5947f502

13 files changed:
ism/modules/panelagent/ecoresocket/ecore_socket_panel_agent_module.cpp
ism/modules/panelagent/wayland/wayland_panel_agent_module.cpp
ism/src/isf_info_manager.cpp
ism/src/isf_info_manager.h
ism/src/isf_panel_agent_base.cpp
ism/src/isf_panel_agent_base.h
ism/src/isf_panel_agent_manager.cpp
ism/src/isf_panel_agent_manager.h
ism/src/isf_remote_client.cpp
ism/src/isf_remote_client.h
ism/src/isf_remote_control.cpp
ism/src/isf_remote_control.h
ism/src/scim_trans_commands.h

index f48b72f..c498136 100644 (file)
@@ -1241,6 +1241,24 @@ private:
         }
     }
 
+    void socket_remoteinput_cursor_position (int client, uint32 cursor) {
+        SCIM_DEBUG_MAIN(4) << __FUNCTION__ << "...\n";
+        LOGD ("client id:%d", client);
+
+        bool ret;
+        ret = (client == -1) ? false : true;
+
+        if (ret) {
+            Socket client_socket(client);
+
+            m_send_trans.clear();
+            m_send_trans.put_command(SCIM_TRANS_CMD_REPLY);
+            m_send_trans.put_command(ISM_REMOTE_TRANS_CMD_RECV_CURSOR_POSITION);
+            m_send_trans.put_data(cursor);
+            m_send_trans.write_to_socket(client_socket);
+        }
+    }
+
     void socket_update_selection(int client, uint32 context, String& uuid, String text) {
         LOGD ("client id:%d", client);
 
@@ -3382,6 +3400,23 @@ private:
                     trans.put_command(SCIM_TRANS_CMD_REPLY);
                     trans.put_command(ret ? SCIM_TRANS_CMD_OK : SCIM_TRANS_CMD_FAIL);
                     trans.write_to_socket(client_socket);
+                } else if (cmd == ISM_REMOTE_TRANS_CMD_SET_CURSOR_POSITION) {
+                    uint32 cursor;
+                    bool ret = false;
+
+                    if (m_recv_trans.get_data(cursor)) {
+                        ret = m_info_manager->remoteinput_set_cursor_position(cursor);
+                    } else {
+                        LOGW ("wrong format of transaction");
+                    }
+
+                    Transaction trans;
+                    Socket client_socket(client_id);
+
+                    trans.clear();
+                    trans.put_command(SCIM_TRANS_CMD_REPLY);
+                    trans.put_command(ret ? SCIM_TRANS_CMD_OK : SCIM_TRANS_CMD_FAIL);
+                    trans.write_to_socket(client_socket);
                 } else {
                     LOGW ("unknown cmd: %d", cmd);
                 }
index 944f470..864d3ba 100644 (file)
@@ -453,8 +453,10 @@ _wsc_im_ctx_cursor_position (void *data, struct zwp_input_method_context_v1 *im_
     LOGD ("wsc_ctx->surrounding_cursor = %d", wsc_ctx->surrounding_cursor);
     g_info_manager->socket_update_cursor_position (cursor_pos);
 
-    if (_TV)
+    if (_TV) {
+        g_info_manager->remoteinput_callback_cursor_position (cursor_pos);
         remote_surrounding_get (wsc_ctx);
+    }
 }
 
 static void
index 938363a..f5a7165 100644 (file)
@@ -2310,6 +2310,20 @@ public:
         return client >= 0;
     }
 
+    bool remoteinput_set_cursor_position (uint32 cursor)
+    {
+        SCIM_DEBUG_MAIN(1) << "PanelAgent::remote_set_cursor_position ()\n";
+        int    client = -1;
+        uint32 context = 0;
+
+        get_focused_context (client, context);
+        if (client >= 0) {
+            m_panel_agent_manager.socket_helper_set_selection (client, context, cursor, cursor);
+        }
+
+        return client >= 0;
+    }
+
     void reshow_input_panel () {
         /* Check whether application is already focus_in */
         if (m_refocus_needed) {
@@ -3260,6 +3274,16 @@ client context helpers: %zu, helpers uuid count: %zu",
         }
     }
 
+    void remoteinput_callback_cursor_position (uint32 cursor) {
+        SCIM_DEBUG_MAIN (4) << __FUNCTION__ << "...\n";
+
+        for (unsigned int i = 0; i < m_current_recv_remoteinput_id.size (); i++) {
+            lock();
+            m_panel_agent_manager.socket_remoteinput_cursor_position (m_current_recv_remoteinput_id.at (i), cursor);
+            unlock ();
+        }
+    }
+
     //ISM_TRANS_CMD_UPDATE_SELECTION
     void socket_update_selection (String text) {
         SCIM_DEBUG_MAIN (4) << __FUNCTION__ << "...\n";
@@ -4793,6 +4817,12 @@ InfoManager::remoteinput_delete_surrounding_text (uint32 offset, uint32 len)
     return m_impl->remoteinput_delete_surrounding_text (offset, len);
 }
 
+bool
+InfoManager::remoteinput_set_cursor_position (uint32 cursor)
+{
+    return m_impl->remoteinput_set_cursor_position (cursor);
+}
+
 /////////////////////////////////Message function begin/////////////////////////////////////////
 
 //ISM_TRANS_CMD_PANEL_RESET_KEYBOARD_ISE
@@ -5267,6 +5297,11 @@ void InfoManager::remoteinput_callback_key_symbol (String key_symbol, bool press
     m_impl->remoteinput_callback_key_symbol (key_symbol, press, timestamp);
 }
 
+void InfoManager::remoteinput_callback_cursor_position (uint32 cursor)
+{
+    m_impl->remoteinput_callback_cursor_position (cursor);
+}
+
 //ISM_TRANS_CMD_UPDATE_SELECTION
 void InfoManager::socket_update_selection (String text)
 {
index d4386ed..f204da5 100644 (file)
@@ -598,6 +598,10 @@ public:
 
     void remoteinput_callback_key_symbol (String key_symbol, bool press, uint32 timestamp);
 
+    bool remoteinput_set_cursor_position (uint32 cursor);
+
+    void remoteinput_callback_cursor_position (uint32 cursor);
+
 /////////////////////////////////Message function begin/////////////////////////////////////////
 
 //ISM_TRANS_CMD_PANEL_RESET_KEYBOARD_ISE
index 5fa7d4e..79dcd76 100644 (file)
@@ -358,6 +358,10 @@ void PanelAgentBase::socket_remoteinput_key_symbol (int client, String& key_symb
 {
 }
 
+void PanelAgentBase::socket_remoteinput_cursor_position (int client, uint32 cursor)
+{
+}
+
 void PanelAgentBase::socket_update_selection (int client, uint32 context, String& uuid, String text)
 {
 }
index 3e4d54e..5682bbb 100644 (file)
@@ -676,6 +676,15 @@ public:
     virtual void socket_remoteinput_key_symbol (int client, String& key_symbol, int press, uint32 timestamp);
 
     /**
+     * @brief socket_remoteinput_cursor_position.
+     *
+     * @param
+     *
+     * @return none.
+     */
+    virtual void socket_remoteinput_cursor_position (int client, uint32 cursor);
+
+    /**
      * @brief socket_update_selection.
      *
      * @param
index f76cb4d..291ef82 100644 (file)
@@ -696,6 +696,14 @@ void PanelAgentManager::socket_remoteinput_key_symbol (int id, String& key_symbo
         _p->socket_remoteinput_key_symbol (id, key_symbol, press, timestamp);
 }
 
+void PanelAgentManager::socket_remoteinput_cursor_position (int id, uint32 cursor)
+{
+    PanelAgentPointer _p = m_impl->get_panel_agent_by_id (id);
+
+    if (!_p.null ())
+        _p->socket_remoteinput_cursor_position (id, cursor);
+}
+
 void PanelAgentManager::socket_update_selection (int id, uint32 context_id, String& uuid, String text)
 {
     PanelAgentPointer _p = m_impl->get_panel_agent_by_id (id);
index c2d2356..a534f8d 100644 (file)
@@ -328,6 +328,7 @@ public:
     void socket_remoteinput_surrounding_text (int client, String& text, uint32 cursor);
     void socket_remoteinput_input_resource (int client, uint32 input_resource);
     void socket_remoteinput_key_symbol (int client, String&key_symbol, int press, uint32_t timestamp);
+    void socket_remoteinput_cursor_position (int client, uint32 cursor);
     void socket_update_selection (int client, uint32 context, String& uuid, String text);
     void socket_get_keyboard_ise_list (int client, uint32 context, const String& uuid, std::vector<String>& list);
     void socket_get_candidate_ui (int client, uint32 context, const String& uuid,  int style,  int mode);
index 72d1f8d..32f8267 100644 (file)
@@ -143,7 +143,7 @@ class RemoteInputClient::RemoteInputClientImpl
 
     String m_surrounding_text;
     String m_key_symbol;
-    uint32 m_hint, m_cursor, m_layout, m_variation, m_autocapital_type, m_input_resource, m_return_key_disabled, m_return_key_type, m_key_press, m_key_timestamp;
+    uint32 m_hint, m_cursor, m_layout, m_variation, m_autocapital_type, m_input_resource, m_return_key_disabled, m_return_key_type, m_key_press, m_key_timestamp, m_cursor_position;
 
 public:
     RemoteInputClientImpl ()
@@ -161,7 +161,8 @@ public:
             m_return_key_disabled (0),
             m_return_key_type (0),
             m_key_press (0),
-            m_key_timestamp (0) {
+            m_key_timestamp (0),
+            m_cursor_position (0) {
     }
 
     int open_connection (void) {
@@ -390,6 +391,16 @@ public:
                         LOGW ("wrong format of transaction");
                     break;
                 }
+                case ISM_REMOTE_TRANS_CMD_RECV_CURSOR_POSITION:
+                {
+                    type = REMOTE_CONTROL_CALLBACK_CURSOR_POSITION_UPDATED;
+
+                    if (m_trans_recv.get_data (m_cursor_position)) {
+                    }
+                    else
+                        LOGW ("wrong format of transaction");
+                    break;
+                }
                 default:
                     break;
             }
@@ -420,6 +431,34 @@ public:
         *press = m_key_press;
         *timestamp = m_key_timestamp;
     }
+
+    remote_client_error_type set_cursor_position (int cursor) {
+        int cmd;
+
+        if (!prepare ())
+            return REMOTE_CLIENT_ERROR_DISCONNECTED;
+
+        m_trans.put_command (ISM_REMOTE_TRANS_CMD_SET_CURSOR_POSITION);
+        m_trans.put_data (cursor);
+        m_trans.write_to_socket (m_socket_remoteinput2panel);
+        if (!m_trans.read_from_socket (m_socket_remoteinput2panel, m_socket_timeout)) {
+            LOGE ("REMOTE_CLIENT_ERROR_TIMEOUT");
+            return REMOTE_CLIENT_ERROR_TIMEOUT;
+        }
+
+        if (m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY &&
+                m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) {
+        } else {
+            LOGE ("REMOTE_CLIENT_ERROR_REQUEST_DENIED");
+            return REMOTE_CLIENT_ERROR_REQUEST_DENIED;
+        }
+
+        return REMOTE_CLIENT_ERROR_NONE;
+    }
+
+    void get_cursor_position (int *cursor) {
+        *cursor = m_cursor_position;
+    }
 };
 
 RemoteInputClient::RemoteInputClient ()
@@ -509,6 +548,18 @@ RemoteInputClient::get_key_symbol (String &key_symbol, int *press, int *timestam
 {
     m_impl->get_key_symbol (key_symbol, press, timestamp);
 }
+
+remote_client_error_type
+RemoteInputClient::set_cursor_position (int cursor)
+{
+    return m_impl->set_cursor_position (cursor);
+}
+
+void
+RemoteInputClient::get_cursor_position (int *cursor)
+{
+    m_impl->get_cursor_position (cursor);
+}
 };
 
 /*
index 6f9ce3d..caacc97 100644 (file)
@@ -36,6 +36,7 @@ typedef enum {
     REMOTE_CONTROL_CALLBACK_TEXT_UPDATED,
     REMOTE_CONTROL_CALLBACK_INPUT_RESOURCE,
     REMOTE_CONTROL_CALLBACK_KEY_EVENT,
+    REMOTE_CONTROL_CALLBACK_CURSOR_POSITION_UPDATED,
 } remote_control_callback_type;
 
 typedef enum {
@@ -68,6 +69,8 @@ public:
     void get_surrounding_text (String &default_text, int *cursor);
     void get_input_resource (int *input_resource);
     void get_key_symbol (String &key_symbol, int *press, int *timestamp);
+    remote_client_error_type set_cursor_position(int cursor);
+    void get_cursor_position (int *cursor);
 };
 }
 
index 5662151..6ab8fe8 100644 (file)
@@ -41,6 +41,8 @@ struct _remote_control_client {
     void* input_resource_changed_cb_user_data;
     remote_control_key_event_cb key_event_cb;
     void* key_event_cb_user_data;
+    remote_control_cursor_position_updated_cb cursor_position_updated_cb;
+    void* cursor_position_updated_cb_user_data;
 
     _remote_control_client() : remote_client(NULL),
                                remote_client_iochannel(NULL),
@@ -59,7 +61,9 @@ struct _remote_control_client {
                                input_resource_changed_cb(NULL),
                                input_resource_changed_cb_user_data(NULL),
                                key_event_cb(NULL),
-                               key_event_cb_user_data(NULL)
+                               key_event_cb_user_data(NULL),
+                               cursor_position_updated_cb(NULL),
+                               cursor_position_updated_cb_user_data(NULL)
     {
     }
 };
@@ -176,6 +180,19 @@ remote_handler(GIOChannel *source, GIOCondition condition, gpointer user_data)
                     }
                     break;
                 }
+                case REMOTE_CONTROL_CALLBACK_CURSOR_POSITION_UPDATED:
+                {
+                    if (focus_flag) {
+                        int cursor = -1;
+
+                        client->remote_client->get_cursor_position (&cursor);
+                        SECURE_LOGD ("REMOTE_CONTROL_CALLBACK_CURSOR_POSITION_UPDATED: %d", cursor);
+
+                        if (client->cursor_position_updated_cb)
+                            client->cursor_position_updated_cb (client->cursor_position_updated_cb_user_data, cursor);
+                    }
+                    break;
+                }
                 case REMOTE_CONTROL_CALLBACK_ERROR:
                     LOGE ("REMOTE_CONTROL_CALLBACK_ERROR");
                     break;
@@ -667,3 +684,72 @@ EXAPI int remote_control_key_event_callback_unset(remote_control_client *client)
     LOGD ("%p", client);
     return REMOTE_CONTROL_ERROR_NONE;
 }
+
+EXAPI int remote_control_set_cursor_position(remote_control_client *client, int cursor_pos)
+{
+    if (client == NULL || cursor_pos < 0) {
+        LOGE ("REMOTE_CONTROL_INVALID_PARAMETER");
+        return REMOTE_CONTROL_INVALID_PARAMETER;
+    }
+
+    remote_control_error_e error_e = (remote_control_error_e)client->remote_client->check_privilege();
+    if (error_e) {
+        LOGE ("REMOTE_CONTROL_PERMISSION_DENIED");
+        return error_e;
+    }
+
+    if (focus_flag) {
+        error_e = (remote_control_error_e)client->remote_client->set_cursor_position(cursor_pos);
+
+        if (!error_e) {
+            LOGD ("%p, (%d)", client, cursor_pos);
+            if (vconf_set_bool (VCONFKEY_ISF_REMOTE_INPUT_DETECTED, 1) != 0)
+                LOGW ("Failed to set vconf key");
+        }
+
+        return error_e;
+    }
+
+    LOGE ("REMOTE_CONTROL_INVALID_OPERATION");
+    return REMOTE_CONTROL_INVALID_OPERATION;
+}
+
+EXAPI int remote_control_cursor_position_updated_callback_set(remote_control_client *client, remote_control_cursor_position_updated_cb func , void *user_data)
+{
+    if (client == NULL || func == NULL) {
+        LOGE ("REMOTE_CONTROL_INVALID_PARAMETER");
+        return REMOTE_CONTROL_INVALID_PARAMETER;
+    }
+
+    remote_control_error_e error_e = (remote_control_error_e)client->remote_client->check_privilege();
+    if (error_e) {
+        LOGE ("REMOTE_CONTROL_PERMISSION_DENIED");
+        return error_e;
+    }
+
+    client->cursor_position_updated_cb = func;
+    client->cursor_position_updated_cb_user_data = user_data;
+
+    LOGD ("%p", client);
+    return REMOTE_CONTROL_ERROR_NONE;
+}
+
+EXAPI int remote_control_cursor_position_updated_callback_unset(remote_control_client *client)
+{
+    if (client == NULL) {
+        LOGE ("REMOTE_CONTROL_INVALID_PARAMETER");
+        return REMOTE_CONTROL_INVALID_PARAMETER;
+    }
+
+    remote_control_error_e error_e = (remote_control_error_e)client->remote_client->check_privilege();
+    if (error_e) {
+        LOGE ("REMOTE_CONTROL_PERMISSION_DENIED");
+        return error_e;
+    }
+
+    client->cursor_position_updated_cb = NULL;
+    client->cursor_position_updated_cb_user_data = NULL;
+
+    LOGD ("%p", client);
+    return REMOTE_CONTROL_ERROR_NONE;
+}
\ No newline at end of file
index a47b8d6..1f41fa1 100644 (file)
@@ -633,6 +633,89 @@ int remote_control_key_event_callback_set(remote_control_client *client, remote_
  */
 int remote_control_key_event_callback_unset(remote_control_client *client);
 
+/**
+ * @brief Requests to set cursor position.
+ *
+ * @since_tizen @if TV 7.0 @endif
+ *
+ * @privlevel platform
+ *
+ * @privilege %http://tizen.org/privilege/internal/default/platform
+ *
+ * @param[in] client The remote control client
+ * @param[in] cursor_pos The cursor position
+ *
+ * @return 0 on success, otherwise a negative error value
+ * @retval #REMOTE_CONTROL_ERROR_NONE No error
+ * @retval #REMOTE_CONTROL_PERMISSION_DENIED The application does not have the privilege to call this function
+ * @retval #REMOTE_CONTROL_INVALID_OPERATION Invalid operation
+ * @retval #REMOTE_CONTROL_INVALID_PARAMETER Invalid parameter
+ * @retval #REMOTE_CONTROL_REPLY_TIMEOUT Reply timeout
+ * @retval #REMOTE_CONTROL_CONNECTION_LOST Connection to server lost
+ */
+int remote_control_set_cursor_position(remote_control_client *client, int cursor_pos);
+
+/**
+ * @brief Called when the the cursor position is changed.
+ *
+ * @since_tizen @if TV 7.0 @endif
+ *
+ * @privlevel platform
+ *
+ * @privilege %http://tizen.org/privilege/internal/default/platform
+ *
+ * @param[in] user_data User data to be passed from the callback registration function
+ * @param[in] cursor_pos The cursor position
+ *
+ * @pre The callback can be registered using remote_control_cursor_position_updated_callback_set() function.
+ *
+ * @see remote_control_cursor_position_updated_callback_set()
+ * @see remote_control_cursor_position_updated_callback_unset()
+ */
+typedef void (*remote_control_cursor_position_updated_cb)(void *user_data, int cursor_pos);
+
+/**
+ * @brief Sets a callback function to be called when the cursor position is changed.
+ *
+ * @since_tizen @if TV 7.0 @endif
+ *
+ * @privlevel platform
+ *
+ * @privilege %http://tizen.org/privilege/internal/default/platform
+ *
+ * @param[in] client The remote control client
+ * @param[in] func Key event callback function
+ * @param[in] user_data User data to be passed to the callback function
+ *
+ * @return 0 on success, otherwise a negative error value
+ * @retval #REMOTE_CONTROL_ERROR_NONE No error
+ * @retval #REMOTE_CONTROL_PERMISSION_DENIED The application does not have the privilege to call this function
+ * @retval #REMOTE_CONTROL_INVALID_PARAMETER Invalid parameter
+ *
+ * @see remote_control_cursor_position_updated_callback_unset()
+ */
+int remote_control_cursor_position_updated_callback_set(remote_control_client *client, remote_control_cursor_position_updated_cb func , void *user_data);
+
+/**
+ * @brief Unsets the callback function.
+ *
+ * @since_tizen @if TV 7.0 @endif
+ *
+ * @privlevel platform
+ *
+ * @privilege %http://tizen.org/privilege/internal/default/platform
+ *
+ * @param[in] client The remote control client
+ *
+ * @return 0 on success, otherwise a negative error value
+ * @retval #REMOTE_CONTROL_ERROR_NONE No error
+ * @retval #REMOTE_CONTROL_PERMISSION_DENIED The application does not have the privilege to call this function
+ * @retval #REMOTE_CONTROL_INVALID_PARAMETER Invalid parameter
+ *
+ * @see remote_control_cursor_position_updated_callback_set()
+ */
+int remote_control_cursor_position_updated_callback_unset(remote_control_client *client);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index 7bd13c7..2279142 100644 (file)
@@ -650,6 +650,8 @@ const int ISM_REMOTE_TRANS_CMD_CHECK_PRIVILEGE            = 1031;
 const int ISM_REMOTE_TRANS_CMD_DELETE_SURROUNDING_TEXT    = 1032;
 const int ISM_TRANS_CMD_PRELAUNCH_ISE                     = 1033;
 const int ISM_REMOTE_TRANS_CMD_RECV_KEY_SYMBOL            = 1034;
+const int ISM_REMOTE_TRANS_CMD_SET_CURSOR_POSITION        = 1035;
+const int ISM_REMOTE_TRANS_CMD_RECV_CURSOR_POSITION       = 1036;
 
 /* IMControl to ISE */
 const int ISM_TRANS_CMD_SET_ISE_MODE                      = 1108;