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