/* -*- Mode: C; c-basic-offset: 2; indent-tabs-mode: nil -*-
 *
 * Pigment media rendering library
 *
 * Copyright © 2006, 2007, 2008 Fluendo Embedded S.L.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * Author(s): Loïc Molinari <loic@fluendo.com>
 *            Julien Moutte <julien@fluendo.com>
 */

/**
 * SECTION:pgmplugin
 * @short_description: Various structs and macros used for plugins handling.
 *
 * Various structs and macros used by Pigment for plugins handling.
 *
 * Last reviewed on 2007-04-12 (0.1.5)
 */

#ifndef __PGM_PLUGIN_H__
#define __PGM_PLUGIN_H__

#include "pgmviewport.h"

G_BEGIN_DECLS

/**
 * PGM_PLUGIN_PATH_NAME:
 *
 * The name of the plugin path environment variable name.
 */
#define PGM_PLUGIN_PATH_NAME "PGM_PLUGIN_PATH"

typedef struct _PgmPluginDesc PgmPluginDesc;

/**
 * PgmPluginInitFunc:
 * @module: the #GTypeModule to use in the init func to register your types
 * (with g_type_module_register_type () or #PGM_DEFINE_DYNAMIC_TYPE or
 * #PGM_DEFINE_DYNAMIC_TYPE_EXTENDED.
 *
 * A plugin should provide a pointer to a function of this type in the
 * #PgmPluginDesc struct. This function will be called to initialize the
 * plugin.
 *
 * Returns: %TRUE if the initialization successes, %FALSE otherwise.
 */
typedef gboolean (*PgmPluginInitFunc) (GTypeModule *module);

/**
 * PgmPluginShutdownFunc:
 * @module: the #GTypeModule that was passed to the #PgmPluginInitFunc function.
 *
 * A plugin should provide a pointer to a function of this type in the
 * #PgmPluginDesc  struct. This function will be called to shutdown the plugin.
 *
 * Returns: %TRUE if the deinitialization successes, %FALSE otherwise.
 */
typedef gboolean (*PgmPluginShutdownFunc) (GTypeModule *module);

/**
 * PgmPluginCreateFunc:
 *
 * A plugin should provide a pointer to a function of this prototype in the
 * %PgmPluginDesc struct. This function will be called by the user to create
 * the %PgmViewport.
 *
 * Returns: a new #PgmViewport.
 */
typedef PgmViewport* (*PgmPluginCreateFunc) (void);

/**
 * PgmPluginDesc:
 * @init: the plugin initialization function pointer.
 * @shutdown: the plugin shutdown function pointer.
 * @create: the plugin create function pointer (returning a %PgmViewport).
 * @name: the plugin name.
 * @version: the version string of Pigment that plugin was compiled for.
 * @description: the plugin description.
 * @license: the plugin license.
 * @origin: the plugin origin URL.
 * @author: the plugin author.
 *
 * Pigment Plugin description structure.
 */
struct _PgmPluginDesc {
  PgmPluginInitFunc      init;
  PgmPluginShutdownFunc  shutdown;
  PgmPluginCreateFunc    create;
  gchar                 *name;
  gchar                 *version;
  gchar                 *description;
  gchar                 *license;
  gchar                 *origin;
  gchar                 *author;
};

/**
 * PGM_PLUGIN_DEFINE:
 * @init: the plugin initialization function pointer.
 * @shutdown: the plugin shutdown function pointer.
 * @create: the plugin creation function pointer (returning a %PgmViewport).
 * @name: the plugin name.
 * @version: the version string of Pigment that plugin was compiled for.
 * @description: the plugin description.
 * @license: the plugin license.
 * @origin: the plugin origin URL.
 * @author: the plugin author.
 *
 * Utility macro to create a #PgmPluginDesc plugin description structure.
 * This is the entry point for every Pigment plugin and it is highly
 * recommended to use this macro to avoid common mistakes maxking entry point
 * unusable.
 */
#define PGM_PLUGIN_DEFINE(init,shutdown,create,name,version,description,license,origin,author) \
  PgmPluginDesc pgm_plugin_desc = {                                     \
    init, shutdown, create, name, version,                              \
    description, license, origin, author                                \
  };

/* These defines are here for compatibility with GLib < 2.13 */
#ifdef G_DEFINE_DYNAMIC_TYPE
#define PGM_DEFINE_DYNAMIC_TYPE(TN, t_n, T_P) \
    G_DEFINE_DYNAMIC_TYPE(TN, t_n, T_P)
#define PGM_DEFINE_DYNAMIC_TYPE_EXTENDED(TN, t_n, T_P, flags, CODE) \
    G_DEFINE_DYNAMIC_TYPE_EXTENDED(TN, t_n, T_P, flags, CODE)
#else
#define PGM_DEFINE_DYNAMIC_TYPE(TN, t_n, T_P) \
    PGM_DEFINE_DYNAMIC_TYPE_EXTENDED (TN, t_n, T_P, 0, {})
#define PGM_DEFINE_DYNAMIC_TYPE_EXTENDED(TypeName, type_name, TYPE_PARENT, flags, CODE) \
static void     type_name##_init              (TypeName        *self); \
static void     type_name##_class_init        (TypeName##Class *klass); \
static void     type_name##_class_finalize    (TypeName##Class *klass); \
static gpointer type_name##_parent_class = NULL; \
static GType    type_name##_type_id = 0; \
static void     type_name##_class_intern_init (gpointer klass) \
{ \
  type_name##_parent_class = g_type_class_peek_parent (klass); \
  type_name##_class_init ((TypeName##Class*) klass); \
} \
GType \
type_name##_get_type (void) \
{ \
  return type_name##_type_id; \
} \
static void \
type_name##_register_type (GTypeModule *type_module) \
{ \
  GType g_define_type_id; \
  const GTypeInfo g_define_type_info = { \
    sizeof (TypeName##Class), \
    (GBaseInitFunc) NULL, \
    (GBaseFinalizeFunc) NULL, \
    (GClassInitFunc) type_name##_class_intern_init, \
    (GClassFinalizeFunc) type_name##_class_finalize, \
    NULL,   /* class_data */ \
    sizeof (TypeName), \
    0,      /* n_preallocs */ \
    (GInstanceInitFunc) type_name##_init, \
    NULL    /* value_table */ \
  }; \
  type_name##_type_id = g_type_module_register_type (type_module, \
                                                     TYPE_PARENT, \
                                                     #TypeName,         \
                                                     &g_define_type_info, \
                                                     (GTypeFlags) flags); \
  g_define_type_id = type_name##_type_id; \
  { CODE ; } \
}
#endif /* G_DEFINE_DYNAMIC_TYPE */

G_END_DECLS

#endif /* __PGM_PLUGIN_H__ */
