Blame src/ibusservice.c

Packit Service 1d8f1c
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
Packit Service 1d8f1c
/* vim:set et sts=4: */
Packit Service 1d8f1c
/* ibus - The Input Bus
Packit Service 1d8f1c
 * Copyright (C) 2008-2015 Peng Huang <shawn.p.huang@gmail.com>
Packit Service 1d8f1c
 * Copyright (C) 2015-2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
Packit Service 1d8f1c
 * Copyright (C) 2008-2018 Red Hat, Inc.
Packit Service 1d8f1c
 *
Packit Service 1d8f1c
 * This library is free software; you can redistribute it and/or
Packit Service 1d8f1c
 * modify it under the terms of the GNU Lesser General Public
Packit Service 1d8f1c
 * License as published by the Free Software Foundation; either
Packit Service 1d8f1c
 * version 2.1 of the License, or (at your option) any later version.
Packit Service 1d8f1c
 *
Packit Service 1d8f1c
 * This library is distributed in the hope that it will be useful,
Packit Service 1d8f1c
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 1d8f1c
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 1d8f1c
 * Lesser General Public License for more details.
Packit Service 1d8f1c
 *
Packit Service 1d8f1c
 * You should have received a copy of the GNU Lesser General Public
Packit Service 1d8f1c
 * License along with this library; if not, write to the Free Software
Packit Service 1d8f1c
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
Packit Service 1d8f1c
 * USA
Packit Service 1d8f1c
 */
Packit Service 1d8f1c
#include "ibusservice.h"
Packit Service 1d8f1c
#include "ibusinternal.h"
Packit Service 1d8f1c
Packit Service 1d8f1c
#define IBUS_SERVICE_GET_PRIVATE(o)  \
Packit Service 1d8f1c
   (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_SERVICE, IBusServicePrivate))
Packit Service 1d8f1c
Packit Service 1d8f1c
enum {
Packit Service 1d8f1c
    LAST_SIGNAL
Packit Service 1d8f1c
};
Packit Service 1d8f1c
Packit Service 1d8f1c
enum {
Packit Service 1d8f1c
    PROP_0,
Packit Service 1d8f1c
    PROP_OBJECT_PATH,
Packit Service 1d8f1c
    PROP_CONNECTION,
Packit Service 1d8f1c
};
Packit Service 1d8f1c
Packit Service 1d8f1c
/* IBusServicePrivate */
Packit Service 1d8f1c
struct _IBusServicePrivate {
Packit Service 1d8f1c
    gchar *object_path;
Packit Service 1d8f1c
    GDBusConnection *connection;
Packit Service 1d8f1c
    GHashTable *table;
Packit Service 1d8f1c
    gboolean constructed;
Packit Service 1d8f1c
};
Packit Service 1d8f1c
Packit Service 1d8f1c
/*
Packit Service 1d8f1c
static guint    service_signals[LAST_SIGNAL] = { 0 };
Packit Service 1d8f1c
*/
Packit Service 1d8f1c
Packit Service 1d8f1c
/* functions prototype */
Packit Service 1d8f1c
static void      ibus_service_base_init      (IBusServiceClass   *class);
Packit Service 1d8f1c
static void      ibus_service_base_fini      (IBusServiceClass   *class);
Packit Service 1d8f1c
static void      ibus_service_class_init     (IBusServiceClass   *class);
Packit Service 1d8f1c
static void      ibus_service_init           (IBusService        *service);
Packit Service 1d8f1c
static void      ibus_service_constructed    (GObject            *object);
Packit Service 1d8f1c
static void      ibus_service_set_property   (IBusService        *service,
Packit Service 1d8f1c
                                              guint               prop_id,
Packit Service 1d8f1c
                                              const GValue       *value,
Packit Service 1d8f1c
                                              GParamSpec         *pspec);
Packit Service 1d8f1c
static void      ibus_service_get_property   (IBusService        *service,
Packit Service 1d8f1c
                                              guint               prop_id,
Packit Service 1d8f1c
                                              GValue             *value,
Packit Service 1d8f1c
                                              GParamSpec         *pspec);
