remove IBusFactoryInfo
[platform/upstream/ibus.git] / src / ibusfactory.c
1 /* vim:set et sts=4: */
2 /* ibus - The Input Bus
3  * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
4  * Copyright (C) 2008-2010 Red Hat, Inc.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
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 /* IBusFactoryPriv */
35 struct _IBusFactoryPrivate {
36     guint id;
37     IBusConnection *connection;
38     GList          *engine_list;
39     GHashTable     *engine_table;
40 };
41 typedef struct _IBusFactoryPrivate IBusFactoryPrivate;
42
43 /* functions prototype */
44 static void     ibus_factory_class_init     (IBusFactoryClass   *klass);
45 static void     ibus_factory_init           (IBusFactory        *factory);
46 static void     ibus_factory_destroy        (IBusFactory        *factory);
47 static gboolean ibus_factory_ibus_message   (IBusFactory        *factory,
48                                              IBusConnection     *connection,
49                                              IBusMessage        *message);
50
51 static void     _engine_destroy_cb          (IBusEngine         *engine,
52                                              IBusFactory        *factory);
53 #if 0
54 static void     ibus_factory_info_class_init(IBusFactoryInfoClass   *klass);
55 static void     ibus_factory_info_init      (IBusFactoryInfo        *info);
56 static void     ibus_factory_info_destroy   (IBusFactoryInfo        *info);
57 static gboolean ibus_factory_info_serialize (IBusFactoryInfo        *info,
58                                              IBusMessageIter        *iter);
59 static gboolean ibus_factory_info_deserialize
60                                             (IBusFactoryInfo        *info,
61                                              IBusMessageIter        *iter);
62 static gboolean ibus_factory_info_copy      (IBusFactoryInfo        *dest,
63                                              const IBusFactoryInfo  *src);
64 #endif
65
66 static IBusServiceClass *factory_parent_class = NULL;
67
68 #if 0
69 static IBusSerializableClass *factory_info_parent_class = NULL;
70 #endif
71
72 GType
73 ibus_factory_get_type (void)
74 {
75     static GType type = 0;
76
77     static const GTypeInfo type_info = {
78         sizeof (IBusFactoryClass),
79         (GBaseInitFunc)     NULL,
80         (GBaseFinalizeFunc) NULL,
81         (GClassInitFunc)    ibus_factory_class_init,
82         NULL,               /* class finalize */
83         NULL,               /* class data */
84         sizeof (IBusFactory),
85         0,
86         (GInstanceInitFunc) ibus_factory_init,
87     };
88
89     if (type == 0) {
90         type = g_type_register_static (IBUS_TYPE_SERVICE,
91                     "IBusFactory",
92                     &type_info,
93                     (GTypeFlags) 0);
94     }
95     return type;
96 }
97
98 IBusFactory *
99 ibus_factory_new (IBusConnection *connection)
100 {
101     g_assert (IBUS_IS_CONNECTION (connection));
102
103     IBusFactory *factory;
104     IBusFactoryPrivate *priv;
105
106     factory = (IBusFactory *) g_object_new (IBUS_TYPE_FACTORY,
107                                             "path", IBUS_PATH_FACTORY,
108                                             NULL);
109     priv = IBUS_FACTORY_GET_PRIVATE (factory);
110
111     priv->connection = g_object_ref (connection);
112     ibus_service_add_to_connection ((IBusService *)factory, connection);
113
114     return factory;
115 }
116
117 static void
118 ibus_factory_class_init (IBusFactoryClass *klass)
119 {
120     // GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
121     IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass);
122
123     factory_parent_class = (IBusServiceClass *) g_type_class_peek_parent (klass);
124
125     g_type_class_add_private (klass, sizeof (IBusFactoryPrivate));
126
127     ibus_object_class->destroy = (IBusObjectDestroyFunc) ibus_factory_destroy;
128
129     IBUS_SERVICE_CLASS (klass)->ibus_message = (ServiceIBusMessageFunc) ibus_factory_ibus_message;
130
131 }
132
133 static void
134 ibus_factory_init (IBusFactory *factory)
135 {
136     IBusFactoryPrivate *priv;
137     priv = IBUS_FACTORY_GET_PRIVATE (factory);
138
139     priv->id = 0;
140     priv->connection = NULL;
141     priv->engine_table = g_hash_table_new_full (g_str_hash,
142                                                 g_str_equal,
143                                                 g_free,
144                                                 NULL);
145     priv->engine_list =  NULL;
146 }
147
148 static void
149 ibus_factory_destroy (IBusFactory *factory)
150 {
151     GList *list;
152     IBusFactoryPrivate *priv;
153     priv = IBUS_FACTORY_GET_PRIVATE (factory);
154
155     list = g_list_copy (priv->engine_list);
156     g_list_foreach (list, (GFunc) ibus_object_destroy, NULL);
157     g_list_free (priv->engine_list);
158     g_list_free (list);
159     priv->engine_list = NULL;
160
161     if (priv->engine_table) {
162         g_hash_table_destroy (priv->engine_table);
163     }
164
165     if (priv->connection) {
166         ibus_service_remove_from_connection ((IBusService *)factory,
167                                              priv->connection);
168         g_object_unref (priv->connection);
169     }
170
171     IBUS_OBJECT_CLASS(factory_parent_class)->destroy (IBUS_OBJECT (factory));
172 }
173
174 static void
175 _engine_destroy_cb (IBusEngine  *engine,
176                     IBusFactory *factory)
177 {
178     IBusFactoryPrivate *priv;
179     priv = IBUS_FACTORY_GET_PRIVATE (factory);
180
181     priv->engine_list = g_list_remove (priv->engine_list, engine);
182     g_object_unref (engine);
183 }
184
185 static gboolean
186 ibus_factory_ibus_message (IBusFactory    *factory,
187                            IBusConnection *connection,
188                            IBusMessage    *message)
189 {
190     g_assert (IBUS_IS_FACTORY (factory));
191     g_assert (IBUS_IS_CONNECTION (connection));
192     g_assert (message != NULL);
193
194     IBusMessage *reply_message;
195     IBusFactoryPrivate *priv;
196     priv = IBUS_FACTORY_GET_PRIVATE (factory);
197
198     g_assert (priv->connection == connection);
199
200     if (ibus_message_is_method_call (message,
201                                      IBUS_INTERFACE_FACTORY,
202                                      "CreateEngine")) {
203         gchar *engine_name;
204         gchar *path;
205         IBusError *error;
206         IBusEngine *engine;
207         gboolean retval;
208         GType engine_type;
209
210         retval = ibus_message_get_args (message,
211                                         &error,
212                                         G_TYPE_STRING, &engine_name,
213                                         G_TYPE_INVALID);
214
215         if (!retval) {
216             reply_message = ibus_message_new_error_printf (message,
217                                         DBUS_ERROR_INVALID_ARGS,
218                                         "The 1st arg should be engine name");
219             ibus_connection_send (connection, reply_message);
220             ibus_message_unref (reply_message);
221             return TRUE;
222         }
223
224         engine_type = (GType )g_hash_table_lookup (priv->engine_table, engine_name);
225
226         if (engine_type == G_TYPE_INVALID) {
227              reply_message = ibus_message_new_error_printf (message,
228                                         DBUS_ERROR_FAILED,
229                                         "Can not create engine %s", engine_name);
230             ibus_connection_send (connection, reply_message);
231             ibus_message_unref (reply_message);
232             return TRUE;
233
234         }
235
236         path = g_strdup_printf ("/org/freedesktop/IBus/Engine/%d", ++priv->id);
237
238         engine = g_object_new (engine_type,
239                                "name", engine_name,
240                                "path", path,
241                                "connection", priv->connection,
242                                NULL);
243
244         priv->engine_list = g_list_append (priv->engine_list, engine);
245         g_signal_connect (engine,
246                           "destroy",
247                           G_CALLBACK (_engine_destroy_cb),
248                           factory);
249
250         reply_message = ibus_message_new_method_return (message);
251         ibus_message_append_args (reply_message,
252                                   IBUS_TYPE_OBJECT_PATH, &path,
253                                   G_TYPE_INVALID);
254         g_free (path);
255         ibus_connection_send (connection, reply_message);
256         ibus_message_unref (reply_message);
257         return TRUE;
258     }
259
260     return factory_parent_class->ibus_message ((IBusService *)factory,
261                                                connection,
262                                                message);
263 }
264
265 void
266 ibus_factory_add_engine (IBusFactory *factory,
267                          const gchar *engine_name,
268                          GType        engine_type)
269 {
270     g_assert (IBUS_IS_FACTORY (factory));
271     g_assert (engine_name);
272     g_assert (g_type_is_a (engine_type, IBUS_TYPE_ENGINE));
273
274     IBusFactoryPrivate *priv;
275     priv = IBUS_FACTORY_GET_PRIVATE (factory);
276
277     g_hash_table_insert (priv->engine_table, g_strdup (engine_name), (gpointer) engine_type);
278 }
279
280 #if 0
281 IBusFactoryInfo *
282 ibus_factory_get_info (IBusFactory *factory)
283 {
284     IBusFactoryPrivate *priv;
285     priv = IBUS_FACTORY_GET_PRIVATE (factory);
286
287     return priv->info;
288 }
289
290 GType
291 ibus_factory_info_get_type (void)
292 {
293     static GType type = 0;
294
295     static const GTypeInfo type_info = {
296         sizeof (IBusFactoryInfoClass),
297         (GBaseInitFunc)     NULL,
298         (GBaseFinalizeFunc) NULL,
299         (GClassInitFunc)    ibus_factory_info_class_init,
300         NULL,               /* class finialize */
301         NULL,               /* class data */
302         sizeof (IBusFactoryInfo),
303         0,
304         (GInstanceInitFunc) ibus_factory_info_init,
305     };
306
307     if (type == 0) {
308         type = g_type_register_static (IBUS_TYPE_SERIALIZABLE,
309                                        "IBusFactoryInfo",
310                                        &type_info,
311                                        0);
312     }
313
314     return type;
315 }
316
317 static void
318 ibus_factory_info_class_init (IBusFactoryInfoClass *klass)
319 {
320     IBusObjectClass *object_class = IBUS_OBJECT_CLASS (klass);
321     IBusSerializableClass *serializable_class = IBUS_SERIALIZABLE_CLASS (klass);
322
323     factory_info_parent_class = (IBusSerializableClass *) g_type_class_peek_parent (klass);
324
325     object_class->destroy = (IBusObjectDestroyFunc) ibus_factory_info_destroy;
326
327     serializable_class->serialize   = (IBusSerializableSerializeFunc) ibus_factory_info_serialize;
328     serializable_class->deserialize = (IBusSerializableDeserializeFunc) ibus_factory_info_deserialize;
329     serializable_class->copy        = (IBusSerializableCopyFunc) ibus_factory_info_copy;
330
331     g_string_append (serializable_class->signature, "osssss");
332 }
333
334 static void
335 ibus_factory_info_init (IBusFactoryInfo *info)
336 {
337     info->path = NULL;
338     info->name = NULL;
339     info->lang = NULL;
340     info->icon = NULL;
341     info->authors = NULL;
342     info->credits = NULL;
343 }
344
345 static void
346 ibus_factory_info_destroy (IBusFactoryInfo *info)
347 {
348     g_free (info->path);
349     g_free (info->name);
350     g_free (info->lang);
351     g_free (info->icon);
352     g_free (info->authors);
353     g_free (info->credits);
354
355     info->path = NULL;
356     info->lang = NULL;
357     info->name = NULL;
358     info->icon = NULL;
359     info->authors = NULL;
360     info->credits = NULL;
361
362     IBUS_OBJECT_CLASS (factory_info_parent_class)->destroy ((IBusObject *)info);
363 }
364
365 static gboolean
366 ibus_factory_info_serialize (IBusFactoryInfo *info,
367                              IBusMessageIter *iter)
368 {
369     gboolean retval;
370
371     retval = factory_info_parent_class->serialize ((IBusSerializable *)info, iter);
372     g_return_val_if_fail (retval, FALSE);
373
374     retval = ibus_message_iter_append (iter, IBUS_TYPE_OBJECT_PATH, &info->path);
375     g_return_val_if_fail (retval, FALSE);
376
377     retval = ibus_message_iter_append (iter, G_TYPE_STRING, &info->name);
378     g_return_val_if_fail (retval, FALSE);
379
380     retval = ibus_message_iter_append (iter, G_TYPE_STRING, &info->lang);
381     g_return_val_if_fail (retval, FALSE);
382
383     retval = ibus_message_iter_append (iter, G_TYPE_STRING, &info->icon);
384     g_return_val_if_fail (retval, FALSE);
385
386     retval = ibus_message_iter_append (iter, G_TYPE_STRING, &info->authors);
387     g_return_val_if_fail (retval, FALSE);
388
389     retval = ibus_message_iter_append (iter, G_TYPE_STRING, &info->credits);
390     g_return_val_if_fail (retval, FALSE);
391
392     return TRUE;
393 }
394
395 static gboolean
396 ibus_factory_info_deserialize (IBusFactoryInfo *info,
397                                IBusMessageIter *iter)
398 {
399     gboolean retval;
400
401     retval = factory_info_parent_class->deserialize ((IBusSerializable *)info, iter);
402     g_return_val_if_fail (retval, FALSE);
403
404     retval = ibus_message_iter_get (iter, IBUS_TYPE_OBJECT_PATH, &info->path);
405     g_return_val_if_fail (retval, FALSE);
406     ibus_message_iter_next (iter);
407     info->path = g_strdup (info->path);
408
409     retval = ibus_message_iter_get (iter, G_TYPE_STRING, &info->name);
410     g_return_val_if_fail (retval, FALSE);
411     ibus_message_iter_next (iter);
412     info->name = g_strdup (info->name);
413
414     retval = ibus_message_iter_get (iter, G_TYPE_STRING, &info->lang);
415     g_return_val_if_fail (retval, FALSE);
416     ibus_message_iter_next (iter);
417     info->lang = g_strdup (info->lang);
418
419     retval = ibus_message_iter_get (iter, G_TYPE_STRING, &info->icon);
420     g_return_val_if_fail (retval, FALSE);
421     ibus_message_iter_next (iter);
422     info->icon = g_strdup (info->icon);
423
424     retval = ibus_message_iter_get (iter, G_TYPE_STRING, &info->authors);
425     g_return_val_if_fail (retval, FALSE);
426     ibus_message_iter_next (iter);
427     info->authors = g_strdup (info->authors);
428
429     retval = ibus_message_iter_get (iter, G_TYPE_STRING, &info->credits);
430     g_return_val_if_fail (retval, FALSE);
431     ibus_message_iter_next (iter);
432     info->credits = g_strdup (info->credits);
433
434     return TRUE;
435 }
436
437 static gboolean
438 ibus_factory_info_copy (IBusFactoryInfo       *dest,
439                         const IBusFactoryInfo *src)
440 {
441     gboolean retval;
442
443     retval = factory_info_parent_class->copy ((IBusSerializable *)dest,
444                                               (IBusSerializable *)src);
445     g_return_val_if_fail (retval, FALSE);
446
447     g_return_val_if_fail (IBUS_IS_FACTORY_INFO (dest), FALSE);
448     g_return_val_if_fail (IBUS_IS_FACTORY_INFO (src), FALSE);
449
450     dest->path = g_strdup (src->path);
451     dest->name = g_strdup (src->name);
452     dest->lang = g_strdup (src->lang);
453     dest->icon = g_strdup (src->icon);
454     dest->authors = g_strdup (src->authors);
455     dest->credits = g_strdup (src->credits);
456
457     return TRUE;
458 }
459
460 IBusFactoryInfo *
461 ibus_factory_info_new (const gchar *path,
462                        const gchar *name,
463                        const gchar *lang,
464                        const gchar *icon,
465                        const gchar *authors,
466                        const gchar *credits)
467 {
468     g_assert (path);
469     g_assert (name);
470     g_assert (lang);
471     g_assert (icon);
472     g_assert (authors);
473     g_assert (credits);
474
475     IBusFactoryInfo *info;
476
477     info = (IBusFactoryInfo *) g_object_new (IBUS_TYPE_FACTORY_INFO, NULL);
478
479     info->path = g_strdup (path);
480     info->name = g_strdup (name);
481     info->lang = g_strdup (lang);
482     info->icon = g_strdup (icon);
483     info->authors = g_strdup (authors);
484     info->credits = g_strdup (credits);
485
486     return info;
487 }
488 #endif