1 /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
2 /* vim:set et sts=4: */
3 /* ibus - The Input Bus
4 * Copyright (C) 2008-2015 Peng Huang <shawn.p.huang@gmail.com>
5 * Copyright (C) 2015-2019 Takao Fujiwara <takao.fujiwara1@gmail.com>
6 * Copyright (C) 2008-2016 Red Hat, Inc.
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
21 * USA
22 */
23
24 #include "ibusbus.h"
25 #include <errno.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <unistd.h>
29 #include <glib/gstdio.h>
30 #include <gio/gio.h>
31 #include "ibusmarshalers.h"
32 #include "ibusinternal.h"
33 #include "ibusshare.h"
34 #include "ibusenginedesc.h"
35 #include "ibusserializable.h"
36 #include "ibusconfig.h"
37
38 #define IBUS_BUS_GET_PRIVATE(o) \
39 ((IBusBusPrivate *)ibus_bus_get_instance_private (o))
40
41 enum {
42 CONNECTED,
43 DISCONNECTED,
44 GLOBAL_ENGINE_CHANGED,
45 NAME_OWNER_CHANGED,
46 LAST_SIGNAL,
47 };
48
49 enum {
50 PROP_0 = 0,
51 PROP_CONNECT_ASYNC,
52 PROP_CLIENT_ONLY,
53 };
54
55 /* IBusBusPriv */
56 struct _IBusBusPrivate {
57 GFileMonitor *monitor;
58 GDBusConnection *connection;
59 gboolean connected;
60 gboolean watch_dbus_signal;
61 guint watch_dbus_signal_id;
62 gboolean watch_ibus_signal;
63 guint watch_ibus_signal_id;
64 IBusConfig *config;
65 gchar *unique_name;
66 gboolean connect_async;
67 gchar *bus_address;
68 gboolean use_portal;
69 gboolean client_only;
70 GCancellable *cancellable;
71 guint portal_name_watch_id;
72 };
73
74 static guint bus_signals[LAST_SIGNAL] = { 0 };
75
76 static IBusBus *_bus = NULL;
77
78 /* functions prototype */
79 static GObject *ibus_bus_constructor (GType type,
80 guint n_params,
81 GObjectConstructParam *params);
82 static void ibus_bus_destroy (IBusObject *object);
83 static void ibus_bus_connect_async (IBusBus *bus);
84 static void ibus_bus_watch_dbus_signal (IBusBus *bus);
85 static void ibus_bus_unwatch_dbus_signal (IBusBus *bus);
86 static void ibus_bus_watch_ibus_signal (IBusBus *bus);
87 static void ibus_bus_unwatch_ibus_signal (IBusBus *bus);
88 static GVariant *ibus_bus_call_sync (IBusBus *bus,
89 const gchar *service,
90 const gchar *path,
91 const gchar *interface,
92 const gchar *member,
93 GVariant *parameters,
94 const GVariantType *reply_type);
95 static void ibus_bus_call_async (IBusBus *bus,
96 const gchar *service,
97 const gchar *path,
98 const gchar *interface,
99 const gchar *member,
100 GVariant *parameters,
101 const GVariantType *reply_type,
102 gpointer source_tag,
103 gint timeout_msec,
104 GCancellable *cancellable,
105 GAsyncReadyCallback callback,
106 gpointer user_data);
107 static void ibus_bus_set_property (IBusBus *bus,
108 guint prop_id,
109 const GValue *value,
110 GParamSpec *pspec);
111 static void ibus_bus_get_property (IBusBus *bus,
112 guint prop_id,
113 GValue *value,
114 GParamSpec *pspec);
115
116 static void ibus_bus_close_connection (IBusBus *bus);
117
G_DEFINE_TYPE_WITH_PRIVATE(IBusBus,ibus_bus,IBUS_TYPE_OBJECT)118 G_DEFINE_TYPE_WITH_PRIVATE (IBusBus, ibus_bus, IBUS_TYPE_OBJECT)
119
120 static void
121 ibus_bus_class_init (IBusBusClass *class)
122 {
123 GObjectClass *gobject_class = G_OBJECT_CLASS (class);
124 IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (class);
125
126 gobject_class->constructor = ibus_bus_constructor;
127 gobject_class->set_property =
128 (GObjectSetPropertyFunc) ibus_bus_set_property;
129 gobject_class->get_property =
130 (GObjectGetPropertyFunc) ibus_bus_get_property;
131 ibus_object_class->destroy = ibus_bus_destroy;
132
133 /* install properties */
134 /**
135 * IBusBus:connect-async:
136 *
137 * Whether the #IBusBus object should connect asynchronously to the bus.
138 *
139 */
140 g_object_class_install_property (
141 gobject_class,
142 PROP_CONNECT_ASYNC,
143 g_param_spec_boolean ("connect-async",
144 "Connect Async",
145 "Connect asynchronously to the bus",
146 FALSE,
147 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
148 /**
149 * IBusBus:client-only:
150 *
151 * Whether the #IBusBus object is for client use only.
152 *
153 */
154 g_object_class_install_property (
155 gobject_class,
156 PROP_CLIENT_ONLY,
157 g_param_spec_boolean ("client-only",
158 "ClientOnly",
159 "Client use only",
160 FALSE,
161 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
162
163 /* install signals */
164 /**
165 * IBusBus::connected:
166 * @bus: The #IBusBus object which recevied the signal
167 *
168 * Emitted when #IBusBus is connected to ibus-daemon.
169 *
170 */
171 bus_signals[CONNECTED] =
172 g_signal_new (I_("connected"),
173 G_TYPE_FROM_CLASS (class),
174 G_SIGNAL_RUN_LAST,
175 0,
176 NULL, NULL,
177 _ibus_marshal_VOID__VOID,
178 G_TYPE_NONE,
179 0);
180
181 /**
182 * IBusBus::disconnected:
183 * @bus: The #IBusBus object which recevied the signal
184 *
185 * Emitted when #IBusBus is disconnected from ibus-daemon.
186 *
187 */
188 bus_signals[DISCONNECTED] =
189 g_signal_new (I_("disconnected"),
190 G_TYPE_FROM_CLASS (class),
191 G_SIGNAL_RUN_LAST,
192 0,
193 NULL, NULL,
194 _ibus_marshal_VOID__VOID,
195 G_TYPE_NONE,
196 0);
197
198 /**
199 * IBusBus::global-engine-changed:
200 * @bus: The #IBusBus object which recevied the signal
201 * @name: The name of the new global engine.
202 *
203 * Emitted when global engine is changed.
204 *
205 */
206 bus_signals[GLOBAL_ENGINE_CHANGED] =
207 g_signal_new (I_("global-engine-changed"),
208 G_TYPE_FROM_CLASS (class),
209 G_SIGNAL_RUN_LAST,
210 0,
211 NULL, NULL,
212 _ibus_marshal_VOID__STRING,
213 G_TYPE_NONE,
214 1,
215 G_TYPE_STRING);
216
217 /**
218 * IBusBus::name-owner-changed:
219 * @bus: The #IBusBus object which recevied the signal
220 * @name: The name which ower is changed.
221 * @old_owner: The unique bus name of the old owner.
222 * @new_owner: The unique bus name of the new owner.
223 *
224 * Emitted when D-Bus name owner is changed.
225 *
226 */
227 bus_signals[NAME_OWNER_CHANGED] =
228 g_signal_new (I_("name-owner-changed"),
229 G_TYPE_FROM_CLASS (class),
230 G_SIGNAL_RUN_LAST,
231 0,
232 NULL, NULL,
233 _ibus_marshal_VOID__STRING_STRING_STRING,
234 G_TYPE_NONE,
235 3,
236 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
237 }
238
239 static void
_connection_dbus_signal_cb(GDBusConnection * connection,const gchar * sender_name,const gchar * object_path,const gchar * interface_name,const gchar * signal_name,GVariant * parameters,gpointer user_data)240 _connection_dbus_signal_cb (GDBusConnection *connection,
241 const gchar *sender_name,
242 const gchar *object_path,
243 const gchar *interface_name,
244 const gchar *signal_name,
245 GVariant *parameters,
246 gpointer user_data)
247 {
248 g_return_if_fail (user_data != NULL);
249 g_return_if_fail (IBUS_IS_BUS (user_data));
250
251 if (g_strcmp0 (signal_name, "NameOwnerChanged") == 0) {
252 gchar *name = NULL;
253 gchar *old_owner = NULL;
254 gchar *new_owner = NULL;
255 g_variant_get (parameters, "(&s&s&s)", &name, &old_owner, &new_owner);
256 g_signal_emit (IBUS_BUS (user_data),
257 bus_signals[NAME_OWNER_CHANGED], 0,
258 name, old_owner, new_owner);
259 }
260 /* FIXME handle other D-Bus signals if needed */
261 }
262
263 static void
_connection_ibus_signal_cb(GDBusConnection * connection,const gchar * sender_name,const gchar * object_path,const gchar * interface_name,const gchar * signal_name,GVariant * parameters,gpointer user_data)264 _connection_ibus_signal_cb (GDBusConnection *connection,
265 const gchar *sender_name,
266 const gchar *object_path,
267 const gchar *interface_name,
268 const gchar *signal_name,
269 GVariant *parameters,
270 gpointer user_data)
271 {
272 g_return_if_fail (user_data != NULL);
273 g_return_if_fail (IBUS_IS_BUS (user_data));
274
275 if (g_strcmp0 (signal_name, "GlobalEngineChanged") == 0) {
276 gchar *engine_name = NULL;
277 g_variant_get (parameters, "(&s)", &engine_name);
278 g_signal_emit (IBUS_BUS (user_data),
279 bus_signals[GLOBAL_ENGINE_CHANGED], 0,
280 engine_name);
281 }
282 /* FIXME handle org.freedesktop.IBus.RegistryChanged signal if needed */
283 }
284
285 static void
_connection_closed_cb(GDBusConnection * connection,gboolean remote_peer_vanished,GError * error,IBusBus * bus)286 _connection_closed_cb (GDBusConnection *connection,
287 gboolean remote_peer_vanished,
288 GError *error,
289 IBusBus *bus)
290 {
291 if (error) {
292 /* We replaced g_warning with g_debug here because
293 * currently when ibus-daemon restarts, GTK client calls this and
294 * _g_dbus_worker_do_read_cb() sets the error message:
295 * "Underlying GIOStream returned 0 bytes on an async read"
296 * http://git.gnome.org/browse/glib/tree/gio/gdbusprivate.c#n693
297 * However we think the error message is almost harmless. */
298 g_debug ("_connection_closed_cb: %s", error->message);
299 }
300 ibus_bus_close_connection (bus);
301 }
302
303 static void
ibus_bus_close_connection(IBusBus * bus)304 ibus_bus_close_connection (IBusBus *bus)
305 {
306 g_free (bus->priv->unique_name);
307 bus->priv->unique_name = NULL;
308
309 bus->priv->watch_dbus_signal_id = 0;
310 bus->priv->watch_ibus_signal_id = 0;
311
312 g_free (bus->priv->bus_address);
313 bus->priv->bus_address = NULL;
314
315 /* Cancel ongoing connect request. */
316 g_cancellable_cancel (bus->priv->cancellable);
317 g_cancellable_reset (bus->priv->cancellable);
318
319 bus->priv->connected = FALSE;
320
321 /* unref the old connection at first */
322 if (bus->priv->connection != NULL) {
323 g_signal_handlers_disconnect_by_func (bus->priv->connection,
324 G_CALLBACK (_connection_closed_cb),
325 bus);
326 if (!g_dbus_connection_is_closed(bus->priv->connection))
327 g_dbus_connection_close(bus->priv->connection, NULL, NULL, NULL);
328 g_object_unref (bus->priv->connection);
329 bus->priv->connection = NULL;
330 g_signal_emit (bus, bus_signals[DISCONNECTED], 0);
331 }
332 }
333
334 static void
ibus_bus_connect_completed(IBusBus * bus)335 ibus_bus_connect_completed (IBusBus *bus)
336 {
337 g_assert (bus->priv->connection);
338
339 bus->priv->connected = TRUE;
340 /* FIXME */
341 ibus_bus_hello (bus);
342
343 g_signal_connect (bus->priv->connection,
344 "closed",
345 (GCallback) _connection_closed_cb,
346 bus);
347 if (bus->priv->watch_dbus_signal) {
348 ibus_bus_watch_dbus_signal (bus);
349 }
350 if (bus->priv->watch_ibus_signal) {
351 ibus_bus_watch_ibus_signal (bus);
352 }
353
354 g_signal_emit (bus, bus_signals[CONNECTED], 0);
355 }
356
357 static void
_bus_connect_start_portal_cb(GObject * source_object,GAsyncResult * res,gpointer user_data)358 _bus_connect_start_portal_cb (GObject *source_object,
359 GAsyncResult *res,
360 gpointer user_data)
361 {
362 IBusBus *bus = IBUS_BUS (user_data);
363 GVariant *result;
364 GError *error = NULL;
365
366 result = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object),
367 res,
368 &error);
369 if (result != NULL) {
370 ibus_bus_connect_completed (bus);
371 g_variant_unref (result);
372 } else {
373 g_error_free (error);
374
375 g_dbus_connection_close (bus->priv->connection, NULL, NULL, NULL);
376 g_object_unref (bus->priv->connection);
377 bus->priv->connection = NULL;
378
379 g_free (bus->priv->bus_address);
380 bus->priv->bus_address = NULL;
381 }
382
383 g_object_unref (bus);
384 }
385
386 static void
_bus_connect_async_cb(GObject * source_object,GAsyncResult * res,gpointer user_data)387 _bus_connect_async_cb (GObject *source_object,
388 GAsyncResult *res,
389 gpointer user_data)
390 {
391 g_return_if_fail (user_data != NULL);
392 g_return_if_fail (IBUS_IS_BUS (user_data));
393
394 IBusBus *bus = IBUS_BUS (user_data);
395 GError *error = NULL;
396
397 bus->priv->connection =
398 g_dbus_connection_new_for_address_finish (res, &error);
399
400 if (error != NULL) {
401 g_warning ("Unable to connect to ibus: %s", error->message);
402 g_error_free (error);
403 error = NULL;
404 }
405
406 if (bus->priv->connection != NULL) {
407 if (bus->priv->use_portal) {
408 g_object_set_data (G_OBJECT (bus->priv->connection),
409 "ibus-portal-connection",
410 GINT_TO_POINTER (TRUE));
411 g_dbus_connection_call (
412 bus->priv->connection,
413 IBUS_SERVICE_PORTAL,
414 IBUS_PATH_IBUS,
415 "org.freedesktop.DBus.Peer",
416 "Ping",
417 g_variant_new ("()"),
418 G_VARIANT_TYPE ("()"),
419 G_DBUS_CALL_FLAGS_NONE,
420 -1,
421 bus->priv->cancellable,
422 (GAsyncReadyCallback) _bus_connect_start_portal_cb,
423 g_object_ref (bus));
424 } else {
425 ibus_bus_connect_completed (bus);
426 }
427 }
428 else {
429 g_free (bus->priv->bus_address);
430 bus->priv->bus_address = NULL;
431 }
432
433 /* unref the ref from ibus_bus_connect */
434 g_object_unref (bus);
435 }
436
437 static gchar *
ibus_bus_get_bus_address(IBusBus * bus)438 ibus_bus_get_bus_address (IBusBus *bus)
439 {
440 if (_bus->priv->use_portal)
441 return g_dbus_address_get_for_bus_sync (G_BUS_TYPE_SESSION, NULL, NULL);
442 else
443 return g_strdup (ibus_get_address ());
444 }
445
446 static void
ibus_bus_connect_async(IBusBus * bus)447 ibus_bus_connect_async (IBusBus *bus)
448 {
449 gchar *bus_address = ibus_bus_get_bus_address (bus);
450
451 if (bus_address == NULL)
452 return;
453
454 if (g_strcmp0 (bus->priv->bus_address, bus_address) == 0) {
455 g_free (bus_address);
456 return;
457 }
458
459 /* Close current connection and cancel ongoing connect request. */
460 ibus_bus_close_connection (bus);
461
462 bus->priv->bus_address = bus_address;
463 g_object_ref (bus);
464 g_dbus_connection_new_for_address (
465 bus_address,
466 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
467 G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION,
468 NULL,
469 bus->priv->cancellable,
470 _bus_connect_async_cb, bus);
471 }
472
473 static gboolean
is_in_flatpak(void)474 is_in_flatpak (void)
475 {
476 static gboolean flatpak_info_read;
477 static gboolean in_flatpak;
478
479 if (flatpak_info_read)
480 return in_flatpak;
481
482 flatpak_info_read = TRUE;
483 if (g_file_test ("/.flatpak-info", G_FILE_TEST_EXISTS))
484 in_flatpak = TRUE;
485 return in_flatpak;
486 }
487
488 static gboolean
ibus_bus_should_connect_portal(IBusBus * bus)489 ibus_bus_should_connect_portal (IBusBus *bus)
490 {
491 return bus->priv->client_only &&
492 (is_in_flatpak () || g_getenv ("IBUS_USE_PORTAL") != NULL);
493 }
494
495 static void
ibus_bus_connect(IBusBus * bus)496 ibus_bus_connect (IBusBus *bus)
497 {
498 const gchar *bus_address = ibus_get_address ();
499
500 if (bus_address == NULL)
501 return;
502
503 if (g_strcmp0 (bus_address, bus->priv->bus_address) == 0 &&
504 bus->priv->connection != NULL)
505 return;
506
507 /* Close current connection and cancel ongoing connect request. */
508 ibus_bus_close_connection (bus);
509
510 bus->priv->connection = g_dbus_connection_new_for_address_sync (
511 bus_address,
512 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
513 G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION,
514 NULL, NULL, NULL);
515 if (bus->priv->connection) {
516 bus->priv->bus_address = g_strdup (bus_address);
517 ibus_bus_connect_completed (bus);
518 }
519 }
520
521 static void
_changed_cb(GFileMonitor * monitor,GFile * file,GFile * other_file,GFileMonitorEvent event_type,IBusBus * bus)522 _changed_cb (GFileMonitor *monitor,
523 GFile *file,
524 GFile *other_file,
525 GFileMonitorEvent event_type,
526 IBusBus *bus)
527 {
528 if (event_type != G_FILE_MONITOR_EVENT_CHANGED &&
529 event_type != G_FILE_MONITOR_EVENT_CREATED &&
530 event_type != G_FILE_MONITOR_EVENT_DELETED)
531 return;
532
533 ibus_bus_connect_async (bus);
534 }
535
536 static void
ibus_bus_init(IBusBus * bus)537 ibus_bus_init (IBusBus *bus)
538 {
539 struct stat buf;
540 gchar *path;
541
542 bus->priv = IBUS_BUS_GET_PRIVATE (bus);
543
544 bus->priv->config = NULL;
545 bus->priv->connection = NULL;
546 bus->priv->watch_dbus_signal = FALSE;
547 bus->priv->watch_dbus_signal_id = 0;
548 bus->priv->watch_ibus_signal = FALSE;
549 bus->priv->watch_ibus_signal_id = 0;
550 bus->priv->unique_name = NULL;
551 bus->priv->connect_async = FALSE;
552 bus->priv->client_only = FALSE;
553 bus->priv->bus_address = NULL;
554 bus->priv->cancellable = g_cancellable_new ();
555
556 path = g_path_get_dirname (ibus_get_socket_path ());
557
558 g_mkdir_with_parents (path, 0700);
559
560 if (stat (path, &buf) == 0) {
561 if (buf.st_uid != getuid ()) {
562 g_warning ("The owner of %s is not %s!",
563 path, ibus_get_user_name ());
564 return;
565 }
566 if (buf.st_mode != (S_IFDIR | S_IRWXU)) {
567 errno = 0;
568 if (g_chmod (path, 0700))
569 g_warning ("chmod failed: %s", errno ? g_strerror (errno) : "");
570 }
571 }
572
573 g_free (path);
574 }
575
576 static void
ibus_bus_set_property(IBusBus * bus,guint prop_id,const GValue * value,GParamSpec * pspec)577 ibus_bus_set_property (IBusBus *bus,
578 guint prop_id,
579 const GValue *value,
580 GParamSpec *pspec)
581 {
582 switch (prop_id) {
583 case PROP_CONNECT_ASYNC:
584 bus->priv->connect_async = g_value_get_boolean (value);
585 break;
586 case PROP_CLIENT_ONLY:
587 bus->priv->client_only = g_value_get_boolean (value);
588 break;
589 default:
590 G_OBJECT_WARN_INVALID_PROPERTY_ID (bus, prop_id, pspec);
591 }
592 }
593
594 static void
ibus_bus_get_property(IBusBus * bus,guint prop_id,GValue * value,GParamSpec * pspec)595 ibus_bus_get_property (IBusBus *bus,
596 guint prop_id,
597 GValue *value,
598 GParamSpec *pspec)
599 {
600 switch (prop_id) {
601 case PROP_CONNECT_ASYNC:
602 g_value_set_boolean (value, bus->priv->connect_async);
603 break;
604 case PROP_CLIENT_ONLY:
605 g_value_set_boolean (value, bus->priv->client_only);
606 break;
607 default:
608 G_OBJECT_WARN_INVALID_PROPERTY_ID (bus, prop_id, pspec);
609 }
610 }
611
612 static void
portal_name_appeared(GDBusConnection * connection,const gchar * name,const gchar * owner,gpointer user_data)613 portal_name_appeared (GDBusConnection *connection,
614 const gchar *name,
615 const gchar *owner,
616 gpointer user_data)
617 {
618 IBusBus *bus = IBUS_BUS (user_data);
619
620 if (bus->priv->connection == NULL)
621 ibus_bus_connect_async (bus);
622 }
623
624 static void
portal_name_vanished(GDBusConnection * connection,const gchar * name,gpointer user_data)625 portal_name_vanished (GDBusConnection *connection,
626 const gchar *name,
627 gpointer user_data)
628 {
629 IBusBus *bus = IBUS_BUS (user_data);
630
631 if (bus->priv->connection)
632 g_dbus_connection_close (bus->priv->connection, NULL, NULL, NULL);
633 }
634
635
636 static GObject*
ibus_bus_constructor(GType type,guint n_params,GObjectConstructParam * params)637 ibus_bus_constructor (GType type,
638 guint n_params,
639 GObjectConstructParam *params)
640 {
641 GObject *object;
642 GFile *file;
643
644 /* share one IBusBus instance in whole application */
645 if (_bus == NULL) {
646 object = G_OBJECT_CLASS (ibus_bus_parent_class)->constructor (
647 type, n_params, params);
648 /* make bus object sink */
649 g_object_ref_sink (object);
650 _bus = IBUS_BUS (object);
651
652 _bus->priv->use_portal = ibus_bus_should_connect_portal (_bus);
653
654 if (!_bus->priv->use_portal) {
655 file = g_file_new_for_path (ibus_get_socket_path ());
656 _bus->priv->monitor = g_file_monitor_file (file, 0, NULL, NULL);
657 g_signal_connect (_bus->priv->monitor, "changed",
658 (GCallback) _changed_cb, _bus);
659 g_object_unref (file);
660 } else {
661 _bus->priv->portal_name_watch_id =
662 g_bus_watch_name (G_BUS_TYPE_SESSION,
663 IBUS_SERVICE_PORTAL,
664 G_BUS_NAME_WATCHER_FLAGS_NONE,
665 portal_name_appeared,
666 portal_name_vanished,
667 _bus, NULL);
668 }
669
670
671 if (_bus->priv->connect_async)
672 ibus_bus_connect_async (_bus);
673 else
674 ibus_bus_connect (_bus);
675 }
676 else {
677 object = g_object_ref (G_OBJECT (_bus));
678 }
679
680 return object;
681 }
682
683 static void
ibus_bus_destroy(IBusObject * object)684 ibus_bus_destroy (IBusObject *object)
685 {
686 g_assert (_bus == (IBusBus *)object);
687
688 IBusBus * bus = _bus;
689 _bus = NULL;
690
691 if (bus->priv->monitor) {
692 g_object_unref (bus->priv->monitor);
693 bus->priv->monitor = NULL;
694 }
695
696 if (bus->priv->config) {
697 ibus_proxy_destroy ((IBusProxy *) bus->priv->config);
698 bus->priv->config = NULL;
699 }
700
701 if (bus->priv->connection) {
702 g_signal_handlers_disconnect_by_func (bus->priv->connection,
703 G_CALLBACK (_connection_closed_cb),
704 bus);
705 /* FIXME should use async close function */
706 g_dbus_connection_close_sync (bus->priv->connection, NULL, NULL);
707 g_object_unref (bus->priv->connection);
708 bus->priv->connection = NULL;
709 }
710
711 g_free (bus->priv->unique_name);
712 bus->priv->unique_name = NULL;
713
714 g_free (bus->priv->bus_address);
715 bus->priv->bus_address = NULL;
716
717 g_cancellable_cancel (bus->priv->cancellable);
718 g_object_unref (bus->priv->cancellable);
719 bus->priv->cancellable = NULL;
720
721 if (bus->priv->portal_name_watch_id) {
722 g_bus_unwatch_name (bus->priv->portal_name_watch_id);
723 bus->priv->portal_name_watch_id = 0;
724 }
725
726 IBUS_OBJECT_CLASS (ibus_bus_parent_class)->destroy (object);
727 }
728
729 static gboolean
_async_finish_void(GTask * task,GError ** error)730 _async_finish_void (GTask *task,
731 GError **error)
732 {
733 /* g_task_propagate_error() is not a public API and
734 * g_task_had_error() needs to be called before
735 * g_task_propagate_pointer() clears task->error.
736 */
737 gboolean had_error = g_task_had_error (task);
738 g_task_propagate_pointer (task, error);
739 if (had_error)
740 return FALSE;
741 return TRUE;
742 }
743
744 static gchar *
_async_finish_object_path(GTask * task,GError ** error)745 _async_finish_object_path (GTask *task,
746 GError **error)
747 {
748 gboolean had_error = g_task_had_error (task);
749 GVariant *result = g_task_propagate_pointer (task, error);
750 GVariant *variant = NULL;
751 gchar *path = NULL;
752
753 if (had_error) {
754 g_assert (result == NULL);
755 return NULL;
756 }
757 g_return_val_if_fail (result != NULL, NULL);
758 g_variant_get (result, "(v)", &variant);
759 path = g_variant_dup_string (variant, NULL);
760 g_variant_unref (variant);
761 g_variant_unref (result);
762 return path;
763 }
764
765 static gchar *
_async_finish_string(GTask * task,GError ** error)766 _async_finish_string (GTask *task,
767 GError **error)
768 {
769 gboolean had_error = g_task_had_error (task);
770 GVariant *variant = g_task_propagate_pointer (task, error);
771 gchar *s = NULL;
772
773 if (had_error) {
774 g_assert (variant == NULL);
775 return NULL;
776 }
777 g_return_val_if_fail (variant != NULL, NULL);
778 g_variant_get (variant, "(&s)", &s);
779 g_variant_unref (variant);
780 return s;
781 }
782
783 static gboolean
_async_finish_gboolean(GTask * task,GError ** error)784 _async_finish_gboolean (GTask *task,
785 GError **error)
786 {
787 gboolean had_error = g_task_had_error (task);
788 GVariant *variant = g_task_propagate_pointer (task, error);
789 gboolean retval = FALSE;
790
791 if (had_error) {
792 g_assert (variant == NULL);
793 return FALSE;
794 }
795 g_return_val_if_fail (variant != NULL, FALSE);
796 g_variant_get (variant, "(b)", &retval);
797 g_variant_unref (variant);
798 return retval;
799 }
800
801 static guint
_async_finish_guint(GTask * task,GError ** error)802 _async_finish_guint (GTask *task,
803 GError **error)
804 {
805 gboolean had_error = g_task_had_error (task);
806 GVariant *variant = g_task_propagate_pointer (task, error);
807 static const guint bad_id = 0;
808 guint id = 0;
809
810 if (had_error) {
811 g_assert (variant == NULL);
812 return bad_id;
813 }
814 g_return_val_if_fail (variant != NULL, bad_id);
815 g_variant_get (variant, "(u)", &id);
816 g_variant_unref (variant);
817 return id;
818 }
819
820 IBusBus *
ibus_bus_new(void)821 ibus_bus_new (void)
822 {
823 IBusBus *bus = IBUS_BUS (g_object_new (IBUS_TYPE_BUS,
824 "connect-async", FALSE,
825 "client-only", FALSE,
826 NULL));
827
828 return bus;
829 }
830
831 IBusBus *
ibus_bus_new_async(void)832 ibus_bus_new_async (void)
833 {
834 IBusBus *bus = IBUS_BUS (g_object_new (IBUS_TYPE_BUS,
835 "connect-async", TRUE,
836 "client-only", FALSE,
837 NULL));
838
839 return bus;
840 }
841
842 IBusBus *
ibus_bus_new_async_client(void)843 ibus_bus_new_async_client (void)
844 {
845 IBusBus *bus = IBUS_BUS (g_object_new (IBUS_TYPE_BUS,
846 "connect-async", TRUE,
847 "client-only", TRUE,
848 NULL));
849
850 return bus;
851 }
852
853 gboolean
ibus_bus_is_connected(IBusBus * bus)854 ibus_bus_is_connected (IBusBus *bus)
855 {
856 g_return_val_if_fail (IBUS_IS_BUS (bus), FALSE);
857
858 if (bus->priv->connection == NULL || g_dbus_connection_is_closed (bus->priv->connection))
859 return FALSE;
860
861 return bus->priv->connected;
862 }
863
864 IBusInputContext *
ibus_bus_create_input_context(IBusBus * bus,const gchar * client_name)865 ibus_bus_create_input_context (IBusBus *bus,
866 const gchar *client_name)
867 {
868 g_return_val_if_fail (IBUS_IS_BUS (bus), NULL);
869 g_return_val_if_fail (client_name != NULL, NULL);
870
871 gchar *path;
872 IBusInputContext *context = NULL;
873 GVariant *result;
874 result = ibus_bus_call_sync (bus,
875 IBUS_SERVICE_IBUS,
876 IBUS_PATH_IBUS,
877 IBUS_INTERFACE_IBUS,
878 "CreateInputContext",
879 g_variant_new ("(s)", client_name),
880 G_VARIANT_TYPE ("(o)"));
881
882 if (result != NULL) {
883 GError *error = NULL;
884 g_variant_get (result, "(&o)", &path);
885 context = ibus_input_context_new (path, bus->priv->connection, NULL, &error);
886 g_variant_unref (result);
887 if (context == NULL) {
888 g_warning ("ibus_bus_create_input_context: %s", error->message);
889 g_error_free (error);
890 }
891 }
892
893 return context;
894 }
895
896 static void
_create_input_context_async_step_two_done(GObject * source_object,GAsyncResult * res,GTask * task)897 _create_input_context_async_step_two_done (GObject *source_object,
898 GAsyncResult *res,
899 GTask *task)
900 {
901 GError *error = NULL;
902 IBusInputContext *context =
903 ibus_input_context_new_async_finish (res, &error);
904 if (context == NULL)
905 g_task_return_error (task, error);
906 else
907 g_task_return_pointer (task, context, NULL);
908 g_object_unref (task);
909 }
910
911 static void
_create_input_context_async_step_one_done(GDBusConnection * connection,GAsyncResult * res,GTask * task)912 _create_input_context_async_step_one_done (GDBusConnection *connection,
913 GAsyncResult *res,
914 GTask *task)
915 {
916 GError *error = NULL;
917 GVariant *variant = g_dbus_connection_call_finish (connection, res, &error);
918 const gchar *path = NULL;
919 IBusBus *bus;
920 GCancellable *cancellable;
921
922 if (variant == NULL) {
923 g_task_return_error (task, error);
924 g_object_unref (task);
925 return;
926 }
927
928 if (g_dbus_connection_is_closed (connection)) {
929 /*
930 * The connection is closed, can not continue next steps, so complete
931 * the asynchronous request with error.
932 */
933 g_variant_unref(variant);
934 g_task_return_new_error (task,
935 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Connection is closed.");
936 return;
937 }
938
939 g_variant_get (variant, "(&o)", &path);
940 g_variant_unref(variant);
941
942 bus = (IBusBus *)g_task_get_source_object (task);
943 g_assert (IBUS_IS_BUS (bus));
944
945 cancellable = g_task_get_cancellable (task);
946
947 ibus_input_context_new_async (path,
948 bus->priv->connection,
949 cancellable,
950 (GAsyncReadyCallback)_create_input_context_async_step_two_done,
951 task);
952 }
953
954 void
ibus_bus_create_input_context_async(IBusBus * bus,const gchar * client_name,gint timeout_msec,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)955 ibus_bus_create_input_context_async (IBusBus *bus,
956 const gchar *client_name,
957 gint timeout_msec,
958 GCancellable *cancellable,
959 GAsyncReadyCallback callback,
960 gpointer user_data)
961 {
962 GTask *task;
963
964 g_return_if_fail (IBUS_IS_BUS (bus));
965 g_return_if_fail (client_name != NULL);
966 g_return_if_fail (callback != NULL);
967
968 task = g_task_new (bus, cancellable, callback, user_data);
969 g_task_set_source_tag (task, ibus_bus_create_input_context_async);
970
971 /* do not use ibus_bus_call_async, instead use g_dbus_connection_call
972 * directly, because we need two async steps for create an IBusInputContext.
973 * 1. Call CreateInputContext to request ibus-daemon create a remote IC.
974 * 2. New local IBusInputContext proxy of the remote IC
975 */
976 g_dbus_connection_call (bus->priv->connection,
977 ibus_bus_get_service_name (bus),
978 IBUS_PATH_IBUS,
979 bus->priv->use_portal ? IBUS_INTERFACE_PORTAL : IBUS_INTERFACE_IBUS,
980 "CreateInputContext",
981 g_variant_new ("(s)", client_name),
982 G_VARIANT_TYPE("(o)"),
983 G_DBUS_CALL_FLAGS_NO_AUTO_START,
984 timeout_msec,
985 cancellable,
986 (GAsyncReadyCallback)_create_input_context_async_step_one_done,
987 task);
988 }
989
990 IBusInputContext *
ibus_bus_create_input_context_async_finish(IBusBus * bus,GAsyncResult * res,GError ** error)991 ibus_bus_create_input_context_async_finish (IBusBus *bus,
992 GAsyncResult *res,
993 GError **error)
994 {
995 GTask *task;
996 gboolean had_error;
997 IBusInputContext *context = NULL;
998
999 g_assert (IBUS_IS_BUS (bus));
1000 g_assert (g_task_is_valid (res, bus));
1001
1002 task = G_TASK (res);
1003 g_assert (g_task_get_source_tag (task) ==
1004 ibus_bus_create_input_context_async);
1005 had_error = g_task_had_error (task);
1006 context = g_task_propagate_pointer (task, error);
1007 if (had_error) {
1008 g_assert (context == NULL);
1009 return NULL;
1010 }
1011 g_assert (IBUS_IS_INPUT_CONTEXT (context));
1012 return context;
1013 }
1014
1015 gchar *
ibus_bus_current_input_context(IBusBus * bus)1016 ibus_bus_current_input_context (IBusBus *bus)
1017 {
1018 g_return_val_if_fail (IBUS_IS_BUS (bus), NULL);
1019
1020 gchar *path = NULL;
1021 GVariant *result;
1022 result = ibus_bus_call_sync (bus,
1023 IBUS_SERVICE_IBUS,
1024 IBUS_PATH_IBUS,
1025 "org.freedesktop.DBus.Properties",
1026 "Get",
1027 g_variant_new ("(ss)",
1028 IBUS_INTERFACE_IBUS,
1029 "CurrentInputContext"),
1030 G_VARIANT_TYPE ("(v)"));
1031
1032 if (result != NULL) {
1033 GVariant *variant = NULL;
1034 g_variant_get (result, "(v)", &variant);
1035 path = g_variant_dup_string (variant, NULL);
1036 g_variant_unref (variant);
1037 g_variant_unref (result);
1038 }
1039
1040 return path;
1041 }
1042
1043 void
ibus_bus_current_input_context_async(IBusBus * bus,gint timeout_msec,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1044 ibus_bus_current_input_context_async (IBusBus *bus,
1045 gint timeout_msec,
1046 GCancellable *cancellable,
1047 GAsyncReadyCallback callback,
1048 gpointer user_data)
1049 {
1050 g_return_if_fail (IBUS_IS_BUS (bus));
1051
1052 ibus_bus_call_async (bus,
1053 IBUS_SERVICE_IBUS,
1054 IBUS_PATH_IBUS,
1055 "org.freedesktop.DBus.Properties",
1056 "Get",
1057 g_variant_new ("(ss)",
1058 IBUS_INTERFACE_IBUS,
1059 "CurrentInputContext"),
1060 G_VARIANT_TYPE ("(v)"),
1061 ibus_bus_current_input_context_async,
1062 timeout_msec,
1063 cancellable,
1064 callback,
1065 user_data);
1066 }
1067
1068 gchar *
ibus_bus_current_input_context_async_finish(IBusBus * bus,GAsyncResult * res,GError ** error)1069 ibus_bus_current_input_context_async_finish (IBusBus *bus,
1070 GAsyncResult *res,
1071 GError **error)
1072 {
1073 GTask *task;
1074
1075 g_assert (IBUS_IS_BUS (bus));
1076 g_assert (g_task_is_valid (res, bus));
1077
1078 task = G_TASK (res);
1079 g_assert(g_task_get_source_tag (task) ==
1080 ibus_bus_current_input_context_async);
1081 return _async_finish_object_path (task, error);
1082 }
1083
1084 static void
ibus_bus_watch_dbus_signal(IBusBus * bus)1085 ibus_bus_watch_dbus_signal (IBusBus *bus)
1086 {
1087 g_return_if_fail (bus->priv->connection != NULL);
1088 g_return_if_fail (bus->priv->watch_dbus_signal_id == 0);
1089
1090 /* Subscribe to dbus signals such as NameOwnerChanged. */
1091 bus->priv->watch_dbus_signal_id
1092 = g_dbus_connection_signal_subscribe (bus->priv->connection,
1093 DBUS_SERVICE_DBUS,
1094 DBUS_INTERFACE_DBUS,
1095 "NameOwnerChanged",
1096 DBUS_PATH_DBUS,
1097 NULL /* arg0 */,
1098 (GDBusSignalFlags) 0,
1099 _connection_dbus_signal_cb,
1100 bus,
1101 NULL /* user_data_free_func */);
1102 /* FIXME handle other D-Bus signals if needed */
1103 }
1104
1105 static void
ibus_bus_unwatch_dbus_signal(IBusBus * bus)1106 ibus_bus_unwatch_dbus_signal (IBusBus *bus)
1107 {
1108 g_return_if_fail (bus->priv->watch_dbus_signal_id != 0);
1109 g_dbus_connection_signal_unsubscribe (bus->priv->connection,
1110 bus->priv->watch_dbus_signal_id);
1111 bus->priv->watch_dbus_signal_id = 0;
1112 }
1113
1114 void
ibus_bus_set_watch_dbus_signal(IBusBus * bus,gboolean watch)1115 ibus_bus_set_watch_dbus_signal (IBusBus *bus,
1116 gboolean watch)
1117 {
1118 g_return_if_fail (IBUS_IS_BUS (bus));
1119
1120 if (bus->priv->watch_dbus_signal == watch)
1121 return;
1122
1123 bus->priv->watch_dbus_signal = watch;
1124
1125 if (ibus_bus_is_connected (bus)) {
1126 if (watch) {
1127 ibus_bus_watch_dbus_signal (bus);
1128 }
1129 else {
1130 ibus_bus_unwatch_dbus_signal (bus);
1131 }
1132 }
1133 }
1134
1135 static void
ibus_bus_watch_ibus_signal(IBusBus * bus)1136 ibus_bus_watch_ibus_signal (IBusBus *bus)
1137 {
1138 g_return_if_fail (bus->priv->connection != NULL);
1139 g_return_if_fail (bus->priv->watch_ibus_signal_id == 0);
1140
1141 /* Subscribe to ibus signals such as GlboalEngineChanged. */
1142 bus->priv->watch_ibus_signal_id
1143 = g_dbus_connection_signal_subscribe (bus->priv->connection,
1144 "org.freedesktop.IBus",
1145 IBUS_INTERFACE_IBUS,
1146 "GlobalEngineChanged",
1147 IBUS_PATH_IBUS,
1148 NULL /* arg0 */,
1149 (GDBusSignalFlags) 0,
1150 _connection_ibus_signal_cb,
1151 bus,
1152 NULL /* user_data_free_func */);
1153 /* FIXME handle org.freedesktop.IBus.RegistryChanged signal if needed */
1154 }
1155
1156 static void
ibus_bus_unwatch_ibus_signal(IBusBus * bus)1157 ibus_bus_unwatch_ibus_signal (IBusBus *bus)
1158 {
1159 g_return_if_fail (bus->priv->watch_ibus_signal_id != 0);
1160 g_dbus_connection_signal_unsubscribe (bus->priv->connection,
1161 bus->priv->watch_ibus_signal_id);
1162 bus->priv->watch_ibus_signal_id = 0;
1163 }
1164
1165 void
ibus_bus_set_watch_ibus_signal(IBusBus * bus,gboolean watch)1166 ibus_bus_set_watch_ibus_signal (IBusBus *bus,
1167 gboolean watch)
1168 {
1169 g_return_if_fail (IBUS_IS_BUS (bus));
1170
1171 if (bus->priv->watch_ibus_signal == watch)
1172 return;
1173
1174 bus->priv->watch_ibus_signal = watch;
1175
1176 if (ibus_bus_is_connected (bus)) {
1177 if (watch) {
1178 ibus_bus_watch_ibus_signal (bus);
1179 }
1180 else {
1181 ibus_bus_unwatch_ibus_signal (bus);
1182 }
1183 }
1184 }
1185
1186 const gchar *
ibus_bus_hello(IBusBus * bus)1187 ibus_bus_hello (IBusBus *bus)
1188 {
1189 g_return_val_if_fail (IBUS_IS_BUS (bus), NULL);
1190 g_return_val_if_fail (ibus_bus_is_connected (bus), NULL);
1191
1192 /* gdbus connection will say hello by self. */
1193 if (bus->priv->connection)
1194 return g_dbus_connection_get_unique_name (bus->priv->connection);
1195 return NULL;
1196 }
1197
1198 guint32
ibus_bus_request_name(IBusBus * bus,const gchar * name,guint32 flags)1199 ibus_bus_request_name (IBusBus *bus,
1200 const gchar *name,
1201 guint32 flags)
1202 {
1203 g_return_val_if_fail (IBUS_IS_BUS (bus), 0);
1204 g_return_val_if_fail (name != NULL, 0);
1205
1206 guint32 retval = 0;
1207 GVariant *result;
1208 result = ibus_bus_call_sync (bus,
1209 DBUS_SERVICE_DBUS,
1210 DBUS_PATH_DBUS,
1211 DBUS_INTERFACE_DBUS,
1212 "RequestName",
1213 g_variant_new ("(su)", name, flags),
1214 G_VARIANT_TYPE ("(u)"));
1215
1216 if (result) {
1217 g_variant_get (result, "(u)", &retval);
1218 g_variant_unref (result);
1219 }
1220
1221 return retval;
1222 }
1223
1224 void
ibus_bus_request_name_async(IBusBus * bus,const gchar * name,guint flags,gint timeout_msec,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1225 ibus_bus_request_name_async (IBusBus *bus,
1226 const gchar *name,
1227 guint flags,
1228 gint timeout_msec,
1229 GCancellable *cancellable,
1230 GAsyncReadyCallback callback,
1231 gpointer user_data)
1232 {
1233 g_return_if_fail (IBUS_IS_BUS (bus));
1234 g_return_if_fail (name != NULL);
1235
1236 ibus_bus_call_async (bus,
1237 DBUS_SERVICE_DBUS,
1238 DBUS_PATH_DBUS,
1239 DBUS_INTERFACE_DBUS,
1240 "RequestName",
1241 g_variant_new ("(su)", name, flags),
1242 G_VARIANT_TYPE ("(u)"),
1243 ibus_bus_request_name_async,
1244 timeout_msec,
1245 cancellable,
1246 callback,
1247 user_data);
1248 }
1249
1250 guint
ibus_bus_request_name_async_finish(IBusBus * bus,GAsyncResult * res,GError ** error)1251 ibus_bus_request_name_async_finish (IBusBus *bus,
1252 GAsyncResult *res,
1253 GError **error)
1254 {
1255 GTask *task;
1256
1257 g_assert (IBUS_IS_BUS (bus));
1258 g_assert (g_task_is_valid (res, bus));
1259
1260 task = G_TASK (res);
1261 g_assert(g_task_get_source_tag (task) == ibus_bus_request_name_async);
1262 return _async_finish_guint (task, error);
1263 }
1264
1265 guint
ibus_bus_release_name(IBusBus * bus,const gchar * name)1266 ibus_bus_release_name (IBusBus *bus,
1267 const gchar *name)
1268 {
1269 g_return_val_if_fail (IBUS_IS_BUS (bus), 0);
1270 g_return_val_if_fail (name != NULL, 0);
1271
1272 guint retval = 0;
1273 GVariant *result;
1274 result = ibus_bus_call_sync (bus,
1275 DBUS_SERVICE_DBUS,
1276 DBUS_PATH_DBUS,
1277 DBUS_INTERFACE_DBUS,
1278 "ReleaseName",
1279 g_variant_new ("(s)", name),
1280 G_VARIANT_TYPE ("(u)"));
1281
1282 if (result) {
1283 g_variant_get (result, "(u)", &retval);
1284 g_variant_unref (result);
1285 }
1286
1287 return retval;
1288 }
1289
1290 void
ibus_bus_release_name_async(IBusBus * bus,const gchar * name,gint timeout_msec,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1291 ibus_bus_release_name_async (IBusBus *bus,
1292 const gchar *name,
1293 gint timeout_msec,
1294 GCancellable *cancellable,
1295 GAsyncReadyCallback callback,
1296 gpointer user_data)
1297 {
1298 g_return_if_fail (IBUS_IS_BUS (bus));
1299 g_return_if_fail (name != NULL);
1300
1301 ibus_bus_call_async (bus,
1302 DBUS_SERVICE_DBUS,
1303 DBUS_PATH_DBUS,
1304 DBUS_INTERFACE_DBUS,
1305 "ReleaseName",
1306 g_variant_new ("(s)", name),
1307 G_VARIANT_TYPE ("(u)"),
1308 ibus_bus_release_name_async,
1309 timeout_msec,
1310 cancellable,
1311 callback,
1312 user_data);
1313 }
1314
1315 guint
ibus_bus_release_name_async_finish(IBusBus * bus,GAsyncResult * res,GError ** error)1316 ibus_bus_release_name_async_finish (IBusBus *bus,
1317 GAsyncResult *res,
1318 GError **error)
1319 {
1320 GTask *task;
1321
1322 g_assert (IBUS_IS_BUS (bus));
1323 g_assert (g_task_is_valid (res, bus));
1324
1325 task = G_TASK (res);
1326 g_assert(g_task_get_source_tag (task) == ibus_bus_release_name_async);
1327 return _async_finish_guint (task, error);
1328 }
1329
1330 GList *
ibus_bus_list_queued_owners(IBusBus * bus,const gchar * name)1331 ibus_bus_list_queued_owners (IBusBus *bus,
1332 const gchar *name)
1333 {
1334 GList *retval = NULL;
1335 GVariant *result;
1336
1337 g_return_val_if_fail (IBUS_IS_BUS (bus), NULL);
1338 g_return_val_if_fail (name != NULL, NULL);
1339
1340 result = ibus_bus_call_sync (bus,
1341 DBUS_SERVICE_DBUS,
1342 DBUS_PATH_DBUS,
1343 DBUS_INTERFACE_DBUS,
1344 "ListQueuedOwners",
1345 g_variant_new ("(s)", name),
1346 G_VARIANT_TYPE ("(as)"));
1347
1348 if (result) {
1349 GVariantIter *iter = NULL;
1350 const gchar *name = NULL;
1351 g_variant_get (result, "(as)", &iter);
1352 while (g_variant_iter_loop (iter, "&s", &name)) {
1353 if (name == NULL) {
1354 continue;
1355 }
1356 retval = g_list_append (retval, g_strdup (name));
1357 }
1358 g_variant_iter_free (iter);
1359 g_variant_unref (result);
1360 }
1361
1362 return retval;
1363 }
1364
1365 gboolean
ibus_bus_name_has_owner(IBusBus * bus,const gchar * name)1366 ibus_bus_name_has_owner (IBusBus *bus,
1367 const gchar *name)
1368 {
1369 g_return_val_if_fail (IBUS_IS_BUS (bus), FALSE);
1370 g_return_val_if_fail (name != NULL, FALSE);
1371
1372 gboolean retval = FALSE;
1373 GVariant *result;
1374 result = ibus_bus_call_sync (bus,
1375 DBUS_SERVICE_DBUS,
1376 DBUS_PATH_DBUS,
1377 DBUS_INTERFACE_DBUS,
1378 "NameHasOwner",
1379 g_variant_new ("(s)", name),
1380 G_VARIANT_TYPE ("(b)"));
1381
1382 if (result) {
1383 g_variant_get (result, "(b)", &retval);
1384 g_variant_unref (result);
1385 }
1386
1387 return retval;
1388 }
1389
1390 void
ibus_bus_name_has_owner_async(IBusBus * bus,const gchar * name,gint timeout_msec,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1391 ibus_bus_name_has_owner_async (IBusBus *bus,
1392 const gchar *name,
1393 gint timeout_msec,
1394 GCancellable *cancellable,
1395 GAsyncReadyCallback callback,
1396 gpointer user_data)
1397 {
1398 g_return_if_fail (IBUS_IS_BUS (bus));
1399 g_return_if_fail (name != NULL);
1400
1401 ibus_bus_call_async (bus,
1402 DBUS_SERVICE_DBUS,
1403 DBUS_PATH_DBUS,
1404 DBUS_INTERFACE_DBUS,
1405 "NameHasOwner",
1406 g_variant_new ("(s)", name),
1407 G_VARIANT_TYPE ("(b)"),
1408 ibus_bus_name_has_owner_async,
1409 timeout_msec,
1410 cancellable,
1411 callback,
1412 user_data);
1413 }
1414
1415 gboolean
ibus_bus_name_has_owner_async_finish(IBusBus * bus,GAsyncResult * res,GError ** error)1416 ibus_bus_name_has_owner_async_finish (IBusBus *bus,
1417 GAsyncResult *res,
1418 GError **error)
1419 {
1420 GTask *task;
1421
1422 g_assert (IBUS_IS_BUS (bus));
1423 g_assert (g_task_is_valid (res, bus));
1424
1425 task = G_TASK (res);
1426 g_assert(g_task_get_source_tag (task) == ibus_bus_name_has_owner_async);
1427 return _async_finish_gboolean (task, error);
1428 }
1429
1430 GList *
ibus_bus_list_names(IBusBus * bus)1431 ibus_bus_list_names (IBusBus *bus)
1432 {
1433 g_return_val_if_fail (IBUS_IS_BUS (bus), NULL);
1434 return NULL;
1435 }
1436
1437 gboolean
ibus_bus_add_match(IBusBus * bus,const gchar * rule)1438 ibus_bus_add_match (IBusBus *bus,
1439 const gchar *rule)
1440 {
1441 g_return_val_if_fail (IBUS_IS_BUS (bus), FALSE);
1442 g_return_val_if_fail (rule != NULL, FALSE);
1443
1444 GVariant *result;
1445 result = ibus_bus_call_sync (bus,
1446 DBUS_SERVICE_DBUS,
1447 DBUS_PATH_DBUS,
1448 DBUS_INTERFACE_DBUS,
1449 "AddMatch",
1450 g_variant_new ("(s)", rule),
1451 NULL);
1452
1453 if (result) {
1454 g_variant_unref (result);
1455 return TRUE;
1456 }
1457 return FALSE;
1458 }
1459
1460 void
ibus_bus_add_match_async(IBusBus * bus,const gchar * rule,gint timeout_msec,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1461 ibus_bus_add_match_async (IBusBus *bus,
1462 const gchar *rule,
1463 gint timeout_msec,
1464 GCancellable *cancellable,
1465 GAsyncReadyCallback callback,
1466 gpointer user_data)
1467 {
1468 g_return_if_fail (IBUS_IS_BUS (bus));
1469 g_return_if_fail (rule != NULL);
1470
1471 ibus_bus_call_async (bus,
1472 DBUS_SERVICE_DBUS,
1473 DBUS_PATH_DBUS,
1474 DBUS_INTERFACE_DBUS,
1475 "AddMatch",
1476 g_variant_new ("(s)", rule),
1477 NULL,
1478 ibus_bus_add_match_async,
1479 timeout_msec,
1480 cancellable,
1481 callback,
1482 user_data);
1483 }
1484
1485 gboolean
ibus_bus_add_match_async_finish(IBusBus * bus,GAsyncResult * res,GError ** error)1486 ibus_bus_add_match_async_finish (IBusBus *bus,
1487 GAsyncResult *res,
1488 GError **error)
1489 {
1490 GTask *task;
1491
1492 g_assert (IBUS_IS_BUS (bus));
1493 g_assert (g_task_is_valid (res, bus));
1494
1495 task = G_TASK (res);
1496 g_assert(g_task_get_source_tag (task) == ibus_bus_add_match_async);
1497 return _async_finish_void (task, error);
1498 }
1499
1500 gboolean
ibus_bus_remove_match(IBusBus * bus,const gchar * rule)1501 ibus_bus_remove_match (IBusBus *bus,
1502 const gchar *rule)
1503 {
1504 g_return_val_if_fail (IBUS_IS_BUS (bus), FALSE);
1505 g_return_val_if_fail (rule != NULL, FALSE);
1506
1507 GVariant *result;
1508 result = ibus_bus_call_sync (bus,
1509 DBUS_SERVICE_DBUS,
1510 DBUS_PATH_DBUS,
1511 DBUS_INTERFACE_DBUS,
1512 "RemoveMatch",
1513 g_variant_new ("(s)", rule),
1514 NULL);
1515
1516 if (result) {
1517 g_variant_unref (result);
1518 return TRUE;
1519 }
1520 return FALSE;
1521 }
1522
1523 void
ibus_bus_remove_match_async(IBusBus * bus,const gchar * rule,gint timeout_msec,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1524 ibus_bus_remove_match_async (IBusBus *bus,
1525 const gchar *rule,
1526 gint timeout_msec,
1527 GCancellable *cancellable,
1528 GAsyncReadyCallback callback,
1529 gpointer user_data)
1530 {
1531 g_return_if_fail (IBUS_IS_BUS (bus));
1532 g_return_if_fail (rule != NULL);
1533
1534 ibus_bus_call_async (bus,
1535 DBUS_SERVICE_DBUS,
1536 DBUS_PATH_DBUS,
1537 DBUS_INTERFACE_DBUS,
1538 "RemoveMatch",
1539 g_variant_new ("(s)", rule),
1540 NULL,
1541 ibus_bus_remove_match_async,
1542 timeout_msec,
1543 cancellable,
1544 callback,
1545 user_data);
1546 }
1547
1548 gboolean
ibus_bus_remove_match_async_finish(IBusBus * bus,GAsyncResult * res,GError ** error)1549 ibus_bus_remove_match_async_finish (IBusBus *bus,
1550 GAsyncResult *res,
1551 GError **error)
1552 {
1553 GTask *task;
1554
1555 g_assert (IBUS_IS_BUS (bus));
1556 g_assert (g_task_is_valid (res, bus));
1557
1558 task = G_TASK (res);
1559 g_assert(g_task_get_source_tag (task) == ibus_bus_remove_match_async);
1560 return _async_finish_void (task, error);
1561 }
1562
1563 gchar *
ibus_bus_get_name_owner(IBusBus * bus,const gchar * name)1564 ibus_bus_get_name_owner (IBusBus *bus,
1565 const gchar *name)
1566 {
1567 g_return_val_if_fail (IBUS_IS_BUS (bus), NULL);
1568 g_return_val_if_fail (name != NULL, NULL);
1569
1570 gchar *retval = NULL;
1571 GVariant *result;
1572 result = ibus_bus_call_sync (bus,
1573 DBUS_SERVICE_DBUS,
1574 DBUS_PATH_DBUS,
1575 DBUS_INTERFACE_DBUS,
1576 "GetNameOwner",
1577 g_variant_new ("(s)", name),
1578 G_VARIANT_TYPE ("(s)"));
1579
1580 if (result) {
1581 g_variant_get (result, "(s)", &retval);
1582 g_variant_unref (result);
1583 }
1584
1585 return retval;
1586 }
1587
1588 void
ibus_bus_get_name_owner_async(IBusBus * bus,const gchar * name,gint timeout_msec,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1589 ibus_bus_get_name_owner_async (IBusBus *bus,
1590 const gchar *name,
1591 gint timeout_msec,
1592 GCancellable *cancellable,
1593 GAsyncReadyCallback callback,
1594 gpointer user_data)
1595 {
1596 g_return_if_fail (IBUS_IS_BUS (bus));
1597 g_return_if_fail (name != NULL);
1598
1599 ibus_bus_call_async (bus,
1600 DBUS_SERVICE_DBUS,
1601 DBUS_PATH_DBUS,
1602 DBUS_INTERFACE_DBUS,
1603 "GetNameOwner",
1604 g_variant_new ("(s)", name),
1605 G_VARIANT_TYPE ("(s)"),
1606 ibus_bus_get_name_owner_async,
1607 timeout_msec,
1608 cancellable,
1609 callback,
1610 user_data);
1611 }
1612
1613 gchar *
ibus_bus_get_name_owner_async_finish(IBusBus * bus,GAsyncResult * res,GError ** error)1614 ibus_bus_get_name_owner_async_finish (IBusBus *bus,
1615 GAsyncResult *res,
1616 GError **error)
1617 {
1618 GTask *task;
1619
1620 g_assert (IBUS_IS_BUS (bus));
1621 g_assert (g_task_is_valid (res, bus));
1622
1623 task = G_TASK (res);
1624 g_assert(g_task_get_source_tag (task) == ibus_bus_get_name_owner_async);
1625 return g_strdup (_async_finish_string (task, error));
1626 }
1627
1628 GDBusConnection *
ibus_bus_get_connection(IBusBus * bus)1629 ibus_bus_get_connection (IBusBus *bus)
1630 {
1631 g_return_val_if_fail (IBUS_IS_BUS (bus), NULL);
1632
1633 return bus->priv->connection;
1634 }
1635
1636 const gchar *
ibus_bus_get_service_name(IBusBus * bus)1637 ibus_bus_get_service_name (IBusBus *bus)
1638 {
1639 if (bus->priv->use_portal)
1640 return IBUS_SERVICE_PORTAL;
1641 return IBUS_SERVICE_IBUS;
1642 }
1643
1644 gboolean
ibus_bus_exit(IBusBus * bus,gboolean restart)1645 ibus_bus_exit (IBusBus *bus,
1646 gboolean restart)
1647 {
1648 g_return_val_if_fail (IBUS_IS_BUS (bus), FALSE);
1649
1650 GVariant *result;
1651 result = ibus_bus_call_sync (bus,
1652 IBUS_SERVICE_IBUS,
1653 IBUS_PATH_IBUS,
1654 IBUS_INTERFACE_IBUS,
1655 "Exit",
1656 g_variant_new ("(b)", restart),
1657 NULL);
1658
1659 ibus_bus_close_connection (bus);
1660
1661 if (result) {
1662 g_variant_unref (result);
1663 return TRUE;
1664 }
1665 return FALSE;
1666 }
1667
1668 void
ibus_bus_exit_async(IBusBus * bus,gboolean restart,gint timeout_msec,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1669 ibus_bus_exit_async (IBusBus *bus,
1670 gboolean restart,
1671 gint timeout_msec,
1672 GCancellable *cancellable,
1673 GAsyncReadyCallback callback,
1674 gpointer user_data)
1675 {
1676 g_return_if_fail (IBUS_IS_BUS (bus));
1677
1678 ibus_bus_call_async (bus,
1679 IBUS_SERVICE_IBUS,
1680 IBUS_PATH_IBUS,
1681 IBUS_INTERFACE_IBUS,
1682 "Exit",
1683 g_variant_new ("(b)", restart),
1684 NULL,
1685 ibus_bus_exit_async,
1686 timeout_msec,
1687 cancellable,
1688 callback,
1689 user_data);
1690 }
1691
1692 gboolean
ibus_bus_exit_async_finish(IBusBus * bus,GAsyncResult * res,GError ** error)1693 ibus_bus_exit_async_finish (IBusBus *bus,
1694 GAsyncResult *res,
1695 GError **error)
1696 {
1697 GTask *task;
1698
1699 g_assert (IBUS_IS_BUS (bus));
1700 g_assert (g_task_is_valid (res, bus));
1701
1702 task = G_TASK (res);
1703 g_assert (g_task_get_source_tag (task) == ibus_bus_exit_async);
1704 return _async_finish_void (task, error);
1705 }
1706
1707 gboolean
ibus_bus_register_component(IBusBus * bus,IBusComponent * component)1708 ibus_bus_register_component (IBusBus *bus,
1709 IBusComponent *component)
1710 {
1711 g_return_val_if_fail (IBUS_IS_BUS (bus), FALSE);
1712 g_return_val_if_fail (IBUS_IS_COMPONENT (component), FALSE);
1713
1714 GVariant *variant = ibus_serializable_serialize ((IBusSerializable *)component);
1715 GVariant *result = ibus_bus_call_sync (bus,
1716 IBUS_SERVICE_IBUS,
1717 IBUS_PATH_IBUS,
1718 IBUS_INTERFACE_IBUS,
1719 "RegisterComponent",
1720 g_variant_new ("(v)", variant),
1721 NULL);
1722 if (result) {
1723 g_variant_unref (result);
1724 return TRUE;
1725 }
1726 return FALSE;
1727 }
1728
1729 void
ibus_bus_register_component_async(IBusBus * bus,IBusComponent * component,gint timeout_msec,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1730 ibus_bus_register_component_async (IBusBus *bus,
1731 IBusComponent *component,
1732 gint timeout_msec,
1733 GCancellable *cancellable,
1734 GAsyncReadyCallback callback,
1735 gpointer user_data)
1736 {
1737 g_return_if_fail (IBUS_IS_BUS (bus));
1738 g_return_if_fail (IBUS_IS_COMPONENT (component));
1739
1740 GVariant *variant = ibus_serializable_serialize ((IBusSerializable *)component);
1741 ibus_bus_call_async (bus,
1742 IBUS_SERVICE_IBUS,
1743 IBUS_PATH_IBUS,
1744 IBUS_INTERFACE_IBUS,
1745 "RegisterComponent",
1746 g_variant_new ("(v)", variant),
1747 NULL,
1748 ibus_bus_register_component_async,
1749 timeout_msec,
1750 cancellable,
1751 callback,
1752 user_data);
1753 }
1754
1755 gboolean
ibus_bus_register_component_async_finish(IBusBus * bus,GAsyncResult * res,GError ** error)1756 ibus_bus_register_component_async_finish (IBusBus *bus,
1757 GAsyncResult *res,
1758 GError **error)
1759 {
1760 GTask *task;
1761
1762 g_assert (IBUS_IS_BUS (bus));
1763 g_assert (g_task_is_valid (res, bus));
1764
1765 task = G_TASK (res);
1766 g_assert (
1767 g_task_get_source_tag (task) == ibus_bus_register_component_async);
1768 return _async_finish_void (task, error);
1769 }
1770
1771 static GList *
ibus_bus_do_list_engines(IBusBus * bus,gboolean active_engines_only)1772 ibus_bus_do_list_engines (IBusBus *bus, gboolean active_engines_only)
1773 {
1774 g_return_val_if_fail (IBUS_IS_BUS (bus), NULL);
1775
1776 GList *retval = NULL;
1777 GVariant *result;
1778 const gchar *property =
1779 active_engines_only ? "ActiveEngines" : "Engines";
1780 result = ibus_bus_call_sync (bus,
1781 IBUS_SERVICE_IBUS,
1782 IBUS_PATH_IBUS,
1783 "org.freedesktop.DBus.Properties",
1784 "Get",
1785 g_variant_new ("(ss)",
1786 IBUS_INTERFACE_IBUS,
1787 property),
1788 G_VARIANT_TYPE ("(v)"));
1789
1790 if (result) {
1791 GVariant *variant = NULL;
1792 GVariantIter *iter = NULL;
1793
1794 g_variant_get (result, "(v)", &variant);
1795 iter = g_variant_iter_new (variant);
1796 GVariant *var;
1797 while (g_variant_iter_loop (iter, "v", &var)) {
1798 IBusSerializable *serializable = ibus_serializable_deserialize (var);
1799 g_object_ref_sink (serializable);
1800 retval = g_list_append (retval, serializable);
1801 }
1802 g_variant_iter_free (iter);
1803 g_variant_unref (variant);
1804 g_variant_unref (result);
1805 }
1806
1807 return retval;
1808 }
1809
1810 GList *
ibus_bus_list_engines(IBusBus * bus)1811 ibus_bus_list_engines (IBusBus *bus)
1812 {
1813 return ibus_bus_do_list_engines (bus, FALSE);
1814 }
1815
1816 void
ibus_bus_list_engines_async(IBusBus * bus,gint timeout_msec,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1817 ibus_bus_list_engines_async (IBusBus *bus,
1818 gint timeout_msec,
1819 GCancellable *cancellable,
1820 GAsyncReadyCallback callback,
1821 gpointer user_data)
1822 {
1823 g_return_if_fail (IBUS_IS_BUS (bus));
1824
1825 ibus_bus_call_async (bus,
1826 IBUS_SERVICE_IBUS,
1827 IBUS_PATH_IBUS,
1828 "org.freedesktop.DBus.Properties",
1829 "Get",
1830 g_variant_new ("(ss)",
1831 IBUS_INTERFACE_IBUS,
1832 "Engines"),
1833 G_VARIANT_TYPE ("(v)"),
1834 ibus_bus_list_engines_async,
1835 timeout_msec,
1836 cancellable,
1837 callback,
1838 user_data);
1839 }
1840
1841 GList *
ibus_bus_list_engines_async_finish(IBusBus * bus,GAsyncResult * res,GError ** error)1842 ibus_bus_list_engines_async_finish (IBusBus *bus,
1843 GAsyncResult *res,
1844 GError **error)
1845 {
1846 GTask *task;
1847 gboolean had_error;
1848 GVariant *result = NULL;
1849 GVariant *variant = NULL;
1850 GList *retval = NULL;
1851 GVariantIter *iter = NULL;
1852 GVariant *var;
1853
1854 g_assert (g_task_is_valid (res, bus));
1855
1856 task = G_TASK (res);
1857 had_error = g_task_had_error (task);
1858 result = g_task_propagate_pointer (task, error);
1859 if (had_error) {
1860 g_assert (result == NULL);
1861 return NULL;
1862 }
1863 g_return_val_if_fail (result != NULL, NULL);
1864
1865 g_variant_get (result, "(v)", &variant);
1866 iter = g_variant_iter_new (variant);
1867 while (g_variant_iter_loop (iter, "v", &var)) {
1868 IBusSerializable *serializable = ibus_serializable_deserialize (var);
1869 g_object_ref_sink (serializable);
1870 retval = g_list_append (retval, serializable);
1871 }
1872 g_variant_iter_free (iter);
1873 g_variant_unref (variant);
1874 g_variant_unref (result);
1875 return retval;
1876 }
1877
1878 #ifndef IBUS_DISABLE_DEPRECATED
1879 GList *
ibus_bus_list_active_engines(IBusBus * bus)1880 ibus_bus_list_active_engines (IBusBus *bus)
1881 {
1882 return ibus_bus_do_list_engines (bus, TRUE);
1883 }
1884
1885 void
ibus_bus_list_active_engines_async(IBusBus * bus,gint timeout_msec,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1886 ibus_bus_list_active_engines_async (IBusBus *bus,
1887 gint timeout_msec,
1888 GCancellable *cancellable,
1889 GAsyncReadyCallback callback,
1890 gpointer user_data)
1891 {
1892 g_return_if_fail (IBUS_IS_BUS (bus));
1893
1894 ibus_bus_call_async (bus,
1895 IBUS_SERVICE_IBUS,
1896 IBUS_PATH_IBUS,
1897 "org.freedesktop.DBus.Properties",
1898 "Get",
1899 g_variant_new ("(ss)",
1900 IBUS_INTERFACE_IBUS,
1901 "ActiveEngines"),
1902 G_VARIANT_TYPE ("(v)"),
1903 ibus_bus_list_active_engines_async,
1904 timeout_msec,
1905 cancellable,
1906 callback,
1907 user_data);
1908 }
1909
1910 GList *
ibus_bus_list_active_engines_async_finish(IBusBus * bus,GAsyncResult * res,GError ** error)1911 ibus_bus_list_active_engines_async_finish (IBusBus *bus,
1912 GAsyncResult *res,
1913 GError **error)
1914 {
1915 return ibus_bus_list_engines_async_finish (bus, res, error);
1916 }
1917 #endif /* IBUS_DISABLE_DEPRECATED */
1918
1919 IBusEngineDesc **
ibus_bus_get_engines_by_names(IBusBus * bus,const gchar * const * names)1920 ibus_bus_get_engines_by_names (IBusBus *bus,
1921 const gchar * const *names)
1922 {
1923 g_return_val_if_fail (IBUS_IS_BUS (bus), NULL);
1924
1925 GVariant *result;
1926 result = ibus_bus_call_sync (bus,
1927 IBUS_SERVICE_IBUS,
1928 IBUS_PATH_IBUS,
1929 IBUS_INTERFACE_IBUS,
1930 "GetEnginesByNames",
1931 g_variant_new("(^as)", names),
1932 G_VARIANT_TYPE ("(av)"));
1933 if (result == NULL)
1934 return NULL;
1935
1936 GArray *array = g_array_new (TRUE, TRUE, sizeof (IBusEngineDesc *));
1937 GVariantIter *iter = NULL;
1938 g_variant_get (result, "(av)", &iter);
1939 GVariant *var;
1940 while (g_variant_iter_loop (iter, "v", &var)) {
1941 IBusEngineDesc *desc = (IBusEngineDesc *) ibus_serializable_deserialize (var);
1942 g_object_ref_sink (desc);
1943 g_array_append_val (array, desc);
1944 }
1945 g_variant_iter_free (iter);
1946 g_variant_unref (result);
1947
1948 return (IBusEngineDesc **)g_array_free (array, FALSE);
1949 }
1950
1951 static void
_config_destroy_cb(IBusConfig * config,IBusBus * bus)1952 _config_destroy_cb (IBusConfig *config,
1953 IBusBus *bus)
1954 {
1955 IBusBusPrivate *priv;
1956 priv = IBUS_BUS_GET_PRIVATE (bus);
1957
1958 g_assert (priv->config == config);
1959
1960 g_object_unref (config);
1961 priv->config = NULL;
1962 }
1963
1964 IBusConfig *
ibus_bus_get_config(IBusBus * bus)1965 ibus_bus_get_config (IBusBus *bus)
1966 {
1967 g_assert (IBUS_IS_BUS (bus));
1968 g_return_val_if_fail (ibus_bus_is_connected (bus), NULL);
1969
1970 IBusBusPrivate *priv;
1971 priv = IBUS_BUS_GET_PRIVATE (bus);
1972
1973 if (priv->config == NULL && priv->connection) {
1974 priv->config = ibus_config_new (priv->connection, NULL, NULL);
1975 if (priv->config) {
1976 g_signal_connect (priv->config, "destroy", G_CALLBACK (_config_destroy_cb), bus);
1977 }
1978 }
1979
1980 return priv->config;
1981 }
1982
1983 #ifndef IBUS_DISABLE_DEPRECATED
1984 gboolean
ibus_bus_get_use_sys_layout(IBusBus * bus)1985 ibus_bus_get_use_sys_layout (IBusBus *bus)
1986 {
1987 g_return_val_if_fail (IBUS_IS_BUS (bus), FALSE);
1988
1989 gboolean retval = FALSE;
1990 GVariant *result;
1991 result = ibus_bus_call_sync (bus,
1992 IBUS_SERVICE_IBUS,
1993 IBUS_PATH_IBUS,
1994 IBUS_INTERFACE_IBUS,
1995 "GetUseSysLayout",
1996 NULL,
1997 G_VARIANT_TYPE ("(b)"));
1998
1999 if (result) {
2000 g_variant_get (result, "(b)", &retval);
2001 g_variant_unref (result);
2002 }
2003
2004 return retval;
2005 }
2006
2007 void
ibus_bus_get_use_sys_layout_async(IBusBus * bus,gint timeout_msec,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)2008 ibus_bus_get_use_sys_layout_async (IBusBus *bus,
2009 gint timeout_msec,
2010 GCancellable *cancellable,
2011 GAsyncReadyCallback callback,
2012 gpointer user_data)
2013 {
2014 g_return_if_fail (IBUS_IS_BUS (bus));
2015
2016 ibus_bus_call_async (bus,
2017 IBUS_SERVICE_IBUS,
2018 IBUS_PATH_IBUS,
2019 IBUS_INTERFACE_IBUS,
2020 "GetUseSysLayout",
2021 NULL,
2022 G_VARIANT_TYPE ("(b)"),
2023 ibus_bus_get_use_sys_layout_async,
2024 timeout_msec,
2025 cancellable,
2026 callback,
2027 user_data);
2028 }
2029
2030 gboolean
ibus_bus_get_use_sys_layout_async_finish(IBusBus * bus,GAsyncResult * res,GError ** error)2031 ibus_bus_get_use_sys_layout_async_finish (IBusBus *bus,
2032 GAsyncResult *res,
2033 GError **error)
2034 {
2035 GTask *task;
2036
2037 g_assert (IBUS_IS_BUS (bus));
2038 g_assert (g_task_is_valid (res, bus));
2039
2040 task = G_TASK (res);
2041 g_assert(g_task_get_source_tag (task) == ibus_bus_get_use_sys_layout_async);
2042 return _async_finish_gboolean (task, error);
2043 }
2044
2045 gboolean
ibus_bus_get_use_global_engine(IBusBus * bus)2046 ibus_bus_get_use_global_engine (IBusBus *bus)
2047 {
2048 g_return_val_if_fail (IBUS_IS_BUS (bus), FALSE);
2049
2050 gboolean retval = FALSE;
2051 GVariant *result;
2052 result = ibus_bus_call_sync (bus,
2053 IBUS_SERVICE_IBUS,
2054 IBUS_PATH_IBUS,
2055 IBUS_INTERFACE_IBUS,
2056 "GetUseGlobalEngine",
2057 NULL,
2058 G_VARIANT_TYPE ("(b)"));
2059
2060 if (result) {
2061 g_variant_get (result, "(b)", &retval);
2062 g_variant_unref (result);
2063 }
2064
2065 return retval;
2066 }
2067
2068 void
ibus_bus_get_use_global_engine_async(IBusBus * bus,gint timeout_msec,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)2069 ibus_bus_get_use_global_engine_async (IBusBus *bus,
2070 gint timeout_msec,
2071 GCancellable *cancellable,
2072 GAsyncReadyCallback callback,
2073 gpointer user_data)
2074 {
2075 g_return_if_fail (IBUS_IS_BUS (bus));
2076
2077 ibus_bus_call_async (bus,
2078 IBUS_SERVICE_IBUS,
2079 IBUS_PATH_IBUS,
2080 IBUS_INTERFACE_IBUS,
2081 "GetUseGlobalEngine",
2082 NULL,
2083 G_VARIANT_TYPE ("(b)"),
2084 ibus_bus_get_use_global_engine_async,
2085 timeout_msec,
2086 cancellable,
2087 callback,
2088 user_data);
2089 }
2090
2091 gboolean
ibus_bus_get_use_global_engine_async_finish(IBusBus * bus,GAsyncResult * res,GError ** error)2092 ibus_bus_get_use_global_engine_async_finish (IBusBus *bus,
2093 GAsyncResult *res,
2094 GError **error)
2095 {
2096 GTask *task;
2097
2098 g_assert (IBUS_IS_BUS (bus));
2099 g_assert (g_task_is_valid (res, bus));
2100
2101 task = G_TASK (res);
2102 g_assert(g_task_get_source_tag (task) ==
2103 ibus_bus_get_use_global_engine_async);
2104 return _async_finish_gboolean (task, error);
2105 }
2106
2107 gboolean
ibus_bus_is_global_engine_enabled(IBusBus * bus)2108 ibus_bus_is_global_engine_enabled (IBusBus *bus)
2109 {
2110 g_return_val_if_fail (IBUS_IS_BUS (bus), FALSE);
2111
2112 gboolean retval = FALSE;
2113 GVariant *result;
2114 result = ibus_bus_call_sync (bus,
2115 IBUS_SERVICE_IBUS,
2116 IBUS_PATH_IBUS,
2117 IBUS_INTERFACE_IBUS,
2118 "IsGlobalEngineEnabled",
2119 NULL,
2120 G_VARIANT_TYPE ("(b)"));
2121
2122 if (result) {
2123 g_variant_get (result, "(b)", &retval);
2124 g_variant_unref (result);
2125 }
2126
2127 return retval;
2128 }
2129
ibus_bus_is_global_engine_enabled_async(IBusBus * bus,gint timeout_msec,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)2130 void ibus_bus_is_global_engine_enabled_async (IBusBus *bus,
2131 gint timeout_msec,
2132 GCancellable *cancellable,
2133 GAsyncReadyCallback callback,
2134 gpointer user_data)
2135 {
2136 g_return_if_fail (IBUS_IS_BUS (bus));
2137
2138 ibus_bus_call_async (bus,
2139 IBUS_SERVICE_IBUS,
2140 IBUS_PATH_IBUS,
2141 IBUS_INTERFACE_IBUS,
2142 "IsGlobalEngineEnabled",
2143 NULL,
2144 G_VARIANT_TYPE ("(b)"),
2145 ibus_bus_is_global_engine_enabled_async,
2146 timeout_msec,
2147 cancellable,
2148 callback,
2149 user_data);
2150 }
2151
ibus_bus_is_global_engine_enabled_async_finish(IBusBus * bus,GAsyncResult * res,GError ** error)2152 gboolean ibus_bus_is_global_engine_enabled_async_finish (IBusBus *bus,
2153 GAsyncResult *res,
2154 GError **error)
2155 {
2156 GTask *task;
2157
2158 g_assert (IBUS_IS_BUS (bus));
2159 g_assert (g_task_is_valid (res, bus));
2160
2161 task = G_TASK (res);
2162 g_assert(g_task_get_source_tag (task) ==
2163 ibus_bus_is_global_engine_enabled_async);
2164 return _async_finish_gboolean (task, error);
2165 }
2166 #endif /* IBUS_DISABLE_DEPRECATED */
2167
2168 IBusEngineDesc *
ibus_bus_get_global_engine(IBusBus * bus)2169 ibus_bus_get_global_engine (IBusBus *bus)
2170 {
2171 g_return_val_if_fail (IBUS_IS_BUS (bus), NULL);
2172
2173 GVariant *result;
2174 IBusEngineDesc *engine = NULL;
2175 result = ibus_bus_call_sync (bus,
2176 IBUS_SERVICE_IBUS,
2177 IBUS_PATH_IBUS,
2178 "org.freedesktop.DBus.Properties",
2179 "Get",
2180 g_variant_new ("(ss)",
2181 IBUS_INTERFACE_IBUS,
2182 "GlobalEngine"),
2183 G_VARIANT_TYPE ("(v)"));
2184
2185 if (result) {
2186 GVariant *variant = NULL;
2187 g_variant_get (result, "(v)", &variant);
2188 if (variant) {
2189 GVariant *obj = g_variant_get_variant (variant);
2190 engine = IBUS_ENGINE_DESC (ibus_serializable_deserialize (obj));
2191 g_variant_unref (obj);
2192 g_variant_unref (variant);
2193 }
2194 g_variant_unref (result);
2195 }
2196
2197 return engine;
2198 }
2199
2200 void
ibus_bus_get_global_engine_async(IBusBus * bus,gint timeout_msec,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)2201 ibus_bus_get_global_engine_async (IBusBus *bus,
2202 gint timeout_msec,
2203 GCancellable *cancellable,
2204 GAsyncReadyCallback callback,
2205 gpointer user_data)
2206 {
2207 g_return_if_fail (IBUS_IS_BUS (bus));
2208
2209 ibus_bus_call_async (bus,
2210 IBUS_SERVICE_IBUS,
2211 IBUS_PATH_IBUS,
2212 "org.freedesktop.DBus.Properties",
2213 "Get",
2214 g_variant_new ("(ss)",
2215 IBUS_INTERFACE_IBUS,
2216 "GlobalEngine"),
2217 G_VARIANT_TYPE ("(v)"),
2218 ibus_bus_get_global_engine_async,
2219 timeout_msec,
2220 cancellable,
2221 callback,
2222 user_data);
2223 }
2224
2225 IBusEngineDesc *
ibus_bus_get_global_engine_async_finish(IBusBus * bus,GAsyncResult * res,GError ** error)2226 ibus_bus_get_global_engine_async_finish (IBusBus *bus,
2227 GAsyncResult *res,
2228 GError **error)
2229 {
2230 GTask *task;
2231 gboolean had_error;
2232 GVariant *result = NULL;
2233
2234 g_assert (g_task_is_valid (res, bus));
2235
2236 task = G_TASK (res);
2237 had_error = g_task_had_error (task);
2238 result = g_task_propagate_pointer (task, error);
2239 if (had_error) {
2240 g_assert (result == NULL);
2241 return NULL;
2242 }
2243 g_return_val_if_fail (result != NULL, NULL);
2244 GVariant *variant = NULL;
2245 g_variant_get (result, "(v)", &variant);
2246
2247 IBusEngineDesc *engine = NULL;
2248 if (variant) {
2249 GVariant *obj = g_variant_get_variant (variant);
2250 engine = IBUS_ENGINE_DESC (ibus_serializable_deserialize (obj));
2251 g_variant_unref (obj);
2252 g_variant_unref (variant);
2253 }
2254 g_variant_unref (result);
2255 return engine;
2256 }
2257
2258 gboolean
ibus_bus_set_global_engine(IBusBus * bus,const gchar * global_engine)2259 ibus_bus_set_global_engine (IBusBus *bus,
2260 const gchar *global_engine)
2261 {
2262 g_return_val_if_fail (IBUS_IS_BUS (bus), FALSE);
2263 g_return_val_if_fail (global_engine != NULL, FALSE);
2264
2265 GVariant *result;
2266 result = ibus_bus_call_sync (bus,
2267 IBUS_SERVICE_IBUS,
2268 IBUS_PATH_IBUS,
2269 IBUS_INTERFACE_IBUS,
2270 "SetGlobalEngine",
2271 g_variant_new ("(s)", global_engine),
2272 NULL);
2273
2274 if (result) {
2275 g_variant_unref (result);
2276 return TRUE;
2277 }
2278 return FALSE;
2279 }
2280
2281 void
ibus_bus_set_global_engine_async(IBusBus * bus,const gchar * global_engine,gint timeout_msec,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)2282 ibus_bus_set_global_engine_async (IBusBus *bus,
2283 const gchar *global_engine,
2284 gint timeout_msec,
2285 GCancellable *cancellable,
2286 GAsyncReadyCallback callback,
2287 gpointer user_data)
2288 {
2289 g_return_if_fail (IBUS_IS_BUS (bus));
2290 g_return_if_fail (global_engine != NULL);
2291
2292 ibus_bus_call_async (bus,
2293 IBUS_SERVICE_IBUS,
2294 IBUS_PATH_IBUS,
2295 IBUS_INTERFACE_IBUS,
2296 "SetGlobalEngine",
2297 g_variant_new ("(s)", global_engine),
2298 NULL, /* no return value */
2299 ibus_bus_set_global_engine_async,
2300 timeout_msec,
2301 cancellable,
2302 callback,
2303 user_data);
2304 }
2305
2306 gboolean
ibus_bus_set_global_engine_async_finish(IBusBus * bus,GAsyncResult * res,GError ** error)2307 ibus_bus_set_global_engine_async_finish (IBusBus *bus,
2308 GAsyncResult *res,
2309 GError **error)
2310 {
2311 GTask *task;
2312
2313 g_assert (IBUS_IS_BUS (bus));
2314 g_assert (g_task_is_valid (res, bus));
2315
2316 task = G_TASK (res);
2317 g_assert (g_task_get_source_tag (task) == ibus_bus_set_global_engine_async);
2318 return _async_finish_void (task, error);
2319 }
2320
2321 gboolean
ibus_bus_preload_engines(IBusBus * bus,const gchar * const * names)2322 ibus_bus_preload_engines (IBusBus *bus,
2323 const gchar * const *names)
2324 {
2325 GVariant *result;
2326 GVariant *variant = NULL;
2327
2328 g_return_val_if_fail (IBUS_IS_BUS (bus), FALSE);
2329 g_return_val_if_fail (names != NULL && names[0] != NULL, FALSE);
2330
2331 variant = g_variant_new_strv(names, -1);
2332 result = ibus_bus_call_sync (bus,
2333 IBUS_SERVICE_IBUS,
2334 IBUS_PATH_IBUS,
2335 "org.freedesktop.DBus.Properties",
2336 "Set",
2337 g_variant_new ("(ssv)",
2338 IBUS_INTERFACE_IBUS,
2339 "PreloadEngines",
2340 variant),
2341 NULL);
2342
2343 if (result) {
2344 g_variant_unref (result);
2345 return TRUE;
2346 }
2347
2348 return FALSE;
2349 }
2350
2351 void
ibus_bus_preload_engines_async(IBusBus * bus,const gchar * const * names,gint timeout_msec,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)2352 ibus_bus_preload_engines_async (IBusBus *bus,
2353 const gchar * const *names,
2354 gint timeout_msec,
2355 GCancellable *cancellable,
2356 GAsyncReadyCallback callback,
2357 gpointer user_data)
2358 {
2359 GVariant *variant = NULL;
2360
2361 g_return_if_fail (IBUS_IS_BUS (bus));
2362 g_return_if_fail (names != NULL && names[0] != NULL);
2363
2364 variant = g_variant_new_strv(names, -1);
2365 ibus_bus_call_async (bus,
2366 IBUS_SERVICE_IBUS,
2367 IBUS_PATH_IBUS,
2368 "org.freedesktop.DBus.Properties",
2369 "Set",
2370 g_variant_new ("(ssv)",
2371 IBUS_INTERFACE_IBUS,
2372 "PreloadEngines",
2373 variant),
2374 NULL, /* no return value */
2375 ibus_bus_preload_engines_async,
2376 timeout_msec,
2377 cancellable,
2378 callback,
2379 user_data);
2380 }
2381
2382 gboolean
ibus_bus_preload_engines_async_finish(IBusBus * bus,GAsyncResult * res,GError ** error)2383 ibus_bus_preload_engines_async_finish (IBusBus *bus,
2384 GAsyncResult *res,
2385 GError **error)
2386 {
2387 GTask *task;
2388
2389 g_assert (IBUS_IS_BUS (bus));
2390 g_assert (g_task_is_valid (res, bus));
2391
2392 task = G_TASK (res);
2393 g_assert (g_task_get_source_tag (task) == ibus_bus_preload_engines_async);
2394 return _async_finish_void (task, error);
2395 }
2396
2397 GVariant *
ibus_bus_get_ibus_property(IBusBus * bus,const gchar * property_name)2398 ibus_bus_get_ibus_property (IBusBus *bus,
2399 const gchar *property_name)
2400 {
2401 GVariant *result;
2402 GVariant *retval = NULL;
2403
2404 g_return_val_if_fail (IBUS_IS_BUS (bus), NULL);
2405 g_return_val_if_fail (property_name != NULL, NULL);
2406
2407 result = ibus_bus_call_sync (bus,
2408 IBUS_SERVICE_IBUS,
2409 IBUS_PATH_IBUS,
2410 "org.freedesktop.DBus.Properties",
2411 "Get",
2412 g_variant_new ("(ss)",
2413 IBUS_INTERFACE_IBUS,
2414 property_name),
2415 G_VARIANT_TYPE ("(v)"));
2416
2417 if (result) {
2418 g_variant_get (result, "(v)", &retval);
2419 g_variant_unref (result);
2420 }
2421
2422 return retval;
2423 }
2424
2425 void
ibus_bus_get_ibus_property_async(IBusBus * bus,const gchar * property_name,gint timeout_msec,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)2426 ibus_bus_get_ibus_property_async (IBusBus *bus,
2427 const gchar *property_name,
2428 gint timeout_msec,
2429 GCancellable *cancellable,
2430 GAsyncReadyCallback callback,
2431 gpointer user_data)
2432 {
2433 g_return_if_fail (IBUS_IS_BUS (bus));
2434 g_return_if_fail (property_name != NULL);
2435
2436 ibus_bus_call_async (bus,
2437 IBUS_SERVICE_IBUS,
2438 IBUS_PATH_IBUS,
2439 "org.freedesktop.DBus.Properties",
2440 "Get",
2441 g_variant_new ("(ss)",
2442 IBUS_INTERFACE_IBUS,
2443 property_name),
2444 G_VARIANT_TYPE ("(v)"),
2445 ibus_bus_get_ibus_property_async,
2446 timeout_msec,
2447 cancellable,
2448 callback,
2449 user_data);
2450 }
2451
2452 GVariant *
ibus_bus_get_ibus_property_async_finish(IBusBus * bus,GAsyncResult * res,GError ** error)2453 ibus_bus_get_ibus_property_async_finish (IBusBus *bus,
2454 GAsyncResult *res,
2455 GError **error)
2456 {
2457 GTask *task;
2458 gboolean had_error;
2459 GVariant *result = NULL;
2460
2461 g_assert (g_task_is_valid (res, bus));
2462
2463 task = G_TASK (res);
2464 had_error = g_task_had_error (task);
2465 result = g_task_propagate_pointer (task, error);
2466 if (had_error) {
2467 g_assert (result == NULL);
2468 return NULL;
2469 }
2470 g_return_val_if_fail (result != NULL, NULL);
2471 GVariant *retval = NULL;
2472 g_variant_get (result, "(v)", &retval);
2473 g_variant_unref (result);
2474
2475 return retval;
2476 }
2477
2478 void
ibus_bus_set_ibus_property(IBusBus * bus,const gchar * property_name,GVariant * value)2479 ibus_bus_set_ibus_property (IBusBus *bus,
2480 const gchar *property_name,
2481 GVariant *value)
2482 {
2483 GVariant *result;
2484
2485 g_return_if_fail (IBUS_IS_BUS (bus));
2486 g_return_if_fail (property_name != NULL);
2487
2488 result = ibus_bus_call_sync (bus,
2489 IBUS_SERVICE_IBUS,
2490 IBUS_PATH_IBUS,
2491 "org.freedesktop.DBus.Properties",
2492 "Set",
2493 g_variant_new ("(ssv)",
2494 IBUS_INTERFACE_IBUS,
2495 property_name,
2496 value),
2497 NULL);
2498
2499 if (result) {
2500 g_variant_unref (result);
2501 }
2502 }
2503
2504 void
ibus_bus_set_ibus_property_async(IBusBus * bus,const gchar * property_name,GVariant * value,gint timeout_msec,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)2505 ibus_bus_set_ibus_property_async (IBusBus *bus,
2506 const gchar *property_name,
2507 GVariant *value,
2508 gint timeout_msec,
2509 GCancellable *cancellable,
2510 GAsyncReadyCallback callback,
2511 gpointer user_data)
2512 {
2513 g_return_if_fail (IBUS_IS_BUS (bus));
2514 g_return_if_fail (property_name != NULL);
2515
2516 ibus_bus_call_async (bus,
2517 IBUS_SERVICE_IBUS,
2518 IBUS_PATH_IBUS,
2519 "org.freedesktop.DBus.Properties",
2520 "Set",
2521 g_variant_new ("(ssv)",
2522 IBUS_INTERFACE_IBUS,
2523 property_name,
2524 value),
2525 NULL, /* no return value */
2526 ibus_bus_set_ibus_property_async,
2527 timeout_msec,
2528 cancellable,
2529 callback,
2530 user_data);
2531 }
2532
2533 gboolean
ibus_bus_set_ibus_property_async_finish(IBusBus * bus,GAsyncResult * res,GError ** error)2534 ibus_bus_set_ibus_property_async_finish (IBusBus *bus,
2535 GAsyncResult *res,
2536 GError **error)
2537 {
2538 GTask *task;
2539 g_assert (IBUS_IS_BUS (bus));
2540 g_assert (g_task_is_valid (res, bus));
2541
2542 task = G_TASK (res);
2543 g_return_val_if_fail (
2544 g_task_get_source_tag (task) == ibus_bus_set_ibus_property_async,
2545 FALSE);
2546 return _async_finish_void (task, error);
2547 }
2548
2549 static GVariant *
ibus_bus_call_sync(IBusBus * bus,const gchar * bus_name,const gchar * path,const gchar * interface,const gchar * member,GVariant * parameters,const GVariantType * reply_type)2550 ibus_bus_call_sync (IBusBus *bus,
2551 const gchar *bus_name,
2552 const gchar *path,
2553 const gchar *interface,
2554 const gchar *member,
2555 GVariant *parameters,
2556 const GVariantType *reply_type)
2557 {
2558 g_assert (IBUS_IS_BUS (bus));
2559 g_assert (member != NULL);
2560 g_return_val_if_fail (ibus_bus_is_connected (bus), NULL);
2561
2562 if (bus->priv->use_portal &&
2563 g_strcmp0 (bus_name, IBUS_SERVICE_IBUS) == 0) {
2564 bus_name = IBUS_SERVICE_PORTAL;
2565 if (g_strcmp0 (interface, IBUS_INTERFACE_IBUS) == 0)
2566 interface = IBUS_INTERFACE_PORTAL;
2567 }
2568
2569 GError *error = NULL;
2570 GVariant *result;
2571 result = g_dbus_connection_call_sync (bus->priv->connection,
2572 bus_name,
2573 path,
2574 interface,
2575 member,
2576 parameters,
2577 reply_type,
2578 G_DBUS_CALL_FLAGS_NO_AUTO_START,
2579 ibus_get_timeout (),
2580 NULL,
2581 &error);
2582
2583 if (result == NULL) {
2584 g_warning ("ibus_bus_call_sync: %s.%s: %s", interface, member, error->message);
2585 g_error_free (error);
2586 return NULL;
2587 }
2588
2589 return result;
2590 }
2591
2592 static void
ibus_bus_call_async_done(GDBusConnection * connection,GAsyncResult * res,gpointer user_data)2593 ibus_bus_call_async_done (GDBusConnection *connection,
2594 GAsyncResult *res,
2595 gpointer user_data)
2596 {
2597 GTask *task;
2598 GError *error = NULL;
2599 GVariant *variant;
2600
2601 g_assert (G_IS_DBUS_CONNECTION (connection));
2602
2603 task = (GTask* ) user_data;
2604 variant = g_dbus_connection_call_finish (connection, res, &error);
2605
2606 if (variant == NULL)
2607 g_task_return_error (task, error);
2608 else
2609 g_task_return_pointer (task, variant, (GDestroyNotify) g_variant_unref);
2610 g_object_unref (task);
2611 }
2612
2613 static void
ibus_bus_call_async(IBusBus * bus,const gchar * bus_name,const gchar * path,const gchar * interface,const gchar * member,GVariant * parameters,const GVariantType * reply_type,gpointer source_tag,gint timeout_msec,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)2614 ibus_bus_call_async (IBusBus *bus,
2615 const gchar *bus_name,
2616 const gchar *path,
2617 const gchar *interface,
2618 const gchar *member,
2619 GVariant *parameters,
2620 const GVariantType *reply_type,
2621 gpointer source_tag,
2622 gint timeout_msec,
2623 GCancellable *cancellable,
2624 GAsyncReadyCallback callback,
2625 gpointer user_data)
2626 {
2627 GTask *task;
2628
2629 g_assert (IBUS_IS_BUS (bus));
2630 g_assert (member != NULL);
2631 g_return_if_fail (ibus_bus_is_connected (bus));
2632
2633 task = g_task_new (bus, cancellable, callback, user_data);
2634 g_task_set_source_tag (task, source_tag);
2635
2636 if (bus->priv->use_portal &&
2637 g_strcmp0 (bus_name, IBUS_SERVICE_IBUS) == 0) {
2638 bus_name = IBUS_SERVICE_PORTAL;
2639 if (g_strcmp0 (interface, IBUS_INTERFACE_IBUS) == 0)
2640 interface = IBUS_INTERFACE_PORTAL;
2641 }
2642
2643 g_dbus_connection_call (bus->priv->connection,
2644 bus_name,
2645 path,
2646 interface,
2647 member,
2648 parameters,
2649 reply_type,
2650 G_DBUS_CALL_FLAGS_NO_AUTO_START,
2651 timeout_msec,
2652 cancellable,
2653 (GAsyncReadyCallback) ibus_bus_call_async_done,
2654 task);
2655 }
2656