summaryrefslogtreecommitdiffstats
path: root/src/ibusfactory.c
diff options
context:
space:
mode:
authorHuang Peng <shawn.p.huang@gmail.com>2009-02-05 10:39:56 +0800
committerHuang Peng <shawn.p.huang@gmail.com>2009-02-05 10:39:56 +0800
commitaedad1ea0a7fef604aa27f4b58433fd8f2ece29e (patch)
treeffcb531d8474bde18b90341bcd4eb639edd74525 /src/ibusfactory.c
parent41ad46305a88637dd99f00a2d2a3f455505d357b (diff)
downloadibus-aedad1ea0a7fef604aa27f4b58433fd8f2ece29e.tar.gz
ibus-aedad1ea0a7fef604aa27f4b58433fd8f2ece29e.tar.xz
ibus-aedad1ea0a7fef604aa27f4b58433fd8f2ece29e.zip
re-implement ibus in c language.
Diffstat (limited to 'src/ibusfactory.c')
-rw-r--r--src/ibusfactory.c483
1 files changed, 483 insertions, 0 deletions
diff --git a/src/ibusfactory.c b/src/ibusfactory.c
new file mode 100644
index 0000000..af9d887
--- /dev/null
+++ b/src/ibusfactory.c
@@ -0,0 +1,483 @@
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2009 Huang Peng <shawn.p.huang@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "ibusfactory.h"
+#include "ibusengine.h"
+#include "ibusshare.h"
+#include "ibusinternal.h"
+
+#define IBUS_FACTORY_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_FACTORY, IBusFactoryPrivate))
+
+enum {
+ LAST_SIGNAL,
+};
+
+/* IBusFactoryPriv */
+struct _IBusFactoryPrivate {
+ guint id;
+ IBusConnection *connection;
+ GList *engine_list;
+ GHashTable *engine_table;
+};
+typedef struct _IBusFactoryPrivate IBusFactoryPrivate;
+
+/* functions prototype */
+static void ibus_factory_class_init (IBusFactoryClass *klass);
+static void ibus_factory_init (IBusFactory *factory);
+static void ibus_factory_destroy (IBusFactory *factory);
+static gboolean ibus_factory_ibus_message (IBusFactory *factory,
+ IBusConnection *connection,
+ IBusMessage *message);
+
+static void _engine_destroy_cb (IBusEngine *engine,
+ IBusFactory *factory);
+static void ibus_factory_info_class_init(IBusFactoryInfoClass *klass);
+static void ibus_factory_info_init (IBusFactoryInfo *info);
+static void ibus_factory_info_destroy (IBusFactoryInfo *info);
+static gboolean ibus_factory_info_serialize (IBusFactoryInfo *info,
+ IBusMessageIter *iter);
+static gboolean ibus_factory_info_deserialize
+ (IBusFactoryInfo *info,
+ IBusMessageIter *iter);
+static gboolean ibus_factory_info_copy (IBusFactoryInfo *dest,
+ const IBusFactoryInfo *src);
+
+static IBusServiceClass *factory_parent_class = NULL;
+static IBusSerializableClass *factory_info_parent_class = NULL;
+
+GType
+ibus_factory_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (IBusFactoryClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ibus_factory_class_init,
+ NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof (IBusFactory),
+ 0,
+ (GInstanceInitFunc) ibus_factory_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_SERVICE,
+ "IBusFactory",
+ &type_info,
+ (GTypeFlags) 0);
+ }
+ return type;
+}
+
+IBusFactory *
+ibus_factory_new (IBusConnection *connection)
+{
+ g_assert (IBUS_IS_CONNECTION (connection));
+
+ IBusFactory *factory;
+ IBusFactoryPrivate *priv;
+
+ factory = (IBusFactory *) g_object_new (IBUS_TYPE_FACTORY,
+ "path", IBUS_PATH_FACTORY,
+ 0);
+ priv = IBUS_FACTORY_GET_PRIVATE (factory);
+
+ priv->connection = g_object_ref (connection);
+ ibus_service_add_to_connection ((IBusService *)factory, connection);
+
+ return factory;
+}
+
+static void
+ibus_factory_class_init (IBusFactoryClass *klass)
+{
+ // GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass);
+
+ factory_parent_class = (IBusServiceClass *) g_type_class_peek_parent (klass);
+
+ g_type_class_add_private (klass, sizeof (IBusFactoryPrivate));
+
+ ibus_object_class->destroy = (IBusObjectDestroyFunc) ibus_factory_destroy;
+
+ IBUS_SERVICE_CLASS (klass)->ibus_message = (ServiceIBusMessageFunc) ibus_factory_ibus_message;
+
+}
+
+static void
+ibus_factory_init (IBusFactory *factory)
+{
+ IBusFactoryPrivate *priv;
+ priv = IBUS_FACTORY_GET_PRIVATE (factory);
+
+ priv->id = 0;
+ priv->connection = NULL;
+ priv->engine_table = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ g_free,
+ NULL);
+ priv->engine_list = NULL;
+}
+
+static void
+ibus_factory_destroy (IBusFactory *factory)
+{
+ GList *list;
+ IBusFactoryPrivate *priv;
+ priv = IBUS_FACTORY_GET_PRIVATE (factory);
+
+ list = g_list_copy (priv->engine_list);
+ g_list_foreach (list, (GFunc) ibus_object_destroy, NULL);
+ g_list_free (priv->engine_list);
+ g_list_free (list);
+ priv->engine_list = NULL;
+
+ if (priv->engine_table) {
+ g_hash_table_destroy (priv->engine_table);
+ }
+
+ if (priv->connection) {
+ ibus_service_remove_from_connection ((IBusService *)factory,
+ priv->connection);
+ g_object_unref (priv->connection);
+ }
+
+ IBUS_OBJECT_CLASS(factory_parent_class)->destroy (IBUS_OBJECT (factory));
+}
+
+static void
+_engine_destroy_cb (IBusEngine *engine,
+ IBusFactory *factory)
+{
+ GList *list;
+ IBusFactoryPrivate *priv;
+ priv = IBUS_FACTORY_GET_PRIVATE (factory);
+
+ list = g_list_remove (priv->engine_list, engine);
+
+ if (list) {
+ g_object_unref (engine);
+ g_list_free_1 (list);
+ }
+}
+
+static gboolean
+ibus_factory_ibus_message (IBusFactory *factory,
+ IBusConnection *connection,
+ IBusMessage *message)
+{
+ g_assert (IBUS_IS_FACTORY (factory));
+ g_assert (IBUS_IS_CONNECTION (connection));
+ g_assert (message != NULL);
+
+ IBusMessage *reply_message;
+ IBusFactoryPrivate *priv;
+ priv = IBUS_FACTORY_GET_PRIVATE (factory);
+
+ g_assert (priv->connection == connection);
+
+ if (ibus_message_is_method_call (message,
+ IBUS_INTERFACE_FACTORY,
+ "CreateEngine")) {
+ gchar *engine_name;
+ gchar *path;
+ IBusError *error;
+ IBusEngine *engine;
+ gboolean retval;
+ GType engine_type;
+
+ retval = ibus_message_get_args (message,
+ &error,
+ G_TYPE_STRING, &engine_name,
+ G_TYPE_INVALID);
+
+ if (!retval) {
+ reply_message = ibus_message_new_error_printf (message,
+ DBUS_ERROR_INVALID_ARGS,
+ "The 1st arg should be engine name");
+ ibus_connection_send (connection, reply_message);
+ ibus_message_unref (reply_message);
+ return TRUE;
+ }
+
+ engine_type = (GType )g_hash_table_lookup (priv->engine_table, engine_name);
+
+ if (engine_type == G_TYPE_INVALID) {
+ reply_message = ibus_message_new_error_printf (message,
+ DBUS_ERROR_FAILED,
+ "Can not create engine %s", engine_name);
+ ibus_connection_send (connection, reply_message);
+ ibus_message_unref (reply_message);
+ return TRUE;
+
+ }
+
+ path = g_strdup_printf ("/org/freedesktop/IBus/Engine/%d", ++priv->id);
+
+ engine = g_object_new (engine_type,
+ "name", engine_name,
+ "path", path,
+ "connection", priv->connection,
+ 0);
+
+ priv->engine_list = g_list_append (priv->engine_list, engine);
+ g_signal_connect (engine,
+ "destroy",
+ G_CALLBACK (_engine_destroy_cb),
+ factory);
+
+ reply_message = ibus_message_new_method_return (message);
+ ibus_message_append_args (reply_message,
+ IBUS_TYPE_OBJECT_PATH, &path,
+ G_TYPE_INVALID);
+ g_free (path);
+ ibus_connection_send (connection, reply_message);
+ ibus_message_unref (reply_message);
+ return TRUE;
+ }
+
+ return factory_parent_class->ibus_message ((IBusService *)factory,
+ connection,
+ message);
+}
+
+void
+ibus_factory_add_engine (IBusFactory *factory,
+ const gchar *engine_name,
+ GType engine_type)
+{
+ g_assert (IBUS_IS_FACTORY (factory));
+ g_assert (engine_name);
+ g_assert (g_type_is_a (engine_type, IBUS_TYPE_ENGINE));
+
+ IBusFactoryPrivate *priv;
+ priv = IBUS_FACTORY_GET_PRIVATE (factory);
+
+ g_hash_table_insert (priv->engine_table, g_strdup (engine_name), (gpointer) engine_type);
+}
+
+#if 0
+IBusFactoryInfo *
+ibus_factory_get_info (IBusFactory *factory)
+{
+ IBusFactoryPrivate *priv;
+ priv = IBUS_FACTORY_GET_PRIVATE (factory);
+
+ return priv->info;
+}
+#endif
+
+GType
+ibus_factory_info_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (IBusFactoryInfoClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ibus_factory_info_class_init,
+ NULL, /* class finialize */
+ NULL, /* class data */
+ sizeof (IBusFactoryInfo),
+ 0,
+ (GInstanceInitFunc) ibus_factory_info_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_SERIALIZABLE,
+ "IBusFactoryInfo",
+ &type_info,
+ 0);
+ }
+
+ return type;
+}
+
+static void
+ibus_factory_info_class_init (IBusFactoryInfoClass *klass)
+{
+ IBusObjectClass *object_class = IBUS_OBJECT_CLASS (klass);
+ IBusSerializableClass *serializable_class = IBUS_SERIALIZABLE_CLASS (klass);
+
+ factory_info_parent_class = (IBusSerializableClass *) g_type_class_peek_parent (klass);
+
+ object_class->destroy = (IBusObjectDestroyFunc) ibus_factory_info_destroy;
+
+ serializable_class->serialize = (IBusSerializableSerializeFunc) ibus_factory_info_serialize;
+ serializable_class->deserialize = (IBusSerializableDeserializeFunc) ibus_factory_info_deserialize;
+ serializable_class->copy = (IBusSerializableCopyFunc) ibus_factory_info_copy;
+
+ g_string_append (serializable_class->signature, "osssss");
+}
+
+static void
+ibus_factory_info_init (IBusFactoryInfo *info)
+{
+ info->path = NULL;
+ info->name = NULL;
+ info->lang = NULL;
+ info->icon = NULL;
+ info->authors = NULL;
+ info->credits = NULL;
+}
+
+static void
+ibus_factory_info_destroy (IBusFactoryInfo *info)
+{
+ g_free (info->path);
+ g_free (info->name);
+ g_free (info->lang);
+ g_free (info->icon);
+ g_free (info->authors);
+ g_free (info->credits);
+
+ info->path = NULL;
+ info->lang = NULL;
+ info->name = NULL;
+ info->icon = NULL;
+ info->authors = NULL;
+ info->credits = NULL;
+
+ IBUS_OBJECT_CLASS (factory_info_parent_class)->destroy ((IBusObject *)info);
+}
+
+static gboolean
+ibus_factory_info_serialize (IBusFactoryInfo *info,
+ IBusMessageIter *iter)
+{
+ gboolean retval;
+
+ retval = factory_info_parent_class->serialize ((IBusSerializable *)info, iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, IBUS_TYPE_OBJECT_PATH, &info->path);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_STRING, &info->name);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_STRING, &info->lang);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_STRING, &info->icon);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_STRING, &info->authors);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_append (iter, G_TYPE_STRING, &info->credits);
+ g_return_val_if_fail (retval, FALSE);
+
+ return TRUE;
+}
+
+static gboolean
+ibus_factory_info_deserialize (IBusFactoryInfo *info,
+ IBusMessageIter *iter)
+{
+ gboolean retval;
+
+ retval = factory_info_parent_class->deserialize ((IBusSerializable *)info, iter);
+ g_return_val_if_fail (retval, FALSE);
+
+ retval = ibus_message_iter_get (iter, IBUS_TYPE_OBJECT_PATH, &info->path);
+ g_return_val_if_fail (retval, FALSE);
+ info->path = g_strdup (info->path);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_STRING, &info->name);
+ g_return_val_if_fail (retval, FALSE);
+ info->name = g_strdup (info->name);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_STRING, &info->lang);
+ g_return_val_if_fail (retval, FALSE);
+ info->lang = g_strdup (info->lang);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_STRING, &info->icon);
+ g_return_val_if_fail (retval, FALSE);
+ info->icon = g_strdup (info->icon);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_STRING, &info->authors);
+ g_return_val_if_fail (retval, FALSE);
+ info->authors = g_strdup (info->authors);
+
+ retval = ibus_message_iter_get (iter, G_TYPE_STRING, &info->credits);
+ g_return_val_if_fail (retval, FALSE);
+ info->credits = g_strdup (info->credits);
+
+ return TRUE;
+}
+
+static gboolean
+ibus_factory_info_copy (IBusFactoryInfo *dest,
+ const IBusFactoryInfo *src)
+{
+ gboolean retval;
+
+ retval = factory_info_parent_class->copy ((IBusSerializable *)dest,
+ (IBusSerializable *)src);
+ g_return_val_if_fail (retval, FALSE);
+
+ g_return_val_if_fail (IBUS_IS_FACTORY_INFO (dest), FALSE);
+ g_return_val_if_fail (IBUS_IS_FACTORY_INFO (src), FALSE);
+
+ dest->path = g_strdup (src->path);
+ dest->name = g_strdup (src->name);
+ dest->lang = g_strdup (src->lang);
+ dest->icon = g_strdup (src->icon);
+ dest->authors = g_strdup (src->authors);
+ dest->credits = g_strdup (src->credits);
+
+ return TRUE;
+}
+
+IBusFactoryInfo *
+ibus_factory_info_new (const gchar *path,
+ const gchar *name,
+ const gchar *lang,
+ const gchar *icon,
+ const gchar *authors,
+ const gchar *credits)
+{
+ g_assert (path);
+ g_assert (name);
+ g_assert (lang);
+ g_assert (icon);
+ g_assert (authors);
+ g_assert (credits);
+
+ IBusFactoryInfo *info;
+
+ info = (IBusFactoryInfo *)g_object_new (IBUS_TYPE_FACTORY_INFO, 0);
+
+ info->path = g_strdup (path);
+ info->name = g_strdup (name);
+ info->lang = g_strdup (lang);
+ info->icon = g_strdup (icon);
+ info->authors = g_strdup (authors);
+ info->credits = g_strdup (credits);
+
+ return info;
+}
+
+