183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik/* GObject - GLib Type, Object, Parameter and Signal Library
283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik * Copyright (C) 2000 Red Hat, Inc.
383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik *
483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik * This library is free software; you can redistribute it and/or
583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik * modify it under the terms of the GNU Lesser General Public
683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik * License as published by the Free Software Foundation; either
783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik * version 2 of the License, or (at your option) any later version.
883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik *
983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik * This library is distributed in the hope that it will be useful,
1083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik * but WITHOUT ANY WARRANTY; without even the implied warranty of
1183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik * Lesser General Public License for more details.
1383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik *
1483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik * You should have received a copy of the GNU Lesser General
1583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik * Public License along with this library; if not, write to the
1683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
1783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik * Boston, MA 02111-1307, USA.
1883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik */
195602b7e275ef5fb76cf7847f35b120dce3111705Michael Natterer
205602b7e275ef5fb76cf7847f35b120dce3111705Michael Natterer#include "config.h"
215602b7e275ef5fb76cf7847f35b120dce3111705Michael Natterer
225602b7e275ef5fb76cf7847f35b120dce3111705Michael Natterer#include "gtypeplugin.h"
235602b7e275ef5fb76cf7847f35b120dce3111705Michael Natterer#include "gobjectalias.h"
245602b7e275ef5fb76cf7847f35b120dce3111705Michael Natterer
255602b7e275ef5fb76cf7847f35b120dce3111705Michael Natterer
263f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost/**
273f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost * SECTION:gtypeplugin
28d6d221911d8a8515bf91c9d0721025669717d6f8Matthias Clasen * @short_description: An interface for dynamically loadable types
29d6d221911d8a8515bf91c9d0721025669717d6f8Matthias Clasen * @see_also: #GTypeModule and g_type_register_dynamic().
30d6d221911d8a8515bf91c9d0721025669717d6f8Matthias Clasen * @title: GTypePlugin
315602b7e275ef5fb76cf7847f35b120dce3111705Michael Natterer *
325602b7e275ef5fb76cf7847f35b120dce3111705Michael Natterer * The GObject type system supports dynamic loading of types. The
335602b7e275ef5fb76cf7847f35b120dce3111705Michael Natterer * #GTypePlugin interface is used to handle the lifecycle of
345602b7e275ef5fb76cf7847f35b120dce3111705Michael Natterer * dynamically loaded types.  It goes as follows:
355602b7e275ef5fb76cf7847f35b120dce3111705Michael Natterer *
363f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost * <orderedlist>
373f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost * <listitem><para>
383f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost *   The type is initially introduced (usually upon loading the module
393f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost *   the first time, or by your main application that knows what modules
403f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost *   introduces what types), like this:
413f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost *   |[
423f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost *   new_type_id = g_type_register_dynamic (parent_type_id,
433f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost *                                                 "TypeName",
443f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost *                                                 new_type_plugin,
453f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost *                                                 type_flags);
463f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost *   ]|
473f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost *   where <literal>new_type_plugin</literal> is an implementation of the
483f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost *   #GTypePlugin interface.
493f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost * </para></listitem>
503f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost * <listitem><para>
513f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost *    The type's implementation is referenced, e.g. through
525602b7e275ef5fb76cf7847f35b120dce3111705Michael Natterer *    g_type_class_ref() or through g_type_create_instance() (this is
535602b7e275ef5fb76cf7847f35b120dce3111705Michael Natterer *    being called by g_object_new()) or through one of the above done on
543f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost *    a type derived from <literal>new_type_id</literal>.
553f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost * </para></listitem>
563f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost * <listitem><para>
573f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost *    This causes the type system to load the type's implementation by calling
585602b7e275ef5fb76cf7847f35b120dce3111705Michael Natterer *    g_type_plugin_use() and g_type_plugin_complete_type_info() on
593f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost *    <literal>new_type_plugin</literal>.
603f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost * </para></listitem>
613f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost * <listitem><para>
623f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost *    At some point the type's implementation isn't required anymore, e.g. after
633f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost *    g_type_class_unref() or g_type_free_instance() (called when the reference
643f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost *    count of an instance drops to zero).
653f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost * </para></listitem>
663f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost * <listitem><para>
673f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost *    This causes the type system to throw away the information retrieved from
683f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost *    g_type_plugin_complete_type_info() and then it calls
693f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost *    g_type_plugin_unuse() on <literal>new_type_plugin</literal>.
703f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost * </para></listitem>
713f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost * <listitem><para>
723f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost *    Things may repeat from the second step.
733f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost * </para></listitem>
743f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost * </orderedlist>
755602b7e275ef5fb76cf7847f35b120dce3111705Michael Natterer *
765602b7e275ef5fb76cf7847f35b120dce3111705Michael Natterer * So basically, you need to implement a #GTypePlugin type that
775602b7e275ef5fb76cf7847f35b120dce3111705Michael Natterer * carries a use_count, once use_count goes from zero to one, you need
785602b7e275ef5fb76cf7847f35b120dce3111705Michael Natterer * to load the implementation to successfully handle the upcoming
795602b7e275ef5fb76cf7847f35b120dce3111705Michael Natterer * g_type_plugin_complete_type_info() call. Later, maybe after
805602b7e275ef5fb76cf7847f35b120dce3111705Michael Natterer * succeeding use/unuse calls, once use_count drops to zero, you can
815602b7e275ef5fb76cf7847f35b120dce3111705Michael Natterer * unload the implementation again. The type system makes sure to call
825602b7e275ef5fb76cf7847f35b120dce3111705Michael Natterer * g_type_plugin_use() and g_type_plugin_complete_type_info() again
835602b7e275ef5fb76cf7847f35b120dce3111705Michael Natterer * when the type is needed again.
845602b7e275ef5fb76cf7847f35b120dce3111705Michael Natterer *
855602b7e275ef5fb76cf7847f35b120dce3111705Michael Natterer * #GTypeModule is an implementation of #GTypePlugin that already
865602b7e275ef5fb76cf7847f35b120dce3111705Michael Natterer * implements most of this except for the actual module loading and
875602b7e275ef5fb76cf7847f35b120dce3111705Michael Natterer * unloading. It even handles multiple registered types per module.
883f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost */
8983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik
9083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik
9183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik/* --- functions --- */
9283c45024e3d3a56ac17eb08dcddae048005bbb71Tim JanikGType
9383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikg_type_plugin_get_type (void)
9483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik{
9583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik  static GType type_plugin_type = 0;
9683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik
9783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik  if (!type_plugin_type)
9883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik    {
9983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik      static const GTypeInfo type_plugin_info = {
10083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik	sizeof (GTypePluginClass),
10183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik	NULL,           /* base_init */
10283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik	NULL,           /* base_finalize */
10383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik      };
10483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik
10507c4d80d55c6b818c3cc4a9535015b0d235b1776Matthias Clasen      type_plugin_type = g_type_register_static (G_TYPE_INTERFACE, g_intern_static_string ("GTypePlugin"), &type_plugin_info, 0);
10683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik    }
10783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik
10883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik  return type_plugin_type;
10983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik}
11083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik
1113f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost/**
1123f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost * g_type_plugin_use:
1133f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost * @plugin: a #GTypePlugin
1146347be5fb68fc3e5e9d5bfedc3cbd5349ef40074Michael Natterer *
1156347be5fb68fc3e5e9d5bfedc3cbd5349ef40074Michael Natterer * Calls the @use_plugin function from the #GTypePluginClass of
1166347be5fb68fc3e5e9d5bfedc3cbd5349ef40074Michael Natterer * @plugin.  There should be no need to use this function outside of
1176347be5fb68fc3e5e9d5bfedc3cbd5349ef40074Michael Natterer * the GObject type system itself.
1183f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost */
11983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikvoid
12083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikg_type_plugin_use (GTypePlugin *plugin)
12183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik{
12283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik  GTypePluginClass *iface;
12383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik
12483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik  g_return_if_fail (G_IS_TYPE_PLUGIN (plugin));
12583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik
12683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik  iface = G_TYPE_PLUGIN_GET_CLASS (plugin);
12783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik  iface->use_plugin (plugin);
12883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik}
12983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik
1303f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost/**
1313f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost * g_type_plugin_unuse:
1323f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost * @plugin: a #GTypePlugin
1336347be5fb68fc3e5e9d5bfedc3cbd5349ef40074Michael Natterer *
1346347be5fb68fc3e5e9d5bfedc3cbd5349ef40074Michael Natterer * Calls the @unuse_plugin function from the #GTypePluginClass of
1356347be5fb68fc3e5e9d5bfedc3cbd5349ef40074Michael Natterer * @plugin.  There should be no need to use this function outside of
1366347be5fb68fc3e5e9d5bfedc3cbd5349ef40074Michael Natterer * the GObject type system itself.
1373f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost */
13883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikvoid
13983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikg_type_plugin_unuse (GTypePlugin *plugin)
14083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik{
14183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik  GTypePluginClass *iface;
14283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik
14383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik  g_return_if_fail (G_IS_TYPE_PLUGIN (plugin));
14483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik
14583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik  iface = G_TYPE_PLUGIN_GET_CLASS (plugin);
14683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik  iface->unuse_plugin (plugin);
14783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik}
14883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik
1493f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost/**
1503f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost * g_type_plugin_complete_type_info:
1513f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost * @plugin: a #GTypePlugin
1523f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost * @g_type: the #GType whose info is completed
1533f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost * @info: the #GTypeInfo struct to fill in
1543f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost * @value_table: the #GTypeValueTable to fill in
1553f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost *
1563f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost * Calls the @complete_type_info function from the #GTypePluginClass of @plugin.
1573f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost * There should be no need to use this function outside of the GObject
1583f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost * type system itself.
1593f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost */
16083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikvoid
16183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikg_type_plugin_complete_type_info (GTypePlugin     *plugin,
16283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik				  GType            g_type,
16383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik				  GTypeInfo       *info,
16483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik				  GTypeValueTable *value_table)
16583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik{
16683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik  GTypePluginClass *iface;
16783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik
16883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik  g_return_if_fail (G_IS_TYPE_PLUGIN (plugin));
16983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik  g_return_if_fail (info != NULL);
17083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik  g_return_if_fail (value_table != NULL);
17183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik
17283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik  iface = G_TYPE_PLUGIN_GET_CLASS (plugin);
17383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik  iface->complete_type_info (plugin,
17483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik			     g_type,
17583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik			     info,
17683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik			     value_table);
17783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik}
17883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik
1793f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost/**
1803f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost * g_type_plugin_complete_interface_info:
1813f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost * @plugin: the #GTypePlugin
1823f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost * @instance_type: the #GType of an instantiable type to which the interface
1833f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost *  is added
1843f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost * @interface_type: the #GType of the interface whose info is completed
1853f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost * @info: the #GInterfaceInfo to fill in
1866347be5fb68fc3e5e9d5bfedc3cbd5349ef40074Michael Natterer *
1876347be5fb68fc3e5e9d5bfedc3cbd5349ef40074Michael Natterer * Calls the @complete_interface_info function from the
1886347be5fb68fc3e5e9d5bfedc3cbd5349ef40074Michael Natterer * #GTypePluginClass of @plugin. There should be no need to use this
1896347be5fb68fc3e5e9d5bfedc3cbd5349ef40074Michael Natterer * function outside of the GObject type system itself.
1903f5419f6f166e20d42ce6222f58110e93347c3f5Stefan Kost */
19183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikvoid
19283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikg_type_plugin_complete_interface_info (GTypePlugin    *plugin,
19383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik				       GType           instance_type,
194743f49cec9f4696c9eba32966d6ac78cd96c586dTim Janik				       GType           interface_type,
19583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik				       GInterfaceInfo *info)
19683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik{
19783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik  GTypePluginClass *iface;
19883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik
19983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik  g_return_if_fail (G_IS_TYPE_PLUGIN (plugin));
20083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik  g_return_if_fail (info != NULL);
20183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik
20283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik  iface = G_TYPE_PLUGIN_GET_CLASS (plugin);
20383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik  iface->complete_interface_info (plugin,
20483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik				  instance_type,
205743f49cec9f4696c9eba32966d6ac78cd96c586dTim Janik				  interface_type,
20683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik				  info);
20783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik}
2083448a27829133bebb3bf1e29a30574304c899040Matthias Clasen
2093448a27829133bebb3bf1e29a30574304c899040Matthias Clasen#define __G_TYPE_PLUGIN_C__
2103448a27829133bebb3bf1e29a30574304c899040Matthias Clasen#include "gobjectaliasdef.c"
211