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 / gimpmoduledb.c < prev    next >
C/C++ Source or Header  |  2004-07-29  |  14KB  |  499 lines

  1. /* LIBGIMP - The GIMP Library
  2.  * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
  3.  *
  4.  * This library is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU Lesser General Public
  6.  * License as published by the Free Software Foundation; either
  7.  * version 2 of the License, or (at your option) any later version.
  8.  *
  9.  * This library is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12.  * Lesser General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU Lesser General Public
  15.  * License along with this library; if not, write to the
  16.  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  17.  * Boston, MA 02111-1307, USA.
  18.  */
  19.  
  20. #include "config.h"
  21.  
  22. #include <string.h>
  23.  
  24. #include <glib-object.h>
  25.  
  26. #include "libgimpbase/gimpbase.h"
  27.  
  28. #include "gimpmoduletypes.h"
  29.  
  30. #include "gimpmodule.h"
  31. #include "gimpmoduledb.h"
  32.  
  33.  
  34. enum
  35. {
  36.   ADD,
  37.   REMOVE,
  38.   MODULE_MODIFIED,
  39.   LAST_SIGNAL
  40. };
  41.  
  42.  
  43. /*  #define DUMP_DB 1  */
  44.  
  45.  
  46. static void         gimp_module_db_class_init     (GimpModuleDBClass *klass);
  47. static void         gimp_module_db_init           (GimpModuleDB      *db);
  48.  
  49. static void         gimp_module_db_finalize            (GObject      *object);
  50.  
  51. static void         gimp_module_db_module_initialize   (const GimpDatafileData *file_data,
  52.                                                         gpointer                user_data);
  53.  
  54. static GimpModule * gimp_module_db_module_find_by_path (GimpModuleDB *db,
  55.                                                         const char   *fullpath);
  56.  
  57. #ifdef DUMP_DB
  58. static void         gimp_module_db_dump_module         (gpointer      data,
  59.                                                         gpointer      user_data);
  60. #endif
  61.  
  62. static void         gimp_module_db_module_on_disk_func (gpointer      data,
  63.                                                         gpointer      user_data);
  64. static void         gimp_module_db_module_remove_func  (gpointer      data,
  65.                                                         gpointer      user_data);
  66. static void         gimp_module_db_module_modified     (GimpModule   *module,
  67.                                                         GimpModuleDB *db);
  68.  
  69.  
  70. static GObjectClass *parent_class = NULL;
  71.  
  72. static guint  db_signals[LAST_SIGNAL] = { 0 };
  73.  
  74.  
  75. GType
  76. gimp_module_db_get_type (void)
  77. {
  78.   static GType db_type = 0;
  79.  
  80.   if (! db_type)
  81.     {
  82.       static const GTypeInfo db_info =
  83.       {
  84.         sizeof (GimpModuleDBClass),
  85.         NULL,           /* base_init */
  86.         NULL,           /* base_finalize */
  87.         (GClassInitFunc) gimp_module_db_class_init,
  88.         NULL,           /* class_finalize */
  89.         NULL,           /* class_data */
  90.         sizeof (GimpModuleDB),
  91.         0,              /* n_preallocs */
  92.         (GInstanceInitFunc) gimp_module_db_init,
  93.       };
  94.  
  95.       db_type = g_type_register_static (G_TYPE_OBJECT,
  96.                                         "GimpModuleDB",
  97.                                         &db_info, 0);
  98.     }
  99.  
  100.   return db_type;
  101. }
  102.  
  103. static void
  104. gimp_module_db_class_init (GimpModuleDBClass *klass)
  105. {
  106.   GObjectClass *object_class = G_OBJECT_CLASS (klass);
  107.  
  108.   parent_class = g_type_class_peek_parent (klass);
  109.  
  110.   db_signals[ADD] =
  111.     g_signal_new ("add",
  112.                   G_TYPE_FROM_CLASS (klass),
  113.                   G_SIGNAL_RUN_FIRST,
  114.                   G_STRUCT_OFFSET (GimpModuleDBClass, add),
  115.                   NULL, NULL,
  116.                   g_cclosure_marshal_VOID__OBJECT,
  117.                   G_TYPE_NONE, 1,
  118.                   GIMP_TYPE_MODULE);
  119.  
  120.   db_signals[REMOVE] =
  121.     g_signal_new ("remove",
  122.                   G_TYPE_FROM_CLASS (klass),
  123.                   G_SIGNAL_RUN_FIRST,
  124.                   G_STRUCT_OFFSET (GimpModuleDBClass, remove),
  125.                   NULL, NULL,
  126.                   g_cclosure_marshal_VOID__OBJECT,
  127.                   G_TYPE_NONE, 1,
  128.                   GIMP_TYPE_MODULE);
  129.  
  130.   db_signals[MODULE_MODIFIED] =
  131.     g_signal_new ("module_modified",
  132.                   G_TYPE_FROM_CLASS (klass),
  133.                   G_SIGNAL_RUN_FIRST,
  134.                   G_STRUCT_OFFSET (GimpModuleDBClass, module_modified),
  135.                   NULL, NULL,
  136.                   g_cclosure_marshal_VOID__OBJECT,
  137.                   G_TYPE_NONE, 1,
  138.                   GIMP_TYPE_MODULE);
  139.  
  140.   object_class->finalize = gimp_module_db_finalize;
  141.  
  142.   klass->add             = NULL;
  143.   klass->remove          = NULL;
  144. }
  145.  
  146. static void
  147. gimp_module_db_init (GimpModuleDB *db)
  148. {
  149.   db->modules      = NULL;
  150.   db->load_inhibit = NULL;
  151.   db->verbose      = FALSE;
  152. }
  153.  
  154. static void
  155. gimp_module_db_finalize (GObject *object)
  156. {
  157.   GimpModuleDB *db = GIMP_MODULE_DB (object);
  158.  
  159.   if (db->modules)
  160.     {
  161.       g_list_free (db->modules);
  162.       db->modules = NULL;
  163.     }
  164.  
  165.   if (db->load_inhibit)
  166.     {
  167.       g_free (db->load_inhibit);
  168.       db->load_inhibit = NULL;
  169.     }
  170.  
  171.   G_OBJECT_CLASS (parent_class)->finalize (object);
  172. }
  173.  
  174. /**
  175.  * gimp_module_db_new:
  176.  * @verbose: Pass %TRUE to enable debugging output.
  177.  *
  178.  * Creates a new #GimpModuleDB instance. The @verbose parameter will be
  179.  * passed to the created #GimpModule instances using gimp_module_new().
  180.  *
  181.  * Return value: The new #GimpModuleDB instance.
  182.  **/
  183. GimpModuleDB *
  184. gimp_module_db_new (gboolean verbose)
  185. {
  186.   GimpModuleDB *db;
  187.  
  188.   db = g_object_new (GIMP_TYPE_MODULE_DB, NULL);
  189.  
  190.   db->verbose = verbose ? TRUE : FALSE;
  191.  
  192.   return db;
  193. }
  194.  
  195. static gboolean
  196. is_in_inhibit_list (const gchar *filename,
  197.                     const gchar *inhibit_list)
  198. {
  199.   gchar       *p;
  200.   gint         pathlen;
  201.   const gchar *start;
  202.   const gchar *end;
  203.  
  204.   if (! inhibit_list || ! strlen (inhibit_list))
  205.     return FALSE;
  206.  
  207.   p = strstr (inhibit_list, filename);
  208.   if (!p)
  209.     return FALSE;
  210.  
  211.   /* we have a substring, but check for colons either side */
  212.   start = p;
  213.   while (start != inhibit_list && *start != G_SEARCHPATH_SEPARATOR)
  214.     start--;
  215.  
  216.   if (*start == G_SEARCHPATH_SEPARATOR)
  217.     start++;
  218.  
  219.   end = strchr (p, G_SEARCHPATH_SEPARATOR);
  220.   if (! end)
  221.     end = inhibit_list + strlen (inhibit_list);
  222.  
  223.   pathlen = strlen (filename);
  224.  
  225.   if ((end - start) == pathlen)
  226.     return TRUE;
  227.  
  228.   return FALSE;
  229. }
  230.  
  231. /**
  232.  * gimp_module_db_set_load_inhibit:
  233.  * @db:           A #GimpModuleDB.
  234.  * @load_inhibit: A #G_SEARCHPATH_SEPARATOR delimited list of module
  235.  *                filenames to exclude from auto-loading.
  236.  *
  237.  * Sets the @load_inhibit flag for all #GimpModule's which are kept
  238.  * by @db (using gimp_module_set_load_inhibit()).
  239.  **/
  240. void
  241. gimp_module_db_set_load_inhibit (GimpModuleDB *db,
  242.                                  const gchar  *load_inhibit)
  243. {
  244.   GList *list;
  245.  
  246.   g_return_if_fail (GIMP_IS_MODULE_DB (db));
  247.  
  248.   if (db->load_inhibit)
  249.     g_free (db->load_inhibit);
  250.  
  251.   db->load_inhibit = g_strdup (load_inhibit);
  252.  
  253.   for (list = db->modules; list; list = g_list_next (list))
  254.     {
  255.       GimpModule *module = list->data;
  256.  
  257.       gimp_module_set_load_inhibit (module,
  258.                                     is_in_inhibit_list (module->filename,
  259.                                                         load_inhibit));
  260.     }
  261. }
  262.  
  263. /**
  264.  * gimp_module_db_get_load_inhibit:
  265.  * @db: A #GimpModuleDB.
  266.  *
  267.  * Return the #G_SEARCHPATH_SEPARATOR selimited list of module filenames
  268.  * which are excluded from auto-loading.
  269.  *
  270.  * Return value: the @db's @load_inhibit string.
  271.  **/
  272. const gchar *
  273. gimp_module_db_get_load_inhibit (GimpModuleDB *db)
  274. {
  275.   g_return_val_if_fail (GIMP_IS_MODULE_DB (db), NULL);
  276.  
  277.   return db->load_inhibit;
  278. }
  279.  
  280. /**
  281.  * gimp_module_db_load:
  282.  * @db:          A #GimpModuleDB.
  283.  * @module_path: A #G_SEARCHPATH_SEPARATOR delimited list of directories
  284.  *               to load modules from.
  285.  *
  286.  * Scans the directories contained in @module_path using
  287.  * gimp_datafiles_read_directories() and creates a #GimpModule
  288.  * instance for every loadable module contained in the directories.
  289.  **/
  290. void
  291. gimp_module_db_load (GimpModuleDB *db,
  292.                      const gchar  *module_path)
  293. {
  294.   g_return_if_fail (GIMP_IS_MODULE_DB (db));
  295.   g_return_if_fail (module_path != NULL);
  296.  
  297.   if (g_module_supported ())
  298.     gimp_datafiles_read_directories (module_path,
  299.                                      G_FILE_TEST_EXISTS,
  300.                                      gimp_module_db_module_initialize,
  301.                                      db);
  302.  
  303. #ifdef DUMP_DB
  304.   g_list_foreach (db->modules, gimp_module_db_dump_module, NULL);
  305. #endif
  306. }
  307.  
  308. /**
  309.  * gimp_module_db_refresh:
  310.  * @db:          A #GimpModuleDB.
  311.  * @module_path: A #G_SEARCHPATH_SEPARATOR delimited list of directories
  312.  *               to load modules from.
  313.  *
  314.  * Does the same as gimp_module_db_load(), plus removes all #GimpModule
  315.  * instances whose modules have been deleted from disk.
  316.  *
  317.  * Note that the #GimpModule's will just be removed from the internal
  318.  * list and not freed as this is not possible with #GTypeModule
  319.  * instances which actually implement types.
  320.  **/
  321. void
  322. gimp_module_db_refresh (GimpModuleDB *db,
  323.                         const gchar  *module_path)
  324. {
  325.   GList *kill_list = NULL;
  326.  
  327.   g_return_if_fail (GIMP_IS_MODULE_DB (db));
  328.   g_return_if_fail (module_path != NULL);
  329.  
  330.   /* remove modules we don't have on disk anymore */
  331.   g_list_foreach (db->modules,
  332.                   gimp_module_db_module_on_disk_func,
  333.                   &kill_list);
  334.   g_list_foreach (kill_list,
  335.                   gimp_module_db_module_remove_func,
  336.                   db);
  337.   g_list_free (kill_list);
  338.  
  339.   /* walk filesystem and add new things we find */
  340.   gimp_datafiles_read_directories (module_path,
  341.                                    G_FILE_TEST_EXISTS,
  342.                                    gimp_module_db_module_initialize,
  343.                                    db);
  344. }
  345.  
  346. /* name must be of the form lib*.so (Unix) or *.dll (Win32) */
  347. static gboolean
  348. valid_module_name (const gchar *filename)
  349. {
  350.   gchar *basename = g_path_get_basename (filename);
  351.  
  352. #if !defined(G_OS_WIN32) && !defined(G_WITH_CYGWIN)
  353.   if (strncmp (basename, "lib", 3))
  354.     goto no_module;
  355.  
  356.   if (! gimp_datafiles_check_extension (basename, ".so"))
  357.     goto no_module;
  358. #else
  359.   if (! gimp_datafiles_check_extension (basename, ".dll"))
  360.     goto no_module;
  361. #endif
  362.  
  363.   g_free (basename);
  364.  
  365.   return TRUE;
  366.  
  367.  no_module:
  368.   g_free (basename);
  369.  
  370.   return FALSE;
  371. }
  372.  
  373. static void
  374. gimp_module_db_module_initialize (const GimpDatafileData *file_data,
  375.                                   gpointer                user_data)
  376. {
  377.   GimpModuleDB *db = GIMP_MODULE_DB (user_data);
  378.   GimpModule   *module;
  379.   gboolean      load_inhibit;
  380.  
  381.   if (! valid_module_name (file_data->filename))
  382.     return;
  383.  
  384.   /* don't load if we already know about it */
  385.   if (gimp_module_db_module_find_by_path (db, file_data->filename))
  386.     return;
  387.  
  388.   load_inhibit = is_in_inhibit_list (file_data->filename,
  389.                                      db->load_inhibit);
  390.  
  391.   module = gimp_module_new (file_data->filename,
  392.                             load_inhibit,
  393.                             db->verbose);
  394.  
  395.   g_signal_connect (module, "modified",
  396.                     G_CALLBACK (gimp_module_db_module_modified),
  397.                     db);
  398.  
  399.   db->modules = g_list_append (db->modules, module);
  400.   g_signal_emit (db, db_signals[ADD], 0, module);
  401. }
  402.  
  403. static GimpModule *
  404. gimp_module_db_module_find_by_path (GimpModuleDB *db,
  405.                                     const char   *fullpath)
  406. {
  407.   GList *list;
  408.  
  409.   for (list = db->modules; list; list = g_list_next (list))
  410.     {
  411.       GimpModule *module = list->data;
  412.  
  413.       if (! strcmp (module->filename, fullpath))
  414.         return module;
  415.     }
  416.  
  417.   return NULL;
  418. }
  419.  
  420. #ifdef DUMP_DB
  421. static void
  422. gimp_module_db_dump_module (gpointer data,
  423.                             gpointer user_data)
  424. {
  425.   GimpModule *module = data;
  426.  
  427.   g_print ("\n%s: %s\n",
  428.            gimp_filename_to_utf8 (module->filename),
  429.            gimp_module_state_name (module->state));
  430.  
  431.   g_print ("  module: %p  lasterr: %s  query: %p register: %p\n",
  432.            module->module,
  433.            module->last_module_error ? module->last_module_error : "NONE",
  434.            module->query_module,
  435.            module->register_module);
  436.  
  437.   if (i->info)
  438.     {
  439.       g_print ("  purpose:   %s\n"
  440.                "  author:    %s\n"
  441.                "  version:   %s\n"
  442.                "  copyright: %s\n"
  443.                "  date:      %s\n",
  444.                module->info->purpose   ? module->info->purpose   : "NONE",
  445.                module->info->author    ? module->info->author    : "NONE",
  446.                module->info->version   ? module->info->version   : "NONE",
  447.                module->info->copyright ? module->info->copyright : "NONE",
  448.                module->info->date      ? module->info->date      : "NONE");
  449.     }
  450. }
  451. #endif
  452.  
  453. static void
  454. gimp_module_db_module_on_disk_func (gpointer data,
  455.                                     gpointer user_data)
  456. {
  457.   GimpModule  *module    = data;
  458.   GList      **kill_list = user_data;
  459.   gboolean     old_on_disk;
  460.  
  461.   old_on_disk = module->on_disk;
  462.  
  463.   module->on_disk = g_file_test (module->filename, G_FILE_TEST_IS_REGULAR);
  464.  
  465.   /* if it's not on the disk, and it isn't in memory, mark it to be
  466.    * removed later.
  467.    */
  468.   if (! module->on_disk && ! module->module)
  469.     {
  470.       *kill_list = g_list_append (*kill_list, module);
  471.       module = NULL;
  472.     }
  473.  
  474.   if (module && module->on_disk != old_on_disk)
  475.     gimp_module_modified (module);
  476. }
  477.  
  478. static void
  479. gimp_module_db_module_remove_func (gpointer data,
  480.                                    gpointer user_data)
  481. {
  482.   GimpModule   *module = data;
  483.   GimpModuleDB *db     = user_data;
  484.  
  485.   g_signal_handlers_disconnect_by_func (module,
  486.                                         gimp_module_db_module_modified,
  487.                                         db);
  488.  
  489.   g_list_remove (db->modules, module);
  490.   g_signal_emit (db, db_signals[REMOVE], 0, module);
  491. }
  492.  
  493. static void
  494. gimp_module_db_module_modified (GimpModule   *module,
  495.                                 GimpModuleDB *db)
  496. {
  497.   g_signal_emit (db, db_signals[MODULE_MODIFIED], 0, module);
  498. }
  499.