2 * Copyright © 2013 Intel Corporation
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
27 int _wkb_ibus_log_dom = -1;
29 #define CHECK_MESSAGE_ERRORS(_msg) \
32 const char *error, *error_msg; \
33 if (eldbus_message_error_get(_msg, &error, &error_msg)) \
35 ERR("Dbus message error: %s: %s", error, error_msg); \
38 DBG("Message '%s' with signature '%s'", eldbus_message_member_get(_msg), eldbus_message_signature_get(_msg)); \
41 struct _wkb_ibus_service
43 Eldbus_Service_Interface *interface;
45 Eldbus_Signal_Handler *name_acquired;
46 Eldbus_Signal_Handler *name_lost;
49 struct _wkb_ibus_context
52 Eldbus_Connection *conn;
53 Ecore_Exe *ibus_daemon;
55 struct _wkb_ibus_service config;
59 struct _wkb_ibus_service panel;
61 Eina_Bool address_pending;
64 static struct _wkb_ibus_context *ctx = NULL;
67 _wkb_config_value_changed_cb(void *data, const Eldbus_Message *msg)
69 const char *section, name;
70 Eldbus_Message_Iter *value;
72 CHECK_MESSAGE_ERRORS(msg)
74 if (!eldbus_message_arguments_get(msg, "ssv", §ion, &name, &value))
76 ERR("Error reading message arguments");
80 DBG("section: '%s', name: '%s', value: '%p", section, name, value);
84 _wkb_name_owner_changed_cb(void *data, const char *bus, const char *old_id, const char *new_id)
86 DBG("NameOwnerChanged Bus=%s | old=%s | new=%s", bus, old_id, new_id);
90 if (strcmp(bus, IBUS_SERVICE_CONFIG) == 0)
99 ecore_main_loop_glib_integrate();
100 obj = eldbus_object_get(ctx->conn, IBUS_SERVICE_CONFIG, IBUS_PATH_CONFIG);
101 ctx->config = eldbus_proxy_get(obj, IBUS_INTERFACE_CONFIG);
102 eldbus_proxy_signal_handler_add(ctx->config, "ValueChanged", _wkb_config_value_changed_cb, ctx);
104 INF("Got config proxy");
111 eldbus_proxy_unref(ctx->config);
119 _wkb_name_acquired_cb(void *data, const Eldbus_Message *msg)
125 CHECK_MESSAGE_ERRORS(msg)
127 if (!eldbus_message_arguments_get(msg, "s", &name))
129 ERR("Error reading message arguments");
133 if (strcmp(name, IBUS_INTERFACE_PANEL) == 0)
135 if (!ctx->panel.interface)
137 ctx->panel.interface = wkb_ibus_panel_register(ctx->conn);
138 INF("Registering Panel Interface: %s", ctx->panel.interface ? "Success" : "Fail");
142 INF("Panel Interface already registered");
146 else if (strcmp(name, IBUS_INTERFACE_CONFIG) == 0)
148 if (!ctx->config.interface)
150 ctx->config.interface = wkb_ibus_config_register(ctx->conn);
151 INF("Registering Config Interface: %s", ctx->config.interface ? "Success" : "Fail");
155 INF("Config Interface already registered");
161 WRN("Unexpected name %s", name);
166 _wkb_name_lost_cb(void *data, const Eldbus_Message *msg)
172 CHECK_MESSAGE_ERRORS(msg)
174 if (!eldbus_message_arguments_get(msg, "s", &name))
176 ERR("Error reading message arguments");
180 DBG("Name = %s", name);
184 _wkb_ibus_shutdown_idler(void *data)
187 return ECORE_CALLBACK_CANCEL;
191 _wkb_name_request_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)
193 const char *error, *error_msg;
196 DBG("NameRequest callback");
198 if (eldbus_message_error_get(msg, &error, &error_msg))
200 ERR("DBus message error: %s: %s", error, error_msg);
204 if (!eldbus_message_arguments_get(msg, "u", &reply))
206 ERR("Error reading message arguments");
210 if (reply != ELDBUS_NAME_REQUEST_REPLY_PRIMARY_OWNER &&
211 reply != ELDBUS_NAME_REQUEST_REPLY_ALREADY_OWNER)
213 ERR("Not primary owner: reply=%d", reply);
220 ecore_idler_add(_wkb_ibus_shutdown_idler, NULL);
224 _wkb_name_release_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)
228 CHECK_MESSAGE_ERRORS(msg)
230 if (!eldbus_message_arguments_get(msg, "u", &reply))
232 ERR("Error reading message arguments");
236 if (reply != ELDBUS_NAME_RELEASE_REPLY_RELEASED)
238 ERR("Unexpected name release reply: %d", reply);
244 _wkb_ibus_launch_daemon(void)
246 DBG("Launching ibus-daemon");
247 ctx->ibus_daemon = ecore_exe_run("ibus-daemon -s", NULL);
248 if (!ctx->ibus_daemon)
250 ERR("Error launching ibus-daemon process");
256 _wkb_ibus_query_address_cb(void *data, int type, void *event)
258 Ecore_Exe_Event_Data *exe_data = (Ecore_Exe_Event_Data *)event;
260 if (strncmp(exe_data->data, "(null)", exe_data->size) == 0)
262 INF("IBus daemon is not running.");
263 _wkb_ibus_launch_daemon();
266 else if (strstr(exe_data->data, "unknown command") != NULL)
268 ERR("ibus command does not support the 'address' argument");
273 ctx->address = strndup(exe_data->data, exe_data->size);
276 ecore_idler_add(ecore_exe_free, exe_data->exe);
277 ctx->address_pending = EINA_FALSE;
278 return ECORE_CALLBACK_DONE;
283 _wkb_ibus_query_address(void)
285 const char *ibus_addr;
286 Ecore_Exe *ibus_exec = NULL;
288 /* Check for IBUS_ADDRESS environment variable */
289 if ((ibus_addr = getenv("IBUS_ADDRESS")) != NULL)
291 DBG("Got IBus address from IBUS_ADDRESS environment variable %s", ibus_addr);
292 ctx->address = strdup(ibus_addr);
296 /* Get IBus address by invoking 'ibus address' from command line */
297 DBG("Querying IBus address from using 'ibus address' command");
298 ibus_exec = ecore_exe_pipe_run("ibus address",
299 ECORE_EXE_PIPE_READ |
300 ECORE_EXE_PIPE_READ_LINE_BUFFERED,
304 ERR("Unable to retrieve IBus address");
308 ctx->address_pending = EINA_TRUE;
309 ecore_event_handler_add(ECORE_EXE_EVENT_DATA, _wkb_ibus_query_address_cb, NULL);
313 wkb_ibus_connect(void)
320 INF("IBus address is not set.", ctx->address_pending);
321 if (!ctx->address_pending)
322 _wkb_ibus_query_address();
327 INF("Connecting to IBus at address '%s'", ctx->address);
328 ctx->conn = eldbus_address_connection_get(ctx->address);
332 ERR("Error connecting to IBus");
337 eldbus_name_owner_changed_callback_add(ctx->conn,
339 _wkb_name_owner_changed_cb,
342 ctx->panel.name_acquired = eldbus_signal_handler_add(ctx->conn,
345 IBUS_INTERFACE_PANEL,
347 _wkb_name_acquired_cb,
350 ctx->panel.name_lost = eldbus_signal_handler_add(ctx->conn,
353 IBUS_INTERFACE_PANEL,
358 eldbus_name_request(ctx->conn, IBUS_SERVICE_PANEL,
359 ELDBUS_NAME_REQUEST_FLAG_REPLACE_EXISTING | ELDBUS_NAME_REQUEST_FLAG_DO_NOT_QUEUE,
360 _wkb_name_request_cb, ctx);
363 eldbus_name_owner_changed_callback_add(ctx->conn,
365 _wkb_name_owner_changed_cb,
369 ctx->config.name_acquired = eldbus_signal_handler_add(ctx->conn,
372 IBUS_INTERFACE_CONFIG,
374 _wkb_name_acquired_cb,
377 ctx->config.name_lost = eldbus_signal_handler_add(ctx->conn,
380 IBUS_INTERFACE_CONFIG,
385 eldbus_name_request(ctx->conn, IBUS_SERVICE_CONFIG,
386 ELDBUS_NAME_REQUEST_FLAG_REPLACE_EXISTING | ELDBUS_NAME_REQUEST_FLAG_DO_NOT_QUEUE,
387 _wkb_name_request_cb, ctx);
396 if (ctx && ctx->refcount > 0)
401 fprintf(stderr, "Error initializing Eina\n");
405 _wkb_ibus_log_dom = eina_log_domain_register("wkb-ibus", EINA_COLOR_LIGHTCYAN);
406 if (_wkb_ibus_log_dom < 0)
408 EINA_LOG_ERR("Unable to register 'wkb-ibus' log domain");
413 if (!ctx && !(ctx = calloc(1, sizeof(*ctx))))
415 ERR("Error calloc\n");
420 _wkb_ibus_query_address();
423 return ++ctx->refcount;
427 wkb_ibus_shutdown(void)
431 fprintf(stderr, "Not initialized\n");
435 if (ctx->refcount == 0)
437 ERR("Refcount already 0");
441 if (--(ctx->refcount) != 0)
444 DBG("Shutting down");
445 wkb_ibus_disconnect();
449 if (ctx->ibus_daemon)
451 DBG("Terminating ibus-daemon");
452 ecore_exe_terminate(ctx->ibus_daemon);
453 ecore_exe_free(ctx->ibus_daemon);
460 ecore_main_loop_quit();
461 DBG("Main loop quit");
465 wkb_ibus_disconnect(void)
469 ERR("Not connected");
475 if (ctx->panel.interface)
477 eldbus_name_release(ctx->conn, IBUS_SERVICE_PANEL, _wkb_name_release_cb, ctx);
478 eldbus_signal_handler_del(ctx->panel.name_acquired);
479 eldbus_signal_handler_del(ctx->panel.name_lost);
480 eldbus_service_interface_unregister(ctx->panel.interface);
481 ctx->panel.interface = NULL;
486 eldbus_proxy_unref(ctx->config);
490 if (ctx->config.interface)
492 eldbus_name_release(ctx->conn, IBUS_SERVICE_CONFIG, _wkb_name_release_cb, ctx);
493 eldbus_signal_handler_del(ctx->config.name_acquired);
494 eldbus_signal_handler_del(ctx->config.name_lost);
495 eldbus_service_interface_unregister(ctx->config.interface);
496 ctx->config.interface = NULL;
500 eldbus_connection_unref(ctx->conn);
504 wkb_ibus_is_connected(void)
506 return ctx->conn != NULL;