Blame src/ibusproxy.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-2010 Peng Huang <shawn.p.huang@gmail.com>
Packit Service 1d8f1c
 * Copyright (C) 2008-2010 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
Packit Service 1d8f1c
#include "ibusproxy.h"
Packit Service 1d8f1c
#include "ibusmarshalers.h"
Packit Service 1d8f1c
#include "ibusinternal.h"
Packit Service 1d8f1c
#include "ibusobject.h"
Packit Service 1d8f1c
Packit Service 1d8f1c
#define IBUS_PROXY_GET_PRIVATE(o)  \
Packit Service 1d8f1c
   (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_PROXY, IBusProxyPrivate))
Packit Service 1d8f1c
Packit Service 1d8f1c
enum {
Packit Service 1d8f1c
    DESTROY,
Packit Service 1d8f1c
    LAST_SIGNAL,
Packit Service 1d8f1c
};
Packit Service 1d8f1c
Packit Service 1d8f1c
static guint            proxy_signals[LAST_SIGNAL] = { 0 };
Packit Service 1d8f1c
Packit Service 1d8f1c
/* functions prototype */
Packit Service 1d8f1c
static void      ibus_proxy_dispose         (GObject            *object);
Packit Service 1d8f1c
static void      ibus_proxy_real_destroy    (IBusProxy          *proxy);
Packit Service 1d8f1c
Packit Service 1d8f1c
static void      ibus_proxy_connection_closed_cb
Packit Service 1d8f1c
                                            (GDBusConnection    *connection,
Packit Service 1d8f1c
                                             gboolean            remote_peer_vanished,
Packit Service 1d8f1c
                                             GError             *error,
Packit Service 1d8f1c
                                             IBusProxy          *proxy);
Packit Service 1d8f1c
static void      initable_iface_init        (GInitableIface     *initable_iface);
Packit Service 1d8f1c
static void      async_initable_iface_init  (GAsyncInitableIface
Packit Service 1d8f1c
                                                                *async_initable_iface);
Packit Service 1d8f1c
G_DEFINE_TYPE_WITH_CODE (IBusProxy, ibus_proxy, G_TYPE_DBUS_PROXY,
Packit Service 1d8f1c
                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init)
Packit Service 1d8f1c
                         G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, async_initable_iface_init)
Packit Service 1d8f1c
                         );
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
ibus_proxy_class_init (IBusProxyClass *class)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    GObjectClass *gobject_class = G_OBJECT_CLASS (class);
Packit Service 1d8f1c
Packit Service 1d8f1c
    gobject_class->dispose = ibus_proxy_dispose;
Packit Service 1d8f1c
Packit Service 1d8f1c
    class->destroy = ibus_proxy_real_destroy;
Packit Service 1d8f1c
Packit Service 1d8f1c
    /* install signals */
Packit Service 1d8f1c
    /**
Packit Service 1d8f1c
     * IBusProxy::destroy:
Packit Service 1d8f1c
     * @object: An IBusProxy.
Packit Service 1d8f1c
     *
Packit Service 1d8f1c
     * Destroy and free an IBusProxy
Packit Service 1d8f1c
     *
Packit Service 1d8f1c
     * See also:  ibus_proxy_destroy().
Packit Service 1d8f1c
     *
Packit Service 1d8f1c
     * <note><para>Argument @user_data is ignored in this function.</para></note>
Packit Service 1d8f1c
     */
Packit Service 1d8f1c
    proxy_signals[DESTROY] =
