Use gdbus in glib, and get rid of libdbus
[platform/upstream/ibus.git] / src / ibusfactory.c
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.
6  *
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.
11  *
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.
16  *
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.
21  */
22 #include "ibusfactory.h"
23 #include "ibusengine.h"
24 #include "ibusshare.h"
25 #include "ibusinternal.h"
26
27 #define IBUS_FACTORY_GET_PRIVATE(o)  \
28    (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_FACTORY, IBusFactoryPrivate))
29
30 enum {
31     LAST_SIGNAL,
32 };
33
34 enum {
35     PROP_0,
36 };
37
38 /* IBusFactoryPriv */
39 struct _IBusFactoryPrivate {
40     guint id;
41     GList          *engine_list;
42     GHashTable     *engine_table;
43 };
44
45 /* functions prototype */
46 static void      ibus_factory_destroy        (IBusFactory        *factory);
47 static void      ibus_factory_set_property   (IBusFactory        *engine,
48                                               guint               prop_id,
49                                               const GValue       *value,
50                                               GParamSpec         *pspec);
51 static void      ibus_factory_get_property   (IBusFactory        *factory,
52                                               guint               prop_id,
53                                               GValue             *value,
54                                               GParamSpec         *pspec);
55 static void      ibus_factory_service_method_call
56                                               (IBusService        *service,
57                                                GDBusConnection    *connection,
58                                                const gchar        *sender,
59                                                const gchar        *object_path,
60                                                const gchar        *interface_name,
61                                                const gchar        *method_name,
62                                                GVariant           *parameters,
63                                                GDBusMethodInvocation
64                                                                   *invocation);
65 static GVariant *ibus_factory_service_get_property
66                                              (IBusService        *service,
67                                               GDBusConnection    *connection,
68                                               const gchar        *sender,
69                                               const gchar        *object_path,
70                                               const gchar        *interface_name,
71                                               const gchar        *property_name,
72                                               GError            **error);
73 static gboolean  ibus_factory_service_set_property
74                                              (IBusService        *service,
75                                               GDBusConnection    *connection,
76                                               const gchar        *sender,
77                                               const gchar        *object_path,
78                                               const gchar        *interface_name,
79                                               const gchar        *property_name,
80                                               GVariant           *value,
81                                               GError            **error);
82 static void      ibus_factory_engine_destroy_cb
83                                              (IBusEngine         *engine,
84                                               IBusFactory        *factory);
85
86 G_DEFINE_TYPE (IBusFactory, ibus_factory, IBUS_TYPE_SERVICE)
87
88 static const gchar introspection_xml[] =
89     "<node>"
90     "  <interface name='org.freedesktop.IBus.Factory'>"
91     "    <method name='CreateEngine'>"
92     "      <arg direction='in'  type='s' name='name' />"
93     "      <arg direction='out' type='o' />"
94     "    </method>"
95     "  </interface>"
96     "</node>";
97
98 static void
99 ibus_factory_class_init (IBusFactoryClass *class)
100 {
101     GObjectClass *gobject_class = G_OBJECT_CLASS (class);
102     IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (class);
103
104     gobject_class->set_property = (GObjectSetPropertyFunc) ibus_factory_set_property;
105     gobject_class->get_property = (GObjectGetPropertyFunc) ibus_factory_get_property;
106
107     ibus_object_class->destroy = (IBusObjectDestroyFunc) ibus_factory_destroy;
108
109     IBUS_SERVICE_CLASS (class)->service_method_call  = ibus_factory_service_method_call;
110     IBUS_SERVICE_CLASS (class)->service_get_property = ibus_factory_service_get_property;
111     IBUS_SERVICE_CLASS (class)->service_set_property = ibus_factory_service_set_property;
112
113     ibus_service_class_add_interfaces (IBUS_SERVICE_CLASS (class), introspection_xml);
114
115     g_type_class_add_private (class, sizeof (IBusFactoryPrivate));
116 }
117
118 static void
119 ibus_factory_init (IBusFactory *factory)
120 {
121     factory->priv = IBUS_FACTORY_GET_PRIVATE (factory);
122     factory->priv->engine_table =
123         g_hash_table_new_full (g_str_hash,
124                                g_str_equal,
125                                g_free,
126                                NULL);
127 }
128
129 static void
130 ibus_factory_destroy (IBusFactory *factory)
131 {
132     GList *list;
133
134     list = g_list_copy (factory->priv->engine_list);
135     g_list_foreach (list, (GFunc) ibus_object_destroy, NULL);
136     g_list_free (factory->priv->engine_list);
137     g_list_free (list);
138     factory->priv->engine_list = NULL;
139
140     if (factory->priv->engine_table) {
141         g_hash_table_destroy (factory->priv->engine_table);
142     }
143
144     IBUS_OBJECT_CLASS(ibus_factory_parent_class)->destroy (IBUS_OBJECT (factory));
145 }
146
147 static void
148 ibus_factory_set_property (IBusFactory  *factory,
149                            guint         prop_id,
150                            const GValue *value,
151                            GParamSpec   *pspec)
152 {
153     switch (prop_id) {
154     #if 0
155     case PROP_CONNECTION:
156         priv->connection = g_value_get_object (value);
157         g_object_ref_sink (priv->connection);
158         ibus_service_add_to_connection ((IBusService *) factory,
159                                         priv->connection);
160         break;
161     #endif
162     default:
163         G_OBJECT_WARN_INVALID_PROPERTY_ID (factory, prop_id, pspec);
164     }
165 }
166
167 static void
168 ibus_factory_get_property (IBusFactory *factory,
169                            guint        prop_id,
170                            GValue      *value,
171                            GParamSpec  *pspec)
172 {
173     switch (prop_id) {
174     #if 0
175     case PROP_CONNECTION:
176         g_value_set_object (value, priv->connection);
177         break;
178     #endif
179     default:
180         G_OBJECT_WARN_INVALID_PROPERTY_ID (factory, prop_id, pspec);
181     }
182 }
183
184 static void
185 ibus_factory_engine_destroy_cb (IBusEngine  *engine,
186                                 IBusFactory *factory)
187 {
188     factory->priv->engine_list = g_list_remove (factory->priv->engine_list, engine);
189     g_object_unref (engine);
190 }
191
192 static void
193 ibus_factory_service_method_call (IBusService           *service,
194                                   GDBusConnection       *connection,
195                                   const gchar           *sender,
196                                   const gchar           *object_path,
197                                   const gchar           *interface_name,
198                                   const gchar           *method_name,
199                                   GVariant              *parameters,
200                                   GDBusMethodInvocation *invocation)
201 {
202     IBusFactory *factory = IBUS_FACTORY (service);
203
204     if (g_strcmp0 (method_name, "CreateEngine") == 0) {
205         gchar *engine_name = NULL;
206         g_variant_get (parameters, "(&s)", &engine_name);
207         GType engine_type = (GType )g_hash_table_lookup (factory->priv->engine_table, engine_name);
208
209         if (engine_type == G_TYPE_INVALID) {
210             gchar *error_message = g_strdup_printf ("Can not fond engine %s", engine_name);
211             g_dbus_method_invocation_return_error (invocation,
212                                                    G_DBUS_ERROR,
213                                                    G_DBUS_ERROR_FAILED,
214                                                    error_message);
215             g_free (error_message);
216         }
217         else {
218             gchar *object_path = g_strdup_printf ("/org/freedesktop/IBus/Engine/%d",
219                                             ++factory->priv->id);
220             IBusEngine *engine = ibus_engine_new_type (engine_type,
221                                                        engine_name,
222                                                        object_path,
223                                                        ibus_service_get_connection ((IBusService *)factory));
224             g_assert (engine != NULL);
225             g_object_ref_sink (engine);
226             factory->priv->engine_list = g_list_append (factory->priv->engine_list, engine);
227             g_signal_connect (engine,
228                               "destroy",
229                               G_CALLBACK (ibus_factory_engine_destroy_cb),
230                               factory);
231             g_dbus_method_invocation_return_value (invocation,
232                                                    g_variant_new ("(o)", object_path));
233             g_free (object_path);
234         }
235         return;
236     }
237
238     IBUS_SERVICE_CLASS (ibus_factory_parent_class)->
239             service_method_call (service,
240                                  connection,
241                                  sender,
242                                  object_path,
243                                  interface_name,
244                                  method_name,
245                                  parameters,
246                                  invocation);
247 }
248
249 static GVariant *
250 ibus_factory_service_get_property (IBusService        *service,
251                                    GDBusConnection    *connection,
252                                    const gchar        *sender,
253                                    const gchar        *object_path,
254                                    const gchar        *interface_name,
255                                    const gchar        *property_name,
256                                    GError            **error)
257 {
258     return IBUS_SERVICE_CLASS (ibus_factory_parent_class)->
259                 service_get_property (service,
260                                       connection,
261                                       sender,
262                                       object_path,
263                                       interface_name,
264                                       property_name,
265                                       error);
266 }
267
268 static gboolean
269 ibus_factory_service_set_property (IBusService        *service,
270                                    GDBusConnection    *connection,
271                                    const gchar        *sender,
272                                    const gchar        *object_path,
273                                    const gchar        *interface_name,
274                                    const gchar        *property_name,
275                                    GVariant           *value,
276                                    GError            **error)
277 {
278     return IBUS_SERVICE_CLASS (ibus_factory_parent_class)->
279                 service_set_property (service,
280                                       connection,
281                                       sender,
282                                       object_path,
283                                       interface_name,
284                                       property_name,
285                                       value,
286                                       error);
287 }
288
289 IBusFactory *
290 ibus_factory_new (GDBusConnection *connection)
291 {
292     g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
293
294     IBusEngine *object = g_object_new (IBUS_TYPE_FACTORY,
295                                        "object-path", IBUS_PATH_FACTORY,
296                                        "connection", connection,
297                                        NULL);
298
299     return IBUS_FACTORY (object);
300 }
301
302 void
303 ibus_factory_add_engine (IBusFactory *factory,
304                          const gchar *engine_name,
305                          GType        engine_type)
306 {
307     g_return_if_fail (IBUS_IS_FACTORY (factory));
308     g_return_if_fail (engine_name != NULL);
309     g_return_if_fail (g_type_is_a (engine_type, IBUS_TYPE_ENGINE));
310
311     g_hash_table_insert (factory->priv->engine_table, g_strdup (engine_name), (gpointer) engine_type);
312 }