Blame bus/component.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
/* bus - The Input Bus
Packit Service 1d8f1c
 * Copyright (C) 2010 Peng Huang <shawn.p.huang@gmail.com>
Packit Service 1d8f1c
 * Copyright (C) 2010 Google 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 "component.h"
Packit Service 1d8f1c
Packit Service 1d8f1c
#include <gio/gio.h>
Packit Service 1d8f1c
#include <glib/gstdio.h>
Packit Service 1d8f1c
#include <stdlib.h>
Packit Service 1d8f1c
#include <string.h>
Packit Service 1d8f1c
Packit Service 1d8f1c
#include "global.h"
Packit Service 1d8f1c
#include "marshalers.h"
Packit Service 1d8f1c
#include "types.h"
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 = 0,
Packit Service 1d8f1c
    PROP_COMPONENT,
Packit Service 1d8f1c
    PROP_FACTORY,
Packit Service 1d8f1c
};
Packit Service 1d8f1c
Packit Service 1d8f1c
struct _BusComponent {
Packit Service 1d8f1c
    IBusObject parent;
Packit Service 1d8f1c
Packit Service 1d8f1c
    /* instance members */
Packit Service 1d8f1c
Packit Service 1d8f1c
    /* an object which represents one XML file in the ibus/component/ directory. */
Packit Service 1d8f1c
    IBusComponent *component;
Packit Service 1d8f1c
    /* a proxy object which starts an engine. */
Packit Service 1d8f1c
    BusFactoryProxy *factory;
Packit Service 1d8f1c
Packit Service 1d8f1c
    /* TRUE if the component started in the verbose mode. */
Packit Service 1d8f1c
    gboolean verbose;
Packit Service 1d8f1c
    /* TRUE if the component needs to be restarted when it dies. */
Packit Service 1d8f1c
    gboolean restart;
Packit Service 1d8f1c
    /* TRUE if the component will be destroyed with factory. */
Packit Service 1d8f1c
    gboolean destroy_with_factory;
Packit Service 1d8f1c
Packit Service 1d8f1c
    /* process id of the process (e.g. ibus-config, ibus-engine-*, ..) of the component. */
Packit Service 1d8f1c
    GPid     pid;
Packit Service 1d8f1c
    guint    child_source_id;
Packit Service 1d8f1c
};
Packit Service 1d8f1c
Packit Service 1d8f1c
struct _BusComponentClass {
Packit Service 1d8f1c
    IBusObjectClass parent;
Packit Service 1d8f1c
    /* class members */
Packit Service 1d8f1c
};
Packit Service 1d8f1c
Packit Service 1d8f1c
/* functions prototype */
Packit Service 1d8f1c
static GObject* bus_component_constructor   (GType                  type,
Packit Service 1d8f1c
                                             guint                  n_construct_params,
Packit Service 1d8f1c
                                             GObjectConstructParam *construct_params);
Packit Service 1d8f1c
static void     bus_component_set_property  (BusComponent          *component,
Packit Service 1d8f1c
                                             guint                  prop_id,
Packit Service 1d8f1c
                                             const GValue          *value,
Packit Service 1d8f1c
                                             GParamSpec            *pspec);
Packit Service 1d8f1c
static void     bus_component_get_property  (BusComponent          *component,
Packit Service 1d8f1c
                                             guint                  prop_id,
Packit Service 1d8f1c
                                             GValue                *value,
Packit Service 1d8f1c
                                             GParamSpec            *pspec);
