From 35febe33e9755487c053d645acf1a4df339d39b6 Mon Sep 17 00:00:00 2001
From: Amos Bird <amosbird@gmail.com>
Date: Thu, 31 May 2018 10:17:23 +0800
Subject: [PATCH] better remote.

---
 src/frontend/ipc/ipc.c                             | 23 ++++++++++++++++++++++
 src/lib/fcitx-gclient/fcitxinputmethod.c           | 17 ++++++++++++++++
 src/lib/fcitx-qt/fcitxqtinputmethodproxy.h         |  7 +++++++
 .../interfaces/org.fcitx.Fcitx.InputMethod.xml     |  3 +++
 src/module/dbus/dbusremote.c                       | 22 +++++++++++++++++++--
 src/module/remote/remote.c                         | 11 +++++++++++
 tools/cli/fcitx-remote.c                           | 10 ++++++++--
 7 files changed, 89 insertions(+), 4 deletions(-)

diff --git a/src/frontend/ipc/ipc.c b/src/frontend/ipc/ipc.c
index 92806f1e..6a5a57e4 100644
--- a/src/frontend/ipc/ipc.c
+++ b/src/frontend/ipc/ipc.c
@@ -179,6 +179,9 @@ const char * im_introspection_xml =
     "<method name=\"SetCurrentIM\">"
     "<arg name=\"im\" direction=\"in\" type=\"s\"/>"
     "</method>"
+    "<method name=\"CommitString\">"
+    "<arg name=\"im\" direction=\"in\" type=\"s\"/>"
+    "</method>"
     "<method name=\"ReloadConfig\">"
     "</method>"
     "<method name=\"ReloadAddonConfig\">"
@@ -666,6 +669,26 @@ static DBusHandlerResult IPCDBusEventHandler(DBusConnection *connection, DBusMes
             reply = FcitxDBusPropertyUnknownMethod(msg);
         }
         dbus_error_free(&error);
+    } else if (dbus_message_is_method_call(msg, FCITX_IM_DBUS_INTERFACE, "CommitString")) {
+        DBusError error;
+        dbus_error_init(&error);
+        char* imname = NULL;
+        if (dbus_message_get_args(msg, &error, DBUS_TYPE_STRING, &imname, DBUS_TYPE_INVALID)) {
+            FcitxInputContext *rec = FcitxInstanceGetCurrentIC(instance);
+            if (rec)
+            {
+                FcitxInstanceCommitString(instance, rec, imname);
+                FcitxLog(INFO, "Commit string: %s", imname);
+            }
+            else
+            {
+                FcitxLog(INFO, "Frondend is null, cannot commit string");
+            }
+            reply = dbus_message_new_method_return(msg);
+        } else {
+            reply = FcitxDBusPropertyUnknownMethod(msg);
+        }
+        dbus_error_free(&error);
     } else if (dbus_message_is_method_call(msg, FCITX_IM_DBUS_INTERFACE, "GetIMAddon")) {
         DBusError error;
         dbus_error_init(&error);
diff --git a/src/lib/fcitx-gclient/fcitxinputmethod.c b/src/lib/fcitx-gclient/fcitxinputmethod.c
index 6ecba1d5..9736c204 100644
--- a/src/lib/fcitx-gclient/fcitxinputmethod.c
+++ b/src/lib/fcitx-gclient/fcitxinputmethod.c
@@ -49,6 +49,9 @@ static const gchar introspection_xml[] =
     "    <method name=\"SetCurrentIM\">\n"
     "      <arg name=\"im\" direction=\"in\" type=\"s\"/>\n"
     "    </method>\n"
+    "    <method name=\"CommitString\">\n"
+    "      <arg name=\"im\" direction=\"in\" type=\"s\"/>\n"
+    "    </method>\n"
     "    <method name=\"ReloadConfig\">\n"
     "    </method>\n"
     "    <method name=\"Restart\">\n"
@@ -594,6 +597,20 @@ void fcitx_input_method_set_current_im(FcitxInputMethod *im, gchar *imname) {
                       G_DBUS_CALL_FLAGS_NO_AUTO_START, 0, NULL, NULL, NULL);
 }
 
