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.
22 #include <dbus/dbus.h>
23 #include "ibusfactory.h"
24 #include "ibusengine.h"
25 #include "ibusshare.h"
26 #include "ibusinternal.h"
28 #define IBUS_FACTORY_GET_PRIVATE(o) \
29 (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_FACTORY, IBusFactoryPrivate))
41 struct _IBusFactoryPrivate {
43 IBusConnection *connection;
45 GHashTable *engine_table;
47 typedef struct _IBusFactoryPrivate IBusFactoryPrivate;
49 /* functions prototype */
50 static void ibus_factory_destroy (IBusFactory *factory);
51 static void ibus_factory_set_property (IBusFactory *engine,
55 static void ibus_factory_get_property (IBusFactory *factory,
60 static gboolean ibus_factory_ibus_message (IBusFactory *factory,
61 IBusConnection *connection,
62 IBusMessage *message);
64 static void _engine_destroy_cb (IBusEngine *engine,
65 IBusFactory *factory);
67 G_DEFINE_TYPE (IBusFactory, ibus_factory, IBUS_TYPE_SERVICE)
70 ibus_factory_new (IBusConnection *connection)
72 g_assert (IBUS_IS_CONNECTION (connection));
75 IBusFactoryPrivate *priv;
77 factory = (IBusFactory *) g_object_new (IBUS_TYPE_FACTORY,
78 "path", IBUS_PATH_FACTORY,
79 "connection", connection,
81 priv = IBUS_FACTORY_GET_PRIVATE (factory);
87 ibus_factory_class_init (IBusFactoryClass *klass)
89 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
90 IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass);
92 g_type_class_add_private (klass, sizeof (IBusFactoryPrivate));
94 gobject_class->set_property = (GObjectSetPropertyFunc) ibus_factory_set_property;
95 gobject_class->get_property = (GObjectGetPropertyFunc) ibus_factory_get_property;
98 ibus_object_class->destroy = (IBusObjectDestroyFunc) ibus_factory_destroy;
100 IBUS_SERVICE_CLASS (klass)->ibus_message = (ServiceIBusMessageFunc) ibus_factory_ibus_message;
103 * IBusFactory:connection:
105 * Connection of this IBusFactory.
107 g_object_class_install_property (gobject_class,
109 g_param_spec_object ("connection",
111 "The connection of factory object",
112 IBUS_TYPE_CONNECTION,
113 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
119 ibus_factory_init (IBusFactory *factory)
121 IBusFactoryPrivate *priv;
122 priv = IBUS_FACTORY_GET_PRIVATE (factory);
125 priv->connection = NULL;
126 priv->engine_table = g_hash_table_new_full (g_str_hash,
130 priv->engine_list = NULL;
134 ibus_factory_destroy (IBusFactory *factory)
137 IBusFactoryPrivate *priv;
138 priv = IBUS_FACTORY_GET_PRIVATE (factory);
140 list = g_list_copy (priv->engine_list);
141 g_list_foreach (list, (GFunc) ibus_object_destroy, NULL);
142 g_list_free (priv->engine_list);
144 priv->engine_list = NULL;
146 if (priv->engine_table) {
147 g_hash_table_destroy (priv->engine_table);
150 if (priv->connection) {
151 g_object_unref (priv->connection);
152 priv->connection = NULL;
155 IBUS_OBJECT_CLASS(ibus_factory_parent_class)->destroy (IBUS_OBJECT (factory));
159 ibus_factory_set_property (IBusFactory *factory,
164 IBusFactoryPrivate *priv;
165 priv = IBUS_FACTORY_GET_PRIVATE (factory);
168 case PROP_CONNECTION:
169 priv->connection = g_value_get_object (value);
170 g_object_ref_sink (priv->connection);
171 ibus_service_add_to_connection ((IBusService *) factory,
176 G_OBJECT_WARN_INVALID_PROPERTY_ID (factory, prop_id, pspec);
181 ibus_factory_get_property (IBusFactory *factory,
186 IBusFactoryPrivate *priv;
187 priv = IBUS_FACTORY_GET_PRIVATE (factory);
190 case PROP_CONNECTION:
191 g_value_set_object (value, priv->connection);
195 G_OBJECT_WARN_INVALID_PROPERTY_ID (factory, prop_id, pspec);
200 _engine_destroy_cb (IBusEngine *engine,
201 IBusFactory *factory)
203 IBusFactoryPrivate *priv;
204 priv = IBUS_FACTORY_GET_PRIVATE (factory);
206 priv->engine_list = g_list_remove (priv->engine_list, engine);
207 g_object_unref (engine);
211 ibus_factory_ibus_message (IBusFactory *factory,
212 IBusConnection *connection,
213 IBusMessage *message)
215 g_assert (IBUS_IS_FACTORY (factory));
216 g_assert (IBUS_IS_CONNECTION (connection));
217 g_assert (message != NULL);
219 IBusMessage *reply_message;
220 IBusFactoryPrivate *priv;
221 priv = IBUS_FACTORY_GET_PRIVATE (factory);
223 g_assert (priv->connection == connection);
225 if (ibus_message_is_method_call (message,
226 IBUS_INTERFACE_FACTORY,
235 retval = ibus_message_get_args (message,
237 G_TYPE_STRING, &engine_name,
241 reply_message = ibus_message_new_error_printf (message,
242 DBUS_ERROR_INVALID_ARGS,
243 "The 1st arg should be engine name");
244 ibus_connection_send (connection, reply_message);
245 ibus_message_unref (reply_message);
249 engine_type = (GType )g_hash_table_lookup (priv->engine_table, engine_name);
251 if (engine_type == G_TYPE_INVALID) {
252 reply_message = ibus_message_new_error_printf (message,
254 "Can not create engine %s", engine_name);
255 ibus_connection_send (connection, reply_message);
256 ibus_message_unref (reply_message);
261 path = g_strdup_printf ("/org/freedesktop/IBus/Engine/%d", ++priv->id);
263 engine = g_object_new (engine_type,
266 "connection", priv->connection,
269 priv->engine_list = g_list_append (priv->engine_list, engine);
270 g_signal_connect (engine,
272 G_CALLBACK (_engine_destroy_cb),
275 reply_message = ibus_message_new_method_return (message);
276 ibus_message_append_args (reply_message,
277 IBUS_TYPE_OBJECT_PATH, &path,
280 ibus_connection_send (connection, reply_message);
281 ibus_message_unref (reply_message);
285 return IBUS_SERVICE_CLASS (ibus_factory_parent_class)->ibus_message (
286 (IBusService *)factory,
292 ibus_factory_add_engine (IBusFactory *factory,
293 const gchar *engine_name,
296 g_assert (IBUS_IS_FACTORY (factory));
297 g_assert (engine_name);
298 g_assert (g_type_is_a (engine_type, IBUS_TYPE_ENGINE));
300 IBusFactoryPrivate *priv;
301 priv = IBUS_FACTORY_GET_PRIVATE (factory);
303 g_hash_table_insert (priv->engine_table, g_strdup (engine_name), (gpointer) engine_type);