Packit Service 1d8f1c
static void      ibus_service_destroy        (IBusService        *service);
Packit Service 1d8f1c
static void      ibus_service_service_method_call
Packit Service 1d8f1c
                                             (IBusService        *service,
Packit Service 1d8f1c
                                              GDBusConnection    *connection,
Packit Service 1d8f1c
                                              const gchar        *sender,
Packit Service 1d8f1c
                                              const gchar        *object_path,
Packit Service 1d8f1c
                                              const gchar        *interface_name,
Packit Service 1d8f1c
                                              const gchar        *method_name,
Packit Service 1d8f1c
                                              GVariant           *parameters,
Packit Service 1d8f1c
                                              GDBusMethodInvocation
Packit Service 1d8f1c
                                                                 *invocation);
Packit Service 1d8f1c
static GVariant *ibus_service_service_get_property
Packit Service 1d8f1c
                                             (IBusService        *service,
Packit Service 1d8f1c
                                              GDBusConnection    *connection,
Packit Service 1d8f1c
                                              const gchar        *sender,
Packit Service 1d8f1c
                                              const gchar        *object_path,
Packit Service 1d8f1c
                                              const gchar        *interface_name,
Packit Service 1d8f1c
                                              const gchar        *property_name,
Packit Service 1d8f1c
                                              GError            **error);
Packit Service 1d8f1c
static gboolean  ibus_service_service_set_property
Packit Service 1d8f1c
                                             (IBusService        *service,
Packit Service 1d8f1c
                                              GDBusConnection    *connection,
Packit Service 1d8f1c
                                              const gchar        *sender,
Packit Service 1d8f1c
                                              const gchar        *object_path,
Packit Service 1d8f1c
                                              const gchar        *interface_name,
Packit Service 1d8f1c
                                              const gchar        *property_name,
Packit Service 1d8f1c
                                              GVariant           *value,
Packit Service 1d8f1c
                                              GError            **error);
Packit Service 1d8f1c
static void      ibus_service_service_method_call_cb
Packit Service 1d8f1c
                                             (GDBusConnection    *connection,
Packit Service 1d8f1c
                                              const gchar        *sender,
Packit Service 1d8f1c
                                              const gchar        *object_path,
Packit Service 1d8f1c
                                              const gchar        *interface_name,
Packit Service 1d8f1c
                                              const gchar        *method_name,
Packit Service 1d8f1c
                                              GVariant           *parameters,
Packit Service 1d8f1c
                                              GDBusMethodInvocation
Packit Service 1d8f1c
                                                                 *invocation,
Packit Service 1d8f1c
                                              IBusService        *service);
Packit Service 1d8f1c
static GVariant *ibus_service_service_get_property_cb
Packit Service 1d8f1c
                                             (GDBusConnection    *connection,
Packit Service 1d8f1c
                                              const gchar        *sender,
Packit Service 1d8f1c
                                              const gchar        *object_path,
Packit Service 1d8f1c
                                              const gchar        *interface_name,
Packit Service 1d8f1c
                                              const gchar        *property_name,
Packit Service 1d8f1c
                                              GError            **error,
Packit Service 1d8f1c
                                              IBusService        *service);
Packit Service 1d8f1c
static gboolean  ibus_service_service_set_property_cb
Packit Service 1d8f1c
                                             (GDBusConnection    *connection,
Packit Service 1d8f1c
                                              const gchar        *sender,
Packit Service 1d8f1c
                                              const gchar        *object_path,
Packit Service 1d8f1c
                                              const gchar        *interface_name,
Packit Service 1d8f1c
                                              const gchar        *property_name,
Packit Service 1d8f1c
                                              GVariant           *value,
Packit Service 1d8f1c
                                              GError            **error,
Packit Service 1d8f1c
                                              IBusService        *service);
Packit Service 1d8f1c
static void      ibus_service_connection_closed_cb
Packit Service 1d8f1c
                                             (GDBusConnection    *connection,
Packit Service 1d8f1c
                                              gboolean            remote_peer_vanished,
Packit Service 1d8f1c
                                              GError             *error,
Packit Service 1d8f1c
                                              IBusService        *service);
Packit Service 1d8f1c
static void      ibus_service_unregister_cb  (GDBusConnection    *connection,
Packit Service 1d8f1c
                                              guint              *ids,
Packit Service 1d8f1c
                                              IBusService        *service);
