Add TV Remote Input API 38/77938/13
authorInHong Han <inhong1.han@samsung.com>
Tue, 31 May 2016 10:59:38 +0000 (19:59 +0900)
committerJihoon Kim <jihoon48.kim@samsung.com>
Thu, 11 Aug 2016 07:34:10 +0000 (16:34 +0900)
Change-Id: Ic9947436de70b3e03e712c950ff22a91f8180dd8

28 files changed:
ism/data/remote-input/openinput.js [new file with mode: 0755]
ism/data/remote-input/remote_input.css
ism/extras/efl_panel/isf_panel_efl.cpp
ism/extras/efl_panel/motion_input.cpp
ism/extras/efl_panel/remote_input.cpp
ism/extras/efl_panel/remote_input.h
ism/extras/efl_panel/websocketserver.cpp
ism/extras/efl_panel/websocketserver.h
ism/modules/panelagent/ecoresocket/ecore_socket_panel_agent_module.cpp
ism/modules/panelagent/wayland/isf_wsc_context.h
ism/modules/panelagent/wayland/wayland_panel_agent_module.cpp
ism/src/Makefile.am
ism/src/isf_control.cpp
ism/src/isf_control.h
ism/src/isf_imcontrol_client.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 [new file with mode: 0644]
ism/src/isf_remote_client.h [new file with mode: 0644]
ism/src/isf_remote_control.cpp [new file with mode: 0644]
ism/src/isf_remote_control.h [new file with mode: 0644]
ism/src/scim.h
ism/src/scim_trans_commands.h
packaging/isf.spec

