summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEduardo Lima (Etrunko) <eduardo.lima@intel.com>2013-10-21 16:03:45 -0200
committerEduardo Lima (Etrunko) <eduardo.lima@intel.com>2013-10-21 19:36:27 -0200
commitc8cfd4454052f45c5b1ae35904a64c506cebb14c (patch)
tree5911392be889dfa3b9ce654978169443f296b105
parent7f4340f88cae3ac59929c1e32af1a49efe4550c1 (diff)
downloadweekeyboard-c8cfd4454052f45c5b1ae35904a64c506cebb14c.tar.gz
weekeyboard-c8cfd4454052f45c5b1ae35904a64c506cebb14c.tar.bz2
weekeyboard-c8cfd4454052f45c5b1ae35904a64c506cebb14c.zip
Added proxy calls to IBusInputContext service
Change-Id: Id94424f6f58e2706c2e827f3f2c5e56a3000672b Signed-off-by: Eduardo Lima (Etrunko) <eduardo.lima@intel.com>
-rw-r--r--src/wkb-ibus-defs.h1
-rw-r--r--src/wkb-ibus.c195
-rw-r--r--src/wkb-ibus.h15
3 files changed, 209 insertions, 2 deletions
diff --git a/src/wkb-ibus-defs.h b/src/wkb-ibus-defs.h
index 37995d5..3d08d8c 100644
--- a/src/wkb-ibus-defs.h
+++ b/src/wkb-ibus-defs.h
@@ -33,6 +33,7 @@ extern "C" {
#define IBUS_INTERFACE_IBUS "org.freedesktop.IBus"
#define IBUS_INTERFACE_PANEL "org.freedesktop.IBus.Panel"
#define IBUS_INTERFACE_CONFIG "org.freedesktop.IBus.Config"
+#define IBUS_INTERFACE_INPUT_CONTEXT "org.freedesktop.IBus.InputContext"
/* from ibustypes.h/ibuserror.c */
#define IBUS_ERROR_NO_ENGINE "org.freedesktop.IBus.Error.NoEngine"
diff --git a/src/wkb-ibus.c b/src/wkb-ibus.c
index f2fd95a..bd47f20 100644
--- a/src/wkb-ibus.c
+++ b/src/wkb-ibus.c
@@ -25,7 +25,11 @@
#include "wkb-ibus.h"
#include "wkb-ibus-defs.h"
+#include "wkb-ibus-helper.h"
#include "wkb-log.h"
+#include "wkb-ibus-config-eet.h"
+
+#include "input-method-client-protocol.h"
#define _check_message_errors(_msg) \
do \
@@ -46,6 +50,22 @@ static const char *IBUS_ADDRESS_ENV = "IBUS_ADDRESS";
static const char *IBUS_ADDRESS_CMD = "ibus address";
static const char *IBUS_DAEMON_CMD = "ibus-daemon -s";
+/* From ibustypes.h */
+static const unsigned int IBUS_CAP_PREEDIT_TEXT = 1 << 0;
+static const unsigned int IBUS_CAP_AUXILIARY_TEXT = 1 << 1;
+static const unsigned int IBUS_CAP_LOOKUP_TABLE = 1 << 2;
+static const unsigned int IBUS_CAP_FOCUS = 1 << 3;
+static const unsigned int IBUS_CAP_PROPERTY = 1 << 4;
+static const unsigned int IBUS_CAP_SURROUNDING_TEXT = 1 << 5;
+
+struct wkb_ibus_input_context
+{
+ Eldbus_Pending *pending;
+ Eldbus_Proxy *ibus_ctx;
+ struct wl_input_method_context *wl_ctx;
+ unsigned int serial;
+};
+
struct _wkb_ibus_context
{
char *address;
@@ -59,6 +79,9 @@ struct _wkb_ibus_context
Eldbus_Service_Interface *panel;
Eldbus_Signal_Handler *name_acquired;
Eldbus_Signal_Handler *name_lost;
+ Eldbus_Proxy *ibus;
+
+ struct wkb_ibus_input_context *input_ctx;
int refcount;
@@ -337,6 +360,8 @@ _wkb_ibus_disconnected_cb(void *data, Eldbus_Connection *conn, void *event_data)
Eina_Bool
wkb_ibus_connect(void)
{
+ Eldbus_Object *obj;
+
if (wkb_ibus->conn)
{
INF("Already connected to IBus");
@@ -413,6 +438,9 @@ wkb_ibus_connect(void)
ELDBUS_NAME_REQUEST_FLAG_REPLACE_EXISTING | ELDBUS_NAME_REQUEST_FLAG_DO_NOT_QUEUE,
_wkb_name_request_cb, wkb_ibus);
+ obj = eldbus_object_get(wkb_ibus->conn, IBUS_SERVICE_IBUS, IBUS_PATH_IBUS);
+ wkb_ibus->ibus = eldbus_proxy_get(obj, IBUS_INTERFACE_IBUS);
+
ecore_event_add(WKB_IBUS_CONNECTED, NULL, NULL, NULL);
return EINA_TRUE;
@@ -545,6 +573,16 @@ wkb_ibus_disconnect(void)
eldbus_signal_handler_del(wkb_ibus->name_acquired);
eldbus_signal_handler_del(wkb_ibus->name_lost);
+ /* IBus InputContext proxy */
+ wkb_ibus_input_context_destroy();
+
+ /* IBus proxy */
+ if (wkb_ibus->ibus)
+ {
+ eldbus_proxy_unref(wkb_ibus->ibus);
+ wkb_ibus->ibus = NULL;
+ }
+
if (wkb_ibus->panel)
{
eldbus_name_release(wkb_ibus->conn, IBUS_SERVICE_PANEL, _wkb_name_release_cb, wkb_ibus);
@@ -571,3 +609,160 @@ wkb_ibus_is_connected(void)
{
return wkb_ibus->conn != NULL;
}
+
+static void
+_ibus_input_ctx_commit_text(void *data, const Eldbus_Message *msg)
+{
+ Eldbus_Message_Iter *iter = NULL;
+ struct wkb_ibus_text *txt;
+
+ _check_message_errors(msg);
+
+ if (!eldbus_message_arguments_get(msg, "v", &iter))
+ {
+ ERR("Error reading message arguments");
+ return;
+ }
+
+ txt = wkb_ibus_text_from_message_iter(iter);
+ DBG("Commit text: '%s'", txt->text);
+ wl_input_method_context_commit_string(wkb_ibus->input_ctx->wl_ctx, wkb_ibus->input_ctx->serial, txt->text);
+ wkb_ibus_text_free(txt);
+}
+
+static void
+_ibus_input_ctx_forward_key_event(void *data, const Eldbus_Message *msg)
+{
+ _check_message_errors(msg);
+}
+
+static void
+_ibus_input_ctx_update_preedit_text(void *data, const Eldbus_Message *msg)
+{
+ _check_message_errors(msg);
+}
+
+static void
+_ibus_input_ctx_show_preedit_text(void *data, const Eldbus_Message *msg)
+{
+ _check_message_errors(msg);
+}
+
+static void
+_ibus_input_ctx_hide_input_text(void *data, const Eldbus_Message *msg)
+{
+ _check_message_errors(msg);
+}
+
+static void
+_ibus_input_ctx_create(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)
+{
+ const char *obj_path;
+ Eldbus_Object *obj;
+ unsigned int capabilities = IBUS_CAP_FOCUS | IBUS_CAP_PREEDIT_TEXT | IBUS_CAP_SURROUNDING_TEXT;
+
+ _check_message_errors(msg);
+
+ if (!eldbus_message_arguments_get(msg, "o", &obj_path))
+ {
+ ERR("Error reading message arguments");
+ goto end;
+ }
+
+ DBG("Got new IBus input context: '%s'", obj_path);
+
+ obj = eldbus_object_get(wkb_ibus->conn, IBUS_SERVICE_IBUS, obj_path);
+ wkb_ibus->input_ctx->ibus_ctx = eldbus_proxy_get(obj, IBUS_INTERFACE_INPUT_CONTEXT);
+
+ eldbus_proxy_signal_handler_add(wkb_ibus->input_ctx->ibus_ctx, "CommitText", _ibus_input_ctx_commit_text, NULL);
+ eldbus_proxy_signal_handler_add(wkb_ibus->input_ctx->ibus_ctx, "ForwardKeyEvent", _ibus_input_ctx_forward_key_event, NULL);
+ eldbus_proxy_signal_handler_add(wkb_ibus->input_ctx->ibus_ctx, "UpdatePreeditText", _ibus_input_ctx_update_preedit_text, NULL);
+ eldbus_proxy_signal_handler_add(wkb_ibus->input_ctx->ibus_ctx, "ShowPreeditText", _ibus_input_ctx_show_preedit_text, NULL);
+ eldbus_proxy_signal_handler_add(wkb_ibus->input_ctx->ibus_ctx, "HidePreeditText", _ibus_input_ctx_hide_input_text, NULL);
+
+ eldbus_proxy_call(wkb_ibus->input_ctx->ibus_ctx, "FocusIn", NULL, NULL, -1, "");
+ eldbus_proxy_call(wkb_ibus->input_ctx->ibus_ctx, "SetCapabilities", NULL, NULL, -1, "u", capabilities);
+
+end:
+ wkb_ibus->input_ctx->pending = NULL;
+}
+
+void
+wkb_ibus_input_context_create(struct wl_input_method_context *wl_ctx)
+{
+ const char *ctx_name = "wayland";
+
+ if (!wkb_ibus)
+ return;
+
+ if (wkb_ibus->input_ctx)
+ {
+ WRN("Input context already exists");
+ wkb_ibus_input_context_destroy();
+ }
+
+ wkb_ibus->input_ctx = calloc(1, sizeof(*(wkb_ibus->input_ctx)));
+ wkb_ibus->input_ctx->wl_ctx = wl_ctx;
+
+ if (!wkb_ibus->conn)
+ {
+ ERR("Not connected");
+ return;
+ }
+
+ if (!wkb_ibus->ibus)
+ {
+ ERR("No IBus proxy");
+ return;
+ }
+
+ wkb_ibus->input_ctx->pending = eldbus_proxy_call(wkb_ibus->ibus, "CreateInputContext", _ibus_input_ctx_create, NULL, -1, "s", ctx_name);
+}
+
+void
+wkb_ibus_input_context_destroy(void)
+{
+ if (!wkb_ibus || !wkb_ibus->input_ctx)
+ return;
+
+ if (wkb_ibus->input_ctx->pending)
+ eldbus_pending_cancel(wkb_ibus->input_ctx->pending);
+
+ if (wkb_ibus->input_ctx->ibus_ctx)
+ {
+ eldbus_proxy_call(wkb_ibus->input_ctx->ibus_ctx, "FocusOut", NULL, NULL, -1, "");
+ eldbus_proxy_unref(wkb_ibus->input_ctx->ibus_ctx);
+ }
+
+end:
+ free(wkb_ibus->input_ctx);
+ wkb_ibus->input_ctx = NULL;
+}
+
+void
+wkb_ibus_input_context_process_key_event(void)
+{
+}
+
+void
+wkb_ibus_input_context_set_surrounding_text(void)
+{
+}
+
+unsigned int
+wkb_ibus_input_context_serial(void)
+{
+ if (!wkb_ibus || !wkb_ibus->input_ctx)
+ return 0;
+
+ return wkb_ibus->input_ctx->serial;
+}
+
+void
+wkb_ibus_input_context_set_serial(unsigned int serial)
+{
+ if (!wkb_ibus || !wkb_ibus->input_ctx)
+ return;
+
+ wkb_ibus->input_ctx->serial = serial;
+}
diff --git a/src/wkb-ibus.h b/src/wkb-ibus.h
index 8e3cc70..63c1d39 100644
--- a/src/wkb-ibus.h
+++ b/src/wkb-ibus.h
@@ -24,6 +24,9 @@
extern "C" {
#endif
+struct wl_input_method_context;
+
+/* Events */
extern int WKB_IBUS_CONNECTED;
extern int WKB_IBUS_DISCONNECTED;
@@ -35,10 +38,18 @@ void wkb_ibus_disconnect(void);
Eina_Bool wkb_ibus_is_connected(void);
-/* Panel */
+/* IBus Input Context */
+void wkb_ibus_input_context_create(struct wl_input_method_context *wl_ctx);
+void wkb_ibus_input_context_destroy(void);
+void wkb_ibus_input_context_process_key_event(void);
+void wkb_ibus_input_context_set_surrounding_text(void);
+unsigned int wkb_ibus_input_context_serial(void);
+void wkb_ibus_input_context_set_serial(unsigned int serial);
+
+/* IBus Panel */
Eldbus_Service_Interface * wkb_ibus_panel_register(Eldbus_Connection *conn);
-/* Config */
+/* IBus Config */
Eldbus_Service_Interface * wkb_ibus_config_register(Eldbus_Connection *conn, const char *path);
void wkb_ibus_config_unregister(void);