Packit Service 1d8f1c
Packit Service 1d8f1c
static const GDBusInterfaceVTable ibus_service_interface_vtable = {
Packit Service 1d8f1c
    (GDBusInterfaceMethodCallFunc) ibus_service_service_method_call_cb,
Packit Service 1d8f1c
    (GDBusInterfaceGetPropertyFunc) ibus_service_service_get_property_cb,
Packit Service 1d8f1c
    (GDBusInterfaceSetPropertyFunc) ibus_service_service_set_property_cb
Packit Service 1d8f1c
};
Packit Service 1d8f1c
Packit Service 1d8f1c
static IBusObjectClass *ibus_service_parent_class = NULL;
Packit Service 1d8f1c
Packit Service 1d8f1c
GType
Packit Service 1d8f1c
ibus_service_get_type (void)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    static GType type = 0;
Packit Service 1d8f1c
Packit Service 1d8f1c
    static const GTypeInfo type_info = {
Packit Service 1d8f1c
        sizeof (IBusServiceClass),
Packit Service 1d8f1c
        (GBaseInitFunc)     ibus_service_base_init,
Packit Service 1d8f1c
        (GBaseFinalizeFunc) ibus_service_base_fini,
Packit Service 1d8f1c
        (GClassInitFunc)    ibus_service_class_init,
Packit Service 1d8f1c
        NULL,               /* class finialize */
Packit Service 1d8f1c
        NULL,               /* class data */
Packit Service 1d8f1c
        sizeof (IBusService),
Packit Service 1d8f1c
        0,
Packit Service 1d8f1c
        (GInstanceInitFunc) ibus_service_init,
Packit Service 1d8f1c
    };