Packit Service 1d8f1c
static void     bus_component_destroy       (BusComponent          *component);
Packit Service 1d8f1c
Packit Service 1d8f1c
G_DEFINE_TYPE (BusComponent, bus_component, IBUS_TYPE_OBJECT)
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
bus_component_class_init (BusComponentClass *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
    gobject_class->constructor  = bus_component_constructor;
Packit Service 1d8f1c
    gobject_class->set_property = (GObjectSetPropertyFunc) bus_component_set_property;
Packit Service 1d8f1c
    gobject_class->get_property = (GObjectGetPropertyFunc) bus_component_get_property;
Packit Service 1d8f1c
    ibus_object_class->destroy  = (IBusObjectDestroyFunc) bus_component_destroy;
Packit Service 1d8f1c
Packit Service 1d8f1c
    /* install properties */
Packit Service 1d8f1c
    g_object_class_install_property (gobject_class,
Packit Service 1d8f1c
                    PROP_COMPONENT,
Packit Service 1d8f1c
                    g_param_spec_object ("component", /* canonical name of the property */
Packit Service 1d8f1c
                        "component", /* nick name */
Packit Service 1d8f1c
                        "component", /* description */
Packit Service 1d8f1c
                        IBUS_TYPE_COMPONENT, /* object type */
Packit Service 1d8f1c
                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
Packit Service 1d8f1c
Packit Service 1d8f1c
    g_object_class_install_property (gobject_class,
Packit Service 1d8f1c
                    PROP_FACTORY,
Packit Service 1d8f1c
                    g_param_spec_object ("factory",
Packit Service 1d8f1c
                        "factory",
Packit Service 1d8f1c
                        "factory",
Packit Service 1d8f1c
                        BUS_TYPE_FACTORY_PROXY,
Packit Service 1d8f1c
                        G_PARAM_READWRITE));
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
bus_component_init (BusComponent *component)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
/**
Packit Service 1d8f1c
 * bus_component_constructor:
Packit Service 1d8f1c
 *
Packit Service 1d8f1c
 * A constructor method which is called after bus_component_init is called.
Packit Service 1d8f1c
 */
Packit Service 1d8f1c
static GObject*
Packit Service 1d8f1c
bus_component_constructor (GType                  type,
Packit Service 1d8f1c
                           guint                  n_construct_params,
Packit Service 1d8f1c
                           GObjectConstructParam *construct_params)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    GObject *object;
Packit Service 1d8f1c
    object = G_OBJECT_CLASS (bus_component_parent_class)->constructor (type,
Packit Service 1d8f1c
                                                                       n_construct_params,
Packit Service 1d8f1c
                                                                       construct_params);
Packit Service 1d8f1c
    BusComponent *component = (BusComponent *) object;
Packit Service 1d8f1c
    /* we have to override the _constructor method since in _init method, the component->component property is not set yet. */
Packit Service 1d8f1c
    g_assert (IBUS_IS_COMPONENT (component->component));
Packit Service 1d8f1c
Packit Service 1d8f1c
    static GQuark quark = 0;
Packit Service 1d8f1c
    if (quark == 0) {
Packit Service 1d8f1c
        quark = g_quark_from_static_string ("BusComponent");
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
    /* associate each engine with BusComponent. a component might have one or more components. For example, ibus-engine-pinyin would
Packit Service 1d8f1c
     * have two - 'pinyin' and 'bopomofo' and ibus-engine-m17n has many. On the other hand, the gtkpanel component does not have an
Packit Service 1d8f1c
     * engine, of course. */
Packit Service 1d8f1c
    GList *engines = ibus_component_get_engines (component->component);
Packit Service 1d8f1c
    GList *p;
Packit Service 1d8f1c
    for (p = engines; p != NULL; p = p->next) {
Packit Service 1d8f1c
        g_object_set_qdata ((GObject *) p->data, quark, component);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
    g_list_free (engines);
Packit Service 1d8f1c
Packit Service 1d8f1c
    return object;
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
bus_component_set_property (BusComponent *component,
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_COMPONENT:
Packit Service 1d8f1c
        g_assert (component->component == NULL);
Packit Service 1d8f1c
        component->component = g_value_dup_object (value);
Packit Service 1d8f1c
        break;
Packit Service 1d8f1c
    case PROP_FACTORY:
Packit Service 1d8f1c
        bus_component_set_factory (component, (BusFactoryProxy *) g_value_get_object (value));
Packit Service 1d8f1c
        break;
Packit Service 1d8f1c
    default:
Packit Service 1d8f1c
        G_OBJECT_WARN_INVALID_PROPERTY_ID (component, prop_id, pspec);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
bus_component_get_property (BusComponent *component,
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_COMPONENT:
Packit Service 1d8f1c
        g_value_set_object (value, bus_component_get_component (component));
Packit Service 1d8f1c
        break;
Packit Service 1d8f1c
    case PROP_FACTORY:
Packit Service 1d8f1c
        g_value_set_object (value, bus_component_get_factory (component));
Packit Service 1d8f1c
        break;
Packit Service 1d8f1c
    default:
Packit Service 1d8f1c
        G_OBJECT_WARN_INVALID_PROPERTY_ID (component, prop_id, pspec);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
bus_component_destroy (BusComponent *component)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    if (component->pid != 0) {
Packit Service 1d8f1c
        bus_component_stop (component);
Packit Service 1d8f1c
        g_spawn_close_pid (component->pid);
Packit Service 1d8f1c
        component->pid = 0;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
    if (component->child_source_id != 0) {
Packit Service 1d8f1c
        g_source_remove (component->child_source_id);
Packit Service 1d8f1c
        component->child_source_id = 0;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
    if (component->component != NULL) {
Packit Service 1d8f1c
        g_object_unref (component->component);
Packit Service 1d8f1c
        component->component = NULL;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
    IBUS_OBJECT_CLASS (bus_component_parent_class)->destroy (IBUS_OBJECT (component));
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
BusComponent *
Packit Service 1d8f1c
bus_component_new (IBusComponent   *component,
Packit Service 1d8f1c
                   BusFactoryProxy *factory)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    g_assert (IBUS_IS_COMPONENT (component));
Packit Service 1d8f1c
Packit Service 1d8f1c
    return (BusComponent *) g_object_new (BUS_TYPE_COMPONENT,
Packit Service 1d8f1c
                                          /* properties below will be set via the bus_component_set_property function. */
Packit Service 1d8f1c
                                          "component", component,
Packit Service 1d8f1c
                                          "factory", factory,
Packit Service 1d8f1c
                                          NULL);
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
bus_component_factory_destroy_cb (BusFactoryProxy *factory,
Packit Service 1d8f1c
                                  BusComponent    *component)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    g_return_if_fail (component->factory == factory);
Packit Service 1d8f1c
Packit Service 1d8f1c
    g_object_unref (component->factory);
Packit Service 1d8f1c
    component->factory = NULL;
Packit Service 1d8f1c
    /* emit the "notify" signal for the factory property on component. */
Packit Service 1d8f1c
    g_object_notify ((GObject *) component, "factory");
Packit Service 1d8f1c
Packit Service 1d8f1c
    if (component->destroy_with_factory)
Packit Service 1d8f1c
        ibus_object_destroy ((IBusObject *) component);
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
IBusComponent *
Packit Service 1d8f1c
bus_component_get_component (BusComponent *component)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    g_assert (BUS_IS_COMPONENT (component));
Packit Service 1d8f1c
    return component->component;
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
void
Packit Service 1d8f1c
bus_component_set_factory (BusComponent    *component,
Packit Service 1d8f1c
                           BusFactoryProxy *factory)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    g_assert (BUS_IS_COMPONENT (component));
Packit Service 1d8f1c
Packit Service 1d8f1c
    if (component->factory == factory) {
Packit Service 1d8f1c
        return;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
    if (component->factory) {
Packit Service 1d8f1c
        g_signal_handlers_disconnect_by_func (component->factory,
Packit Service 1d8f1c
                                              bus_component_factory_destroy_cb,
Packit Service 1d8f1c
                                              component);
Packit Service 1d8f1c
        g_object_unref (component->factory);
Packit Service 1d8f1c
        component->factory = NULL;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
    if (factory) {
Packit Service 1d8f1c
        g_assert (BUS_IS_FACTORY_PROXY (factory));
Packit Service 1d8f1c
        component->factory = (BusFactoryProxy *) g_object_ref (factory);
Packit Service 1d8f1c
        g_signal_connect (factory, "destroy",
Packit Service 1d8f1c
                          G_CALLBACK (bus_component_factory_destroy_cb), component);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
    /* emit the "notify" signal for the factory property on component. */
Packit Service 1d8f1c
    g_object_notify ((GObject*) component, "factory");
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
BusFactoryProxy *
Packit Service 1d8f1c
bus_component_get_factory (BusComponent *component)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    g_assert (BUS_IS_COMPONENT (component));
Packit Service 1d8f1c
    return component->factory;
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
const gchar *
Packit Service 1d8f1c
bus_component_get_name (BusComponent *component)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    g_assert (BUS_IS_COMPONENT (component));
Packit Service 1d8f1c
Packit Service 1d8f1c
    return ibus_component_get_name (component->component);
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
GList *
Packit Service 1d8f1c
bus_component_get_engines (BusComponent *component)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    g_assert (BUS_IS_COMPONENT (component));
Packit Service 1d8f1c
Packit Service 1d8f1c
    return ibus_component_get_engines (component->component);
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
void
Packit Service 1d8f1c
bus_component_set_destroy_with_factory (BusComponent *component,
Packit Service 1d8f1c
                                        gboolean      with_factory)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    g_assert (BUS_IS_COMPONENT (component));
Packit Service 1d8f1c
Packit Service 1d8f1c
    component->destroy_with_factory = with_factory;
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
void
Packit Service 1d8f1c
bus_component_set_restart (BusComponent *component,
Packit Service 1d8f1c
                           gboolean      restart)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    g_assert (BUS_IS_COMPONENT (component));
Packit Service 1d8f1c
    component->restart = restart;
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
/**
Packit Service 1d8f1c
 * bus_component_child_cb:
Packit Service 1d8f1c
 *
Packit Service 1d8f1c
 * A callback function to be called when the child process is terminated.
Packit Service 1d8f1c
 */
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
bus_component_child_cb (GPid          pid,
Packit Service 1d8f1c
                        gint          status,
Packit Service 1d8f1c
                        BusComponent *component)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    g_assert (BUS_IS_COMPONENT (component));
Packit Service 1d8f1c
    g_assert (component->pid == pid);
Packit Service 1d8f1c
    g_spawn_close_pid (pid);
Packit Service 1d8f1c
    component->pid = 0;
Packit Service 1d8f1c
    component->child_source_id = 0;
Packit Service 1d8f1c
Packit Service 1d8f1c
    if (component->restart) {
Packit Service 1d8f1c
        bus_component_start (component, component->verbose);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
gboolean
Packit Service 1d8f1c
bus_component_start (BusComponent *component,
Packit Service 1d8f1c
                     gboolean      verbose)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    g_assert (BUS_IS_COMPONENT (component));
Packit Service 1d8f1c
Packit Service 1d8f1c
    if (component->pid != 0)
Packit Service 1d8f1c
        return TRUE;
Packit Service 1d8f1c
Packit Service 1d8f1c
    component->verbose = verbose;
Packit Service 1d8f1c
Packit Service 1d8f1c
    gint argc;
Packit Service 1d8f1c
    gchar **argv;
Packit Service 1d8f1c
    gboolean retval;
Packit Service 1d8f1c
Packit Service 1d8f1c
    GError *error = NULL;
Packit Service 1d8f1c
    if (!g_shell_parse_argv (ibus_component_get_exec (component->component),
Packit Service 1d8f1c
                             &argc,
Packit Service 1d8f1c
                             &argv,
Packit Service 1d8f1c
                             &error)) {
Packit Service 1d8f1c
        g_warning ("Can not parse component %s exec: %s",
Packit Service 1d8f1c
                   ibus_component_get_name (component->component),
Packit Service 1d8f1c
                   error->message);
Packit Service 1d8f1c
        g_error_free (error);
Packit Service 1d8f1c
        return FALSE;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
    error = NULL;
Packit Service 1d8f1c
    GSpawnFlags flags = G_SPAWN_DO_NOT_REAP_CHILD;
Packit Service 1d8f1c
    if (!verbose) {
Packit Service 1d8f1c
        flags |= G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
    retval = g_spawn_async (NULL, argv, NULL,
Packit Service 1d8f1c
                            flags,
Packit Service 1d8f1c
                            NULL, NULL,
Packit Service 1d8f1c
                            &(component->pid), &error);
Packit Service 1d8f1c
    g_strfreev (argv);
Packit Service 1d8f1c
    if (!retval) {
Packit Service 1d8f1c
        g_warning ("Can not execute component %s: %s",
Packit Service 1d8f1c
                   ibus_component_get_name (component->component),
Packit Service 1d8f1c
                   error->message);
Packit Service 1d8f1c
        g_error_free (error);
Packit Service 1d8f1c
        return FALSE;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
    component->child_source_id =
Packit Service 1d8f1c
        g_child_watch_add (component->pid,
Packit Service 1d8f1c
                           (GChildWatchFunc) bus_component_child_cb,
Packit Service 1d8f1c
                           component);
Packit Service 1d8f1c
Packit Service 1d8f1c
    return TRUE;
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
gboolean
Packit Service 1d8f1c
bus_component_stop (BusComponent *component)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    g_assert (BUS_IS_COMPONENT (component));
Packit Service 1d8f1c
Packit Service 1d8f1c
    if (component->pid == 0)
Packit Service 1d8f1c
        return TRUE;
Packit Service 1d8f1c
Packit Service 1d8f1c
    kill (component->pid, SIGTERM);
Packit Service 1d8f1c
    return TRUE;
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
gboolean
Packit Service 1d8f1c
bus_component_is_running (BusComponent *component)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    g_assert (BUS_IS_COMPONENT (component));
Packit Service 1d8f1c
Packit Service 1d8f1c
    return (component->pid != 0);
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
BusComponent *
Packit Service 1d8f1c
bus_component_from_engine_desc (IBusEngineDesc *engine)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    g_assert (IBUS_IS_ENGINE_DESC (engine));
Packit Service 1d8f1c
Packit Service 1d8f1c
    static GQuark quark = 0;
Packit Service 1d8f1c
    if (quark == 0) {
Packit Service 1d8f1c
        quark = g_quark_from_static_string ("BusComponent");
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
    return (BusComponent *) g_object_get_qdata ((GObject *) engine, quark);
Packit Service 1d8f1c
}