Packit Service 1d8f1c
        g_signal_new (I_("destroy"),
Packit Service 1d8f1c
            G_TYPE_FROM_CLASS (gobject_class),
Packit Service 1d8f1c
            G_SIGNAL_RUN_LAST,
Packit Service 1d8f1c
            G_STRUCT_OFFSET (IBusProxyClass, destroy),
Packit Service 1d8f1c
            NULL, NULL,
Packit Service 1d8f1c
            _ibus_marshal_VOID__VOID,
Packit Service 1d8f1c
            G_TYPE_NONE, 0);
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
ibus_proxy_init (IBusProxy *proxy)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    proxy->own = TRUE;
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
/**
Packit Service 1d8f1c
 * ibus_proxy_dispose:
Packit Service 1d8f1c
 *
Packit Service 1d8f1c
 * Override GObject's dispose function.
Packit Service 1d8f1c
 */
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
ibus_proxy_dispose (GObject *object)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    if (! (IBUS_PROXY_FLAGS (object) & IBUS_IN_DESTRUCTION)) {
Packit Service 1d8f1c
        IBUS_PROXY_SET_FLAGS (object, IBUS_IN_DESTRUCTION);
Packit Service 1d8f1c
        if (! (IBUS_PROXY_FLAGS (object) & IBUS_DESTROYED)) {
Packit Service 1d8f1c
            g_signal_emit (object, proxy_signals[DESTROY], 0);
Packit Service 1d8f1c
            IBUS_PROXY_SET_FLAGS (object, IBUS_DESTROYED);
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        IBUS_PROXY_UNSET_FLAGS (object, IBUS_IN_DESTRUCTION);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
    G_OBJECT_CLASS(ibus_proxy_parent_class)->dispose (object);
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
/**
Packit Service 1d8f1c
 * ibus_proxy_real_destroy:
Packit Service 1d8f1c
 *
Packit Service 1d8f1c
 * Handle "destroy" signal which is emitted by ibus_proxy_dispose.
Packit Service 1d8f1c
 */
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
ibus_proxy_real_destroy (IBusProxy *proxy)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    GDBusConnection *connection = g_dbus_proxy_get_connection ((GDBusProxy *) proxy);
Packit Service 1d8f1c
    g_assert (connection != NULL);
Packit Service 1d8f1c
    if (!g_dbus_connection_is_closed (connection) && proxy->own) {
Packit Service 1d8f1c
        g_dbus_proxy_call ((GDBusProxy *)proxy,
Packit Service 1d8f1c
                           "org.freedesktop.IBus.Service.Destroy",
Packit Service 1d8f1c
                           NULL,
Packit Service 1d8f1c
                           G_DBUS_CALL_FLAGS_NONE,
Packit Service 1d8f1c
                           -1, NULL, NULL, NULL);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
    g_signal_handlers_disconnect_by_func (connection,
Packit Service 1d8f1c
                                          (GCallback) ibus_proxy_connection_closed_cb,
Packit Service 1d8f1c
                                          proxy);
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
ibus_proxy_connection_closed_cb (GDBusConnection *connection,
Packit Service 1d8f1c
                                 gboolean         remote_peer_vanished,
Packit Service 1d8f1c
                                 GError          *error,
Packit Service 1d8f1c
                                 IBusProxy       *proxy)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    ibus_proxy_destroy (proxy);
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
void
Packit Service 1d8f1c
ibus_proxy_destroy (IBusProxy *proxy)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    g_assert (IBUS_IS_PROXY (proxy));
Packit Service 1d8f1c
Packit Service 1d8f1c
    if (! (IBUS_PROXY_FLAGS (proxy) & IBUS_IN_DESTRUCTION)) {
Packit Service 1d8f1c
        g_object_run_dispose (G_OBJECT (proxy));
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static gboolean
Packit Service 1d8f1c
ibus_proxy_init_finish (IBusProxy  *proxy,
Packit Service 1d8f1c
                        GError    **error)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    g_assert (IBUS_IS_PROXY (proxy));
Packit Service 1d8f1c
    g_assert (error == NULL || *error == NULL);
Packit Service 1d8f1c
Packit Service 1d8f1c
    GDBusConnection *connection =
Packit Service 1d8f1c
            g_dbus_proxy_get_connection ((GDBusProxy *)proxy);
Packit Service 1d8f1c
Packit Service 1d8f1c
    if (connection == NULL || g_dbus_connection_is_closed (connection)) {
Packit Service 1d8f1c
        /*
Packit Service 1d8f1c
         * When proxy is created asynchronously, the connection may be closed
Packit Service 1d8f1c
         * before proxy is ready. In this case, we need override interfaces
Packit Service 1d8f1c
         * GInitable and GAsyncInitable to report the error.
Packit Service 1d8f1c
         */
Packit Service 1d8f1c
        if (error != NULL)
Packit Service 1d8f1c
            *error = g_error_new (G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
Packit Service 1d8f1c
                    "Connection is closed.");
Packit Service 1d8f1c
        return FALSE;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
    g_signal_connect (connection, "closed",
Packit Service 1d8f1c
            G_CALLBACK (ibus_proxy_connection_closed_cb), proxy);
Packit Service 1d8f1c
Packit Service 1d8f1c
    return TRUE;
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
static GInitableIface *initable_iface_parent = NULL;
Packit Service 1d8f1c
Packit Service 1d8f1c
static gboolean
Packit Service 1d8f1c
initable_init (GInitable     *initable,
Packit Service 1d8f1c
               GCancellable  *cancellable,
Packit Service 1d8f1c
               GError       **error)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    if (!initable_iface_parent->init (initable, cancellable, error))
Packit Service 1d8f1c
        return FALSE;
Packit Service 1d8f1c
    return ibus_proxy_init_finish ((IBusProxy *)initable, error);
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
initable_iface_init (GInitableIface *initable_iface)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    initable_iface_parent = g_type_interface_peek_parent (initable_iface);
Packit Service 1d8f1c
    initable_iface->init = initable_init;
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static GAsyncInitableIface *async_initable_iface_parent = NULL;
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
async_initable_init_async (GAsyncInitable      *initable,
Packit Service 1d8f1c
                           gint                 io_priority,
Packit Service 1d8f1c
                           GCancellable        *cancellable,
Packit Service 1d8f1c
                           GAsyncReadyCallback  callback,
Packit Service 1d8f1c
                           gpointer             user_data)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    async_initable_iface_parent->init_async (initable,
Packit Service 1d8f1c
            io_priority, cancellable, callback, user_data);
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static gboolean
Packit Service 1d8f1c
async_initable_init_finish (GAsyncInitable  *initable,
Packit Service 1d8f1c
                            GAsyncResult    *res,
Packit Service 1d8f1c
                            GError         **error)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    if (!async_initable_iface_parent->init_finish (initable, res, error))
Packit Service 1d8f1c
        return FALSE;
Packit Service 1d8f1c
    return ibus_proxy_init_finish ((IBusProxy *)initable, error);
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
async_initable_iface_init (GAsyncInitableIface *async_initable_iface)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    async_initable_iface_parent = g_type_interface_peek_parent (async_initable_iface);
Packit Service 1d8f1c
    async_initable_iface->init_async = async_initable_init_async;
Packit Service 1d8f1c
    async_initable_iface->init_finish = async_initable_init_finish;
Packit Service 1d8f1c
}