Packit Service 1d8f1c
Packit Service 1d8f1c
    if (type == 0) {
Packit Service 1d8f1c
        type = g_type_register_static (IBUS_TYPE_OBJECT,
Packit Service 1d8f1c
                                       "IBusService",
Packit Service 1d8f1c
                                       &type_info,
Packit Service 1d8f1c
                                       0);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
    return type;
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
ibus_service_base_init (IBusServiceClass *class)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    GArray *old = class->interfaces;
Packit Service 1d8f1c
    class->interfaces = g_array_new (TRUE, TRUE, sizeof (GDBusInterfaceInfo *));
Packit Service 1d8f1c
    if (old != NULL) {
Packit Service 1d8f1c
        GDBusInterfaceInfo **p = (GDBusInterfaceInfo **)old->data;
Packit Service 1d8f1c
        while (*p != NULL) {
Packit Service 1d8f1c
            g_array_append_val (class->interfaces, *p++);
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
ibus_service_base_fini (IBusServiceClass *class)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    GDBusInterfaceInfo **interfaces = (GDBusInterfaceInfo **) g_array_free (class->interfaces, FALSE);
Packit Service 1d8f1c
    GDBusInterfaceInfo **p = interfaces;
Packit Service 1d8f1c
    while (*p != NULL) {
Packit Service 1d8f1c
        g_dbus_interface_info_unref (*p++);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
    g_free (interfaces);
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static const gchar introspection_xml[] =
Packit Service 1d8f1c
    "<node>"
Packit Service 1d8f1c
    "  <interface name='org.freedesktop.IBus.Service'>"
Packit Service 1d8f1c
    "    <method name='Destroy' />"
Packit Service 1d8f1c
    "  </interface>"
Packit Service 1d8f1c
    "</node>";
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
ibus_service_class_init (IBusServiceClass *class)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    GObjectClass *gobject_class = G_OBJECT_CLASS (class);
Packit Service 1d8f1c
    IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (class);
Packit Service 1d8f1c
Packit Service 1d8f1c
    ibus_service_parent_class = IBUS_OBJECT_CLASS (g_type_class_peek_parent (class));
Packit Service 1d8f1c
Packit Service 1d8f1c
    gobject_class->constructed  = ibus_service_constructed;
Packit Service 1d8f1c
    gobject_class->set_property = (GObjectSetPropertyFunc) ibus_service_set_property;
Packit Service 1d8f1c
    gobject_class->get_property = (GObjectGetPropertyFunc) ibus_service_get_property;
Packit Service 1d8f1c
    ibus_object_class->destroy  = (IBusObjectDestroyFunc) ibus_service_destroy;
Packit Service 1d8f1c
Packit Service 1d8f1c
    /* virtual functions */
Packit Service 1d8f1c
    class->service_method_call = ibus_service_service_method_call;
Packit Service 1d8f1c
    class->service_get_property = ibus_service_service_get_property;
Packit Service 1d8f1c
    class->service_set_property = ibus_service_service_set_property;
Packit Service 1d8f1c
Packit Service 1d8f1c
    /* class members */
Packit Service 1d8f1c
    ibus_service_class_add_interfaces (class, introspection_xml);
Packit Service 1d8f1c
Packit Service 1d8f1c
    /* install properties */
Packit Service 1d8f1c
    /**
Packit Service 1d8f1c
     * IBusService:object-path:
Packit Service 1d8f1c
     *
Packit Service 1d8f1c
     * The path of service object.
Packit Service 1d8f1c
     */
Packit Service 1d8f1c
    g_object_class_install_property (
Packit Service 1d8f1c
                    gobject_class,
Packit Service 1d8f1c
                    PROP_OBJECT_PATH,
Packit Service 1d8f1c
                    g_param_spec_string (
Packit Service 1d8f1c
                        "object-path",
Packit Service 1d8f1c
                        "object path",
Packit Service 1d8f1c
                        "The path of service object",
Packit Service 1d8f1c
                        NULL,
Packit Service 1d8f1c
                        G_PARAM_READWRITE |
Packit Service 1d8f1c
                        G_PARAM_CONSTRUCT_ONLY |
Packit Service 1d8f1c
                        G_PARAM_STATIC_NAME |
Packit Service 1d8f1c
                        G_PARAM_STATIC_NICK |
Packit Service 1d8f1c
                        G_PARAM_STATIC_BLURB)
Packit Service 1d8f1c
                    );
Packit Service 1d8f1c
    /**
Packit Service 1d8f1c
     * IBusService:connection:
Packit Service 1d8f1c
     *
Packit Service 1d8f1c
     * The connection of service object.
Packit Service 1d8f1c
     */
Packit Service 1d8f1c
    g_object_class_install_property (
Packit Service 1d8f1c
                    gobject_class,
Packit Service 1d8f1c
                    PROP_CONNECTION,
Packit Service 1d8f1c
                    g_param_spec_object (
Packit Service 1d8f1c
                        "connection",
Packit Service 1d8f1c
                        "connection",
Packit Service 1d8f1c
                        "The connection of service object",
Packit Service 1d8f1c
                        G_TYPE_DBUS_CONNECTION,
Packit Service 1d8f1c
                        G_PARAM_READWRITE |
Packit Service 1d8f1c
                        G_PARAM_CONSTRUCT_ONLY |
Packit Service 1d8f1c
                        G_PARAM_STATIC_NAME |
Packit Service 1d8f1c
                        G_PARAM_STATIC_NICK |
Packit Service 1d8f1c
                        G_PARAM_STATIC_BLURB)
Packit Service 1d8f1c
                    );
Packit Service 1d8f1c
Packit Service 1d8f1c
    g_type_class_add_private (class, sizeof (IBusServicePrivate));
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
ibus_service_init (IBusService *service)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    service->priv = IBUS_SERVICE_GET_PRIVATE (service);
Packit Service 1d8f1c
    service->priv->table = g_hash_table_new (NULL, NULL);
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
ibus_service_constructed (GObject *object)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    IBusService *service = (IBusService *)object;
Packit Service 1d8f1c
    if (service->priv->connection) {
Packit Service 1d8f1c
        GError *error = NULL;
Packit Service 1d8f1c
        if (!ibus_service_register (service, service->priv->connection, &error)) {
Packit Service 1d8f1c
            g_warning ("%s", error->message);
Packit Service 1d8f1c
            g_error_free (error);
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
    service->priv->constructed = TRUE;
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
ibus_service_set_property (IBusService  *service,
Packit Service 1d8f1c
                           guint         prop_id,
Packit Service 1d8f1c
                           const GValue *value,
Packit Service 1d8f1c
                           GParamSpec   *pspec)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    switch (prop_id) {
Packit Service 1d8f1c
    case PROP_OBJECT_PATH:
Packit Service 1d8f1c
        service->priv->object_path = g_value_dup_string (value);
Packit Service 1d8f1c
        break;
Packit Service 1d8f1c
    case PROP_CONNECTION:
Packit Service 1d8f1c
        service->priv->connection = g_value_dup_object (value);
Packit Service 1d8f1c
        break;
Packit Service 1d8f1c
    default:
Packit Service 1d8f1c
        G_OBJECT_WARN_INVALID_PROPERTY_ID (service, prop_id, pspec);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
ibus_service_get_property (IBusService *service,
Packit Service 1d8f1c
                           guint        prop_id,
Packit Service 1d8f1c
                           GValue      *value,
Packit Service 1d8f1c
                           GParamSpec  *pspec)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    switch (prop_id) {
Packit Service 1d8f1c
    case PROP_OBJECT_PATH:
Packit Service 1d8f1c
        g_value_set_string (value, service->priv->object_path);
Packit Service 1d8f1c
        break;
Packit Service 1d8f1c
    case PROP_CONNECTION:
Packit Service 1d8f1c
        g_value_set_object (value, service->priv->connection);
Packit Service 1d8f1c
        break;
Packit Service 1d8f1c
    default:
Packit Service 1d8f1c
        G_OBJECT_WARN_INVALID_PROPERTY_ID (service, prop_id, pspec);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
ibus_service_destroy (IBusService *service)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    g_free (service->priv->object_path);
Packit Service 1d8f1c
    service->priv->object_path = NULL;
Packit Service 1d8f1c
Packit Service 1d8f1c
    if (service->priv->connection) {
Packit Service 1d8f1c
        g_object_unref (service->priv->connection);
Packit Service 1d8f1c
        service->priv->connection = NULL;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
    if (service->priv->table) {
Packit Service 1d8f1c
        g_hash_table_foreach_remove (service->priv->table,
Packit Service 1d8f1c
                        (GHRFunc)ibus_service_unregister_cb, service);
Packit Service 1d8f1c
        g_hash_table_destroy (service->priv->table);
Packit Service 1d8f1c
        service->priv->table = NULL;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
    IBUS_OBJECT_CLASS(ibus_service_parent_class)->destroy (IBUS_OBJECT (service));
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
ibus_service_service_method_call (IBusService           *service,
Packit Service 1d8f1c
                                  GDBusConnection       *connection,
Packit Service 1d8f1c
                                  const gchar           *sender,
Packit Service 1d8f1c
                                  const gchar           *object_path,
Packit Service 1d8f1c
                                  const gchar           *interface_name,
Packit Service 1d8f1c
                                  const gchar           *method_name,
Packit Service 1d8f1c
                                  GVariant              *parameters,
Packit Service 1d8f1c
                                  GDBusMethodInvocation *invocation)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    if (g_strcmp0 (method_name, "Destroy") == 0) {
Packit Service 1d8f1c
        g_dbus_method_invocation_return_value (invocation, NULL);
Packit Service 1d8f1c
        ibus_object_destroy ((IBusObject *)service);
Packit Service 1d8f1c
        return;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
    g_dbus_method_invocation_return_error (invocation,
Packit Service 1d8f1c
                                           G_DBUS_ERROR,
Packit Service 1d8f1c
                                           G_DBUS_ERROR_UNKNOWN_METHOD,
Packit Service 1d8f1c
                                           "%s::%s", interface_name, method_name);
Packit Service 1d8f1c
    return;
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static GVariant *
Packit Service 1d8f1c
ibus_service_service_get_property (IBusService     *service,
Packit Service 1d8f1c
                                  GDBusConnection  *connection,
Packit Service 1d8f1c
                                  const gchar      *sender,
Packit Service 1d8f1c
                                  const gchar      *object_path,
Packit Service 1d8f1c
                                  const gchar      *interface_name,
Packit Service 1d8f1c
                                  const gchar      *property_name,
Packit Service 1d8f1c
                                  GError          **error)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    return NULL;
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static gboolean
Packit Service 1d8f1c
ibus_service_service_set_property (IBusService     *service,
Packit Service 1d8f1c
                                  GDBusConnection  *connection,
Packit Service 1d8f1c
                                  const gchar      *sender,
Packit Service 1d8f1c
                                  const gchar      *object_path,
Packit Service 1d8f1c
                                  const gchar      *interface_name,
Packit Service 1d8f1c
                                  const gchar      *property_name,
Packit Service 1d8f1c
                                  GVariant         *value,
Packit Service 1d8f1c
                                  GError          **error)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    return FALSE;
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
ibus_service_service_method_call_cb (GDBusConnection       *connection,
Packit Service 1d8f1c
                                     const gchar           *sender,
Packit Service 1d8f1c
                                     const gchar           *object_path,
Packit Service 1d8f1c
                                     const gchar           *interface_name,
Packit Service 1d8f1c
                                     const gchar           *method_name,
Packit Service 1d8f1c
                                     GVariant              *parameters,
Packit Service 1d8f1c
                                     GDBusMethodInvocation *invocation,
Packit Service 1d8f1c
                                     IBusService           *service)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    IBUS_SERVICE_GET_CLASS (service)->service_method_call (service,
Packit Service 1d8f1c
                                                           connection,
Packit Service 1d8f1c
                                                           sender,
Packit Service 1d8f1c
                                                           object_path,
Packit Service 1d8f1c
                                                           interface_name,
Packit Service 1d8f1c
                                                           method_name,
Packit Service 1d8f1c
                                                           parameters,
Packit Service 1d8f1c
                                                           invocation);
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static GVariant *
Packit Service 1d8f1c
ibus_service_service_get_property_cb (GDBusConnection   *connection,
Packit Service 1d8f1c
                                      const gchar       *sender,
Packit Service 1d8f1c
                                      const gchar       *object_path,
Packit Service 1d8f1c
                                      const gchar       *interface_name,
Packit Service 1d8f1c
                                      const gchar       *property_name,
Packit Service 1d8f1c
                                      GError           **error,
Packit Service 1d8f1c
                                      IBusService       *service)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    return IBUS_SERVICE_GET_CLASS (service)->service_get_property (service,
Packit Service 1d8f1c
                                                                   connection,
Packit Service 1d8f1c
                                                                   sender,
Packit Service 1d8f1c
                                                                   object_path,
Packit Service 1d8f1c
                                                                   interface_name,
Packit Service 1d8f1c
                                                                   property_name,
Packit Service 1d8f1c
                                                                   error);
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static gboolean
Packit Service 1d8f1c
ibus_service_service_set_property_cb (GDBusConnection    *connection,
Packit Service 1d8f1c
                                      const gchar        *sender,
Packit Service 1d8f1c
                                      const gchar        *object_path,
Packit Service 1d8f1c
                                      const gchar        *interface_name,
Packit Service 1d8f1c
                                      const gchar        *property_name,
Packit Service 1d8f1c
                                      GVariant           *value,
Packit Service 1d8f1c
                                      GError            **error,
Packit Service 1d8f1c
                                      IBusService        *service)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    return IBUS_SERVICE_GET_CLASS (service)->service_set_property (service,
Packit Service 1d8f1c
                                                                   connection,
Packit Service 1d8f1c
                                                                   sender,
Packit Service 1d8f1c
                                                                   object_path,
Packit Service 1d8f1c
                                                                   interface_name,
Packit Service 1d8f1c
                                                                   property_name,
Packit Service 1d8f1c
                                                                   value,
Packit Service 1d8f1c
                                                                   error);
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
ibus_service_connection_closed_cb (GDBusConnection    *connection,
Packit Service 1d8f1c
                                   gboolean            remote_peer_vanished,
Packit Service 1d8f1c
                                   GError             *error,
Packit Service 1d8f1c
                                   IBusService        *service)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    ibus_service_unregister (service, connection);
Packit Service 1d8f1c
    if (connection == service->priv->connection) {
Packit Service 1d8f1c
        ibus_object_destroy ((IBusObject *) service);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
ibus_service_unregister_cb (GDBusConnection    *connection,
Packit Service 1d8f1c
                            guint              *ids,
Packit Service 1d8f1c
                            IBusService        *service)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    guint *p = ids;
Packit Service 1d8f1c
    while (*p != 0) {
Packit Service 1d8f1c
        g_dbus_connection_unregister_object (connection, *p++);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
    g_signal_handlers_disconnect_by_func (connection,
Packit Service 1d8f1c
                    G_CALLBACK (ibus_service_connection_closed_cb), service);
Packit Service 1d8f1c
    g_object_unref (connection);
Packit Service 1d8f1c
    g_free (ids);
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
IBusService *
Packit Service 1d8f1c
ibus_service_new (GDBusConnection *connection,
Packit Service 1d8f1c
                  const gchar     *object_path)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
Packit Service 1d8f1c
    g_return_val_if_fail (object_path != NULL, NULL);
Packit Service 1d8f1c
Packit Service 1d8f1c
    GObject *obj = g_object_new (IBUS_TYPE_SERVICE,
Packit Service 1d8f1c
                                 "object-path", object_path,
Packit Service 1d8f1c
                                 "connection", connection,
Packit Service 1d8f1c
                                 NULL);
Packit Service 1d8f1c
    return IBUS_SERVICE (obj);
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
const gchar *
Packit Service 1d8f1c
ibus_service_get_object_path (IBusService *service)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    g_return_val_if_fail (IBUS_IS_SERVICE (service), NULL);
Packit Service 1d8f1c
    return service->priv->object_path;
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
GDBusConnection *
Packit Service 1d8f1c
ibus_service_get_connection (IBusService *service)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    g_return_val_if_fail (IBUS_IS_SERVICE (service), NULL);
Packit Service 1d8f1c
    return service->priv->connection;
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
gboolean
Packit Service 1d8f1c
ibus_service_register (IBusService     *service,
Packit Service 1d8f1c
                       GDBusConnection *connection,
Packit Service 1d8f1c
                       GError         **error)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    GArray *array = NULL;
Packit Service 1d8f1c
    GArray *interfaces;
Packit Service 1d8f1c
    GDBusInterfaceInfo **p;
Packit Service 1d8f1c
Packit Service 1d8f1c
    g_return_val_if_fail (IBUS_IS_SERVICE (service), FALSE);
Packit Service 1d8f1c
    g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), FALSE);
Packit Service 1d8f1c
    g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
Packit Service 1d8f1c
Packit Service 1d8f1c
    if (g_hash_table_lookup (service->priv->table, connection)) {
Packit Service 1d8f1c
        if (error) {
Packit Service 1d8f1c
            *error = g_error_new (G_DBUS_ERROR, G_DBUS_ERROR_OBJECT_PATH_IN_USE,
Packit Service 1d8f1c
                            "Service %p has been registered with connection %p.",
Packit Service 1d8f1c
                            service, connection);
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        goto error_out;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
    interfaces = IBUS_SERVICE_GET_CLASS (service)->interfaces;
Packit Service 1d8f1c
    g_assert (interfaces);
Packit Service 1d8f1c
    p = (GDBusInterfaceInfo **)interfaces->data;
Packit Service 1d8f1c
    if (*p == NULL) {
Packit Service 1d8f1c
        if (error) {
Packit Service 1d8f1c
            *error = g_error_new (G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
Packit Service 1d8f1c
                            "Service %p does not have any interface.",
Packit Service 1d8f1c
                            service);
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        goto error_out;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
    array = g_array_new (TRUE, TRUE, sizeof (guint));
Packit Service 1d8f1c
    while (*p != NULL) {
Packit Service 1d8f1c
        guint id = g_dbus_connection_register_object (connection,
Packit Service 1d8f1c
                                                      service->priv->object_path,
Packit Service 1d8f1c
                                                      *p,
Packit Service 1d8f1c
                                                      &ibus_service_interface_vtable,
Packit Service 1d8f1c
                                                      g_object_ref (service),
Packit Service 1d8f1c
                                                      (GDestroyNotify)g_object_unref,
Packit Service 1d8f1c
                                                      error);
Packit Service 1d8f1c
        if (id != 0) {
Packit Service 1d8f1c
            g_array_append_val (array, id);
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        else {
Packit Service 1d8f1c
            g_object_unref (service);
Packit Service 1d8f1c
            goto error_out;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        p++;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
    g_signal_connect (connection, "closed",
Packit Service 1d8f1c
                    G_CALLBACK (ibus_service_connection_closed_cb), service);
Packit Service 1d8f1c
    g_hash_table_insert (service->priv->table,
Packit Service 1d8f1c
                    g_object_ref (connection), g_array_free (array, FALSE));
Packit Service 1d8f1c
    return TRUE;
Packit Service 1d8f1c
Packit Service 1d8f1c
error_out:
Packit Service 1d8f1c
    if (array != NULL) {
Packit Service 1d8f1c
        guint *ids = (guint*) array->data;
Packit Service 1d8f1c
        while (*ids != 0) {
Packit Service 1d8f1c
            g_dbus_connection_unregister_object (connection, *ids++);
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        g_array_free (array, TRUE);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
    return FALSE;
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
void
Packit Service 1d8f1c
ibus_service_unregister (IBusService     *service,
Packit Service 1d8f1c
                         GDBusConnection *connection)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    g_return_if_fail (IBUS_IS_SERVICE (service));
Packit Service 1d8f1c
    g_return_if_fail (G_IS_DBUS_CONNECTION (connection));
Packit Service 1d8f1c
Packit Service 1d8f1c
    guint *ids = (guint *) g_hash_table_lookup (service->priv->table, connection);
Packit Service 1d8f1c
    g_return_if_fail (ids != NULL);
Packit Service 1d8f1c
Packit Service 1d8f1c
    g_hash_table_remove (service->priv->table, connection);
Packit Service 1d8f1c
    ibus_service_unregister_cb (connection, ids, service);
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
gboolean
Packit Service 1d8f1c
ibus_service_emit_signal (IBusService *service,
Packit Service 1d8f1c
                          const gchar *dest_bus_name,
Packit Service 1d8f1c
                          const gchar *interface_name,
Packit Service 1d8f1c
                          const gchar *signal_name,
Packit Service 1d8f1c
                          GVariant    *parameters,
Packit Service 1d8f1c
                          GError    **error)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    g_return_val_if_fail (IBUS_IS_SERVICE (service), FALSE);
Packit Service 1d8f1c
    g_return_val_if_fail (interface_name != NULL, FALSE);
Packit Service 1d8f1c
    g_return_val_if_fail (signal_name != NULL, FALSE);
Packit Service 1d8f1c
    g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
Packit Service 1d8f1c
    g_return_val_if_fail (service->priv->connection != NULL, FALSE);
Packit Service 1d8f1c
    
Packit Service 1d8f1c
    return g_dbus_connection_emit_signal (service->priv->connection,
Packit Service 1d8f1c
                                          dest_bus_name,
Packit Service 1d8f1c
                                          service->priv->object_path,
Packit Service 1d8f1c
                                          interface_name,
Packit Service 1d8f1c
                                          signal_name,
Packit Service 1d8f1c
                                          parameters,
Packit Service 1d8f1c
                                          error);
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
gboolean
Packit Service 1d8f1c
ibus_service_class_add_interfaces (IBusServiceClass   *class,
Packit Service 1d8f1c
                                   const gchar        *xml_data)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    g_return_val_if_fail (IBUS_IS_SERVICE_CLASS (class), FALSE);
Packit Service 1d8f1c
    g_return_val_if_fail (xml_data != NULL, FALSE);
Packit Service 1d8f1c
Packit Service 1d8f1c
    GError *error = NULL;
Packit Service 1d8f1c
    GDBusNodeInfo *introspection_data = g_dbus_node_info_new_for_xml (xml_data, &error);
Packit Service 1d8f1c
    if (introspection_data == NULL) {
Packit Service 1d8f1c
        g_warning ("%s", error->message);
Packit Service 1d8f1c
        g_error_free (error);
Packit Service 1d8f1c
        return FALSE;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
    else {
Packit Service 1d8f1c
        GDBusInterfaceInfo **p = introspection_data->interfaces;
Packit Service 1d8f1c
        while (*p != NULL) {
Packit Service 1d8f1c
            g_dbus_interface_info_ref (*p);
Packit Service 1d8f1c
            g_array_append_val (class->interfaces, *p);
Packit Service 1d8f1c
            p++;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        g_dbus_node_info_unref (introspection_data);
Packit Service 1d8f1c
        return TRUE;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
}