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 "ibusfactory.h"
23 #include "ibusengine.h"
24 #include "ibusmarshalers.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 {
44 GHashTable *engine_table;
47 static guint factory_signals[LAST_SIGNAL] = { 0 };
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,
59 static void ibus_factory_service_method_call
60 (IBusService *service,
61 GDBusConnection *connection,
63 const gchar *object_path,
64 const gchar *interface_name,
65 const gchar *method_name,
69 static GVariant *ibus_factory_service_get_property
70 (IBusService *service,
71 GDBusConnection *connection,
73 const gchar *object_path,
74 const gchar *interface_name,
75 const gchar *property_name,
77 static gboolean ibus_factory_service_set_property
78 (IBusService *service,
79 GDBusConnection *connection,
81 const gchar *object_path,
82 const gchar *interface_name,
83 const gchar *property_name,
86 static void ibus_factory_engine_destroy_cb
88 IBusFactory *factory);
90 G_DEFINE_TYPE (IBusFactory, ibus_factory, IBUS_TYPE_SERVICE)
92 static const gchar introspection_xml[] =
94 " <interface name='org.freedesktop.IBus.Factory'>"
95 " <method name='CreateEngine'>"
96 " <arg direction='in' type='s' name='name' />"
97 " <arg direction='out' type='o' />"
103 ibus_factory_real_create_engine (IBusFactory *factory,
104 const gchar *engine_name)
107 gchar *object_path = NULL;
108 IBusEngine *engine = NULL;
110 engine_type = (GType) g_hash_table_lookup (factory->priv->engine_table,
113 g_return_val_if_fail (engine_type != G_TYPE_INVALID, NULL);
115 object_path = g_strdup_printf ("/org/freedesktop/IBus/Engine/%d",
116 ++factory->priv->id);
117 engine = ibus_engine_new_with_type (engine_type,
120 ibus_service_get_connection ((IBusService *)factory));
121 g_free (object_path);
127 _ibus_factory_create_engine_accumulator (GSignalInvocationHint *ihint,
129 const GValue *handler_return,
132 gboolean retval = TRUE;
133 GObject *object = g_value_get_object (handler_return);
135 if (object != NULL) {
136 g_value_copy (handler_return, return_accu);
144 ibus_factory_class_init (IBusFactoryClass *class)
146 GObjectClass *gobject_class = G_OBJECT_CLASS (class);
147 IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (class);
149 gobject_class->set_property = (GObjectSetPropertyFunc) ibus_factory_set_property;
150 gobject_class->get_property = (GObjectGetPropertyFunc) ibus_factory_get_property;
152 ibus_object_class->destroy = (IBusObjectDestroyFunc) ibus_factory_destroy;
154 IBUS_SERVICE_CLASS (class)->service_method_call = ibus_factory_service_method_call;
155 IBUS_SERVICE_CLASS (class)->service_get_property = ibus_factory_service_get_property;
156 IBUS_SERVICE_CLASS (class)->service_set_property = ibus_factory_service_set_property;
157 class->create_engine = ibus_factory_real_create_engine;
159 ibus_service_class_add_interfaces (IBUS_SERVICE_CLASS (class), introspection_xml);
161 g_type_class_add_private (class, sizeof (IBusFactoryPrivate));
164 * IBusFactory::create-engine:
165 * @factory: the factory which received the signal
166 * @engine_name: the engine_name which received the signal
167 * @returns: (transfer full): An IBusEngine
169 * The ::create-engine signal is a signal to create IBusEngine
170 * with @engine_name, which gets emitted when IBusFactory
171 * received CreateEngine dbus method. The callback functions
172 * will be called until a callback returns a non-null object
175 factory_signals[CREATE_ENGINE] =
176 g_signal_new (I_("create-engine"),
177 G_TYPE_FROM_CLASS (gobject_class),
179 G_STRUCT_OFFSET (IBusFactoryClass, create_engine),
180 _ibus_factory_create_engine_accumulator,
182 _ibus_marshal_OBJECT__STRING,
189 ibus_factory_init (IBusFactory *factory)
191 factory->priv = IBUS_FACTORY_GET_PRIVATE (factory);
192 factory->priv->engine_table =
193 g_hash_table_new_full (g_str_hash,
200 ibus_factory_destroy (IBusFactory *factory)
204 list = g_list_copy (factory->priv->engine_list);
205 g_list_free_full (list, (GDestroyNotify)ibus_object_destroy);
206 g_list_free(factory->priv->engine_list);
207 factory->priv->engine_list = NULL;
209 if (factory->priv->engine_table) {
210 g_hash_table_destroy (factory->priv->engine_table);
213 IBUS_OBJECT_CLASS(ibus_factory_parent_class)->destroy (IBUS_OBJECT (factory));
217 ibus_factory_set_property (IBusFactory *factory,
224 G_OBJECT_WARN_INVALID_PROPERTY_ID (factory, prop_id, pspec);
229 ibus_factory_get_property (IBusFactory *factory,
236 G_OBJECT_WARN_INVALID_PROPERTY_ID (factory, prop_id, pspec);
241 ibus_factory_engine_destroy_cb (IBusEngine *engine,
242 IBusFactory *factory)
244 factory->priv->engine_list = g_list_remove (factory->priv->engine_list, engine);
245 g_object_unref (engine);
249 ibus_factory_service_method_call (IBusService *service,
250 GDBusConnection *connection,
252 const gchar *object_path,
253 const gchar *interface_name,
254 const gchar *method_name,
255 GVariant *parameters,
256 GDBusMethodInvocation *invocation)
258 IBusFactory *factory = IBUS_FACTORY (service);
260 if (g_strcmp0 (method_name, "CreateEngine") == 0) {
261 gchar *engine_name = NULL;
262 IBusEngine *engine = NULL;
264 g_variant_get (parameters, "(&s)", &engine_name);
265 g_signal_emit (factory, factory_signals[CREATE_ENGINE],
266 0, engine_name, &engine);
268 if (engine != NULL) {
269 gchar *object_path = NULL;
270 GValue value = { 0, };
272 g_value_init (&value, G_TYPE_STRING);
273 g_object_get_property (G_OBJECT (engine), "object-path", &value);
274 object_path = g_value_dup_string (&value);
275 g_value_unset (&value);
277 g_assert (engine != NULL);
278 g_assert (object_path != NULL);
279 g_object_ref_sink (engine);
280 factory->priv->engine_list = g_list_append (factory->priv->engine_list, engine);
281 g_signal_connect (engine,
283 G_CALLBACK (ibus_factory_engine_destroy_cb),
285 g_dbus_method_invocation_return_value (invocation,
286 g_variant_new ("(o)", object_path));
287 g_free (object_path);
290 gchar *error_message = g_strdup_printf ("Can not fond engine %s", engine_name);
291 g_dbus_method_invocation_return_error (invocation,
295 g_free (error_message);
300 IBUS_SERVICE_CLASS (ibus_factory_parent_class)->
301 service_method_call (service,
312 ibus_factory_service_get_property (IBusService *service,
313 GDBusConnection *connection,
315 const gchar *object_path,
316 const gchar *interface_name,
317 const gchar *property_name,
320 return IBUS_SERVICE_CLASS (ibus_factory_parent_class)->
321 service_get_property (service,
331 ibus_factory_service_set_property (IBusService *service,
332 GDBusConnection *connection,
334 const gchar *object_path,
335 const gchar *interface_name,
336 const gchar *property_name,
340 return IBUS_SERVICE_CLASS (ibus_factory_parent_class)->
341 service_set_property (service,
352 ibus_factory_new (GDBusConnection *connection)
354 g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
356 IBusFactory *object = g_object_new (IBUS_TYPE_FACTORY,
357 "object-path", IBUS_PATH_FACTORY,
358 "connection", connection,
361 return IBUS_FACTORY (object);
365 ibus_factory_add_engine (IBusFactory *factory,
366 const gchar *engine_name,
369 g_return_if_fail (IBUS_IS_FACTORY (factory));
370 g_return_if_fail (engine_name != NULL);
371 g_return_if_fail (g_type_is_a (engine_type, IBUS_TYPE_ENGINE));
373 g_hash_table_insert (factory->priv->engine_table, g_strdup (engine_name), (gpointer) engine_type);
377 ibus_factory_create_engine (IBusFactory *factory,
378 const gchar *engine_name)
380 IBusEngine *engine = NULL;
382 g_assert (engine_name != NULL);
384 g_signal_emit (factory, factory_signals[CREATE_ENGINE],
385 0, engine_name, &engine);