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.
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.
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.
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.
22 #include "ibusfactory.h"
23 #include "ibusengine.h"
24 #include "ibusshare.h"
25 #include "ibusinternal.h"
27 #define IBUS_FACTORY_GET_PRIVATE(o) \
28 (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_FACTORY, IBusFactoryPrivate))
35 struct _IBusFactoryPrivate {
37 IBusConnection *connection;
39 GHashTable *engine_table;
41 typedef struct _IBusFactoryPrivate IBusFactoryPrivate;
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);
51 static void _engine_destroy_cb (IBusEngine *engine,
52 IBusFactory *factory);
54 static IBusServiceClass *factory_parent_class = NULL;
57 ibus_factory_get_type (void)
59 static GType type = 0;
61 static const GTypeInfo type_info = {
62 sizeof (IBusFactoryClass),
64 (GBaseFinalizeFunc) NULL,
65 (GClassInitFunc) ibus_factory_class_init,
66 NULL, /* class finalize */
67 NULL, /* class data */
70 (GInstanceInitFunc) ibus_factory_init,
74 type = g_type_register_static (IBUS_TYPE_SERVICE,
83 ibus_factory_new (IBusConnection *connection)
85 g_assert (IBUS_IS_CONNECTION (connection));
88 IBusFactoryPrivate *priv;
90 factory = (IBusFactory *) g_object_new (IBUS_TYPE_FACTORY,
91 "path", IBUS_PATH_FACTORY,
93 priv = IBUS_FACTORY_GET_PRIVATE (factory);
95 priv->connection = g_object_ref (connection);
96 ibus_service_add_to_connection ((IBusService *)factory, connection);
102 ibus_factory_class_init (IBusFactoryClass *klass)
104 // GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
105 IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass);
107 factory_parent_class = (IBusServiceClass *) g_type_class_peek_parent (klass);
109 g_type_class_add_private (klass, sizeof (IBusFactoryPrivate));
111 ibus_object_class->destroy = (IBusObjectDestroyFunc) ibus_factory_destroy;
113 IBUS_SERVICE_CLASS (klass)->ibus_message = (ServiceIBusMessageFunc) ibus_factory_ibus_message;
118 ibus_factory_init (IBusFactory *factory)
120 IBusFactoryPrivate *priv;
121 priv = IBUS_FACTORY_GET_PRIVATE (factory);
124 priv->connection = NULL;
125 priv->engine_table = g_hash_table_new_full (g_str_hash,
129 priv->engine_list = NULL;
133 ibus_factory_destroy (IBusFactory *factory)
136 IBusFactoryPrivate *priv;
137 priv = IBUS_FACTORY_GET_PRIVATE (factory);
139 list = g_list_copy (priv->engine_list);
140 g_list_foreach (list, (GFunc) ibus_object_destroy, NULL);
141 g_list_free (priv->engine_list);
143 priv->engine_list = NULL;
145 if (priv->engine_table) {
146 g_hash_table_destroy (priv->engine_table);
149 if (priv->connection) {
150 ibus_service_remove_from_connection ((IBusService *)factory,
152 g_object_unref (priv->connection);
155 IBUS_OBJECT_CLASS(factory_parent_class)->destroy (IBUS_OBJECT (factory));
159 _engine_destroy_cb (IBusEngine *engine,
160 IBusFactory *factory)
162 IBusFactoryPrivate *priv;
163 priv = IBUS_FACTORY_GET_PRIVATE (factory);
165 priv->engine_list = g_list_remove (priv->engine_list, engine);
166 g_object_unref (engine);
170 ibus_factory_ibus_message (IBusFactory *factory,
171 IBusConnection *connection,
172 IBusMessage *message)
174 g_assert (IBUS_IS_FACTORY (factory));
175 g_assert (IBUS_IS_CONNECTION (connection));
176 g_assert (message != NULL);
178 IBusMessage *reply_message;
179 IBusFactoryPrivate *priv;
180 priv = IBUS_FACTORY_GET_PRIVATE (factory);
182 g_assert (priv->connection == connection);
184 if (ibus_message_is_method_call (message,
185 IBUS_INTERFACE_FACTORY,
194 retval = ibus_message_get_args (message,
196 G_TYPE_STRING, &engine_name,
200 reply_message = ibus_message_new_error_printf (message,
201 DBUS_ERROR_INVALID_ARGS,
202 "The 1st arg should be engine name");
203 ibus_connection_send (connection, reply_message);
204 ibus_message_unref (reply_message);
208 engine_type = (GType )g_hash_table_lookup (priv->engine_table, engine_name);
210 if (engine_type == G_TYPE_INVALID) {
211 reply_message = ibus_message_new_error_printf (message,
213 "Can not create engine %s", engine_name);
214 ibus_connection_send (connection, reply_message);
215 ibus_message_unref (reply_message);
220 path = g_strdup_printf ("/org/freedesktop/IBus/Engine/%d", ++priv->id);
222 engine = g_object_new (engine_type,
225 "connection", priv->connection,
228 priv->engine_list = g_list_append (priv->engine_list, engine);
229 g_signal_connect (engine,
231 G_CALLBACK (_engine_destroy_cb),
234 reply_message = ibus_message_new_method_return (message);
235 ibus_message_append_args (reply_message,
236 IBUS_TYPE_OBJECT_PATH, &path,
239 ibus_connection_send (connection, reply_message);
240 ibus_message_unref (reply_message);
244 return factory_parent_class->ibus_message ((IBusService *)factory,
250 ibus_factory_add_engine (IBusFactory *factory,
251 const gchar *engine_name,
254 g_assert (IBUS_IS_FACTORY (factory));
255 g_assert (engine_name);
256 g_assert (g_type_is_a (engine_type, IBUS_TYPE_ENGINE));
258 IBusFactoryPrivate *priv;
259 priv = IBUS_FACTORY_GET_PRIVATE (factory);
261 g_hash_table_insert (priv->engine_table, g_strdup (engine_name), (gpointer) engine_type);