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))
40 struct _IBusFactoryPrivate {
42 IBusConnection *connection;
44 GHashTable *engine_table;
46 typedef struct _IBusFactoryPrivate IBusFactoryPrivate;
48 /* functions prototype */
49 static void ibus_factory_destroy (IBusFactory *factory);
50 static void ibus_factory_set_property (IBusFactory *engine,
54 static void ibus_factory_get_property (IBusFactory *factory,
59 static gboolean ibus_factory_ibus_message (IBusFactory *factory,
60 IBusConnection *connection,
61 IBusMessage *message);
63 static void _engine_destroy_cb (IBusEngine *engine,
64 IBusFactory *factory);
66 G_DEFINE_TYPE (IBusFactory, ibus_factory, IBUS_TYPE_SERVICE)
69 ibus_factory_new (IBusConnection *connection)
71 g_assert (IBUS_IS_CONNECTION (connection));
74 IBusFactoryPrivate *priv;
76 factory = (IBusFactory *) g_object_new (IBUS_TYPE_FACTORY,
77 "path", IBUS_PATH_FACTORY,
78 "connection", connection,
80 priv = IBUS_FACTORY_GET_PRIVATE (factory);
86 ibus_factory_class_init (IBusFactoryClass *klass)
88 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
89 IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass);
91 g_type_class_add_private (klass, sizeof (IBusFactoryPrivate));
93 gobject_class->set_property = (GObjectSetPropertyFunc) ibus_factory_set_property;
94 gobject_class->get_property = (GObjectGetPropertyFunc) ibus_factory_get_property;
97 ibus_object_class->destroy = (IBusObjectDestroyFunc) ibus_factory_destroy;
99 IBUS_SERVICE_CLASS (klass)->ibus_message = (ServiceIBusMessageFunc) ibus_factory_ibus_message;
102 * IBusFactory:connection:
104 * Connection of this IBusFactory.
106 g_object_class_install_property (gobject_class,
108 g_param_spec_object ("connection",
110 "The connection of factory object",
111 IBUS_TYPE_CONNECTION,
112 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
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 g_object_unref (priv->connection);
151 priv->connection = NULL;
154 IBUS_OBJECT_CLASS(ibus_factory_parent_class)->destroy (IBUS_OBJECT (factory));
158 ibus_factory_set_property (IBusFactory *factory,
163 IBusFactoryPrivate *priv;
164 priv = IBUS_FACTORY_GET_PRIVATE (factory);
167 case PROP_CONNECTION:
168 priv->connection = g_value_get_object (value);
169 g_object_ref_sink (priv->connection);
170 ibus_service_add_to_connection ((IBusService *) factory,
175 G_OBJECT_WARN_INVALID_PROPERTY_ID (factory, prop_id, pspec);
180 ibus_factory_get_property (IBusFactory *factory,
185 IBusFactoryPrivate *priv;
186 priv = IBUS_FACTORY_GET_PRIVATE (factory);
189 case PROP_CONNECTION:
190 g_value_set_object (value, priv->connection);
194 G_OBJECT_WARN_INVALID_PROPERTY_ID (factory, prop_id, pspec);
199 _engine_destroy_cb (IBusEngine *engine,
200 IBusFactory *factory)
202 IBusFactoryPrivate *priv;
203 priv = IBUS_FACTORY_GET_PRIVATE (factory);
205 priv->engine_list = g_list_remove (priv->engine_list, engine);
206 g_object_unref (engine);
210 ibus_factory_ibus_message (IBusFactory *factory,
211 IBusConnection *connection,
212 IBusMessage *message)
214 g_assert (IBUS_IS_FACTORY (factory));
215 g_assert (IBUS_IS_CONNECTION (connection));
216 g_assert (message != NULL);
218 IBusMessage *reply_message;
219 IBusFactoryPrivate *priv;
220 priv = IBUS_FACTORY_GET_PRIVATE (factory);
222 g_assert (priv->connection == connection);
224 if (ibus_message_is_method_call (message,
225 IBUS_INTERFACE_FACTORY,
234 retval = ibus_message_get_args (message,
236 G_TYPE_STRING, &engine_name,
240 reply_message = ibus_message_new_error_printf (message,
241 DBUS_ERROR_INVALID_ARGS,
242 "The 1st arg should be engine name");
243 ibus_connection_send (connection, reply_message);
244 ibus_message_unref (reply_message);
248 engine_type = (GType )g_hash_table_lookup (priv->engine_table, engine_name);
250 if (engine_type == G_TYPE_INVALID) {
251 reply_message = ibus_message_new_error_printf (message,
253 "Can not create engine %s", engine_name);
254 ibus_connection_send (connection, reply_message);
255 ibus_message_unref (reply_message);
260 path = g_strdup_printf ("/org/freedesktop/IBus/Engine/%d", ++priv->id);
262 engine = g_object_new (engine_type,
265 "connection", priv->connection,
268 priv->engine_list = g_list_append (priv->engine_list, engine);
269 g_signal_connect (engine,
271 G_CALLBACK (_engine_destroy_cb),
274 reply_message = ibus_message_new_method_return (message);
275 ibus_message_append_args (reply_message,
276 IBUS_TYPE_OBJECT_PATH, &path,
279 ibus_connection_send (connection, reply_message);
280 ibus_message_unref (reply_message);
284 return IBUS_SERVICE_CLASS (ibus_factory_parent_class)->ibus_message (
285 (IBusService *)factory,
291 ibus_factory_add_engine (IBusFactory *factory,
292 const gchar *engine_name,
295 g_assert (IBUS_IS_FACTORY (factory));
296 g_assert (engine_name);
297 g_assert (g_type_is_a (engine_type, IBUS_TYPE_ENGINE));
299 IBusFactoryPrivate *priv;
300 priv = IBUS_FACTORY_GET_PRIVATE (factory);
302 g_hash_table_insert (priv->engine_table, g_strdup (engine_name), (gpointer) engine_type);