+/**
+ * fcitx_input_method_commit_string:
+ * @im: A #FcitxInputMethod
+ * @imname: (transfer none): commit string
+ *
+ * Commit string
+ **/
+FCITX_EXPORT_API
+void fcitx_input_method_commit_string(FcitxInputMethod *im, gchar *imname) {
+    g_dbus_proxy_call(G_DBUS_PROXY(im), "CommitString",
+                      g_variant_new("(s)", imname),
+                      G_DBUS_CALL_FLAGS_NO_AUTO_START, 0, NULL, NULL, NULL);
+}
+
 /**
  * fcitx_input_method_activate:
  * @im: A #FcitxInputMethod
diff --git a/src/lib/fcitx-qt/fcitxqtinputmethodproxy.h b/src/lib/fcitx-qt/fcitxqtinputmethodproxy.h
index 49b34cb0..66b5900c 100644
--- a/src/lib/fcitx-qt/fcitxqtinputmethodproxy.h
+++ b/src/lib/fcitx-qt/fcitxqtinputmethodproxy.h
@@ -205,6 +205,13 @@ public Q_SLOTS: // METHODS
         return asyncCallWithArgumentList(QLatin1String("SetCurrentIM"), argumentList);
     }
 
+    inline QDBusPendingReply<> CommitString(const QString &im)
+    {
+        QList<QVariant> argumentList;
+        argumentList << QVariant::fromValue(im);
+        return asyncCallWithArgumentList(QLatin1String("CommitString"), argumentList);
+    }
+
     inline QDBusPendingReply<> ToggleIM()
     {
         QList<QVariant> argumentList;
diff --git a/src/lib/fcitx-qt/interfaces/org.fcitx.Fcitx.InputMethod.xml b/src/lib/fcitx-qt/interfaces/org.fcitx.Fcitx.InputMethod.xml
index 00dc20ab..c6603865 100644
--- a/src/lib/fcitx-qt/interfaces/org.fcitx.Fcitx.InputMethod.xml
+++ b/src/lib/fcitx-qt/interfaces/org.fcitx.Fcitx.InputMethod.xml
@@ -36,6 +36,9 @@
     <method name="SetCurrentIM">
       <arg name="im" direction="in" type="s"/>
     </method>
+    <method name="CommitString">
+      <arg name="im" direction="in" type="s"/>
+    </method>
     <method name="ReloadConfig">
     </method>
     <method name="ReloadAddonConfig">
diff --git a/src/module/dbus/dbusremote.c b/src/module/dbus/dbusremote.c
index e99abb4c..961ac199 100644
--- a/src/module/dbus/dbusremote.c
+++ b/src/module/dbus/dbusremote.c
@@ -74,6 +74,7 @@ void usage(FILE* fp)
             "\t-a\t\tprint fcitx's dbus address\n"
             "\t-m <imname>\tprint corresponding addon name for im\n"
             "\t-s <imname>\tswitch to the input method uniquely identified by <imname>\n"
+            "\t-w <text>\tsend <text> via fcitx\n"
             "\t[no option]\tdisplay fcitx state, %d for close, %d for inactive, %d for acitve\n"
             "\t-h\t\tdisplay this help and exit\n",
            IS_CLOSED, IS_INACTIVE, IS_ACTIVE);
@@ -87,7 +88,8 @@ enum {
     FCITX_DBUS_TOGGLE,
     FCITX_DBUS_GET_CURRENT_STATE,
     FCITX_DBUS_GET_IM_ADDON,
-    FCITX_DBUS_SET_CURRENT_IM
+    FCITX_DBUS_SET_CURRENT_IM,
+    FCITX_DBUS_COMMIT_STRING
 };
 
 int main (int argc, char* argv[])
@@ -100,7 +102,7 @@ int main (int argc, char* argv[])
     int ret = 1;
     int messageType = FCITX_DBUS_GET_CURRENT_STATE;
     char *imname = NULL;
-    while ((c = getopt(argc, argv, "chortTeam:s:")) != -1) {
+    while ((c = getopt(argc, argv, "chortTeam:s:w:")) != -1) {
         switch (c) {
         case 'o':
             messageType = FCITX_DBUS_ACTIVATE;
@@ -133,6 +135,11 @@ int main (int argc, char* argv[])
             imname = strdup(optarg);
             break;
 
+        case 'w':
+            messageType = FCITX_DBUS_COMMIT_STRING;
+            imname = strdup(optarg);
+            break;
+
         case 'a':
             address = _fcitx_get_address();
             if (address) {
@@ -166,6 +173,7 @@ int main (int argc, char* argv[])
         CASE(GET_CURRENT_STATE, GetCurrentState);
         CASE(GET_IM_ADDON, GetIMAddon);
         CASE(SET_CURRENT_IM, SetCurrentIM);
+        CASE(COMMIT_STRING, CommitString);
 
         default:
             goto some_error;
@@ -232,6 +240,16 @@ int main (int argc, char* argv[])
             dbus_connection_flush(conn);
             ret = 0;
         } while(0);
+    }
+    else if (messageType == FCITX_DBUS_COMMIT_STRING) {
+        do {
+            if (!fcitx_utf8_check_string(imname))
+                break;
+            dbus_message_append_args(message, DBUS_TYPE_STRING, &imname, DBUS_TYPE_INVALID);
+            dbus_connection_send(conn, message, NULL);
+            dbus_connection_flush(conn);
+            ret = 0;
+        } while(0);
     } else {
         dbus_connection_send(conn, message, NULL);
         dbus_connection_flush(conn);
diff --git a/src/module/remote/remote.c b/src/module/remote/remote.c
index eda44972..728771a1 100644
--- a/src/module/remote/remote.c
+++ b/src/module/remote/remote.c
@@ -181,6 +181,17 @@ static void RemoteProcessEvent(void* p)
         FcitxInstanceSwitchIMByName(remote->owner, imname);
         break;
     }
+    case 5: {
+        char buf[1024];
+        int n = read(client_fd, buf, 1023);
+        buf[n] = '\0';
+        FcitxInputContext *rec = FcitxInstanceGetCurrentIC(remote->owner);
+        if (rec)
+        {
+            FcitxInstanceCommitString(remote->owner, rec, buf);
+        }
+        break;
+    }
     default:
         break;
         /// }}}
diff --git a/tools/cli/fcitx-remote.c b/tools/cli/fcitx-remote.c
index 5e06ea76..21670da2 100644
--- a/tools/cli/fcitx-remote.c
+++ b/tools/cli/fcitx-remote.c
@@ -75,6 +75,7 @@ void usage(FILE* fp)
             "\t-r\t\treload fcitx config\n"
             "\t-t,-T\t\tswitch Active/Inactive\n"
             "\t-s <imname>\tswitch to the input method uniquely identified by <imname>\n"
+            "\t-w <text>\tsend <text> via fcitx\n"
             "\t[no option]\tdisplay fcitx state, %d for close, %d for inactive, %d for acitve\n"
             "\t-h\t\tdisplay this help and exit\n",
             IS_CLOSED, IS_INACTIVE, IS_ACTIVE);
@@ -89,7 +90,7 @@ int main(int argc, char *argv[])
     char c;
     char* imname = 0;
 
-    while ((c = getopt(argc, argv, "chortTs:")) != -1) {
+    while ((c = getopt(argc, argv, "chortTs:w:")) != -1) {
         switch (c) {
         case 'o':
             o = 1;
@@ -114,6 +115,11 @@ int main(int argc, char *argv[])
             imname = optarg;
             break;
 
+        case 'w':
+            o = 5;
+            imname = optarg;
+            break;
+
         case 'h':
             usage(stderr);
             return 0;
@@ -140,7 +146,7 @@ int main(int argc, char *argv[])
         int buf;
         read(socket_fd, &buf, sizeof(buf));
         printf("%d\n", buf);
-    } else if (o == 4) {
+    } else if (o == 4 || o == 5) {
        write(socket_fd, imname, strlen(imname));
     }
     close(socket_fd);
-- 
2.16.2


