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_destroy (IBusFactory *factory);
45 static gboolean ibus_factory_ibus_message (IBusFactory *factory,
46 IBusConnection *connection,
47 IBusMessage *message);
49 static void _engine_destroy_cb (IBusEngine *engine,
50 IBusFactory *factory);
52 G_DEFINE_TYPE (IBusFactory, ibus_factory, IBUS_TYPE_SERVICE)
55 ibus_factory_new (IBusConnection *connection)
57 g_assert (IBUS_IS_CONNECTION (connection));
60 IBusFactoryPrivate *priv;
62 factory = (IBusFactory *) g_object_new (IBUS_TYPE_FACTORY,
63 "path", IBUS_PATH_FACTORY,
65 priv = IBUS_FACTORY_GET_PRIVATE (factory);
67 priv->connection = g_object_ref_sink (connection);
68 ibus_service_add_to_connection ((IBusService *)factory, connection);
74 ibus_factory_class_init (IBusFactoryClass *klass)
76 // GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
77 IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass);
79 g_type_class_add_private (klass, sizeof (IBusFactoryPrivate));
81 ibus_object_class->destroy = (IBusObjectDestroyFunc) ibus_factory_destroy;
83 IBUS_SERVICE_CLASS (klass)->ibus_message = (ServiceIBusMessageFunc) ibus_factory_ibus_message;
88 ibus_factory_init (IBusFactory *factory)
90 IBusFactoryPrivate *priv;
91 priv = IBUS_FACTORY_GET_PRIVATE (factory);
94 priv->connection = NULL;
95 priv->engine_table = g_hash_table_new_full (g_str_hash,
99 priv->engine_list = NULL;
103 ibus_factory_destroy (IBusFactory *factory)
106 IBusFactoryPrivate *priv;
107 priv = IBUS_FACTORY_GET_PRIVATE (factory);
109 list = g_list_copy (priv->engine_list);
110 g_list_foreach (list, (GFunc) ibus_object_destroy, NULL);
111 g_list_free (priv->engine_list);
113 priv->engine_list = NULL;
115 if (priv->engine_table) {
116 g_hash_table_destroy (priv->engine_table);
119 if (priv->connection) {
120 ibus_service_remove_from_connection ((IBusService *)factory,
122 g_object_unref (priv->connection);
125 IBUS_OBJECT_CLASS(ibus_factory_parent_class)->destroy (IBUS_OBJECT (factory));
129 _engine_destroy_cb (IBusEngine *engine,
130 IBusFactory *factory)
132 IBusFactoryPrivate *priv;
133 priv = IBUS_FACTORY_GET_PRIVATE (factory);
135 priv->engine_list = g_list_remove (priv->engine_list, engine);
136 g_object_unref (engine);
140 ibus_factory_ibus_message (IBusFactory *factory,
141 IBusConnection *connection,
142 IBusMessage *message)
144 g_assert (IBUS_IS_FACTORY (factory));
145 g_assert (IBUS_IS_CONNECTION (connection));
146 g_assert (message != NULL);
148 IBusMessage *reply_message;
149 IBusFactoryPrivate *priv;
150 priv = IBUS_FACTORY_GET_PRIVATE (factory);
152 g_assert (priv->connection == connection);
154 if (ibus_message_is_method_call (message,
155 IBUS_INTERFACE_FACTORY,
164 retval = ibus_message_get_args (message,
166 G_TYPE_STRING, &engine_name,
170 reply_message = ibus_message_new_error_printf (message,
171 DBUS_ERROR_INVALID_ARGS,
172 "The 1st arg should be engine name");
173 ibus_connection_send (connection, reply_message);
174 ibus_message_unref (reply_message);
178 engine_type = (GType )g_hash_table_lookup (priv->engine_table, engine_name);
180 if (engine_type == G_TYPE_INVALID) {
181 reply_message = ibus_message_new_error_printf (message,
183 "Can not create engine %s", engine_name);
184 ibus_connection_send (connection, reply_message);
185 ibus_message_unref (reply_message);
190 path = g_strdup_printf ("/org/freedesktop/IBus/Engine/%d", ++priv->id);
192 engine = g_object_new (engine_type,
195 "connection", priv->connection,
198 priv->engine_list = g_list_append (priv->engine_list, engine);
199 g_signal_connect (engine,
201 G_CALLBACK (_engine_destroy_cb),
204 reply_message = ibus_message_new_method_return (message);
205 ibus_message_append_args (reply_message,
206 IBUS_TYPE_OBJECT_PATH, &path,
209 ibus_connection_send (connection, reply_message);
210 ibus_message_unref (reply_message);
214 return IBUS_SERVICE_CLASS (ibus_factory_parent_class)->ibus_message (
215 (IBusService *)factory,
221 ibus_factory_add_engine (IBusFactory *factory,
222 const gchar *engine_name,
225 g_assert (IBUS_IS_FACTORY (factory));
226 g_assert (engine_name);
227 g_assert (g_type_is_a (engine_type, IBUS_TYPE_ENGINE));
229 IBusFactoryPrivate *priv;
230 priv = IBUS_FACTORY_GET_PRIVATE (factory);
232 g_hash_table_insert (priv->engine_table, g_strdup (engine_name), (gpointer) engine_type);