home *** CD-ROM | disk | FTP | other *** search
/ Chip 2005 February / CMCD0205.ISO / Linux / gimp-2.2.0.tar.gz / gimp-2.2.0.tar / gimp-2.2.0 / libgimpmodule / gimpmodule.c next >
C/C++ Source or Header  |  2004-07-06  |  15KB  |  589 lines

  1. /* LIBGIMP - The GIMP Library
  2.  * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
  3.  *
  4.  * gimpmodule.c
  5.  * (C) 1999 Austin Donnelly <austin@gimp.org>
  6.  *
  7.  * This library is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2 of the License, or (at your option) any later version.
  11.  *
  12.  * This library is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Lesser General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with this library; if not, write to the
  19.  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  20.  * Boston, MA 02111-1307, USA.
  21.  */
  22.  
  23. #include "config.h"
  24.  
  25. #include <string.h>
  26.  
  27. #include <glib-object.h>
  28.  
  29. #include "libgimpbase/gimpbase.h"
  30.  
  31. #include "gimpmodule.h"
  32.  
  33. #include "libgimp/libgimp-intl.h"
  34.  
  35.  
  36. enum
  37. {
  38.   MODIFIED,
  39.   LAST_SIGNAL
  40. };
  41.  
  42.  
  43. static void       gimp_module_class_init     (GimpModuleClass *klass);
  44. static void       gimp_module_init           (GimpModule      *module);
  45.  
  46. static void       gimp_module_finalize       (GObject         *object);
  47.  
  48. static gboolean   gimp_module_load           (GTypeModule     *module);
  49. static void       gimp_module_unload         (GTypeModule     *module);
  50.  
  51. static gboolean   gimp_module_open           (GimpModule      *module);
  52. static gboolean   gimp_module_close          (GimpModule      *module);
  53. static void       gimp_module_set_last_error (GimpModule      *module,
  54.                                               const gchar     *error_str);
  55.  
  56.  
  57. static guint module_signals[LAST_SIGNAL];
  58.  
  59. static GTypeModuleClass *parent_class = NULL;
  60.  
  61.  
  62. GType
  63. gimp_module_get_type (void)
  64. {
  65.   static GType module_type = 0;
  66.  
  67.   if (! module_type)
  68.     {
  69.       static const GTypeInfo module_info =
  70.       {
  71.         sizeof (GimpModuleClass),
  72.         NULL,           /* base_init */
  73.         NULL,           /* base_finalize */
  74.         (GClassInitFunc) gimp_module_class_init,
  75.         NULL,           /* class_finalize */
  76.         NULL,           /* class_data */
  77.         sizeof (GimpModule),
  78.         0,              /* n_preallocs */
  79.         (GInstanceInitFunc) gimp_module_init,
  80.       };
  81.  
  82.       module_type = g_type_register_static (G_TYPE_TYPE_MODULE,
  83.                                             "GimpModule",
  84.                                             &module_info, 0);
  85.     }
  86.  
  87.   return module_type;
  88. }
  89.  
  90. static void
  91. gimp_module_class_init (GimpModuleClass *klass)
  92. {
  93.   GObjectClass     *object_class;
  94.   GTypeModuleClass *module_class;
  95.  
  96.   object_class = G_OBJECT_CLASS (klass);
  97.   module_class = G_TYPE_MODULE_CLASS (klass);
  98.  
  99.   parent_class = g_type_class_peek_parent (klass);
  100.  
  101.   module_signals[MODIFIED] =
  102.     g_signal_new ("modified",
  103.           G_TYPE_FROM_CLASS (klass),
  104.           G_SIGNAL_RUN_FIRST,
  105.           G_STRUCT_OFFSET (GimpModuleClass, modified),
  106.           NULL, NULL,
  107.           g_cclosure_marshal_VOID__VOID,
  108.           G_TYPE_NONE, 0);
  109.  
  110.   object_class->finalize = gimp_module_finalize;
  111.  
  112.   module_class->load     = gimp_module_load;
  113.   module_class->unload   = gimp_module_unload;
  114.  
  115.   klass->modified        = NULL;
  116. }
  117.  
  118. static void
  119. gimp_module_init (GimpModule *module)
  120. {
  121.   module->filename          = NULL;
  122.   module->verbose           = FALSE;
  123.   module->state             = GIMP_MODULE_STATE_ERROR;
  124.   module->on_disk           = FALSE;
  125.   module->load_inhibit      = FALSE;
  126.  
  127.   module->module            = NULL;
  128.   module->info              = NULL;
  129.   module->last_module_error = NULL;
  130.  
  131.   module->query_module      = NULL;
  132.   module->register_module   = NULL;
  133. }
  134.  
  135. static void
  136. gimp_module_finalize (GObject *object)
  137. {
  138.   GimpModule *module;
  139.  
  140.   module = GIMP_MODULE (object);
  141.  
  142.   if (module->info)
  143.     {
  144.       gimp_module_info_free (module->info);
  145.       module->info = NULL;
  146.     }
  147.  
  148.   if (module->last_module_error)
  149.     {
  150.       g_free (module->last_module_error);
  151.       module->last_module_error = NULL;
  152.     }
  153.  
  154.   if (module->filename)
  155.     {
  156.       g_free (module->filename);
  157.       module->filename = NULL;
  158.     }
  159.  
  160.   G_OBJECT_CLASS (parent_class)->finalize (object);
  161. }
  162.  
  163. static gboolean
  164. gimp_module_load (GTypeModule *module)
  165. {
  166.   GimpModule *gimp_module;
  167.   gpointer    func;
  168.  
  169.   g_return_val_if_fail (GIMP_IS_MODULE (module), FALSE);
  170.  
  171.   gimp_module = GIMP_MODULE (module);
  172.  
  173.   g_return_val_if_fail (gimp_module->filename != NULL, FALSE);
  174.   g_return_val_if_fail (gimp_module->module == NULL, FALSE);
  175.  
  176.   if (gimp_module->verbose)
  177.     g_print (_("Loading module: '%s'\n"),
  178.              gimp_filename_to_utf8 (gimp_module->filename));
  179.  
  180.   if (! gimp_module_open (gimp_module))
  181.     return FALSE;
  182.  
  183.   if (! gimp_module_query_module (gimp_module))
  184.     return FALSE;
  185.  
  186.   /* find the gimp_module_register symbol */
  187.   if (! g_module_symbol (gimp_module->module, "gimp_module_register", &func))
  188.     {
  189.       gimp_module_set_last_error (gimp_module,
  190.                                   "Missing gimp_module_register() symbol");
  191.  
  192.       if (gimp_module->verbose)
  193.     g_message (_("Module '%s' load error: %s"),
  194.            gimp_filename_to_utf8 (gimp_module->filename),
  195.                    gimp_module->last_module_error);
  196.  
  197.       gimp_module_close (gimp_module);
  198.  
  199.       gimp_module->state = GIMP_MODULE_STATE_ERROR;
  200.  
  201.       return FALSE;
  202.     }
  203.  
  204.   gimp_module->register_module = func;
  205.  
  206.   if (! gimp_module->register_module (module))
  207.     {
  208.       gimp_module_set_last_error (gimp_module,
  209.                                   "gimp_module_register() returned FALSE");
  210.  
  211.       if (gimp_module->verbose)
  212.     g_message (_("Module '%s' load error: %s"),
  213.            gimp_filename_to_utf8 (gimp_module->filename),
  214.                    gimp_module->last_module_error);
  215.  
  216.       gimp_module_close (gimp_module);
  217.  
  218.       gimp_module->state = GIMP_MODULE_STATE_LOAD_FAILED;
  219.  
  220.       return FALSE;
  221.     }
  222.  
  223.   gimp_module->state = GIMP_MODULE_STATE_LOADED;
  224.  
  225.   return TRUE;
  226. }
  227.  
  228. static void
  229. gimp_module_unload (GTypeModule *module)
  230. {
  231.   GimpModule *gimp_module;
  232.  
  233.   g_return_if_fail (GIMP_IS_MODULE (module));
  234.  
  235.   gimp_module = GIMP_MODULE (module);
  236.  
  237.   g_return_if_fail (gimp_module->module != NULL);
  238.  
  239.   gimp_module_close (gimp_module);
  240. }
  241.  
  242.  
  243. /*  public functions  */
  244.  
  245. /**
  246.  * gimp_module_new:
  247.  * @filename:     The filename of a loadable module.
  248.  * @load_inhibit: Pass %TRUE to exclude this module from auto-loading.
  249.  * @verbose:      Pass %TRUE to enable debugging output.
  250.  *
  251.  * Creates a new #GimpModule instance.
  252.  *
  253.  * Return value: The new #GimpModule object.
  254.  **/
  255. GimpModule *
  256. gimp_module_new (const gchar *filename,
  257.                  gboolean     load_inhibit,
  258.                  gboolean     verbose)
  259. {
  260.   GimpModule *module;
  261.  
  262.   g_return_val_if_fail (filename != NULL, NULL);
  263.  
  264.   module = g_object_new (GIMP_TYPE_MODULE, NULL);
  265.  
  266.   module->filename     = g_strdup (filename);
  267.   module->load_inhibit = load_inhibit ? TRUE : FALSE;
  268.   module->verbose      = verbose ? TRUE : FALSE;
  269.   module->on_disk      = TRUE;
  270.  
  271.   if (! module->load_inhibit)
  272.     {
  273.       if (gimp_module_load (G_TYPE_MODULE (module)))
  274.         gimp_module_unload (G_TYPE_MODULE (module));
  275.     }
  276.   else
  277.     {
  278.       if (verbose)
  279.     {
  280.       gchar *filename_utf8 = g_filename_to_utf8 (filename,
  281.                              -1, NULL, NULL, NULL);
  282.       g_print (_("Skipping module: '%s'\n"), filename_utf8);
  283.       g_free (filename_utf8);
  284.     }
  285.  
  286.       module->state = GIMP_MODULE_STATE_NOT_LOADED;
  287.     }
  288.  
  289.   return module;
  290. }
  291.  
  292. /**
  293.  * gimp_module_query_module:
  294.  * @module: A #GimpModule.
  295.  *
  296.  * Queries the module without actually registering any of the types it
  297.  * may implement. After successful query, the @info field of the
  298.  * #GimpModule struct will be available for further inspection.
  299.  *
  300.  * Return value: %TRUE on success.
  301.  **/
  302. gboolean
  303. gimp_module_query_module (GimpModule *module)
  304. {
  305.   const GimpModuleInfo *info;
  306.   gboolean              close_module = FALSE;
  307.   gpointer              func;
  308.  
  309.   g_return_val_if_fail (GIMP_IS_MODULE (module), FALSE);
  310.  
  311.   if (! module->module)
  312.     {
  313.       if (! gimp_module_open (module))
  314.         return FALSE;
  315.  
  316.       close_module = TRUE;
  317.     }
  318.  
  319.   /* find the gimp_module_query symbol */
  320.   if (! g_module_symbol (module->module, "gimp_module_query", &func))
  321.     {
  322.       gimp_module_set_last_error (module,
  323.                                   "Missing gimp_module_query() symbol");
  324.  
  325.       if (module->verbose)
  326.         g_message (_("Module '%s' load error: %s"),
  327.                    gimp_filename_to_utf8 (module->filename),
  328.                    module->last_module_error);
  329.  
  330.       gimp_module_close (module);
  331.  
  332.       module->state = GIMP_MODULE_STATE_ERROR;
  333.       return FALSE;
  334.     }
  335.  
  336.   module->query_module = func;
  337.  
  338.   if (module->info)
  339.     {
  340.       gimp_module_info_free (module->info);
  341.       module->info = NULL;
  342.     }
  343.  
  344.   info = module->query_module (G_TYPE_MODULE (module));
  345.  
  346.   if (! info || info->abi_version != GIMP_MODULE_ABI_VERSION)
  347.     {
  348.       gimp_module_set_last_error (module,
  349.                                   info ?
  350.                                   "module ABI version does not match" :
  351.                                   "gimp_module_query() returned NULL");
  352.  
  353.       if (module->verbose)
  354.         g_message (_("Module '%s' load error: %s"),
  355.                    gimp_filename_to_utf8 (module->filename),
  356.                    module->last_module_error);
  357.  
  358.       gimp_module_close (module);
  359.  
  360.       module->state = GIMP_MODULE_STATE_ERROR;
  361.       return FALSE;
  362.     }
  363.  
  364.   module->info = gimp_module_info_copy (info);
  365.  
  366.   if (close_module)
  367.     return gimp_module_close (module);
  368.  
  369.   return TRUE;
  370. }
  371.  
  372. /**
  373.  * gimp_module_modified:
  374.  * @module: A #GimpModule.
  375.  *
  376.  * Emits the "modified" signal. Call it whenever you have modified the module
  377.  * manually (which you shouldn't do).
  378.  **/
  379. void
  380. gimp_module_modified (GimpModule *module)
  381. {
  382.   g_return_if_fail (GIMP_IS_MODULE (module));
  383.  
  384.   g_signal_emit (module, module_signals[MODIFIED], 0);
  385. }
  386.  
  387. /**
  388.  * gimp_module_set_load_inhibit:
  389.  * @module:       A #GimpModule.
  390.  * @load_inhibit: Pass %TRUE to exclude this module from auto-loading.
  391.  *
  392.  * Sets the @load_inhibit property if the module. Emits "modified".
  393.  **/
  394. void
  395. gimp_module_set_load_inhibit (GimpModule *module,
  396.                               gboolean    load_inhibit)
  397. {
  398.   g_return_if_fail (GIMP_IS_MODULE (module));
  399.  
  400.   if (load_inhibit != module->load_inhibit)
  401.     {
  402.       module->load_inhibit = load_inhibit ? TRUE : FALSE;
  403.  
  404.       gimp_module_modified (module);
  405.     }
  406. }
  407.  
  408. /**
  409.  * gimp_module_state_name:
  410.  * @state: A #GimpModuleState.
  411.  *
  412.  * Returns the translated textual representation of a #GimpModuleState.
  413.  * The returned string must not be freed.
  414.  *
  415.  * Return value: The @state's name.
  416.  **/
  417. const gchar *
  418. gimp_module_state_name (GimpModuleState state)
  419. {
  420.   static const gchar * const statenames[] =
  421.   {
  422.     N_("Module error"),
  423.     N_("Loaded"),
  424.     N_("Load failed"),
  425.     N_("Not loaded")
  426.   };
  427.  
  428.   g_return_val_if_fail (state >= GIMP_MODULE_STATE_ERROR &&
  429.                         state <= GIMP_MODULE_STATE_NOT_LOADED, NULL);
  430.  
  431.   return gettext (statenames[state]);
  432. }
  433.  
  434. /**
  435.  * gimp_module_register_enum:
  436.  * @module:
  437.  * @name:
  438.  * @const_static_values:
  439.  *
  440.  * Registers an enum similar to g_enum_register_static() but for
  441.  * modules. This function should actually live in GLib but since
  442.  * there's no such API, it is provided here.
  443.  *
  444.  * Return value: a new enum #GType
  445.  **/
  446. GType
  447. gimp_module_register_enum (GTypeModule      *module,
  448.                            const gchar        *name,
  449.                            const GEnumValue *const_static_values)
  450. {
  451.   GTypeInfo enum_type_info = { 0, };
  452.  
  453.   g_return_val_if_fail (G_IS_TYPE_MODULE (module), 0);
  454.   g_return_val_if_fail (name != NULL, 0);
  455.   g_return_val_if_fail (const_static_values != NULL, 0);
  456.  
  457.   g_enum_complete_type_info (G_TYPE_ENUM,
  458.                              &enum_type_info, const_static_values);
  459.  
  460.   return g_type_module_register_type (G_TYPE_MODULE (module),
  461.                                       G_TYPE_ENUM, name, &enum_type_info, 0);
  462. }
  463.  
  464.  
  465. /*  private functions  */
  466.  
  467. static gboolean
  468. gimp_module_open (GimpModule *module)
  469. {
  470.   module->module = g_module_open (module->filename, 0);
  471.  
  472.   if (! module->module)
  473.     {
  474.       module->state = GIMP_MODULE_STATE_ERROR;
  475.       gimp_module_set_last_error (module, g_module_error ());
  476.  
  477.       if (module->verbose)
  478.         g_message (_("Module '%s' load error: %s"),
  479.                    gimp_filename_to_utf8 (module->filename),
  480.                    module->last_module_error);
  481.  
  482.       return FALSE;
  483.     }
  484.  
  485.   return TRUE;
  486. }
  487.  
  488. static gboolean
  489. gimp_module_close (GimpModule *module)
  490. {
  491.   g_module_close (module->module); /* FIXME: error handling */
  492.   module->module          = NULL;
  493.   module->query_module    = NULL;
  494.   module->register_module = NULL;
  495.  
  496.   module->state = GIMP_MODULE_STATE_NOT_LOADED;
  497.  
  498.   return TRUE;
  499. }
  500.  
  501. static void
  502. gimp_module_set_last_error (GimpModule  *module,
  503.                             const gchar *error_str)
  504. {
  505.   if (module->last_module_error)
  506.     g_free (module->last_module_error);
  507.  
  508.   module->last_module_error = g_strdup (error_str);
  509. }
  510.  
  511.  
  512. /*  GimpModuleInfo functions  */
  513.  
  514. /**
  515.  * gimp_module_info_new:
  516.  * @abi_version: The #GIMP_MODULE_ABI_VERSION the module was compiled against.
  517.  * @purpose:     The module's general purpose.
  518.  * @author:      The module's author.
  519.  * @version:     The module's version.
  520.  * @copyright:   The module's copyright.
  521.  * @date:        The module's release date.
  522.  *
  523.  * Creates a newly allocated #GimpModuleInfo struct.
  524.  *
  525.  * Return value: The new #GimpModuleInfo struct.
  526.  **/
  527. GimpModuleInfo *
  528. gimp_module_info_new (guint32      abi_version,
  529.                       const gchar *purpose,
  530.                       const gchar *author,
  531.                       const gchar *version,
  532.                       const gchar *copyright,
  533.                       const gchar *date)
  534. {
  535.   GimpModuleInfo *info;
  536.  
  537.   info = g_new0 (GimpModuleInfo, 1);
  538.  
  539.   info->abi_version = abi_version;
  540.   info->purpose     = g_strdup (purpose);
  541.   info->author      = g_strdup (author);
  542.   info->version     = g_strdup (version);
  543.   info->copyright   = g_strdup (copyright);
  544.   info->date        = g_strdup (date);
  545.  
  546.   return info;
  547. }
  548.  
  549. /**
  550.  * gimp_module_info_copy:
  551.  * @info: The #GimpModuleInfo struct to copy.
  552.  *
  553.  * Copies a #GimpModuleInfo struct.
  554.  *
  555.  * Return value: The new copy.
  556.  **/
  557. GimpModuleInfo *
  558. gimp_module_info_copy (const GimpModuleInfo *info)
  559. {
  560.   g_return_val_if_fail (info != NULL, NULL);
  561.  
  562.   return gimp_module_info_new (info->abi_version,
  563.                                info->purpose,
  564.                                info->author,
  565.                                info->version,
  566.                                info->copyright,
  567.                                info->date);
  568. }
  569.  
  570. /**
  571.  * gimp_module_info_free:
  572.  * @info: The #GimpModuleInfo struct to free
  573.  *
  574.  * Frees the passed #GimpModuleInfo.
  575.  **/
  576. void
  577. gimp_module_info_free (GimpModuleInfo *info)
  578. {
  579.   g_return_if_fail (info != NULL);
  580.  
  581.   g_free (info->purpose);
  582.   g_free (info->author);
  583.   g_free (info->version);
  584.   g_free (info->copyright);
  585.   g_free (info->date);
  586.  
  587.   g_free (info);
  588. }
  589.