diff --git a/ism/data/remote-input/openinput.js b/ism/data/remote-input/openinput.js
new file mode 100755 (executable)
index 0000000..afb7a1b
--- /dev/null
@@ -0,0 +1,560 @@
+document.write("<script type='text/javascript' src='ajaxCaller.js'><"+"/script>");
+document.write("<script type='text/javascript' src='util.js'><"+"/script>");
+document.write("<script type='text/javascript' src='jquery-2.0.2.min.js'><"+"/script>");
+
+var openInput;
+
+if(!openInput) openInput = {};
+
+openInput.TV_KEY_ENTER = 0;
+openInput.TV_KEY_SPACE = 1;
+openInput.TV_KEY_BACKSPACE = 2;
+openInput.TV_KEY_ESCAPE = 3;
+openInput.TV_KEY_SELECT = 36;
+openInput.TV_KEY_POWER = 124;
+openInput.TV_KEY_MENU = 10001;
+openInput.TV_KEY_HOME = 10002;
+openInput.TV_KEY_BACK = 10003;
+openInput.TV_KEY_UP = 111;
+openInput.TV_KEY_DOWN = 116;
+openInput.TV_KEY_LEFT = 113;
+openInput.TV_KEY_RIGHT = 114;
+openInput.TV_KEY_SWITCHMODE = 235;
+openInput.TV_KEY_CHANNEL_LIST = 68;
+openInput.TV_KEY_INFO = 69;
+openInput.TV_KEY_EXIT = 182;
+openInput.TV_KEY_CHANNEL_UP = 112;
+openInput.TV_KEY_CHANNEL_DOWN = 117;
+openInput.TV_KEY_MUTE = 121;
+openInput.TV_KEY_VOLUME_DOWN = 122;
+openInput.TV_KEY_VOLUME_UP = 123;
+
+openInput.initialize = function(_app_id) {
+    if (this.impl === undefined) {
+        this.handler = _app_id;
+        this.impl = new WebHelperClientInternal(this);
+    }
+
+    this.impl.activate();
+};
+
+function WebHelperClientInternal(client) {
+    this.MessageTypes = {
+        PLAIN:"plain",
+        QUERY:"query",
+        REPLY:"reply"
+    };
+
+    this.MessageCommands = {
+        INIT:"init",
+        EXIT:"exit",
+
+        FOCUS_IN:"focus_in",
+        FOCUS_OUT:"focus_out",
+        SHOW:"show",
+        HIDE:"hide",
+        SET_ROTATION:"set_rotation",
+        UPDATE_CURSOR_POSITION:"update_cursor_position",
+        SET_LANGUAGE:"set_language",
+        SET_IMDATA:"set_imdata",
+        GET_IMDATA:"get_imdata",
+        SET_RETURN_KEY_TYPE:"set_return_key_type",
+        GET_RETURN_KEY_TYPE:"get_return_key_type",
+        SET_RETURN_KEY_DISABLE:"set_return_key_disable",
+        GET_RETURN_KEY_DISABLE:"get_return_key_disable",
+        SET_LAYOUT:"set_layout",
+        GET_LAYOUT:"get_layout",
+        RESET_INPUT_CONTEXT:"reset_input_context",
+        PROCESS_KEY_EVENT:"process_key_event",
+
+        LOG:"log",
+        COMMIT_STRING:"commit_string",
+        UPDATE_PREEDIT_STRING:"update_preedit_string",
+        SEND_KEY_EVENT:"send_key_event",
+        SEND_MOUSE_KEY:"send_mouse_key",
+        SEND_MOUSE_MOVE:"send_mouse_move",
+        SEND_WHEEL_MOVE:"send_wheel_move",
+        SEND_AIR_INPUT:"send_air_input",
+        SEND_AIR_SETTING:"send_air_setting",
+        FORWARD_KEY_EVENT:"forward_key_event",
+        SET_KEYBOARD_SIZES:"set_keyboard_sizes",
+        CONNECT:"connect"
+    };
+
+    this.log = function(str) {
+        if (this.socket !== "undefined") {
+            this.socket.send(
+                this.MessageTypes.PLAIN + "|" +
+                this.MessageCommands.LOG + "|" +
+                str);
+        }
+    };
+
+    this.sendKeyEvent = function(code) {
+        if (this.socket !== "undefined") {
+            this.socket.send(
+                this.MessageTypes.PLAIN + "|" +
+                this.MessageCommands.SEND_KEY_EVENT + "|" +
+                code);
+        }
+    };
+
+    this.sendMouse_KeyEvent = function(code) {
+        if (this.socket !== "undefined") {
+            this.socket.send(
+                this.MessageTypes.PLAIN + "|" +
+                this.MessageCommands.SEND_MOUSE_KEY + "|" +
+                code);
+        }
+    };
+
+    this.sendMouse_MoveEvent = function(code) {
+        if (this.socket !== "undefined") {
+            this.socket.send(
+                this.MessageTypes.PLAIN + "|" +
+                this.MessageCommands.SEND_MOUSE_MOVE + "|" +
+                code);
+        }
+    };
+
+    this.sendWheel_MoveEvent = function(code) {
+        if (this.socket !== "undefined") {
+            this.socket.send(
+                this.MessageTypes.PLAIN + "|" +
+                this.MessageCommands.SEND_WHEEL_MOVE + "|" +
+                code);
+        }
+    };
+
+    this.commitStr = function(str) {
+        if (this.socket !== "undefined") {
+            this.socket.send(
+                this.MessageTypes.PLAIN + "|" +
+                this.MessageCommands.COMMIT_STRING + "|" +
+                str);
+        }
+    };
+
+    this.updatePreeditString = function(str) {
+        if (this.socket !== "undefined") {
+            this.socket.send(
+                this.MessageTypes.PLAIN + "|" +
+                this.MessageCommands.UPDATE_PREEDIT_STRING + "|" +
+                str);
+        }
+    };
+
+    this.getAppropriateWsUrl = function() {
+
+        var pcol;
+        var u = document.URL;
+
+        if (u.substring(0, 5) == "https") {
+            pcol = "wss://";
+            u = u.substr(8);
+        } else {
+            pcol = "ws://";
+            if (u.substring(0, 4) == "http")
+                u = u.substr(7);
+        }
+
+        u = u.split('/');
+        return pcol + u[0];
+    };
+
+    this.connectWebSocket = function() {
+        if (typeof MozWebSocket != "undefined") {
+            this.socket =
+                new MozWebSocket(this.getAppropriateWsUrl(), "keyboard-protocol");
+        } else {
+            this.socket =
+                new WebSocket(this.getAppropriateWsUrl(), "keyboard-protocol");
+        }
+    };
+
+    this.activate = function() {
+        this.connectWebSocket();
+        this.registerHandlers(this);
+    };
+
+    this.registerHandlers = function(handler) {
+        try {
+            this.socket.onopen = function() {
+                this.send(
+                handler.MessageTypes.PLAIN + "|" +
+                handler.MessageCommands.CONNECT + "|" +
+                "websocket");
+            };
+
+            this.socket.onmessage = function(msg) {
+                var items = msg.data.split("|");
+                alert (items[1]);
+                //handler.defaultHandler(items);
+            };
+
+            this.socket.onclose = function(evt) {
+                /* Try to reconnect if disconnected uncleanly */
+                if (evt.wasClean === false) {
+                    /*
+                    setTimeout((function(handler) {
+                        alert("connecting again!");
+                        this.connectWebSocket();
+                        this.registerHandlers(this);
+                    }).call(handler), 500);
+                    */
+                }
+            };
+        } catch(exception) {
+            alert(exception);
+        }
+    };
+}
+
+//TV
+openInput.tv = {};
+
+(function(window)
+{
+    var MOUSE_CLICK = 555;
+
+    var pre_x = 0;
+    var pre_y = 0;
+    var touch_Pressed=0;
+    var touch_Moved=0;
+    var scroll_pre_x = 0;
+    var scroll_pre_y = 0;
+
+    var id_num = 0;
+    var count = 0;
+
+    var flush_timeout;
+    var cal_flush_timeout;
+    var CAL_FLUSH_TIMEOUT = 3000;
+    var FLUSH_TIMEOUT = 3000;
+    var FLUSH_ENTER_TIMEOUT = 50;
+    var click_start_time = 0;
+
+    var pre_str = "";
+    var pre_pre_str = "";
+    var TMP_CHAR = " ";
+    var TMP_TIMESTAMP = 0;
+    var EMPTY_CHECKER_TIMEOUT = 10;
+    var latest_typed_timestamp = 0;
+    var cur_air_mode = 0;
+    var cur_reset_mode = 0;
+    var cur_touch_mode = 0;
+    var forceEnable_air = 0;
+    var touchmove_delta;
+    var air_delta;
+    var gry_basic_a = -0.043;
+    var gry_basic_b = 0.005;
+    var gry_basic_g = -0.002;
+    var gry_sum_a = 0;
+    var gry_sum_b = 0;
+    var gry_sum_g = 0;
+    var gry_sum_count = 0;
+    var progress = ["",".","..","...","...."];
+    var progress_count=0;
+    var cur_mode = 0;
+
+    var entry_flag = 0;
+    var entry_id = "";
+
+    openInput.tv.sendKeyEvent = function(_code)
+    {
+        event.preventDefault();
+        openInput.impl.sendKeyEvent(_code);
+    };
+
+    function sendMouse_MoveEvent(_coordinate) {
+        event.preventDefault();
+        if (event.touches.length < 2) {
+            openInput.impl.sendMouse_MoveEvent(_coordinate);
+        }
+    }
+
+    function sendMouse_KeyEvent(_mouseCode) {
+        event.preventDefault();
+        if (event.touches.length < 2) {
+            openInput.impl.sendMouse_KeyEvent(_mouseCode);
+        }
+    }
+
+    function check_entry() {
+        if(document.activeElement == document.getElementById(entry_id))
+            return 1;
+        else
+            return 0;
+    }
+
+    openInput.tv.setMousepad = function(_mousepad_id) {
+        $(document).on("touchstart", "#"+_mousepad_id, function() {
+            event.preventDefault();
+            click_start_time = new Date;
+            pre_x = event.touches[0].pageX;
+            pre_y = event.touches[0].pageY;
+            touch_Pressed=1;
+            touch_Moved=0;
+
+            if (check_entry()) {
+                sendFlushCurStr();
+                touch_Pressed=0;
+                document.getElementById(entry_id).blur();
+                return;
+            }
+            /*
+            if(document.activeElement == document.getElementById(entry_id)) {
+                sendFlushCurStr();
+                touch_Pressed=0;
+                return;
+            }*/
+        });
+
+        $(document).on("touchmove", "#"+_mousepad_id, function() {
+            event.preventDefault();
+
+            var coordinate;
+            touch_Moved=1;
+            event.preventDefault();
+            if((pre_x==0) && (pre_y==0)) {
+                pre_x = event.touches[0].pageX;
+                pre_y = event.touches[0].pageY;
+                return;
+            }
+            if((event.touches[0].pageX-pre_x == 0) && (event.touches[0].pageY-pre_y == 0)) {
+                return;
+            }
+
+            if(check_entry()) {
+                touch_Moved=0;
+                touch_Pressed=0;
+                document.getElementById(entry_id).blur();
+                return;
+            }
+            touchmove_delta = parseInt(Math.sqrt(((event.touches[0].pageX-pre_x) * (event.touches[0].pageX-pre_x)) + ((event.touches[0].pageY-pre_y)*(event.touches[0].pageY-pre_y))));
+
+            coordinate = (event.touches[0].pageX-pre_x).toString() + "," + (event.touches[0].pageY-pre_y).toString();
+
+            sendMouse_MoveEvent(coordinate);
+
+            pre_x = event.touches[0].pageX;
+            pre_y = event.touches[0].pageY;
+        });
+
+        $(document).on("touchend", "#"+_mousepad_id, function() {
+            event.preventDefault();
+
+            var coordinate, coordinate2;
+            var direction = 0, count = 0;
+            var click_end_time = new Date;
+            var click_time = click_end_time - click_start_time;
+
+            if(check_entry()){
+                sendFlushCurStr();
+                //hide_keypad();
+                touch_Moved=0;
+                touch_Pressed=0;
+                document.getElementById(entry_id).blur();
+            }
+            else if(touch_Pressed==1 && click_time < 350){
+                    sendMouse_KeyEvent(MOUSE_CLICK);
+                    touch_Moved=0;
+                    touch_Pressed=0;
+            }
+
+            cur_touch_mode = 0;
+        });
+    };
+
+    function sendWheel_MoveEvent (_coordinate) {
+        event.preventDefault();
+        if (event.touches.length < 2) {
+            openInput.impl.sendWheel_MoveEvent(_coordinate);
+        }
+    }
+
+    openInput.tv.setMousescroll = function(_mousescroll_id, _type) {
+        $(document).on("touchstart", "#"+_mousescroll_id, function() {
+            scroll_pre_x = event.touches[0].pageX;
+            scroll_pre_y = event.touches[0].pageY;
+
+            if(check_entry()) {
+                sendFlushCurStr();
+                document.getElementById(entry_id).blur();
+               return;
+            }
+        });
+
+        $(document).on("touchmove", "#"+_mousescroll_id, function() {
+            event.preventDefault();
+            var coordinate;
+
+            if(check_entry()) {
+                sendFlushCurStr();
+                document.getElementById(entry_id).blur();
+                return;
+            }
+            if(scroll_pre_y == 0){
+                scroll_pre_x = event.touches[0].pageX;
+                scroll_pre_y = event.touches[0].pageY;
+                return;
+            }
+            if(((event.touches[0].pageX-scroll_pre_x == 0) && (event.touches[0].pageY-scroll_pre_y == 0))||(event.touches[0].pageY-scroll_pre_y == 0)){
+                return;
+            }
+
+            if (_type === 1)
+                var coordinate = ((event.touches[0].pageX-scroll_pre_x)*-1).toString()+","+((event.touches[0].pageY-scroll_pre_y)*-1).toString();
+            else
+                var coordinate = (event.touches[0].pageX-scroll_pre_x).toString()+","+(event.touches[0].pageY-scroll_pre_y).toString();
+
+            if (Math.abs((event.touches[0].pageY-scroll_pre_y)) >= 3){
+              sendWheel_MoveEvent(coordinate);
+            }
+            scroll_pre_x = event.touches[0].pageX;
+            scroll_pre_y = event.touches[0].pageY;
+        });
+
+        $(document).on("touchend", "#"+_mousescroll_id, function() {
+            scroll_pre_y=0;
+        });
+    };
+
+    function removeTmpChar(str){
+        if (TMP_CHAR.length < 1) return;
+        if (str.length >= TMP_CHAR.length) {
+            str = str.substring (TMP_CHAR.length);
+        }
+        return str;
+    }
+
+    function sendCommitStr(str) {
+        str = removeTmpChar(str);
+        event.preventDefault();
+        openInput.impl.commitStr(str);
+    }
+
+    function sendPreeditStr(str) {
+        str = removeTmpChar(str);
+        event.preventDefault();
+        openInput.impl.updatePreeditString(str);
+    }
+
+    function sendFlushCurStr() {
+        var entry = document.getElementById(entry_id);
+        var str = entry.value;
+        if (str.length > 0) {
+            entry.value = TMP_CHAR;
+            pre_str = "";
+            pre_pre_str = "";
+            sendCommitStr(str);
+            window.clearInterval(flush_timeout);
+        }
+    }
+
+    function hide_keypad() {
+        var entry = document.getElementById(entry_id);
+        entry.blur();
+        Android.hideKeyboard();
+
+        setTimeout(function() {
+            window.scrollTo(0,1);
+            var entry = document.getElementById(entry_id);
+            entry.focus();
+            entry.value = TMP_CHAR;
+        }, 300);
+    }
+
+    openInput.tv.setEntry = function(_entry_id) {
+        if (entry_flag != 0)
+            return;
+
+        entry_id = _entry_id;
+        entry_flag = 1;
+        $(document).ready(function() {
+            var entry = document.getElementById(entry_id);
+            entry.value = TMP_CHAR;
+
+            $(document).on("input", "#"+entry_id, function() {
+                window.clearInterval(flush_timeout);
+                var cur_timestamp = (new Date).getTime();
+                latest_typed_timestamp = cur_timestamp;
+
+                //To prevent multiline field in textarea when the enter key is typed and send commit string and enter key event
+                if(this.value.substring(this.value.length - 1) == "\n"){
+                    this.value = this.value.substring(0, this.value.length - 1);
+                    sendFlushCurStr(entry_id);
+                    entry.value = TMP_CHAR;
+                    TMP_TIMESTAMP = cur_timestamp;
+                    empty_checker_timeout = window.setInterval("reArrangeCursorPos()", EMPTY_CHECKER_TIMEOUT);
+                    openInput.tv.sendKeyEvent(openInput.TV_KEY_ENTER);
+                    return false;
+                }
+
+                //To prevent removing the TMP_CHAR(first) character for the all time
+                if(TMP_CHAR.substring(0, TMP_CHAR.length - 1) == this.value){
+                    entry.value = TMP_CHAR;
+                    TMP_TIMESTAMP = cur_timestamp;
+                    empty_checker_timeout = window.setInterval("reArrangeCursorPos()", EMPTY_CHECKER_TIMEOUT);
+                    return false;
+                }
+
+                //To prevent duplicating preedit string error for Note2, S3 web browser
+                if(pre_str == this.value){
+                    return;
+                }
+
+                /*To prevent wrong preedit string error for Tizen phone, when next character is made in CJK
+                  correct event must happen like [pre_str:ê°€ for ê°„ -> preedit:ê°„ ->  pre_str: ê°„ for ê°€ë‚˜ -> preedit:가나 ]
+                  wrong event happen from tizen  [pre_str:ê°€ for ê°„ -> preedit:ê°„ -> preedit:가나 -> pre_str: ê°€ for ê°€ë‚˜ -> preedit: ê°€ -> pre_str: ê°„ for  ê°€ ] */
+                if(pre_pre_str == this.value) {
+                    return;
+                }
+                pre_pre_str = pre_str;
+                pre_str = this.value;
+
+                //send commit string when the space key is typed
+                if(this.value.substring(this.value.length - 1) == " ") {
+                    sendFlushCurStr(entry_id);
+                } else {
+                    flush_timeout = window.setInterval("sendFlushCurStr()", FLUSH_TIMEOUT);
+                    sendPreeditStr(this.value);
+                }
+            });
+
+            $(document).on("propertychange", "#"+entry_id, function() {
+                alert("document_propertychange");
+            });
+
+            $(document).on("keydown", "#"+entry_id, function() {
+                //To prevent Ctrl + C event (keycode 17:Ctrl, 67:C)
+                if(event.keyCode == 17 || event.keyCode == 67) return;
+
+                //To enable back space key continually, even there is no charactor for Note2, S3 web browser
+                if(this.value == TMP_CHAR && event.keyCode == openInput.TV_KEY_BACKSPACE) {
+                    openInput.tv.sendKeyEvent(event.keyCode);
+                } else if(this.value.length > TMP_CHAR.length && TMP_CHAR == this.value.substring(0, this.value.length - 1)
+                    && event.keyCode == openInput.TV_KEY_BACKSPACE) {
+                    openInput.tv.sendKeyEvent(event.keyCode);
+                }
+            });
+        });
+    };
+
+    window.openInput.tv = openInput.tv;
+})(window);
+
+
+//air conditioner
+openInput.air = {};
+
+(function(window)
+{
+    openInput.air.sendKeyEvent = function(_code)
+    {
+        event.preventDefault();
+        openInput.impl.sendKeyEvent(_code);
+    };
+
+    window.openInput.air = openInput.air;
+})(window);
\ No newline at end of file
index a76254b..7657406 100644 (file)
@@ -100,15 +100,24 @@ div {
 .cell_width5 {
     width:5%;
 }
+.cell_width7 {
+    width:7%;
+}
 .cell_width10 {
     width:10%;
 }
 .cell_width15 {
     width:15%;
 }
+.cell_width20 {
+    width:20%;
+}
 .cell_width25 {
     width:25%;
 }
+.cell_width30 {
+    width:30%;
+}
 .cell_width33 {
     width:33.33%;
 }
@@ -118,21 +127,54 @@ div {
 .cell_width75 {
     width:75%;
 }
+.cell_height1 {
+    height:1%;
+}
+.cell_height3 {
+    height:3%;
+}
+.cell_height4 {
+    height:4%;
+}
 .cell_height5 {
     height:5%;
 }
+.cell_height6 {
+    height:6%;
+}
 .cell_height7 {
     height:7%;
 }
+.cell_height8 {
+    height:8%;
+}
+.cell_height9 {
+    height:9%;
+}
 .cell_height10 {
     height:10%;
 }
+.cell_height11 {
+    height:11%;
+}
+.cell_height12 {
+    height:12%;
+}
 .cell_height13 {
     height:13%;
 }
+.cell_height14 {
+    height:14%;
+}
 .cell_height15 {
     height:15%;
 }
+.cell_height16 {
+    height:16%;
+}
+.cell_height17 {
+    height:17%;
+}
 .cell_height18 {
     height:18%;
 }
@@ -142,9 +184,18 @@ div {
 .cell_height25 {
     height:25%;
 }
+.cell_height30 {
+    height:30%;
+}
+.cell_height34 {
+    height:34%;
+}
 .cell_height40 {
     height:40%;
 }
+.cell_height43 {
+    height:43%;
+}
 .cell_height50 {
     height:50%;
 }
index 4cc7c07..14ddbe4 100644 (file)
@@ -244,8 +244,8 @@ static void       slot_set_keyboard_mode               (int mode);
 static void       slot_get_ise_state                   (int &state);
 static void       slot_start_default_ise               (void);
 static void       slot_stop_default_ise                (void);
-static void       slot_enable_remote_input             (void);
-static void       slot_disable_remote_input            (void);
+static void       slot_send_remote_input_message       (const String &msg, bool len);
+static void       slot_recv_remote_surrounding_text    (int cursor, const String &text);
 
 static void       slot_run_helper                      (const String &uuid, const String &config, const String &display);
 
@@ -3992,8 +3992,8 @@ static bool initialize_panel_agent (const ConfigPointer& config, const String &d
     _info_manager->signal_connect_start_default_ise          (slot (slot_start_default_ise));
     _info_manager->signal_connect_stop_default_ise           (slot (slot_stop_default_ise));
     _info_manager->signal_connect_show_panel                 (slot (slot_show_helper_ise_selector));
-    _info_manager->signal_connect_enable_remote_input        (slot (slot_enable_remote_input));
-    _info_manager->signal_connect_disable_remote_input       (slot (slot_disable_remote_input));
+    _info_manager->signal_connect_remoteinput_send_input_message(slot (slot_send_remote_input_message));
+    _info_manager->signal_connect_remoteinput_send_surrounding_text(slot (slot_recv_remote_surrounding_text));
 
     _info_manager->signal_connect_get_recent_ise_geometry    (slot (slot_get_recent_ise_geometry));
     _info_manager->signal_connect_check_privilege_by_sockfd  (slot (slot_check_privilege_by_sockfd));
@@ -5857,16 +5857,29 @@ static void slot_register_helper_properties (int id, const PropertyList &props)
 #endif
 }
 
-static void slot_enable_remote_input (void)
+static void slot_send_remote_input_message (const String &msg, bool len)
 {
     SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
-    LOGD("Enable remote input");
+
+    String con = msg.c_str ();
+    ISE_MESSAGE message = CISEMessageSerializer::deserialize(con);
+
+    if (remote_input_impl == NULL) {
+        remote_input_impl = Remote_Input::get_instance();
+    }
+
+    remote_input_impl->handle_websocket_message(message);
 }
 
-static void slot_disable_remote_input (void)
+static void slot_recv_remote_surrounding_text (int cursor, const String &text)
 {
     SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
-    LOGD("Disable remote input");
+
+    if (remote_input_impl == NULL) {
+        remote_input_impl = Remote_Input::get_instance();
+    }
+
+    remote_input_impl->handle_recv_panel_message(3, text.c_str (), cursor);
 }
 
 static void slot_show_ise (void)
@@ -7314,7 +7327,9 @@ int main (int argc, char *argv [])
          LOGW ("bt_hid_host_initialize failed\n");
 #endif
 
+#ifdef _TV
     launch_remote_input = scim_global_config_read (String (SCIM_GLOBAL_CONFIG_LAUNCH_REMOTE_INPUT), launch_remote_input);
+#endif
      /* Create remote input */
     if (launch_remote_input) {
          LOGD("remote input start");
index 57c8531..7d7ef42 100644 (file)
@@ -30,7 +30,7 @@ void hpfitler(const _Tp* Y, _Tp* Trend, int numObs, double smoothing)
     }
     else
     {
-        float e[]={smoothing,-4*smoothing,(1+6*smoothing),-4*smoothing,smoothing};
+        float e[]={(float)smoothing,-4*(float)smoothing,(1+6*(float)smoothing),-4*(float)smoothing,(float)smoothing};
         for (int i=0;i<numObs;i++)
         {
             cvSetReal2D(A,i,i,e[2]);
@@ -66,6 +66,7 @@ void hpfitler(const _Tp* Y, _Tp* Trend, int numObs, double smoothing)
     cvReleaseMat(&b);
     cvReleaseMat(&A);
 }
+
 void hpfitler(std::deque<Point2Df>& pY, std::deque<Point2Df>& pTrend, double smoothing)
 {
     if (pTrend.empty())
@@ -91,6 +92,7 @@ void hpfitler(std::deque<Point2Df>& pY, std::deque<Point2Df>& pTrend, double smo
     delete[] Y;
     delete[] Trend;
 }
+
 void hpfitler(std::deque<Point3Df>& pY, std::deque<Point3Df>& pTrend, double smoothing)
 {
     if (pTrend.empty())
@@ -151,7 +153,7 @@ bool Motion_Input::filter_raw_sensor_data(Point3Df *origin_AccData, Point3Df *or
     _GyrFilterBuffer.push_back(GyrData);
     _AccFilterBuffer.push_back(AccData);
 
-    if (_GyrFilterBuffer.size() > _filterNumber)
+    if (_GyrFilterBuffer.size() > (unsigned int)_filterNumber)
     {
         _GyrFilterBuffer.pop_front();
         std::deque<Point3Df> filter_points(_GyrFilterBuffer.size());
@@ -172,7 +174,7 @@ bool Motion_Input::filter_raw_sensor_data(Point3Df *origin_AccData, Point3Df *or
         GyrData.z = zoom_m * (GyrData.z * (1 - rate) + filter_points[_filterNumber - 1].z * rate);
     }
 
-    if (_AccFilterBuffer.size() > _filterNumber)
+    if (_AccFilterBuffer.size() > (unsigned int)_filterNumber)
     {
         _AccFilterBuffer.pop_front();
         std::deque<Point3Df> filter_points(_AccFilterBuffer.size());
index dfc0ccf..86ef3c9 100644 (file)
@@ -23,8 +23,8 @@
  */
 
 #include "remote_input.h"
-#include <math.h>
 #include <iostream>
+#include <math.h>
 
 using namespace scim;
 
@@ -38,98 +38,14 @@ extern std::vector<TOOLBAR_MODE_T>  _modes;
 
 static InfoManager*      _info_manager;
 
-static unsigned int _ise_selector_ise_idx = 0;
-
-// Global variables for remote keyboard
-int priv_id;
-int ret;
-notification_h noti = NULL;
-int noti_count = 0;
-unsigned int preedit_from_remote = 0;
-
-char tv_ip_address[128] = {0};
-char tv_id[128] = {0};
-char db_server_ip[128] = {0};
+static char* surrounding_text = 0;
+static int cursor_pos = 0;
 
 static WebSocketServer *g_web_socket_server = NULL;
 Remote_Input* Remote_Input::m_instance = NULL;
 
-int entry_focused = 0;
 static Motion_Input motion_input;
 
-// curl enum value //
-enum {
-    ERROR_ARGS = 1 ,
-    ERROR_CURL_INIT = 2
-} ;
-
-enum {
-    OPTION_FALSE = 0 ,
-    OPTION_TRUE = 1
-} ;
-
-enum {
-    FLAG_DEFAULT = 0
-} ;
-
-static size_t showSize( void *source , size_t size , size_t nmemb , void *userData ){
-    // we don't touch the data here, so the cast is commented out
-    const char* data = static_cast< const char* >( source ) ;
-    const int bufferSize = size * nmemb ;
-    LOGD ("received TV ID : %s", data);
-    strcpy(tv_id, data);
-
-    return bufferSize;
-}
-
-void get_current_ip()
-{
-    int sock_fd;
-    struct ifconf conf;
-    struct ifreq* ifr;
-    struct sockaddr_in* sin = NULL;
-    char buff[128];
-    int num, i;
-
-    sock_fd = socket(PF_INET, SOCK_DGRAM, 0);
-    if (sock_fd < 0)
-    {
-        LOGD ("Fail to create socket");
-        return;
-    }
-    conf.ifc_len = 128;
-    conf.ifc_buf = buff;
-
-    ioctl(sock_fd, SIOCGIFCONF, &conf);
-    num = conf.ifc_len / sizeof(struct ifreq);
-    ifr = conf.ifc_req;
-
-    for (i = 0; i < num; i++)
-    {
-        sin = (struct sockaddr_in*)(&ifr->ifr_addr);
-
-        ioctl(sock_fd, SIOCGIFFLAGS, ifr);
-        if (((ifr->ifr_flags & IFF_LOOPBACK) == 0)
-                && (ifr->ifr_flags & IFF_UP))
-        {
-            char noti_str[128] = {0};
-            strcat(noti_str, ifr->ifr_name);
-            strcat(noti_str, ":http://");
-            strcat(noti_str, inet_ntoa(sin->sin_addr));
-            strcat(noti_str, ":7172");
-//            post_notification("Wifi ", noti_str);
-        }
-        ifr++;
-    }
-
-    tv_ip_address[0] = '\0';
-    //strcat(tv_ip_address, "http://");
-    strcat(tv_ip_address, inet_ntoa(sin->sin_addr));
-    strcat(tv_ip_address, ":7172");
-
-    close(sock_fd);
-}
-
 Remote_Input::Remote_Input()
 {
     if (m_instance != NULL) {
@@ -202,7 +118,7 @@ void Remote_Input::exit()
 bool Remote_Input::init_uinput_keyboard_device() {
     //For initialize uinput device for keyboard
      struct uinput_user_dev device_key;
-     int uinput_keys[] = {KEY_POWER, KEY_F6, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, KEY_MINUS, KEY_0, KEY_REDO, KEY_F10, KEY_F9, KEY_F8, KEY_F7, KEY_F12, KEY_F11, KEY_LEFTMETA, KEY_HOMEPAGE, KEY_BOOKMARKS, KEY_MENU, KEY_F18, KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_ENTER, KEY_BACK, KEY_EXIT, KEY_ESC, KEY_BACKSPACE, KEY_POWER, KEY_PHONE};
+     int uinput_keys[] = {KEY_POWER, KEY_F6, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, KEY_MINUS, KEY_0, KEY_REDO, KEY_F10, KEY_F9, KEY_F8, KEY_F7, KEY_F5, KEY_F12, KEY_F11, KEY_LEFTMETA, KEY_HOMEPAGE, KEY_BOOKMARKS, KEY_MENU, KEY_F18, KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_ENTER, KEY_BACK, KEY_EXIT, KEY_ESC, KEY_BACKSPACE, KEY_POWER, KEY_PHONE};
      memset(&device_key, 0, sizeof device_key);
 
      fd_uinput_keyboard = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
@@ -212,7 +128,8 @@ bool Remote_Input::init_uinput_keyboard_device() {
          return false;
      }
 
-     strcpy(device_key.name,"Remote-Input(Keyboard)");
+     const char *dev_name = "Remote-Input(Keyboard)";
+     strncpy(device_key.name, dev_name, 1 + strlen(dev_name));
      device_key.id.bustype = BUS_USB;
      device_key.id.vendor = 1;
      device_key.id.product = 1;
@@ -236,7 +153,7 @@ bool Remote_Input::init_uinput_keyboard_device() {
          return false;
      }
 
-     for (int i  = 0; i < sizeof(uinput_keys)/sizeof(uinput_keys[0]); i ++)
+     for (unsigned int i  = 0; i < sizeof(uinput_keys)/sizeof(uinput_keys[0]); i ++)
      {
          if (ioctl(fd_uinput_keyboard, UI_SET_KEYBIT, uinput_keys[i]) < 0)
          {
@@ -256,7 +173,6 @@ bool Remote_Input::init_uinput_keyboard_device() {
 
 bool Remote_Input::init_uinput_mouse_device() {
     //For initialize uinput device for mouse
-    //     int fd_uinput_mouse = 0;
 
     struct uinput_user_dev device_mouse;
     int uinput_btns[] = {BTN_LEFT, BTN_RIGHT, BTN_MIDDLE};
@@ -271,7 +187,8 @@ bool Remote_Input::init_uinput_mouse_device() {
         return false;
     }
 
-    strcpy(device_mouse.name, "Remote-Input(Mouse)");
+    const char *dev_name = "Remote-Input(Mouse)";
+    strncpy(device_mouse.name, dev_name, 1 + strlen(dev_name));
     device_mouse.id.bustype = BUS_USB;
     device_mouse.id.vendor = 1;
     device_mouse.id.product = 1;
@@ -289,7 +206,7 @@ bool Remote_Input::init_uinput_mouse_device() {
         return false;
     }
 
-    for (int i  = 0; i < sizeof(uinput_btns)/sizeof(uinput_btns[0]); i++)
+    for (unsigned int i  = 0; i < sizeof(uinput_btns)/sizeof(uinput_btns[0]); i++)
     {
         if (ioctl(fd_uinput_mouse, UI_SET_KEYBIT, uinput_btns[i]) < 0)
         {
@@ -304,7 +221,7 @@ bool Remote_Input::init_uinput_mouse_device() {
         return false;
     }
 
-    for (int i  = 0; i < sizeof(uinput_rel_axes)/sizeof(uinput_rel_axes[0]); i++)
+    for (unsigned int i  = 0; i < sizeof(uinput_rel_axes)/sizeof(uinput_rel_axes[0]); i++)
     {
         if (ioctl(fd_uinput_mouse, UI_SET_RELBIT, uinput_rel_axes[i]) < 0)
         {
@@ -451,38 +368,67 @@ void Remote_Input::handle_websocket_message(ISE_MESSAGE &message)
             int e = atoi(message.values.at(0).c_str());
             LOGD("send_key_event key num : %d", e);
             switch (e) {
-                case 8://backspace
-                    LOGD ("back");
-                    _info_manager->forward_key_event(KeyEvent(SCIM_KEY_BackSpace));
-                    _info_manager->forward_key_event(KeyEvent(SCIM_KEY_BackSpace, SCIM_KEY_ReleaseMask));
-                    break;
-
-                case 13://enter
+                case 0: //enter
                     LOGD ("enter");
-                    _info_manager->forward_key_event(KeyEvent(SCIM_KEY_Select));
-                    _info_manager->forward_key_event(KeyEvent(SCIM_KEY_Select, SCIM_KEY_ReleaseMask));
+                    _info_manager->remoteinput_forward_key_event(KeyEvent(SCIM_KEY_Select));
+                    break;
+                case 1: //space
+                    LOGD ("space");
+                    _info_manager->remoteinput_forward_key_event(KeyEvent(SCIM_KEY_KP_Space));
+                    break;
+                case 2: //backspace
+                    LOGD ("backspace");
+                    _info_manager->remoteinput_forward_key_event(KeyEvent(SCIM_KEY_BackSpace));
+                    break;
+                case 3: //esc
+                    LOGD ("esc");
+                    _info_manager->remoteinput_forward_key_event(KeyEvent(SCIM_KEY_Escape));
+                    break;
+                case 4: //up
+                    LOGD ("up");
+                    _info_manager->remoteinput_forward_key_event(KeyEvent(SCIM_KEY_Up));
+                    break;
+                case 5: //down
+                    LOGD ("down");
+                    _info_manager->remoteinput_forward_key_event(KeyEvent(SCIM_KEY_Down));
+                    break;
+                case 6: //left
+                    LOGD ("left");
+                    _info_manager->remoteinput_forward_key_event(KeyEvent(SCIM_KEY_Left));
+                    break;
+                case 7: //right
+                    LOGD ("right");
+                    _info_manager->remoteinput_forward_key_event(KeyEvent(SCIM_KEY_Right));
+                    break;
+                case 8: //page_up
+                    LOGD ("page_up");
+                    _info_manager->remoteinput_forward_key_event(KeyEvent(SCIM_KEY_Page_Up));
+                    break;
+                case 9: //page_down
+                    LOGD ("page_down");
+                    _info_manager->remoteinput_forward_key_event(KeyEvent(SCIM_KEY_Page_Down));
                     break;
-
                 case 10001://Menu
                     LOGD ("menu");
-                    panel_send_uinput_event_for_key(UINPUT_KEYBOARD, KEY_PHONE);
+                    //panel_send_uinput_event_for_key(UINPUT_KEYBOARD, KEY_PHONE);
+                    panel_send_uinput_event_for_key(UINPUT_KEYBOARD, KEY_LEFTMETA); //for tv product binary
                     break;
 
                 case 10002://Home
                     LOGD ("home");
-                    panel_send_uinput_event_for_key(UINPUT_KEYBOARD, KEY_MENU);
+                    //panel_send_uinput_event_for_key(UINPUT_KEYBOARD, KEY_MENU);
+                    panel_send_uinput_event_for_key(UINPUT_KEYBOARD, KEY_F5); //for tv product binary
                     break;
 
                 case 10003://Back
                     LOGD ("back");
-                    panel_send_uinput_event_for_key(UINPUT_KEYBOARD, KEY_BACK); //for TDC, 2.4 binary
-                    //panel_send_uinput_event_for_key(UINPUT_KEYBOARD, KEY_ESC); //for tv product binary
+                    //panel_send_uinput_event_for_key(UINPUT_KEYBOARD, KEY_BACK); //for TDC, 3.0 binary
+                    panel_send_uinput_event_for_key(UINPUT_KEYBOARD, KEY_ESC); //for tv product binary
                     break;
 
                 case 124://TV_KEY_POWER
                     LOGD ("TV_KEY_POWER");
                     panel_send_uinput_event_for_key(UINPUT_KEYBOARD, KEY_POWER);
-                    g_web_socket_server->on_init();
                     break;
 
                 case 235://TV_KEY_SWITCHMODE
@@ -565,42 +511,6 @@ void Remote_Input::handle_websocket_message(ISE_MESSAGE &message)
                     panel_send_uinput_event_for_key(UINPUT_KEYBOARD, KEY_F11);
                     break;
 
-                case 304://GAME_A
-                    LOGD ("GAME_A");
-                    //panel_send_uinput_event_for_key(UINPUT_KEYBOARD, );
-                    //ecore_x_test_fake_key_press("BNT_A");
-                    break;
-
-                case 305://GAME_B
-                    LOGD ("GAME_B");
-                    //panel_send_uinput_event_for_key(UINPUT_KEYBOARD, );
-                    //ecore_x_test_fake_key_press("BNT_B");
-                    break;
-
-                case 307://GAME_X
-                    LOGD ("GAME_X");
-                    //panel_send_uinput_event_for_key(UINPUT_KEYBOARD, );
-                    //ecore_x_test_fake_key_press("BNT_X");
-                    break;
-
-                case 308://GAME_Y
-                    LOGD ("GAME_Y");
-                    //panel_send_uinput_event_for_key(UINPUT_KEYBOARD, );
-                    //ecore_x_test_fake_key_press("BNT_Y");
-                    break;
-
-                case 314://GAME_SELECT
-                    LOGD ("GAME_SELECT");
-                    //panel_send_uinput_event_for_key(UINPUT_KEYBOARD, );
-                    //ecore_x_test_fake_key_press("BNT_SELECT");
-                    break;
-
-                case 315://GAME_START
-                    LOGD ("GAME_START");
-                    //panel_send_uinput_event_for_key(UINPUT_KEYBOARD, );
-                    //ecore_x_test_fake_key_press("BNT_START");
-                    break;
-
                 default:
                     LOGD ("unknow key=%d", e);
                     break;
@@ -620,7 +530,7 @@ void Remote_Input::handle_websocket_message(ISE_MESSAGE &message)
             attrs.push_back(scim::Attribute(0, scim::utf8_mbstowcs((char*)message.values.at(0).c_str()).length(), scim::SCIM_ATTR_DECORATE, scim::SCIM_ATTR_DECORATE_UNDERLINE));
 
             LOGD( "commit_str:|%s|", message.values.at(0).c_str());
-            _info_manager->commit_string(scim::utf8_mbstowcs((char*)message.values.at(0).c_str()));
+            _info_manager->remoteinput_commit_string(scim::utf8_mbstowcs((char*)message.values.at(0).c_str()));
         }
     }
 
@@ -629,18 +539,8 @@ void Remote_Input::handle_websocket_message(ISE_MESSAGE &message)
             scim::AttributeList attrs;
             attrs.push_back(scim::Attribute(0, scim::utf8_mbstowcs((char*)message.values.at(0).c_str()).length(), scim::SCIM_ATTR_DECORATE, scim::SCIM_ATTR_DECORATE_UNDERLINE));
 
-            if (preedit_from_remote == 1){
-                LOGD ("preedit:|%s| from same %d", message.values.at(0).c_str(),preedit_from_remote);
-                _info_manager->update_preedit_string(scim::utf8_mbstowcs((char*)message.values.at(0).c_str()), attrs);
-                preedit_from_remote = 1;
-            }
-            else{
-                //FIXME flush_imengine fuction need
-                //flush_immengine_by_remote();
-                LOGD ("preedit:|%s| from different %d", message.values.at(0).c_str(),preedit_from_remote);
-                _info_manager->update_preedit_string(scim::utf8_mbstowcs((char*)message.values.at(0).c_str()), attrs);
-                preedit_from_remote = 1;
-            }
+            LOGD ("preedit:|%s|", message.values.at(0).c_str());
+            _info_manager->remoteinput_update_preedit_string(scim::utf8_mbstowcs((char*)message.values.at(0).c_str()), attrs, -1);
         }
     }
 
@@ -668,7 +568,7 @@ void Remote_Input::handle_websocket_message(ISE_MESSAGE &message)
         if (message.values.size() == 1) {
 
             std::size_t tmp_offset = message.values.at(0).find(',');
-            int x = atoi(message.values.at(0).substr(0, tmp_offset).c_str());
+            //int x = atoi(message.values.at(0).substr(0, tmp_offset).c_str());
             int y = atoi(message.values.at(0).substr(tmp_offset+1).c_str());
             panel_send_uinput_event_for_wheel(UINPUT_MOUSE, (__s32)y);
         }
@@ -679,13 +579,14 @@ void Remote_Input::handle_websocket_message(ISE_MESSAGE &message)
 
             double set_data[5] = {0};
             char *pch;
+            char *ptr[2];
             char *string = (char *)message.values.at(0).c_str();
             int count=0;
 
-            pch = strtok (string,",");
+            pch = strtok_r (string, ",", &ptr[0]);
             while (pch !=NULL){
                 set_data[count++]=atof(pch);
-                pch = strtok (NULL,",");
+                pch = strtok_r (NULL, ",", &ptr[1]);
             }
 
             LOGD( "2. SETTING data : %f, %f, %f, %f, %f" ,set_data[0],set_data[1],set_data[2],set_data[3],set_data[4] );
@@ -699,13 +600,14 @@ void Remote_Input::handle_websocket_message(ISE_MESSAGE &message)
 
             double dataBuf[6] = {0};
             char *pch;
+            char *ptr[2];
             char *string = (char *)message.values.at(0).c_str();
             int count=0;
 
-            pch = strtok (string,",");
+            pch = strtok_r (string, ",", &ptr[0]);
             while (pch !=NULL){
                 dataBuf[count++]=atof(pch);
-                pch = strtok (NULL,",");
+                pch = strtok_r (NULL, ",", &ptr[1]);
             }
             //LOGD( "2. CV Air Input data : %f, %f, %f, %f, %f, %f" ,dataBuf[0],dataBuf[1],dataBuf[2],dataBuf[3],dataBuf[4],dataBuf[5] );
             panel_send_uinput_event_for_air_mouse(UINPUT_MOUSE, dataBuf);
@@ -713,60 +615,23 @@ void Remote_Input::handle_websocket_message(ISE_MESSAGE &message)
     }
 }
 
-void Remote_Input::post_notification(const char* _ptitle, const char* _ptext)
-{
-    if (_ptext == NULL)
-        return;
-    notification_status_message_post(_ptext);
-}
-
-void Remote_Input::ongoing_notification(const char* _ptitle, const char* _ptext)
-{
-    if (_ptext == NULL)
-        return;
-    noti = notification_create(NOTIFICATION_TYPE_ONGOING);
-    ret = notification_set_layout(noti, NOTIFICATION_LY_ONGOING_EVENT);
-
-    if (ret != NOTIFICATION_ERROR_NONE)
-    {
-        LOGW ( "Fail to notification_set_image [%d]", ret);
-    }
-
-    ret = notification_set_image(noti, NOTIFICATION_IMAGE_TYPE_ICON, "/usr/share/scim/ise-wifi-keyboard/wifikeyboard.png");
-    if (ret != NOTIFICATION_ERROR_NONE)
-    {
-        LOGW ( "Fail to notification_set_image [%d]", ret);
-    }
-
-    ret = notification_set_text(noti, NOTIFICATION_TEXT_TYPE_TITLE, _ptext, NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
-    if (ret != NOTIFICATION_ERROR_NONE)
-    {
-        LOGW ( "Fail to notification_set_text [%d]", ret);
-    }
-
-    ret = notification_set_text(noti, NOTIFICATION_TEXT_TYPE_CONTENT, _ptitle, NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
-    if (ret != NOTIFICATION_ERROR_NONE)
-    {
-        LOGW ( "Fail to notification_set_text [%d]", ret);
-    }
-
-    //ret = notification_insert(noti, &priv_id);
-    if (ret != NOTIFICATION_ERROR_NONE)
-    {
-        LOGW ( "Fail to notification_insert [%d]", ret);
-    }
-}
-
-void Remote_Input::del_notification()
+void Remote_Input::handle_recv_panel_message(int mode, const char* text, int cursor)
 {
-    ret = notification_free(noti);
-    if (ret != NOTIFICATION_ERROR_NONE)
-    {
-        LOGW ( "Fail to notification_free [%d]", ret);
+    switch (mode) {
+        case 1:
+            break;
+        case 2:
+            break;
+        case 3:
+        {
+            if (cursor_pos != cursor || strcmp (surrounding_text, text) != 0) {
+                cursor_pos = cursor;
+                surrounding_text = strdup(text);
+                g_web_socket_server->get_surrounding_text(cursor, text);
+            }
+            break;
+        }
+        default:
+            break;
     }
-    //notification_delete_group_by_priv_id(NULL, NOTIFICATION_TYPE_NOTI, priv_id);
-    noti_count = 0;
 }
-
-
-
index d60ae80..ad2ecfe 100644 (file)
@@ -30,7 +30,6 @@
 
 #include <dlog.h>
 
-#include <notification.h>
 #include <stdio.h>
 #include <stdlib.h>
 
 #include <linux/uinput.h>
 
 #include "scim.h"
-#include "scim_private.h"
 #include "motion_input.h"
 #include "websocketserver.h"
 
-#define LOG_TAG                                         "ISF_REMOTE_INPUT"
 using namespace scim;
 
 enum UINPUT_DEVICE{
@@ -101,12 +98,7 @@ public:
 
     void handle_websocket_message(ISE_MESSAGE &message);
 
-    void del_notification();
-
-    void ongoing_notification(const char* _ptitle, const char* _ptext);
-
-    void post_notification(const char* _ptitle, const char* _ptext);
-
+    void handle_recv_panel_message(int mode, const char* text, int cursor);
 };
 
 #endif /* __REMOTE_INPUT_H__ */
index 62a49f4..91484c0 100644 (file)
@@ -164,16 +164,10 @@ static int callback_http(struct lws *wsi,
         enum lws_callback_reasons reason,
         void *user, void *in, size_t len)
 {
-    LOGD(" ");
-#if 0
-    char client_name[128];
-    char client_ip[128];
-#endif
     char buf[256];
     int n, m;
-    unsigned char *p;
+    unsigned int i;
     static unsigned char buffer[4096];
-    struct stat stat_buf;
     struct per_session_data__http *pss = (struct per_session_data__http *)user;
 #ifdef EXTERNAL_POLL
     int fd = (int)(long)in;
@@ -181,64 +175,13 @@ static int callback_http(struct lws *wsi,
 
     switch (reason) {
     case LWS_CALLBACK_HTTP:
-
-        /* check for the "send a big file by hand" example case */
-
-        if (!strcmp((const char *)in, "/leaf.jpg")) {
-
-            /* well, let's demonstrate how to send the hard way */
-
-            p = buffer;
-
-            pss->fd = open(LOCAL_RESOURCE_PATH"/leaf.jpg", O_RDONLY);
-            if (pss->fd < 0)
-                return -1;
-
-            fstat(pss->fd, &stat_buf);
-
-            /*
-             * we will send a big jpeg file, but it could be
-             * anything.  Set the Content-Type: appropriately
-             * so the browser knows what to do with it.
-             */
-
-            p += sprintf((char *)p,
-                "HTTP/1.0 200 OK\x0d\x0a"
-                "Server: libwebsockets\x0d\x0a"
-                "Content-Type: image/jpeg\x0d\x0a"
-                    "Content-Length: %u\x0d\x0a\x0d\x0a",
-                    (unsigned int)stat_buf.st_size);
-
-            /*
-             * send the http headers...
-             * this won't block since it's the first payload sent
-             * on the connection since it was established
-             * (too small for partial)
-             */
-
-            n = lws_write(wsi, buffer,
-                   p - buffer, LWS_WRITE_HTTP);
-
-            if (n < 0) {
-                close(pss->fd);
-                return -1;
-            }
-            /*
-             * book us a LWS_CALLBACK_HTTP_WRITEABLE callback
-             */
-            lws_callback_on_writable(wsi);
-            break;
-        }
-
-        /* if not, send a file the easy way */
-
-        for (n = 0; n < (sizeof(whitelist) / sizeof(whitelist[0]) - 1); n++)
-            if (in && strcmp((const char *)in, whitelist[n].urlpath) == 0)
+        for (i = 0; i < (sizeof(whitelist) / sizeof(whitelist[0]) - 1); i++)
+            if ((const char *)in && strcmp((const char *)in, whitelist[i].urlpath) == 0)
                 break;
 
-        sprintf(buf, LOCAL_RESOURCE_PATH"%s", whitelist[n].urlpath);
+        snprintf(buf, sizeof(buf), LOCAL_RESOURCE_PATH"%s", whitelist[i].urlpath);
 
-        if (lws_serve_http_file(wsi, buf, whitelist[n].mimetype, NULL, NULL))
+        if (lws_serve_http_file(wsi, buf, whitelist[i].mimetype, NULL, 0))
             return -1; /* through completion or error, close the socket */
 
         /*
@@ -250,7 +193,7 @@ static int callback_http(struct lws *wsi,
         break;
 
     case LWS_CALLBACK_HTTP_FILE_COMPLETION:
-//      lwsl_info("LWS_CALLBACK_HTTP_FILE_COMPLETION seen\n");
+        //lwsl_info("LWS_CALLBACK_HTTP_FILE_COMPLETION seen\n");
         /* kill the connection after we sent one file */
         return -1;
 
@@ -441,31 +384,21 @@ callback_keyboard(struct lws *wsi,
             std::string str = (const char *)in;
             LOGD("Receive MSG :|%s|", str.c_str());
             ISE_MESSAGE message = CISEMessageSerializer::deserialize(str);
-/*
-            if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_LOGIN]) == 0) {
-                if (message.values.at(0).compare(CMagicKeyManager::get_magic_key()) == 0) {
-                    LOGD("LOGIN successful, validating client");
-                    pss->valid = true;
-                } else {
-                    LOGD("LOGIN failed, invalidating client");
-                    pss->valid = false;
-                }
-            }
-*/
-                pthread_mutex_lock(&g_ws_server_mutex);
-                std::queue<ISE_MESSAGE>& messages = agent->get_recv_message_queue();
-                messages.push(message);
-                pthread_mutex_unlock(&g_ws_server_mutex);
 
-                const char *recved_message = "recved";
-                ecore_pipe_write(agent->get_recv_message_pipe(), recved_message, strlen(recved_message));
+            pthread_mutex_lock(&g_ws_server_mutex);
+            std::queue<ISE_MESSAGE>& messages = agent->get_recv_message_queue();
+            messages.push(message);
+            pthread_mutex_unlock(&g_ws_server_mutex);
 
-                /* If we received reply message, let's send signal to wake up our main thread */
-                if (message.type.compare(ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_REPLY]) == 0) {
-                    pthread_mutex_lock(&g_ws_query_mutex);
-                    pthread_cond_signal(&g_ws_query_condition);
-                    pthread_mutex_unlock(&g_ws_query_mutex);
-                }
+            const char *recved_message = "recved";
+            ecore_pipe_write(agent->get_recv_message_pipe(), recved_message, strlen(recved_message));
+
+            /* If we received reply message, let's send signal to wake up our main thread */
+            if (message.type.compare(ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_REPLY]) == 0) {
+                pthread_mutex_lock(&g_ws_query_mutex);
+                pthread_cond_signal(&g_ws_query_condition);
+                pthread_mutex_unlock(&g_ws_query_mutex);
+            }
         }
 
         break;
@@ -479,26 +412,12 @@ callback_keyboard(struct lws *wsi,
 void *process_ws_server(void *data)
 {
     LOGD(" ");
-    unsigned int oldus = 0;
 
     while (!force_exit && !g_ws_server_exit) {
         struct timeval tv;
         gettimeofday(&tv, NULL);
 
         /*
-         * This provokes the LWS_CALLBACK_SERVER_WRITEABLE for every
-         * live websocket connection using the DUMB_INCREMENT protocol,
-         * as soon as it can take more packets (usually immediately)
-         */
-
-        /*
-        if (((unsigned int)tv.tv_usec - oldus) > 50000) {
-            libwebsocket_callback_on_writable_all_protocol(&protocols[PROTOCOL_KEYBOARD]);
-            oldus = tv.tv_usec;
-        }
-        */
-
-        /*
          * If libwebsockets sockets are all we care about,
          * you can use this api which takes care of the poll()
          * and looping through finding who needed service.
@@ -507,7 +426,11 @@ void *process_ws_server(void *data)
          * the number of ms in the second argument.
          */
 
-        lws_service(g_ws_server_context, 50);
+        if (g_ws_server_context) {
+            lws_service(g_ws_server_context, 50);
+        } else {
+            LOGD("WARNING : g_ws_server_context is NULL");
+        }
     }
     return NULL;
 }
@@ -566,9 +489,7 @@ bool WebSocketServer::init()
 
     info.iface = NULL;
     info.protocols = protocols;
-#ifndef LWS_NO_EXTENSIONS
-    info.extensions = lws_get_internal_extensions();
-#endif
+    info.extensions = NULL;
     info.ssl_cert_filepath = NULL;
     info.ssl_private_key_filepath = NULL;
     info.gid = -1;
@@ -619,7 +540,7 @@ bool WebSocketServer::exit()
 
     g_ws_server_exit = true;
 
-    feedback_deinitialize(); // Deinitialize feedback
+    feedback_deinitialize(); //Deinitialize feedback
 
     if (m_recv_message_pipe) {
         ecore_pipe_del(m_recv_message_pipe);
@@ -731,6 +652,26 @@ void WebSocketServer::on_focus_out(int ic)
     }
 }
 
+void WebSocketServer::get_surrounding_text(int cursor, const char *text)
+{
+    LOGD(" ");
+    ISE_MESSAGE message;
+    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_PLAIN];
+    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMANDS_GET_SURROUNDING_TEXT];
+    message.values.push_back(text);
+    message.values.push_back(to_string(cursor));
+
+    pthread_mutex_lock(&g_ws_server_mutex);
+    m_send_message_queue.push(message);
+    pthread_mutex_unlock(&g_ws_server_mutex);
+
+    if (g_ws_server_context) {
+        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
+    } else {
+        LOGD("WARNING : g_ws_server_context is NULL");
+    }
+}
+
 void WebSocketServer::on_show(int ic)
 {
     LOGD(" ");
@@ -816,8 +757,8 @@ void WebSocketServer::on_set_language(unsigned int language)
     message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_SET_LANGUAGE];
 
     bool found = false;
-    for (unsigned int loop = 0;loop < sizeof(ISE_LANGUAGE_TYPES) / sizeof(ISE_TYPE_VALUE_STRING);loop++) {
-        if (language == ISE_LANGUAGE_TYPES[loop].type_value) {
+    for (size_t loop = 0;loop < sizeof(ISE_LANGUAGE_TYPES) / sizeof(ISE_TYPE_VALUE_STRING);loop++) {
+        if ((int)language == ISE_LANGUAGE_TYPES[loop].type_value) {
             message.values.push_back(ISE_LANGUAGE_TYPES[loop].type_string);
             found = true;
         }
@@ -903,8 +844,8 @@ void WebSocketServer::on_set_return_key_type(unsigned int type)
     message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_SET_RETURN_KEY_TYPE];
 
     bool found = false;
-    for (unsigned int loop = 0;loop < sizeof(ISE_RETURN_KEY_TYPES) / sizeof(ISE_TYPE_VALUE_STRING);loop++) {
-        if (type == ISE_RETURN_KEY_TYPES[loop].type_value) {
+    for (size_t loop = 0;loop < sizeof(ISE_RETURN_KEY_TYPES) / sizeof(ISE_TYPE_VALUE_STRING);loop++) {
+        if ((int)type == ISE_RETURN_KEY_TYPES[loop].type_value) {
             message.values.push_back(ISE_RETURN_KEY_TYPES[loop].type_string);
             found = true;
         }
@@ -966,8 +907,8 @@ void WebSocketServer::on_set_return_key_disable(unsigned int disabled)
     message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_SET_RETURN_KEY_DISABLE];
 
     bool found = false;
-    for (unsigned int loop = 0;loop < sizeof(ISE_TRUEFALSE_TYPES) / sizeof(ISE_TYPE_VALUE_STRING);loop++) {
-        if (disabled == ISE_TRUEFALSE_TYPES[loop].type_value) {
+    for (size_t loop = 0;loop < sizeof(ISE_TRUEFALSE_TYPES) / sizeof(ISE_TYPE_VALUE_STRING);loop++) {
+        if ((int)disabled == ISE_TRUEFALSE_TYPES[loop].type_value) {
             message.values.push_back(ISE_TRUEFALSE_TYPES[loop].type_string);
             found = true;
         }
@@ -1064,7 +1005,6 @@ void WebSocketServer::on_get_layout(unsigned int *layout)
     }
 
     wait_for_reply_message();
-
     std::vector<std::string> values;
     /* Check if we received reply for GET_LAYOUT message */
     if (process_recved_messages_until_reply_found(
@@ -1119,7 +1059,6 @@ void WebSocketServer::on_process_key_event(unsigned int code, unsigned int mask,
     }
 
     wait_for_reply_message();
-
     std::vector<std::string> values;
     /* Check if we received reply for PROCESS_KEY_EVENT message */
     if (process_recved_messages_until_reply_found(
@@ -1168,33 +1107,27 @@ void WebSocketServer::wait_for_reply_message()
     pthread_mutex_lock(&g_ws_query_mutex);
     pthread_cond_timedwait(&g_ws_query_condition, &g_ws_query_mutex, &timeout);
     pthread_mutex_unlock(&g_ws_query_mutex);
-
 }
 
 void WebSocketServer::process_recved_messages()
 {
     LOGD(" ");
-    pthread_mutex_lock(&g_ws_server_mutex);
 
+    pthread_mutex_lock(&g_ws_server_mutex);
     while (m_recv_message_queue.size() > 0) {
         ISE_MESSAGE &message = m_recv_message_queue.front();
-
         handle_recved_message(message);
-
         m_recv_message_queue.pop();
     }
-
     pthread_mutex_unlock(&g_ws_server_mutex);
 }
 
 bool WebSocketServer::process_recved_messages_until_reply_found(std::string command, std::vector<std::string> &values)
 {
     LOGD(" ");
-
     bool ret = false;
 
     pthread_mutex_lock(&g_ws_server_mutex);
-
     while (ret == false && m_recv_message_queue.size() > 0) {
         ISE_MESSAGE &message = m_recv_message_queue.front();
 
@@ -1204,10 +1137,8 @@ bool WebSocketServer::process_recved_messages_until_reply_found(std::string comm
             values = message.values;
         }
         handle_recved_message(message);
-
         m_recv_message_queue.pop();
     }
-
     pthread_mutex_unlock(&g_ws_server_mutex);
 
     return ret;
@@ -1217,11 +1148,6 @@ void WebSocketServer::handle_recved_message(ISE_MESSAGE &message)
 {
     LOGD(" ");
     LOGD("Received message : %s, %s, %s", message.type.c_str(), message.command.c_str() , message.values.at(0).c_str());
-    /*FIXME delte login
-    if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_LOGIN]) == 0) {
-        libwebsocket_callback_on_writable_all_protocol(&protocols[PROTOCOL_KEYBOARD]);
-    }
-    */
 
     if (remote_input_impl == NULL) {
         remote_input_impl = Remote_Input::get_instance();
index 72383a8..a10b2be 100644 (file)
@@ -78,6 +78,8 @@ typedef enum {
     ISE_MESSAGE_COMMAND_LOGIN,
 
     ISE_MESSAGE_COMMANDS_NUM,
+
+    ISE_MESSAGE_COMMANDS_GET_SURROUNDING_TEXT,
 } ISE_MESSAGE_COMMANDS;
 
 const std::string ISE_MESSAGE_COMMAND_STRINGS[] = {
@@ -237,6 +239,8 @@ public:
     void on_focus_in(int ic);
     void on_focus_out(int ic);
 
+    void get_surrounding_text(int cursor, const char *text);
+
     void on_show(int ic);
     void on_hide(int ic);
 
index 7579f70..fff9768 100755 (executable)
@@ -1023,6 +1023,80 @@ private:
         m_send_trans.write_to_socket(client_socket);
     }
 
+    void socket_remoteinput_focus_in (int client) {
+        SCIM_DEBUG_MAIN(4) << __FUNCTION__ << "...\n";
+        LOGD ("client id:%d\n", 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_TRANS_CMD_RECV_REMOTE_FOCUS_IN);
+            m_send_trans.write_to_socket(client_socket);
+        }
+    }
+
+    void socket_remoteinput_focus_out (int client) {
+        SCIM_DEBUG_MAIN(4) << __FUNCTION__ << "...\n";
+        LOGD ("client id:%d\n", 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_TRANS_CMD_RECV_REMOTE_FOCUS_OUT);
+            m_send_trans.write_to_socket(client_socket);
+        }
+    }
+
+    void socket_remoteinput_entry_metadata (int client, uint32 hint, uint32 layout, int variation, uint32 autocapital_type) {
+        SCIM_DEBUG_MAIN(4) << __FUNCTION__ << "...\n";
+        LOGD ("client id:%d\n", 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_TRANS_CMD_RECV_REMOTE_ENTRY_METADATA);
+            m_send_trans.put_data(hint);
+            m_send_trans.put_data(layout);
+            m_send_trans.put_data(variation);
+            m_send_trans.put_data(autocapital_type);
+            m_send_trans.write_to_socket(client_socket);
+        }
+    }
+
+    void socket_remoteinput_default_text (int client, String& text, uint32 cursor) {
+        SCIM_DEBUG_MAIN(4) << __FUNCTION__ << "...\n";
+        LOGD ("client id:%d\n", 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_TRANS_CMD_RECV_REMOTE_DEFAULT_TEXT);
+            m_send_trans.put_data(text);
+            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\n", client);
 
@@ -2921,10 +2995,37 @@ private:
                     trans.put_command(SCIM_TRANS_CMD_OK);
                     trans.write_to_socket(client_socket);
                     m_info_manager->hide_helper_ise ();
-                } else if (cmd == ISM_TRANS_CMD_ENABLE_REMOTE_INPUT) {
-                    m_info_manager->enable_remote_input (client_id);
-                } else if (cmd == ISM_TRANS_CMD_DISABLE_REMOTE_INPUT) {
-                    m_info_manager->disable_remote_input (client_id);
+                } else {
+                    LOGW ("unknow cmd: %d\n", cmd);
+                }
+            }
+
+            socket_transaction_end();
+        } else if (client_info.type == REMOTEINPUT_ACT_CLIENT) {
+            socket_transaction_start();
+            while (m_recv_trans.get_command(cmd)) {
+                LOGD ("PanelAgent::cmd = %d\n", cmd);
+                if (cmd == ISM_TRANS_CMD_SEND_REMOTE_INPUT_MESSAGE) {
+                    char*   buf = NULL;
+                    size_t  len;
+                    bool ret = false;
+
+                    if (m_recv_trans.get_data(&buf, len)) {
+                        ret = m_info_manager->remoteinput_send_input_message(client_id, buf, len);
+                    } else {
+                        LOGW ("wrong format of transaction\n");
+                    }
+
+                    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);
+
+                    if (NULL != buf)
+                        delete[] buf;
                 } else {
                     LOGW ("unknow cmd: %d\n", cmd);
                 }
@@ -3343,7 +3444,7 @@ private:
         uint32 key;
         String type = scim_socket_accept_connection(key,
                       String("Panel"),
-                      String("FrontEnd,FrontEnd_Active,Helper,Helper_Active,IMControl_Active,IMControl_Passive,SocketConfig"),
+                      String("FrontEnd,FrontEnd_Active,Helper,Helper_Active,IMControl_Active,IMControl_Passive,RemoteInput_Active,RemoteInput_Passive,SocketConfig"),
                       client,
                       m_socket_timeout);
 
@@ -3354,7 +3455,9 @@ private:
                                ((type == "Helper") ? HELPER_CLIENT :
                                ((type == "Helper_Active") ? HELPER_ACT_CLIENT :
                                ((type == "IMControl_Active") ? IMCONTROL_ACT_CLIENT :
-                               ((type == "IMControl_Passive") ? IMCONTROL_CLIENT : CONFIG_CLIENT))))));
+                               ((type == "IMControl_Passive") ? IMCONTROL_CLIENT :
+                               ((type == "RemoteInput_Active") ? REMOTEINPUT_ACT_CLIENT :
+                               ((type == "RemoteInput_Passive") ? REMOTEINPUT_CLIENT : CONFIG_CLIENT))))))));
             lock();
             m_info_manager->add_client(client.get_id(), key, _type);
             unlock();
index d576f8b..4c7307a 100644 (file)
@@ -134,6 +134,11 @@ void isf_wsc_context_focus_out (WSCContextISF *wsc_ctx);
 void isf_wsc_context_preedit_string_get (WSCContextISF *wsc_ctx, char** str, int *cursor_pos);
 void isf_wsc_context_autocapital_type_set (WSCContextISF* wsc_ctx, Ecore_IMF_Autocapital_Type autocapital_type);
 void isf_wsc_context_bidi_direction_set (WSCContextISF* wsc_ctx, Ecore_IMF_BiDi_Direction direction);
+void isf_wsc_context_send_default_text (WSCContextISF* wsc_ctx, const char *text, int cursor);
+void isf_wsc_context_send_entry_metadata (WSCContextISF* wsc_ctx, Ecore_IMF_Input_Hints hint,
+                                          Ecore_IMF_Input_Panel_Layout layout, int variation,
+                                          Ecore_IMF_Autocapital_Type type);
+
 #if !(ENABLE_GRAB_KEYBOARD)
 void isf_wsc_context_filter_key_event (WSCContextISF* wsc_ctx,
                                        uint32_t serial,
index 960c664..9e3115b 100644 (file)
@@ -77,11 +77,13 @@ struct _WSCContextISFImpl {
     WSCContextISF           *parent;
     Ecore_Wl_Window         *client_window;
     Ecore_IMF_Input_Mode     input_mode;
+    WideString               surrounding_text;
     WideString               preedit_string;
     AttributeList            preedit_attrlist;
     Ecore_IMF_Autocapital_Type autocapital_type;
     Ecore_IMF_Input_Hints    input_hint;
     Ecore_IMF_BiDi_Direction bidi_direction;
+    Ecore_IMF_Input_Panel_Layout panel_layout;
     void                    *imdata;
     int                      imdata_size;
     int                      preedit_caret;
@@ -89,6 +91,7 @@ struct _WSCContextISFImpl {
     int                      cursor_y;
     int                      cursor_top_y;
     int                      cursor_pos;
+    int                      variation;
     bool                     use_preedit;
     bool                     is_on;
     bool                     preedit_started;
@@ -106,6 +109,7 @@ struct _WSCContextISFImpl {
                            autocapital_type(ECORE_IMF_AUTOCAPITAL_TYPE_SENTENCE),
                            input_hint(ECORE_IMF_INPUT_HINT_NONE),
                            bidi_direction(ECORE_IMF_BIDI_DIRECTION_NEUTRAL),
+                           panel_layout(ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL),
                            imdata(NULL),
                            imdata_size(0),
                            preedit_caret(0),
@@ -113,6 +117,7 @@ struct _WSCContextISFImpl {
                            cursor_y(0),
                            cursor_top_y(0),
                            cursor_pos(-1),
+                           variation(0),
                            use_preedit(true),
                            is_on(true),
                            preedit_started(false),
@@ -296,6 +301,9 @@ _wsc_im_ctx_content_type(void *data, struct wl_input_method_context *im_ctx, uin
     isf_wsc_context_input_panel_language_set (wsc_ctx, wsc_context_input_panel_language_get(wsc_ctx));
 
     caps_mode_check (wsc_ctx, EINA_TRUE, EINA_TRUE);
+
+    isf_wsc_context_send_entry_metadata (wsc_ctx, wsc_context_input_hint_get (wsc_ctx), wsc_context_input_panel_layout_get (wsc_ctx),
+        wsc_context_input_panel_layout_variation_get (wsc_ctx), wsc_context_autocapital_type_get(wsc_ctx));
 }
 
 static void
@@ -903,6 +911,7 @@ delete_ic_impl (WSCContextISFImpl *impl)
             rec->imdata_size = 0;
             rec->parent = 0;
             rec->client_window = 0;
+            rec->surrounding_text = WideString ();
             rec->preedit_string = WideString ();
             rec->preedit_attrlist.clear ();
 
@@ -1262,7 +1271,7 @@ insert_text (const char *text, uint32_t offset, const char *insert)
 {
     uint32_t tlen = strlen (text), ilen = strlen (insert);
     char *new_text = (char*)malloc (tlen + ilen + 1);
-    if (tlen < offset)
+    if ((unsigned int) tlen < offset)
         offset = tlen;
     memcpy (new_text, text, offset);
     memcpy (new_text + offset, insert, ilen);
@@ -1480,6 +1489,7 @@ isf_wsc_context_focus_in (WSCContextISF *wsc_ctx)
         _focused_ic = context_scim;
 
         context_scim->impl->is_on = _config->read (String (SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), context_scim->impl->is_on);
+        context_scim->impl->surrounding_text.clear ();
         context_scim->impl->preedit_string.clear ();
         context_scim->impl->preedit_attrlist.clear ();
         context_scim->impl->preedit_caret = 0;
@@ -1512,6 +1522,8 @@ isf_wsc_context_focus_in (WSCContextISF *wsc_ctx)
 
         g_info_manager->get_active_helper_option (WAYLAND_MODULE_CLIENT_ID, _active_helper_option);
 
+        g_info_manager->remoteinput_callback_focus_in ();
+
         /* At the moment we received focus_in, our surrounding text has not been updated yet -
         which means it will always turn Shift key on, resulting the whole keyboard blinking.
         This is only a temporary solution - the caps_mode_check() needs be executed on
@@ -1554,6 +1566,8 @@ isf_wsc_context_focus_out (WSCContextISF *wsc_ctx)
         g_info_manager->focus_out (WAYLAND_MODULE_CLIENT_ID, context_scim->id);
 
         _focused_ic = 0;
+
+        g_info_manager->remoteinput_callback_focus_out ();
     }
     _x_key_event_is_valid = false;
 }
@@ -1627,6 +1641,52 @@ isf_wsc_context_bidi_direction_set (WSCContextISF* wsc_ctx, Ecore_IMF_BiDi_Direc
     }
 }
 
+void
+isf_wsc_context_send_default_text (WSCContextISF* wsc_ctx, const char *text, int cursor)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    WSCContextISF *context_scim = wsc_ctx;
+
+    if (!context_scim || !context_scim->impl)
+        return;
+
+    char *conv_text = strdup (utf8_wcstombs (context_scim->impl->surrounding_text).c_str ());
+    if (!conv_text)
+        return;
+
+    if (strcmp (conv_text, text) != 0 || context_scim->impl->cursor_pos != cursor) {
+        context_scim->impl->surrounding_text = utf8_mbstowcs (String (text));
+        context_scim->impl->cursor_pos = cursor;
+
+        String _text(text);
+        g_info_manager->remoteinput_callback_default_text (_text, context_scim->impl->cursor_pos);
+    }
+    free (conv_text);
+}
+
+void
+isf_wsc_context_send_entry_metadata (WSCContextISF* wsc_ctx, Ecore_IMF_Input_Hints hint,
+                                     Ecore_IMF_Input_Panel_Layout layout, int variation,
+                                     Ecore_IMF_Autocapital_Type type)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    WSCContextISF *context_scim = wsc_ctx;
+
+    if (context_scim && context_scim->impl &&
+        (context_scim->impl->input_hint != hint || context_scim->impl->panel_layout != layout ||
+            context_scim->impl->variation != variation || context_scim->impl->autocapital_type != type)) {
+        context_scim->impl->input_hint = hint;
+        context_scim->impl->panel_layout = layout;
+        context_scim->impl->variation = variation;
+        context_scim->impl->autocapital_type = type;
+
+        g_info_manager->remoteinput_callback_entry_metadata (context_scim->impl->input_hint, context_scim->impl->panel_layout,
+            context_scim->impl->variation, context_scim->impl->autocapital_type);
+    }
+}
+
 #ifdef _TV
 static
 bool is_number_key(const char *str)
@@ -2283,6 +2343,9 @@ panel_req_show_help (WSCContextISF *ic)
 
         g_info_manager->socket_show_help (help);
     }
+
+    g_info_manager->remoteinput_callback_focus_out ();
+    LOGD("Remote control button click");
 }
 #endif
 
@@ -2847,6 +2910,8 @@ public:
         if (len == 0) {
             LOGD ("update");
             g_info_manager->socket_update_surrounding_text (wsc_ctx->surrounding_text ? wsc_ctx->surrounding_text : "", wsc_ctx->surrounding_cursor);
+            isf_wsc_context_send_default_text (wsc_ctx, wsc_ctx->surrounding_text ? wsc_ctx->surrounding_text : "", wsc_ctx->surrounding_cursor);
+
         } else if (len < 0) {
             LOGW ("failed");
         } else {
index 95d9146..db4cc32 100644 (file)
@@ -97,7 +97,9 @@ libsciminclude_HEADERS        = scim.h \
                          isf_info_manager.h \
                          isf_panel_agent_base.h \
                          isf_panel_agent_module.h \
-                         isf_message_queue.h
+                         isf_message_queue.h \
+                         isf_remote_control.h \
+                         isf_remote_client.h
 
 noinst_LTLIBRARIES     = libltdlc.la libprivilege_checker.la libisf_pkg.la
 
@@ -157,9 +159,13 @@ libscim@SCIM_EPOCH@_la_SOURCES = \
                          isf_panel_agent_manager.cpp \
                          isf_info_manager.cpp \
                          isf_panel_agent_base.cpp \
-                         isf_panel_agent_module.cpp
+                         isf_panel_agent_module.cpp \
+                         isf_remote_control.cpp \
+                         isf_remote_client.cpp
 
 libscim@SCIM_EPOCH@_la_CXXFLAGS = @EVAS_CFLAGS@ \
+                         @ECORE_CFLAGS@ \
+                         @ECORE_IMF_CFLAGS@ \
                          @DLOG_CFLAGS@ \
                          @DB_UTIL_CFLAGS@ \
                          @TZPLATFORM_CONFIG_CFLAGS@ \
@@ -172,6 +178,7 @@ libscim@SCIM_EPOCH@_la_LDFLAGS  = -version-info $(SCIM_CURRENT):$(SCIM_REVISION)
                          @LIBTOOL_EXPORT_OPTIONS@ \
                          @LIBICONV@ \
                          @LTLIBINTL@ \
+                         @ECORE_LIBS@ \
                          @DLOG_LIBS@ \
                          @DB_UTIL_LIBS@ \
                          @TZPLATFORM_CONFIG_LIBS@ \
index 4760c22..5f3bb33 100644 (file)
@@ -88,26 +88,6 @@ EXAPI int isf_control_get_active_ise (char **uuid)
     return strUuid.length ();
 }
 
-EXAPI int isf_control_enable_remote_input (void)
-{
-    IMControlClient imcontrol_client;
-    imcontrol_client.open_connection ();
-    imcontrol_client.prepare ();
-    imcontrol_client.enable_remote_input ();
-    imcontrol_client.close_connection ();
-    return 0;
-}
-
-EXAPI int isf_control_disable_remote_input (void)
-{
-    IMControlClient imcontrol_client;
-    imcontrol_client.open_connection ();
-    imcontrol_client.prepare ();
-    imcontrol_client.disable_remote_input ();
-    imcontrol_client.close_connection ();
-    return 0;
-}
-
 EXAPI int isf_control_get_ise_list (char ***uuid_list)
 {
     if (uuid_list == NULL)
index 8bef778..6f26b7b 100644 (file)
@@ -82,20 +82,6 @@ EXAPI int isf_control_set_active_ise_by_uuid (const char *uuid);
 EXAPI int isf_control_get_active_ise (char **uuid);
 
 /**
- * @brief Enable remote input.
- *
- * @return 0 if successfully, otherwise return -1;
- */
-EXAPI int isf_control_enable_remote_input (void);
-
-/**
- * @brief Disable remote input.
- *
- * @return 0 if successfully, otherwise return -1;
- */
-EXAPI int isf_control_disable_remote_input (void);
-
-/**
  * @brief Get the list of all ISEs' UUID.
  *
  * @param uuid_list The list is used to store all ISEs' UUID.
index 49f3efb..1b0827d 100644 (file)
@@ -283,38 +283,6 @@ public:
         return true;
     }
 
-    void enable_remote_input (void) {
-        int cmd;
-
-        m_trans.put_command (ISM_TRANS_CMD_ENABLE_REMOTE_INPUT);
-        m_trans.write_to_socket (m_socket_imclient2panel);
-        if (!m_trans.read_from_socket (m_socket_imclient2panel, m_socket_timeout))
-            std::cerr << __func__ << " read_from_socket() may be timeout \n";
-
-        if (m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY &&
-                m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) {
-            ;
-        } else {
-            std::cerr << __func__ << " get_command() is failed!!!\n";
-        }
-    }
-
-    void disable_remote_input (void) {
-        int cmd;
-
-        m_trans.put_command (ISM_TRANS_CMD_DISABLE_REMOTE_INPUT);
-        m_trans.write_to_socket (m_socket_imclient2panel);
-        if (!m_trans.read_from_socket (m_socket_imclient2panel, m_socket_timeout))
-            std::cerr << __func__ << " read_from_socket() may be timeout \n";
-
-        if (m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY &&
-                m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) {
-            ;
-        } else {
-            std::cerr << __func__ << " get_command() is failed!!!\n";
-        }
-    }
-
     bool get_ise_list (int* count, char*** iselist) {
         int cmd;
         uint32 count_temp = 0;
@@ -668,16 +636,6 @@ bool IMControlClient::set_initial_ise_by_uuid (const char* uuid)
     return m_impl->set_initial_ise_by_uuid (uuid);
 }
 
-void IMControlClient::enable_remote_input (void)
-{
-    m_impl->enable_remote_input ();
-}
-
-void IMControlClient::disable_remote_input (void)
-{
-    m_impl->disable_remote_input ();
-}
-
 bool IMControlClient::get_active_ise (String &uuid)
 {
     return m_impl->get_active_ise (uuid);
index 632f4f4..4b68c77 100644 (file)
@@ -257,6 +257,11 @@ class InfoManager::InfoManagerImpl
     bool                                m_is_imengine_aux;
     bool                                m_is_imengine_candidate;
 
+    int                                 m_current_send_remoteinput_id;
+    int                                 m_current_recv_remoteinput_id;
+    IntIntRepository                    m_send_remoteinput_map;
+    IntIntRepository                    m_recv_remoteinput_map;
+
     int                                 m_last_socket_client;
     uint32                              m_last_client_context;
     String                              m_last_context_uuid;
@@ -371,8 +376,8 @@ class InfoManager::InfoManagerImpl
 
     InfoManagerSignalIntRect             m_signal_get_recent_ise_geometry;
 
-    InfoManagerSignalVoid                m_signal_enable_remote_input;
-    InfoManagerSignalVoid                m_signal_disable_remote_input;
+    InfoManagerSignalStringBool          m_signal_remoteinput_send_input_message;
+    InfoManagerSignalIntString           m_signal_remoteinput_send_surrounding_text;
 
     InfoManagerSignalIntString2          m_signal_check_privilege_by_sockfd;
 
@@ -390,11 +395,14 @@ public:
           m_active_client_id (-1),
           m_should_shared_ise (false),
           m_ise_exiting (false), m_is_imengine_aux (false), m_is_imengine_candidate (false),
+          m_current_send_remoteinput_id (0), m_current_recv_remoteinput_id (0),
           m_last_socket_client (-1), m_last_client_context (0),
           m_ise_context_buffer (NULL), m_ise_context_length (0) {
         m_current_ise_name = String (_ ("English Keyboard"));
         m_imcontrol_repository.clear ();
         m_imcontrol_map.clear ();
+        m_send_remoteinput_map.clear ();
+        m_recv_remoteinput_map.clear ();
         m_panel_client_map.clear ();
     }
 
@@ -1259,16 +1267,23 @@ public:
         m_signal_show_panel ();
     }
 
-    void enable_remote_input (int client_id)
-    {
-        SCIM_DEBUG_MAIN(4) << "PanelAgent::enable_remote_input ()\n";
-        m_signal_enable_remote_input ();
+    //ISM_TRANS_CMD_SEND_REMOTE_INPUT_MESSAGE
+    bool send_remote_input_message (int client_id, char* buf, size_t len) {
+        SCIM_DEBUG_MAIN(4) << "InfoManager::send_remote_input_message ()\n";
+
+        if(buf == NULL) {
+            return false;
+        }
+
+        String msg (buf);
+        m_signal_remoteinput_send_input_message (msg, 1);
+        return true;
     }
 
-    void disable_remote_input (int client_id)
-    {
-        SCIM_DEBUG_MAIN(4) << "PanelAgent::disable_remote_input ()\n";
-        m_signal_disable_remote_input ();
+    void send_remote_surrounding_text (const char* text, uint32 cursor) {
+        SCIM_DEBUG_MAIN(4) << "InfoManager::send_remote_surrounding_text ()\n";
+
+        m_signal_remoteinput_send_surrounding_text (cursor, text);
     }
 
     //ISM_TRANS_CMD_HIDE_ISF_CONTROL
@@ -1923,7 +1938,7 @@ public:
         return m_signal_check_privilege_by_sockfd (client_id, privilege);
     }
 
-    bool update_preedit_string (const WideString &str, const AttributeList &attrs)
+    bool remoteinput_update_preedit_string (WideString str, AttributeList &attrs, uint32 caret)
     {
         SCIM_DEBUG_MAIN(1) << "PanelAgent::update_preedit_string ()\n";
         int    client = -1;
@@ -1933,7 +1948,7 @@ public:
 
         get_focused_context (client, context);
         if (client >= 0) {
-            m_panel_agent_manager.update_preedit_string (client, context, str, attrs);
+            m_panel_agent_manager.update_preedit_string (client, context, str, attrs, caret);
         }
 
         unlock ();
@@ -1941,7 +1956,7 @@ public:
         return client >= 0;
     }
 
-    bool commit_string (const WideString &str)
+    bool remoteinput_commit_string (const WideString &str)
     {
         SCIM_DEBUG_MAIN(1) << "PanelAgent::commit_string ()\n";
         int    client = -1;
@@ -1959,7 +1974,7 @@ public:
         return client >= 0;
     }
 
-    bool send_key_event (const KeyEvent &key)
+    bool remoteinput_send_key_event (const KeyEvent &key)
     {
         SCIM_DEBUG_MAIN(1) << "PanelAgent::send_key_event ()\n";
         int    client = -1;
@@ -1973,7 +1988,7 @@ public:
         return client >= 0;
     }
 
-    bool forward_key_event (const KeyEvent &key)
+    bool remoteinput_forward_key_event (const KeyEvent &key)
     {
         SCIM_DEBUG_MAIN(1) << "PanelAgent::forward_key_event ()\n";
         int    client = -1;
@@ -2293,14 +2308,14 @@ public:
         return m_signal_check_privilege_by_sockfd.connect (slot);
     }
 
-    Connection signal_connect_enable_remote_input        (InfoManagerSlotVoid*                slot)
+    Connection signal_connect_remoteinput_send_input_message   (InfoManagerSlotStringBool*                slot)
     {
-        return m_signal_enable_remote_input.connect (slot);
+        return m_signal_remoteinput_send_input_message.connect (slot);
     }
 
-    Connection signal_connect_disable_remote_input        (InfoManagerSlotVoid*                slot)
+    Connection signal_connect_remoteinput_send_surrounding_text (InfoManagerSlotIntString*                slot)
     {
-        return m_signal_disable_remote_input.connect (slot);
+        return m_signal_remoteinput_send_surrounding_text.connect (slot);
     }
 
     //ISM_TRANS_CMD_REGISTER_PANEL_CLIENT
@@ -2452,6 +2467,12 @@ public:
         } else if (info.type == IMCONTROL_CLIENT) {
             m_imcontrol_map [m_pending_active_imcontrol_id] = client_id;
             m_pending_active_imcontrol_id = -1;
+        } else if (info.type == REMOTEINPUT_ACT_CLIENT) {
+            m_current_send_remoteinput_id = client_id;
+            m_send_remoteinput_map [m_current_send_remoteinput_id] = 1;
+        } else if (info.type == REMOTEINPUT_CLIENT) {
+            m_current_recv_remoteinput_id = client_id;
+            m_recv_remoteinput_map [m_current_recv_remoteinput_id] = 1;
         }
 
         LOGD ("%d clients connecting", m_client_repository.size());
@@ -2638,6 +2659,24 @@ public:
 
             if (iter2 != m_imcontrol_map.end ())
                 m_imcontrol_map.erase (iter2);
+        } else if (client_info.type == REMOTEINPUT_ACT_CLIENT) {
+            SCIM_DEBUG_MAIN (4) << "It's a REMOTEINPUT_ACT_CLIENT client.\n";
+
+            IntIntRepository::iterator iter = m_send_remoteinput_map.find (client_id);
+
+            if (iter != m_send_remoteinput_map.end())
+                m_send_remoteinput_map.erase (iter);
+
+            m_current_send_remoteinput_id = -1;
+        } else if (client_info.type == REMOTEINPUT_CLIENT) {
+            SCIM_DEBUG_MAIN (4) << "It's a REMOTEINPUT_CLIENT client.\n";
+
+            IntIntRepository::iterator iter = m_recv_remoteinput_map.find (client_id);
+
+            if (iter != m_recv_remoteinput_map.end())
+                m_recv_remoteinput_map.erase (iter);
+
+            m_current_recv_remoteinput_id = -1;
         } else if (client_info.type == CONFIG_CLIENT) {
             SCIM_DEBUG_MAIN(4) << "It's a CONFIG_CLIENT client.\n";
         }
@@ -2725,6 +2764,43 @@ client context helpers: %d, helpers uuid count: %d",
             unlock ();
         }
     }
+
+    void remoteinput_callback_focus_in () {
+        SCIM_DEBUG_MAIN (4) << __FUNCTION__ << "...\n";
+        LOGD ("");
+
+        lock();
+        m_panel_agent_manager.socket_remoteinput_focus_in (m_current_recv_remoteinput_id);
+        unlock ();
+    }
+
+    void remoteinput_callback_focus_out () {
+        SCIM_DEBUG_MAIN (4) << __FUNCTION__ << "...\n";
+        LOGD ("");
+
+        lock();
+        m_panel_agent_manager.socket_remoteinput_focus_out (m_current_recv_remoteinput_id);
+        unlock ();
+    }
+
+    void remoteinput_callback_entry_metadata (uint32 hint, uint32 layout, int variation, uint32 autocapital_type) {
+        SCIM_DEBUG_MAIN (4) << __FUNCTION__ << "...\n";
+        LOGD ("");
+
+        lock();
+        m_panel_agent_manager.socket_remoteinput_entry_metadata (m_current_recv_remoteinput_id, hint, layout, variation, autocapital_type);
+        unlock ();
+    }
+
+    void remoteinput_callback_default_text (String text, uint32 cursor) {
+        SCIM_DEBUG_MAIN (4) << __FUNCTION__ << "...\n";
+        LOGD ("");
+
+        lock();
+        m_panel_agent_manager.socket_remoteinput_default_text (m_current_recv_remoteinput_id, text, cursor);
+        unlock ();
+    }
+
     //ISM_TRANS_CMD_UPDATE_SELECTION
     void socket_update_selection (String text) {
         SCIM_DEBUG_MAIN (4) << __FUNCTION__ << "...\n";
@@ -4123,24 +4199,24 @@ InfoManager::update_ise_list (std::vector<String>& strList)
 }
 
 bool
-InfoManager::update_preedit_string (const WideString &str, const AttributeList &attrs)
+InfoManager::remoteinput_update_preedit_string (WideString str, AttributeList &attrs, uint32 caret)
 {
-    return m_impl->update_preedit_string (str, attrs);
+    return m_impl->remoteinput_update_preedit_string (str, attrs, caret);
 }
 bool
-InfoManager::commit_string (const WideString &str)
+InfoManager::remoteinput_commit_string (const WideString &str)
 {
-    return m_impl->commit_string (str);
+    return m_impl->remoteinput_commit_string (str);
 }
 bool
-InfoManager::send_key_event (const KeyEvent &key)
+InfoManager::remoteinput_send_key_event (const KeyEvent &key)
 {
-    return m_impl->send_key_event (key);
+    return m_impl->remoteinput_send_key_event (key);
 }
 bool
-InfoManager::forward_key_event (const KeyEvent &key)
+InfoManager::remoteinput_forward_key_event (const KeyEvent &key)
 {
-    return m_impl->forward_key_event (key);
+    return m_impl->remoteinput_forward_key_event (key);
 }
 
 /////////////////////////////////Message function begin/////////////////////////////////////////
@@ -4435,16 +4511,15 @@ void InfoManager::get_recent_ise_geometry (int client_id, uint32 angle, _OUT_ st
     m_impl->get_recent_ise_geometry (client_id, angle, info);
 }
 
-//ISM_TRANS_CMD_ENABLE_REMOTE_INPUT
-void InfoManager::enable_remote_input (int client_id)
+//ISM_TRANS_CMD_SEND_REMOTE_INPUT_MESSAGE
+bool InfoManager::remoteinput_send_input_message (int client_id, char* buf, size_t len)
 {
-    m_impl->enable_remote_input (client_id);
+    return m_impl->send_remote_input_message (client_id, buf, len);
 }
 
-//ISM_TRANS_CMD_DISABLE_REMOTE_INPUT
-void InfoManager::disable_remote_input (int client_id)
+void InfoManager::remoteinput_send_surrounding_text (const char* text, uint32 cursor)
 {
-    m_impl->disable_remote_input (client_id);
+    return m_impl->send_remote_surrounding_text (text, cursor);
 }
 
 //ISM_TRANS_CMD_REGISTER_PANEL_CLIENT
@@ -4531,6 +4606,26 @@ void InfoManager::socket_update_surrounding_text (String text, uint32 cursor)
     m_impl->socket_update_surrounding_text (text, cursor);
 }
 
+void InfoManager::remoteinput_callback_focus_in (void)
+{
+    m_impl->remoteinput_callback_focus_in ();
+}
+
+void InfoManager::remoteinput_callback_focus_out (void)
+{
+    m_impl->remoteinput_callback_focus_out ();
+}
+
+void InfoManager::remoteinput_callback_entry_metadata (uint32 hint, uint32 layout, int variation, uint32 autocapital_type)
+{
+    m_impl->remoteinput_callback_entry_metadata (hint, layout, variation, autocapital_type);
+}
+
+void InfoManager::remoteinput_callback_default_text (String text, uint32 cursor)
+{
+    m_impl->remoteinput_callback_default_text (text, cursor);
+}
+
 //ISM_TRANS_CMD_UPDATE_SELECTION
 void InfoManager::socket_update_selection (String text)
 {
@@ -5326,15 +5421,15 @@ InfoManager::signal_connect_check_privilege_by_sockfd  (InfoManagerSlotIntString
 }
 
 Connection
-InfoManager::signal_connect_enable_remote_input         (InfoManagerSlotVoid*                slot)
+InfoManager::signal_connect_remoteinput_send_input_message  (InfoManagerSlotStringBool*          slot)
 {
-    return m_impl->signal_connect_enable_remote_input (slot);
+    return m_impl->signal_connect_remoteinput_send_input_message (slot);
 }
 
 Connection
-InfoManager::signal_connect_disable_remote_input         (InfoManagerSlotVoid*                slot)
+InfoManager::signal_connect_remoteinput_send_surrounding_text  (InfoManagerSlotIntString*                slot)
 {
-    return m_impl->signal_connect_disable_remote_input (slot);
+    return m_impl->signal_connect_remoteinput_send_surrounding_text (slot);
 }
 
 } /* namespace scim */
index d93d633..5fee7d3 100644 (file)
@@ -70,6 +70,8 @@ enum ClientType {
     HELPER_ACT_CLIENT,
     IMCONTROL_ACT_CLIENT,
     IMCONTROL_CLIENT,
+    REMOTEINPUT_ACT_CLIENT,
+    REMOTEINPUT_CLIENT,
     CONFIG_CLIENT
 };
 
@@ -558,28 +560,25 @@ public:
     void update_ise_list (std::vector<String>& strList);
 
 
-    bool update_preedit_string (const WideString &str, const AttributeList &attrs) ;
+    bool remoteinput_update_preedit_string (WideString str, AttributeList &attrs, uint32 caret);
 
-    bool commit_string (const WideString &str) ;
+    bool remoteinput_commit_string (const WideString &str);
 
-    bool send_key_event (const KeyEvent &key) ;
+    bool remoteinput_send_key_event (const KeyEvent &key);
 
-    bool forward_key_event (const KeyEvent &key) ;
+    bool remoteinput_forward_key_event (const KeyEvent &key);
 
+    bool remoteinput_send_input_message (int client_id, char*  buf, size_t  len);
 
-    /**
-     * @brief Enable remote input.
-     *
-     * @return none.
-     */
-    void enable_remote_input (int client_id);
+    void remoteinput_send_surrounding_text (const char* text, uint32 cursor);
 
-    /**
-     * @brief Disable remote input.
-     *
-     * @return none.
-     */
-    void disable_remote_input (int client_id);
+    void remoteinput_callback_focus_in (void);
+
+    void remoteinput_callback_focus_out (void);
+
+    void remoteinput_callback_entry_metadata (uint32 hint, uint32 layout, int variation, uint32 autocapital_type);
+
+    void remoteinput_callback_default_text (String text, uint32 cursor);
 
 /////////////////////////////////Message function begin/////////////////////////////////////////
 
@@ -1525,21 +1524,11 @@ public:
      */
     Connection signal_connect_get_recent_ise_geometry (InfoManagerSlotIntRect*             slot);
 
-    /**
-     * @brief Signal: Enable remote input.
-     *
-     * slot prototype: void enabl_remote_input (void);
-     */
-    Connection signal_connect_enable_remote_input (InfoManagerSlotVoid*                slot);
+    Connection signal_connect_check_privilege_by_sockfd  (InfoManagerSlotIntString2* slot);
 
-    /**
-     * @brief Signal: Disable remote input.
-     *
-     * slot prototype: void disable_remote_input (void);
-     */
-    Connection signal_connect_disable_remote_input (InfoManagerSlotVoid*                slot);
+    Connection signal_connect_remoteinput_send_input_message (InfoManagerSlotStringBool*          slot);
 
-    Connection signal_connect_check_privilege_by_sockfd  (InfoManagerSlotIntString2* slot);
+    Connection signal_connect_remoteinput_send_surrounding_text (InfoManagerSlotIntString*          slot);
 };
 
 /**  @} */
index 81fbeb2..5c303bc 100644 (file)
@@ -353,6 +353,26 @@ void PanelAgentBase::socket_update_surrounding_text (int client, uint32 context,
     LOGW ("not implemented for %s", m_name.c_str ());
 }
 
+void PanelAgentBase::socket_remoteinput_focus_in (int client)
+{
+    LOGW ("not implemented for %s", m_name.c_str ());
+}
+
+void PanelAgentBase::socket_remoteinput_focus_out (int client)
+{
+    LOGW ("not implemented for %s", m_name.c_str ());
+}
+
+void PanelAgentBase::socket_remoteinput_entry_metadata (int client, uint32 hint, uint32 layout, int variation, uint32 autocapital_type)
+{
+    LOGW ("not implemented for %s", m_name.c_str ());
+}
+
+void PanelAgentBase::socket_remoteinput_default_text (int client, String& text, uint32 cursor)
+{
+    LOGW ("not implemented for %s", m_name.c_str ());
+}
+
 void PanelAgentBase::socket_update_selection (int client, uint32 context, String& uuid, String text)
 {
     LOGW ("not implemented for %s", m_name.c_str ());
index debaaa7..27a0607 100644 (file)
@@ -548,6 +548,42 @@ public:
     virtual void socket_update_surrounding_text (int client, uint32 context,const String& uuid, String& text, uint32 cursor);
 
     /**
+     * @brief socket_remoteinput_focus_in.
+     *
+     * @param
+     *
+     * @return none.
+     */
+    virtual void socket_remoteinput_focus_in (int client);
+
+    /**
+     * @brief socket_remoteinput_focus_out.
+     *
+     * @param
+     *
+     * @return none.
+     */
+    virtual void socket_remoteinput_focus_out (int client);
+
+    /**
+     * @brief socket_remoteinput_entry_metadata.
+     *
+     * @param
+     *
+     * @return none.
+     */
+    virtual void socket_remoteinput_entry_metadata (int client, uint32 hint, uint32 layout, int variation, uint32 autocapital_type);
+
+    /**
+     * @brief socket_remoteinput_default_text.
+     *
+     * @param
+     *
+     * @return none.
+     */
+    virtual void socket_remoteinput_default_text (int client, String& text, uint32 cursor);
+
+    /**
      * @brief socket_update_selection.
      *
      * @param
index dc152ac..48c77f8 100644 (file)
@@ -572,6 +572,38 @@ void PanelAgentManager::socket_update_surrounding_text (int id, uint32 context_i
         _p->socket_update_surrounding_text (id, context_id, uuid, text, cursor);
 }
 
+void PanelAgentManager::socket_remoteinput_focus_in (int id)
+{
+    PanelAgentPointer _p = m_impl->get_panel_agent_by_id (id);
+
+    if (!_p.null ())
+        _p->socket_remoteinput_focus_in (id);
+}
+
+void PanelAgentManager::socket_remoteinput_focus_out (int id)
+{
+    PanelAgentPointer _p = m_impl->get_panel_agent_by_id (id);
+
+    if (!_p.null ())
+        _p->socket_remoteinput_focus_out (id);
+}
+
+void PanelAgentManager::socket_remoteinput_entry_metadata (int id, uint32 hint, uint32 layout, int variation, uint32 autocapital_type)
+{
+    PanelAgentPointer _p = m_impl->get_panel_agent_by_id (id);
+
+    if (!_p.null ())
+        _p->socket_remoteinput_entry_metadata (id, hint, layout, variation, autocapital_type);
+}
+
+void PanelAgentManager::socket_remoteinput_default_text (int id, String& text, uint32 cursor)
+{
+    PanelAgentPointer _p = m_impl->get_panel_agent_by_id (id);
+
+    if (!_p.null ())
+        _p->socket_remoteinput_default_text (id, text, 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 6bb4431..5164a10 100644 (file)
@@ -315,6 +315,10 @@ public:
     void reset_ise_option (int client_id, uint32 context);
     void reset_helper_context (int client_id, uint32 context, const String& uuid);
     void socket_update_surrounding_text (int client, uint32 context, const String& uuid, String& text, uint32 cursor);
+    void socket_remoteinput_focus_in (int client);
+    void socket_remoteinput_focus_out (int client);
+    void socket_remoteinput_entry_metadata (int client, uint32 hint, uint32 layout, int variation, uint32 autocapital_type);
+    void socket_remoteinput_default_text (int client, String& text, 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);
diff --git a/ism/src/isf_remote_client.cpp b/ism/src/isf_remote_client.cpp
new file mode 100644 (file)
index 0000000..28edbef
--- /dev/null
@@ -0,0 +1,393 @@
+/*
+ * ISF(Input Service Framework)
+ *
+ * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable.
+ * Copyright (c) 2012-2015 Samsung Electronics Co., Ltd.
+ *
+ * Contact: Inhong Han <inhong1.han@samsung.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#define Uses_SCIM_TRANSACTION
+#define Uses_ISF_REMOTE_CLIENT
+#define Uses_SCIM_PANEL_AGENT
+#define Uses_SCIM_IMENGINE_MODULE
+#define Uses_SCIM_HELPER_MODULE
+
+#include <string.h>
+#include <dlog.h>
+#include "scim.h"
+
+#ifdef LOG_TAG
+# undef LOG_TAG
+#endif
+#define LOG_TAG             "ISF_REMOTE_CLIENT"
+
+namespace scim
+{
+
+typedef Signal1<void, int> RemoteInputClientSignalVoid;
+
+#if ENABLE_LAZY_LAUNCH
+static bool check_panel (const String &display)
+{
+    SocketAddress address;
+    SocketClient client;
+
+    uint32 magic;
+
+    address.set_address (scim_get_default_panel_socket_address (display));
+
+    if (!client.connect (address))
+        return false;
+
+    if (!scim_socket_open_connection (magic,
+        String ("ConnectionTester"),
+        String ("Panel"),
+        client,
+        1000)) {
+        return false;
+    }
+
+    return true;
+}
+
+static bool
+check_socket_frontend (void)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    SocketAddress address;
+    SocketClient client;
+
+    uint32 magic;
+
+    address.set_address (scim_get_default_socket_frontend_address ());
+
+    if (!client.connect (address)) {
+        std::cerr << "check_socket_frontend's connect () failed.\n";
+        return false;
+    }
+
+    if (!scim_socket_open_connection (magic,
+                                      String ("ConnectionTester"),
+                                      String ("SocketFrontEnd"),
+                                      client,
+                                      500)) {
+        std::cerr << "check_socket_frontend's scim_socket_open_connection () failed.\n";
+        return false;
+    }
+
+    return true;
+}
+
+static int
+launch_socket_frontend ()
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    std::vector<String>     engine_list;
+    std::vector<String>     helper_list;
+    std::vector<String>     load_engine_list;
+
+    std::vector<String>::iterator it;
+
+    std::cerr << "Launching a ISF daemon with Socket FrontEnd...\n";
+    //get modules list
+    scim_get_imengine_module_list (engine_list);
+    scim_get_helper_module_list (helper_list);
+
+    for (it = engine_list.begin (); it != engine_list.end (); it++) {
+        if (*it != "socket")
+            load_engine_list.push_back (*it);
+    }
+    for (it = helper_list.begin (); it != helper_list.end (); it++)
+        load_engine_list.push_back (*it);
+
+    return scim_launch (true,
+        "simple",
+        (load_engine_list.size () > 0 ? scim_combine_string_list (load_engine_list, ',') : "none"),
+        "socket",
+        NULL);
+}
+#endif
+
+class RemoteInputClient::RemoteInputClientImpl
+{
+    SocketClient                                m_socket_remoteinput2panel;
+    SocketClient                                m_socket_panel2remoteinput;
+    int                                         m_socket_timeout;
+    uint32                                      m_socket_r2p_magic_key;
+    uint32                                      m_socket_p2r_magic_key;
+    Transaction                                 m_trans;
+    Transaction                                 m_trans_recv;
+    RemoteInputClientSignalVoid                 m_signal_show_ise;
+    RemoteInputClientSignalVoid                 m_signal_hide_ise;
+
+    String m_default_text;
+    uint32 m_hint, m_cursor, m_layout, m_variation, m_autocapital_type;
+
+public:
+    RemoteInputClientImpl ()
+          : m_socket_timeout (scim_get_default_socket_timeout ()),
+            m_socket_r2p_magic_key (0),
+            m_socket_p2r_magic_key (0),
+            m_default_text (""),
+            m_hint (0),
+            m_cursor (0),
+            m_layout (0),
+            m_variation (0),
+            m_autocapital_type (0) {
+    }
+
+    int open_connection (void) {
+        const char *p = getenv ("DISPLAY");
+        String display;
+        if (p) display = String (p);
+
+        SocketAddress addr (scim_get_default_panel_socket_address (display));
+
+        if (m_socket_remoteinput2panel.is_connected ()) close_connection ();
+
+        bool ret=false, ret2=false;
+        int count = 0;
+
+        /* Try three times. */
+        while (1) {
+            ret = m_socket_remoteinput2panel.connect (addr);
+            ret2 = m_socket_panel2remoteinput.connect (addr);
+            if (!ret) {
+                scim_usleep (100000);
+#if ENABLE_LAZY_LAUNCH
+                if (!check_socket_frontend ())
+                    launch_socket_frontend ();
+                if (!check_panel (display))
+                    scim_launch_panel (true, "socket", display, NULL);
+#endif
+                for (int i = 0; i < 200; ++i) {
+                    if (m_socket_remoteinput2panel.connect (addr)) {
+                        ret = true;
+                        break;
+                    }
+                    scim_usleep (100000);
+                }
+            }
+
+            if (ret && scim_socket_open_connection (m_socket_r2p_magic_key, String ("RemoteInput_Active"), String ("Panel"), m_socket_remoteinput2panel, m_socket_timeout)) {
+                if (ret2 && scim_socket_open_connection (m_socket_p2r_magic_key, String ("RemoteInput_Passive"), String ("Panel"), m_socket_panel2remoteinput, m_socket_timeout))
+                    break;
+            }
+            m_socket_remoteinput2panel.close ();
+            m_socket_panel2remoteinput.close ();
+
+            if (count++ >= 3) break;
+
+            scim_usleep (100000);
+        }
+
+        return m_socket_remoteinput2panel.get_id ();
+    }
+
+    void close_connection (void) {
+        m_socket_remoteinput2panel.close ();
+        m_socket_panel2remoteinput.close ();
+        m_socket_r2p_magic_key = 0;
+        m_socket_p2r_magic_key = 0;
+    }
+
+    bool is_connected (void) const {
+        return (m_socket_remoteinput2panel.is_connected () && m_socket_panel2remoteinput.is_connected ());
+    }
+
+    int  get_panel2remote_connection_number (void) const {
+        if (m_socket_panel2remoteinput.is_connected ())
+            return m_socket_panel2remoteinput.get_id ();
+        return -1;
+    }
+
+    bool prepare (void) {
+        if (!m_socket_remoteinput2panel.is_connected ()) return false;
+
+        m_trans.clear ();
+        m_trans.put_command (SCIM_TRANS_CMD_REQUEST);
+        m_trans.put_data (m_socket_r2p_magic_key);
+
+        return true;
+    }
+
+    bool has_pending_event (void) const {
+        if (m_socket_panel2remoteinput.is_connected () && m_socket_panel2remoteinput.wait_for_data (0) > 0)
+            return true;
+
+        return false;
+    }
+
+    bool send_remote_input_message (const char* str) {
+        int cmd;
+
+        m_trans.put_command (ISM_TRANS_CMD_SEND_REMOTE_INPUT_MESSAGE);
+        m_trans.put_data (str, strlen (str)+1);
+        m_trans.write_to_socket (m_socket_remoteinput2panel);
+        if (!m_trans.read_from_socket (m_socket_remoteinput2panel, m_socket_timeout)) {
+            std::cerr << __func__ << " read_from_socket() may be timeout \n";
+            return false;
+        }
+
+        if (m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY &&
+                m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) {
+        } else {
+            std::cerr << __func__ << " get_command() or get_data() may fail!!!\n";
+            return false;
+        }
+
+        return true;
+    }
+
+    remote_control_callback_type recv_callback_message(void) {
+        if (! m_socket_panel2remoteinput.is_connected () || ! m_trans_recv.read_from_socket(m_socket_panel2remoteinput, m_socket_timeout))
+            return REMOTE_CONTROL_CALLBACK_ERROR;
+
+        int cmd;
+
+        if (! m_trans_recv.get_command (cmd) || cmd != SCIM_TRANS_CMD_REPLY) {
+            LOGW ("wrong format of transaction\n");
+            return REMOTE_CONTROL_CALLBACK_ERROR;
+        }
+
+        remote_control_callback_type type = REMOTE_CONTROL_CALLBACK_ERROR;
+        while (m_trans_recv.get_command (cmd)) {
+            LOGD ("RemoteInput_Client::cmd = %d\n", cmd);
+            switch (cmd) {
+                case ISM_TRANS_CMD_RECV_REMOTE_FOCUS_IN:
+                    type = REMOTE_CONTROL_CALLBACK_FOCUS_IN;
+                    break;
+                case ISM_TRANS_CMD_RECV_REMOTE_FOCUS_OUT:
+                    type = REMOTE_CONTROL_CALLBACK_FOCUS_OUT;
+                    break;
+                case ISM_TRANS_CMD_RECV_REMOTE_ENTRY_METADATA:
+                {
+                    type = REMOTE_CONTROL_CALLBACK_ENTRY_METADATA;
+
+                    if (m_trans_recv.get_data (m_hint) && m_trans_recv.get_data (m_layout) && m_trans_recv.get_data (m_variation) &&
+                        m_trans_recv.get_data (m_autocapital_type)) {
+                    }
+                    else
+                        LOGW ("wrong format of transaction\n");
+                    break;
+                }
+                case ISM_TRANS_CMD_RECV_REMOTE_DEFAULT_TEXT:
+                {
+                    type = REMOTE_CONTROL_CALLBACK_DEFAULT_TEXT;
+
+                    if (m_trans_recv.get_data (m_default_text) && m_trans_recv.get_data (m_cursor)) {
+                    }
+                    else
+                        LOGW ("wrong format of transaction\n");
+                    break;
+                }
+                default:
+                    break;
+            }
+        }
+        return type;
+    }
+
+    void get_entry_metadata (int *hint, int *layout, int *variation, int *autocapital_type) {
+        *hint = m_hint;
+        *layout = m_layout;
+        *variation = m_variation;
+        *autocapital_type = m_autocapital_type;
+    }
+
+    void get_default_text (String &default_text, int *cursor) {
+        default_text = m_default_text;
+        *cursor = m_cursor;
+    }
+};
+
+RemoteInputClient::RemoteInputClient ()
+        : m_impl (new RemoteInputClientImpl ())
+{
+}
+
+RemoteInputClient::~RemoteInputClient ()
+{
+    delete m_impl;
+}
+
+int
+RemoteInputClient::open_connection (void)
+{
+    return m_impl->open_connection ();
+}
+
+void
+RemoteInputClient::close_connection (void)
+{
+    m_impl->close_connection ();
+}
+
+bool RemoteInputClient::is_connected (void) const
+{
+    return m_impl->is_connected ();
+}
+
+int RemoteInputClient::get_panel2remote_connection_number (void) const
+{
+    return m_impl->get_panel2remote_connection_number ();
+}
+
+bool
+RemoteInputClient::prepare (void)
+{
+    return m_impl->prepare ();
+}
+
+bool
+RemoteInputClient::has_pending_event (void) const
+{
+    return m_impl->has_pending_event ();
+}
+
+bool
+RemoteInputClient::send_remote_input_message (const char* str)
+{
+    return m_impl->send_remote_input_message (str);
+}
+
+remote_control_callback_type
+RemoteInputClient::recv_callback_message (void)
+{
+    return m_impl->recv_callback_message ();
+}
+
+void
+RemoteInputClient::get_entry_metadata (int *hint, int *layout, int *variation, int *autocapital_type)
+{
+    m_impl->get_entry_metadata (hint, layout, variation, autocapital_type);
+}
+
+void
+RemoteInputClient::get_default_text (String &default_text, int *cursor)
+{
+    m_impl->get_default_text (default_text, cursor);
+}
+};
+
+/*
+vi:ts=4:nowrap:ai:expandtab
+*/
diff --git a/ism/src/isf_remote_client.h b/ism/src/isf_remote_client.h
new file mode 100644 (file)
index 0000000..045f722
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * ISF(Input Service Framework)
+ *
+ * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable.
+ * Copyright (c) 2012-2015 Samsung Electronics Co., Ltd.
+ *
+ * Contact: Inhong Han <inhong1.han@samsung.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef __ISF_REMOTE_CLIENT_H
+#define __ISF_REMOTE_CLIENT_H
+
+namespace scim
+{
+
+typedef enum {
+    REMOTE_CONTROL_CALLBACK_ERROR,
+    REMOTE_CONTROL_CALLBACK_FOCUS_IN,
+    REMOTE_CONTROL_CALLBACK_FOCUS_OUT,
+    REMOTE_CONTROL_CALLBACK_ENTRY_METADATA,
+    REMOTE_CONTROL_CALLBACK_DEFAULT_TEXT,
+} remote_control_callback_type;
+
+class EXAPI RemoteInputClient
+{
+    class RemoteInputClientImpl;
+    RemoteInputClientImpl *m_impl;
+
+public:
+    RemoteInputClient ();
+    ~RemoteInputClient ();
+
+    int  open_connection        (void);
+    void close_connection       (void);
+    bool is_connected           (void) const;
+    int  get_panel2remote_connection_number (void) const;
+    bool prepare                (void);
+    bool has_pending_event      (void) const;
+    bool send_remote_input_message (const char* str);
+    remote_control_callback_type recv_callback_message (void);
+    void get_entry_metadata (int *hint, int *layout, int *variation, int *autocapital_type);
+    void get_default_text (String &default_text, int *cursor);
+};
+}
+
+#endif /* __ISF_REMOTE_CLIENT_H */
+
+/*
+vi:ts=4:nowrap:ai:expandtab
+*/
diff --git a/ism/src/isf_remote_control.cpp b/ism/src/isf_remote_control.cpp
new file mode 100644 (file)
index 0000000..a2c2a75
--- /dev/null
@@ -0,0 +1,278 @@
+#define Uses_SCIM_TRANSACTION
+#define Uses_ISF_REMOTE_CLIENT
+#define Uses_STL_STRING
+
+#include <Ecore.h>
+#include <dlog.h>
+
+#include "scim.h"
+#include "isf_remote_control.h"
+
+#ifdef LOG_TAG
+# undef LOG_TAG
+#endif
+#define LOG_TAG             "ISF_REMOTE_CONTROL"
+
+using namespace scim;
+
+static bool focus_flag, event_check_flag;
+
+enum remote_control_command_option{
+    REMOTE_CONTROL_COMMAND_KEY = 0,
+    REMOTE_CONTROL_COMMAND_COMMIT,
+    REMOTE_CONTROL_COMMAND_PREEDIT,
+};
+
+struct _remote_control_client {
+    RemoteInputClient remote_client;
+    Ecore_Fd_Handler *remote_fd_handler = NULL;
+    int remote_client_id;
+    remote_control_focus_in_cb focus_in_cb;
+    void* focus_in_cb_user_data;
+    remote_control_focus_out_cb focus_out_cb;
+    void* focus_out_cb_user_data;
+    remote_control_entry_metadata_cb metadata_cb;
+    void* metadata_cb_user_data;
+    remote_control_default_text_cb default_text_cb;
+    void* default_text_cb_user_data;
+};
+
+static Eina_Bool
+remote_handler(void *data, Ecore_Fd_Handler *fd_handler)
+{
+    remote_control_client *client = static_cast<remote_control_client*>(data);
+
+    if (client->remote_client.has_pending_event()) {
+        switch (client->remote_client.recv_callback_message()) {
+            case REMOTE_CONTROL_CALLBACK_FOCUS_IN:
+            {
+                focus_flag = true;
+                event_check_flag = false;
+                client->focus_in_cb (client->focus_in_cb_user_data);
+                break;
+            }
+            case REMOTE_CONTROL_CALLBACK_FOCUS_OUT:
+            {
+                focus_flag = false;
+                client->focus_out_cb (client->focus_out_cb_user_data);
+                break;
+            }
+            case REMOTE_CONTROL_CALLBACK_ENTRY_METADATA:
+            {
+                if (focus_flag) {
+                    remote_control_entry_metadata_s *data = new remote_control_entry_metadata_s;
+                    int hint, layout, variation, autocapital_type;
+
+                    client->remote_client.get_entry_metadata (&hint, &layout, &variation, &autocapital_type);
+                    data->hint = static_cast<Ecore_IMF_Input_Hints> (hint);
+                    data->layout = static_cast<Ecore_IMF_Input_Panel_Layout> (layout);
+                    data->variation = variation;
+                    data->autocapital_type = static_cast<Ecore_IMF_Autocapital_Type> (autocapital_type);
+
+                    client->metadata_cb (client->metadata_cb_user_data, data);
+                    delete data;
+                }
+                break;
+            }
+            case REMOTE_CONTROL_CALLBACK_DEFAULT_TEXT:
+            {
+                if (focus_flag && !event_check_flag) {
+                    String default_text;
+                    int cursor;
+
+                    client->remote_client.get_default_text (default_text, &cursor);
+                    remote_control_update_preedit_string(client, default_text.c_str (), NULL, 0);
+                    client->default_text_cb (client->default_text_cb_user_data, strdup (default_text.c_str ()), cursor);
+                }
+            }
+            case REMOTE_CONTROL_CALLBACK_ERROR:
+                break;
+            default:
+                break;
+        }
+    }
+    return ECORE_CALLBACK_RENEW;
+}
+
+EXAPI remote_control_client * remote_control_connect(void)
+{
+    remote_control_client *client = new remote_control_client;
+    focus_flag = false;
+    event_check_flag = false;
+
+    if (client) {
+        RemoteInputClient *remote_client = new RemoteInputClient;
+        client->remote_client = *remote_client;
+        if (!client->remote_client.open_connection())
+            goto cleanup;
+
+        client->remote_client_id = client->remote_client.get_panel2remote_connection_number();
+
+        if (client->remote_client_id >= 0) {
+            client->remote_fd_handler = ecore_main_fd_handler_add(client->remote_client_id, ECORE_FD_READ, remote_handler, client, NULL, NULL);
+
+            if (client->remote_fd_handler == NULL)
+                goto cleanup;
+        } else
+            goto cleanup;
+
+    } else
+        goto cleanup;
+
+    return client;
+cleanup:
+    if (client)
+        delete client;
+
+    return NULL;
+}
+
+EXAPI int remote_control_disconnect(remote_control_client *client)
+{
+    if (client == NULL)
+        return REMOTE_CONTROL_INVALID_PARAMETER;
+
+    if (client->remote_fd_handler)
+        ecore_main_fd_handler_del(client->remote_fd_handler);
+
+    client->remote_client.close_connection();
+    delete client;
+    client = NULL;
+
+    return REMOTE_CONTROL_ERROR_NONE;
+}
+
+EXAPI int remote_control_focus_in_callback_set(remote_control_client *client, remote_control_focus_in_cb func, void *user_data)
+{
+    if (client == NULL)
+        return REMOTE_CONTROL_INVALID_PARAMETER;
+
+    client->focus_in_cb = func;
+    client->focus_in_cb_user_data = user_data;
+
+    return REMOTE_CONTROL_ERROR_NONE;
+}
+
+EXAPI int remote_control_focus_in_callback_unset(remote_control_client *client)
+{
+    if (client == NULL)
+        return REMOTE_CONTROL_INVALID_PARAMETER;
+
+    client->focus_in_cb = NULL;
+    client->focus_in_cb_user_data = NULL;
+
+    return REMOTE_CONTROL_ERROR_NONE;
+}
+
+EXAPI int remote_control_focus_out_callback_set(remote_control_client *client, remote_control_focus_out_cb func , void *user_data)
+{
+    if (client == NULL)
+        return REMOTE_CONTROL_INVALID_PARAMETER;
+
+    client->focus_out_cb = func;
+    client->focus_out_cb_user_data = user_data;
+
+    return REMOTE_CONTROL_ERROR_NONE;
+}
+
+EXAPI int remote_control_focus_out_callback_unset(remote_control_client *client)
+{
+    if (client == NULL)
+        return REMOTE_CONTROL_INVALID_PARAMETER;
+
+    client->focus_out_cb = NULL;
+    client->focus_out_cb_user_data = NULL;
+
+    return REMOTE_CONTROL_ERROR_NONE;
+}
+
+EXAPI int remote_control_entry_metadata_callback_set(remote_control_client *client, remote_control_entry_metadata_cb func, void *user_data)
+{
+    if (client == NULL)
+        return REMOTE_CONTROL_INVALID_PARAMETER;
+
+    client->metadata_cb = func;
+    client->metadata_cb_user_data = user_data;
+
+    return REMOTE_CONTROL_ERROR_NONE;
+}
+
+EXAPI int remote_control_entry_metadata_callback_unset(remote_control_client *client)
+{
+    if (client == NULL)
+        return REMOTE_CONTROL_INVALID_PARAMETER;
+
+    client->metadata_cb = NULL;
+    client->metadata_cb_user_data = NULL;
+
+    return REMOTE_CONTROL_ERROR_NONE;
+}
+
+EXAPI int remote_control_default_text_callback_set(remote_control_client *client, remote_control_default_text_cb func, void *user_data)
+{
+    if (client == NULL)
+        return REMOTE_CONTROL_INVALID_PARAMETER;
+
+    client->default_text_cb = func;
+    client->default_text_cb_user_data = user_data;
+
+    return REMOTE_CONTROL_ERROR_NONE;
+}
+
+EXAPI int remote_control_default_text_callback_unset(remote_control_client *client)
+{
+    if (client == NULL)
+        return REMOTE_CONTROL_INVALID_PARAMETER;
+
+    client->default_text_cb = NULL;
+    client->default_text_cb_user_data = NULL;
+
+    return REMOTE_CONTROL_ERROR_NONE;
+}
+
+EXAPI int remote_control_send_key_event(remote_control_client *client, remote_control_key_type_e key)
+{
+    if (client == NULL || key < REMOTE_CONTROL_KEY_ENTER || key > REMOTE_CONTROL_KEY_PAGE_DOWN)
+        return REMOTE_CONTROL_INVALID_PARAMETER;
+
+    char key_str[10] = {};
+    snprintf(key_str, sizeof(key_str), "%d", key);
+    String command = String ("|plain|send_key_event|") + String (key_str) + String ("|");
+
+    client->remote_client.prepare();
+    if (focus_flag && client->remote_client.send_remote_input_message(command.c_str ())) {
+        event_check_flag = true;
+        return REMOTE_CONTROL_ERROR_NONE;
+    }
+    return REMOTE_CONTROL_INVALID_OPERATION;
+}
+
+EXAPI int remote_control_send_commit_string(remote_control_client *client, const char *text)
+{
+    if (client == NULL || !text || strlen(text) == 0)
+        return REMOTE_CONTROL_INVALID_PARAMETER;
+
+    String command = String ("|plain|commit_string|") + String (text) + String ("|");
+
+    client->remote_client.prepare();
+    if (focus_flag && client->remote_client.send_remote_input_message(command.c_str ())) {
+        event_check_flag = true;
+        return REMOTE_CONTROL_ERROR_NONE;
+    }
+    return REMOTE_CONTROL_INVALID_OPERATION;
+}
+
+EXAPI int remote_control_update_preedit_string(remote_control_client *client, const char *text, Eina_List *attrs, int cursor_pos)
+{
+    if (client == NULL || !text || strlen(text) == 0 || cursor_pos < 0)
+        return REMOTE_CONTROL_INVALID_PARAMETER;
+
+    String command = String ("|plain|update_preedit_string|") + String (text) + String ("|");
+
+    client->remote_client.prepare();
+    if (focus_flag && client->remote_client.send_remote_input_message(command.c_str ())) {
+        event_check_flag = true;
+        return REMOTE_CONTROL_ERROR_NONE;
+    }
+    return REMOTE_CONTROL_INVALID_OPERATION;
+}
\ No newline at end of file
diff --git a/ism/src/isf_remote_control.h b/ism/src/isf_remote_control.h
new file mode 100644 (file)
index 0000000..cdcbea3
--- /dev/null
@@ -0,0 +1,77 @@
+#ifndef _ISF_REMOTE_CONTROL_H_
+#define _ISF_REMOTE_CONTROL_H_
+
+#include <Ecore_IMF.h>
+#include <scim_visibility.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef enum {
+    REMOTE_CONTROL_ERROR_NONE = 0,
+    REMOTE_CONTROL_INVALID_PARAMETER,
+    REMOTE_CONTROL_INVALID_OPERATION,
+} remote_control_error_e;
+
+typedef enum {
+    REMOTE_CONTROL_KEY_ENTER = 0,
+    REMOTE_CONTROL_KEY_SPACE,
+    REMOTE_CONTROL_KEY_BACKSPACE,
+    REMOTE_CONTROL_KEY_ESC,
+    REMOTE_CONTROL_KEY_UP,
+    REMOTE_CONTROL_KEY_DOWN,
+    REMOTE_CONTROL_KEY_LEFT,
+    REMOTE_CONTROL_KEY_RIGHT,
+    REMOTE_CONTROL_KEY_PAGE_UP,
+    REMOTE_CONTROL_KEY_PAGE_DOWN,
+} remote_control_key_type_e;
+
+typedef struct {
+    Ecore_IMF_Input_Hints hint;
+    Ecore_IMF_Input_Panel_Layout layout;
+    int variation;
+    Ecore_IMF_Autocapital_Type autocapital_type;
+} remote_control_entry_metadata_s;
+
+typedef struct _remote_control_client remote_control_client;
+
+EXAPI remote_control_client * remote_control_connect(void);
+
+EXAPI int remote_control_disconnect(remote_control_client *client);
+
+typedef void (*remote_control_focus_in_cb)(void *user_data);
+
+EXAPI int remote_control_focus_in_callback_set(remote_control_client *client, remote_control_focus_in_cb func, void *user_data);
+
+EXAPI int remote_control_focus_in_callback_unset(remote_control_client *client);
+
+typedef void (*remote_control_focus_out_cb)(void *user_data);
+
+EXAPI int remote_control_focus_out_callback_set(remote_control_client *client, remote_control_focus_out_cb func , void *user_data);
+
+EXAPI int remote_control_focus_out_callback_unset(remote_control_client *client);
+
+typedef void (*remote_control_entry_metadata_cb)(void *user_data, remote_control_entry_metadata_s *data);
+
+EXAPI int remote_control_entry_metadata_callback_set(remote_control_client *client, remote_control_entry_metadata_cb func, void *user_data);
+
+EXAPI int remote_control_entry_metadata_callback_unset(remote_control_client *client);
+
+typedef void (*remote_control_default_text_cb)(void *user_data, char *default_text, int cursor_pos);
+
+EXAPI int remote_control_default_text_callback_set(remote_control_client *client, remote_control_default_text_cb func, void *user_data);
+
+EXAPI int remote_control_default_text_callback_unset(remote_control_client *client);
+
+EXAPI int remote_control_send_key_event(remote_control_client *client, remote_control_key_type_e key);
+
+EXAPI int remote_control_send_commit_string(remote_control_client *client, const char *text);
+
+EXAPI int remote_control_update_preedit_string(remote_control_client *client, const char *text, Eina_List *attrs, int cursor_pos);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
index a026400..e5a9287 100644 (file)
     #include <isf_imcontrol_client.h>
 #endif
 
+#ifdef Uses_ISF_REMOTE_CLIENT
+    #include <isf_remote_client.h>
+#endif
+
 #ifdef Uses_SCIM_HOTKEY
     #include <scim_hotkey.h>
 #endif
index 0e69829..21340d7 100644 (file)
@@ -637,8 +637,11 @@ const int ISM_TRANS_CMD_SHOW_HELPER_ISE_LIST              = 1021;
 const int ISM_TRANS_CMD_SHOW_HELPER_ISE_SELECTOR          = 1022;
 const int ISM_TRANS_CMD_IS_HELPER_ISE_ENABLED             = 1023;
 const int ISM_TRANS_CMD_GET_RECENT_ISE_GEOMETRY           = 1024;
-const int ISM_TRANS_CMD_ENABLE_REMOTE_INPUT               = 1025;
-const int ISM_TRANS_CMD_DISABLE_REMOTE_INPUT              = 1026;
+const int ISM_TRANS_CMD_SEND_REMOTE_INPUT_MESSAGE         = 1025;
+const int ISM_TRANS_CMD_RECV_REMOTE_FOCUS_IN              = 1026;
+const int ISM_TRANS_CMD_RECV_REMOTE_FOCUS_OUT             = 1027;
+const int ISM_TRANS_CMD_RECV_REMOTE_ENTRY_METADATA        = 1028;
+const int ISM_TRANS_CMD_RECV_REMOTE_DEFAULT_TEXT          = 1029;
 
 /* IMControl to ISE */
 const int ISM_TRANS_CMD_SET_ISE_MODE                      = 1108;
index 49fe333..c8ecdb5 100644 (file)
@@ -145,7 +145,7 @@ ln -sf %{_libdir}/ecore_imf/modules/wayland/v-1.16/module.so %{_libdir}/ecore_im
 %{_sysconfdir}/scim/config
 %{_datadir}/scim/isf_candidate_theme1.edj
 %{_datadir}/scim/icons/*
-%attr(766,app,app) %{_datadir}/scim/remote-input/*
+%attr(755,root,root) %{_datadir}/scim/remote-input/*
 %{_bindir}/isf-demo-efl
 %{_bindir}/isf-panel-efl
 %{_bindir}/scim