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-2010 Peng Huang <shawn.p.huang@gmail.com>
5 * Copyright (C) 2008-2010 Red Hat, Inc.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
23 #include "ibusproxy.h"
24 #include "ibusmarshalers.h"
25 #include "ibusinternal.h"
26 #include "ibusobject.h"
28 #define IBUS_PROXY_GET_PRIVATE(o) \
29 (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_PROXY, IBusProxyPrivate))
36 static guint proxy_signals[LAST_SIGNAL] = { 0 };
38 /* functions prototype */
39 static void ibus_proxy_dispose (GObject *object);
40 static void ibus_proxy_real_destroy (IBusProxy *proxy);
42 static void ibus_proxy_connection_closed_cb
43 (GDBusConnection *connection,
44 gboolean remote_peer_vanished,
47 static void initable_iface_init (GInitableIface *initable_iface);
48 static void async_initable_iface_init (GAsyncInitableIface
49 *async_initable_iface);
50 G_DEFINE_TYPE_WITH_CODE (IBusProxy, ibus_proxy, G_TYPE_DBUS_PROXY,
51 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init)
52 G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, async_initable_iface_init)
56 ibus_proxy_class_init (IBusProxyClass *class)
58 GObjectClass *gobject_class = G_OBJECT_CLASS (class);
60 gobject_class->dispose = ibus_proxy_dispose;
62 class->destroy = ibus_proxy_real_destroy;
67 * @object: An IBusProxy.
69 * Destroy and free an IBusProxy
71 * See also: ibus_proxy_destroy().
73 * <note><para>Argument @user_data is ignored in this function.</para></note>
75 proxy_signals[DESTROY] =
76 g_signal_new (I_("destroy"),
77 G_TYPE_FROM_CLASS (gobject_class),
79 G_STRUCT_OFFSET (IBusProxyClass, destroy),
81 _ibus_marshal_VOID__VOID,
86 ibus_proxy_init (IBusProxy *proxy)
94 * Override GObject's dispose function.
97 ibus_proxy_dispose (GObject *object)
99 if (! (IBUS_PROXY_FLAGS (object) & IBUS_IN_DESTRUCTION)) {
100 IBUS_PROXY_SET_FLAGS (object, IBUS_IN_DESTRUCTION);
101 if (! (IBUS_PROXY_FLAGS (object) & IBUS_DESTROYED)) {
102 g_signal_emit (object, proxy_signals[DESTROY], 0);
103 IBUS_PROXY_SET_FLAGS (object, IBUS_DESTROYED);
105 IBUS_PROXY_UNSET_FLAGS (object, IBUS_IN_DESTRUCTION);
108 G_OBJECT_CLASS(ibus_proxy_parent_class)->dispose (object);
112 * ibus_proxy_real_destroy:
114 * Handle "destroy" signal which is emitted by ibus_proxy_dispose.
117 ibus_proxy_real_destroy (IBusProxy *proxy)
119 GDBusConnection *connection = g_dbus_proxy_get_connection ((GDBusProxy *) proxy);
120 g_assert (connection != NULL);
121 if (!g_dbus_connection_is_closed (connection) && proxy->own) {
122 g_dbus_proxy_call ((GDBusProxy *)proxy,
123 "org.freedesktop.IBus.Service.Destroy",
125 G_DBUS_CALL_FLAGS_NONE,
126 -1, NULL, NULL, NULL);
128 g_signal_handlers_disconnect_by_func (connection,
129 (GCallback) ibus_proxy_connection_closed_cb,
134 ibus_proxy_connection_closed_cb (GDBusConnection *connection,
135 gboolean remote_peer_vanished,
139 ibus_proxy_destroy (proxy);
143 ibus_proxy_destroy (IBusProxy *proxy)
145 g_assert (IBUS_IS_PROXY (proxy));
147 if (! (IBUS_PROXY_FLAGS (proxy) & IBUS_IN_DESTRUCTION)) {
148 g_object_run_dispose (G_OBJECT (proxy));
153 ibus_proxy_init_finish (IBusProxy *proxy,
156 g_assert (IBUS_IS_PROXY (proxy));
157 g_assert (error == NULL || *error == NULL);
159 GDBusConnection *connection =
160 g_dbus_proxy_get_connection ((GDBusProxy *)proxy);
162 if (connection == NULL || g_dbus_connection_is_closed (connection)) {
164 * When proxy is created asynchronously, the connection may be closed
165 * before proxy is ready. In this case, we need override interfaces
166 * GInitable and GAsyncInitable to report the error.
169 *error = g_error_new (G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
170 "Connection is closed.");
174 g_signal_connect (connection, "closed",
175 G_CALLBACK (ibus_proxy_connection_closed_cb), proxy);
181 static GInitableIface *initable_iface_parent = NULL;
184 initable_init (GInitable *initable,
185 GCancellable *cancellable,
188 if (!initable_iface_parent->init (initable, cancellable, error))
190 return ibus_proxy_init_finish ((IBusProxy *)initable, error);
194 initable_iface_init (GInitableIface *initable_iface)
196 initable_iface_parent = g_type_interface_peek_parent (initable_iface);
197 initable_iface->init = initable_init;
200 static GAsyncInitableIface *async_initable_iface_parent = NULL;
203 async_initable_init_async (GAsyncInitable *initable,
205 GCancellable *cancellable,
206 GAsyncReadyCallback callback,
209 async_initable_iface_parent->init_async (initable,
210 io_priority, cancellable, callback, user_data);
214 async_initable_init_finish (GAsyncInitable *initable,
218 if (!async_initable_iface_parent->init_finish (initable, res, error))
220 return ibus_proxy_init_finish ((IBusProxy *)initable, error);
224 async_initable_iface_init (GAsyncInitableIface *async_initable_iface)
226 async_initable_iface_parent = g_type_interface_peek_parent (async_initable_iface);
227 async_initable_iface->init_async = async_initable_init_async;
228 async_initable_iface->init_finish = async_initable_init_finish;