Blame src/ibusservice.c

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