From b70424b20a5d923ecfcd204f0507e6b4a351ed75 Mon Sep 17 00:00:00 2001 From: Jehan Date: Sun, 1 Jul 2018 09:10:54 +0200 Subject: [PATCH] app: add base classes for the extension manager. Right now it only loads AppStream data, which is completely useless, yet is a base of a managed extension system. Having proper metadata is what will allow to actually know what is installed. This is only the first draft. Note that I am not adding the extension path into GimpCoreConfig on purpose, since the point is not to have people manage their extension directories manually anymore. The extensions will be loaded from the build-time system path or the config directory, and that's all. What will probably be stored in the config though will be the remote repositories URLs (allowing third-party extension repositories). --- app/Makefile.am | 1 + app/core/Makefile.am | 7 + app/core/core-types.h | 2 + app/core/gimp.c | 7 +- app/core/gimp.h | 1 + app/core/gimpextension-error.c | 39 +++++ app/core/gimpextension-error.h | 41 +++++ app/core/gimpextension.c | 258 ++++++++++++++++++++++++++++ app/core/gimpextension.h | 60 +++++++ app/core/gimpextensionmanager.c | 291 ++++++++++++++++++++++++++++++++ app/core/gimpextensionmanager.h | 58 +++++++ configure.ac | 9 + 12 files changed, 772 insertions(+), 2 deletions(-) create mode 100644 app/core/gimpextension-error.c create mode 100644 app/core/gimpextension-error.h create mode 100644 app/core/gimpextension.c create mode 100644 app/core/gimpextension.h create mode 100644 app/core/gimpextensionmanager.c create mode 100644 app/core/gimpextensionmanager.h diff --git a/app/Makefile.am b/app/Makefile.am index d271f8c558..57b493d601 100644 --- a/app/Makefile.am +++ b/app/Makefile.am @@ -158,6 +158,7 @@ gimpconsoleldadd = \ $(libgimpcolor) \ $(libgimpmodule) \ $(libgimpbase) \ + $(APPSTREAM_GLIB_LIBS) \ $(GDK_PIXBUF_LIBS) \ $(FREETYPE_LIBS) \ $(FONTCONFIG_LIBS) \ diff --git a/app/core/Makefile.am b/app/core/Makefile.am index bad1af34d9..7c69367e67 100644 --- a/app/core/Makefile.am +++ b/app/core/Makefile.am @@ -15,6 +15,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir) \ -I$(top_builddir)/app \ -I$(top_srcdir)/app \ + $(APPSTREAM_GLIB_CFLAGS) \ $(CAIRO_CFLAGS) \ $(GEGL_CFLAGS) \ $(GDK_PIXBUF_CFLAGS) \ @@ -214,6 +215,12 @@ libappcore_a_sources = \ gimpdynamicsoutput.h \ gimperror.c \ gimperror.h \ + gimpextension.c \ + gimpextension.h \ + gimpextension-error.c \ + gimpextension-error.h \ + gimpextensionmanager.c \ + gimpextensionmanager.h \ gimpfilloptions.c \ gimpfilloptions.h \ gimpfilter.c \ diff --git a/app/core/core-types.h b/app/core/core-types.h index a9709f53fa..2e16f0e3da 100644 --- a/app/core/core-types.h +++ b/app/core/core-types.h @@ -183,6 +183,8 @@ typedef struct _GimpAsyncSet GimpAsyncSet; typedef struct _GimpBuffer GimpBuffer; typedef struct _GimpDrawableFilter GimpDrawableFilter; typedef struct _GimpEnvironTable GimpEnvironTable; +typedef struct _GimpExtension GimpExtension; +typedef struct _GimpExtensionManager GimpExtensionManager; typedef struct _GimpGuide GimpGuide; typedef struct _GimpHistogram GimpHistogram; typedef struct _GimpIdTable GimpIdTable; diff --git a/app/core/gimp.c b/app/core/gimp.c index 5974edec29..cf059ac266 100644 --- a/app/core/gimp.c +++ b/app/core/gimp.c @@ -57,6 +57,7 @@ #include "gimpcontext.h" #include "gimpdynamics.h" #include "gimpdocumentlist.h" +#include "gimpextensionmanager.h" #include "gimpgradient.h" #include "gimpidtable.h" #include "gimpimage.h" @@ -278,8 +279,9 @@ gimp_constructed (GObject *object) gimp_paint_init (gimp); - gimp->plug_in_manager = gimp_plug_in_manager_new (gimp); - gimp->pdb = gimp_pdb_new (gimp); + gimp->extension_manager = gimp_extension_manager_new (gimp); + gimp->plug_in_manager = gimp_plug_in_manager_new (gimp); + gimp->pdb = gimp_pdb_new (gimp); xcf_init (gimp); @@ -514,6 +516,7 @@ gimp_real_initialize (Gimp *gimp, gimp_pdb_compat_procs_register (gimp->pdb, gimp->pdb_compat_mode); gimp_plug_in_manager_initialize (gimp->plug_in_manager, status_callback); + gimp_extension_manager_initialize (gimp->extension_manager); status_callback (NULL, "", 1.0); } diff --git a/app/core/gimp.h b/app/core/gimp.h index d18abe1e78..1f82dac7f1 100644 --- a/app/core/gimp.h +++ b/app/core/gimp.h @@ -75,6 +75,7 @@ struct _Gimp GimpModuleDB *module_db; gboolean write_modulerc; + GimpExtensionManager *extension_manager; GimpPlugInManager *plug_in_manager; GList *filter_history; diff --git a/app/core/gimpextension-error.c b/app/core/gimpextension-error.c new file mode 100644 index 0000000000..7615461313 --- /dev/null +++ b/app/core/gimpextension-error.c @@ -0,0 +1,39 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimpextension-error.c + * Copyright (C) 2018 Jehan + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "config.h" + +#include + +#include "gimpextension-error.h" + + +/** + * gimp_extension_error_quark: + * + * This function is never called directly. Use GIMP_EXTENSION_ERROR() instead. + * + * Return value: the #GQuark that defines the GimpExtension error domain. + **/ +GQuark +gimp_extension_error_quark (void) +{ + return g_quark_from_static_string ("gimp-extension-error-quark"); +} diff --git a/app/core/gimpextension-error.h b/app/core/gimpextension-error.h new file mode 100644 index 0000000000..c81fd6fb0f --- /dev/null +++ b/app/core/gimpextension-error.h @@ -0,0 +1,41 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimpextension-error.h + * Copyright (C) 2018 Jehan + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __GIMP_EXTENSION_ERROR_H__ +#define __GIMP_EXTENSION_ERROR_H__ + + +typedef enum +{ + /* Generic error condition. */ + GIMP_EXTENSION_FAILED, + GIMP_EXTENSION_BAD_APPDATA, + GIMP_EXTENSION_BAD_ID, + GIMP_EXTENSION_NO_VERSION, +} GimpExtensionErrorCode; + + +#define GIMP_EXTENSION_ERROR (gimp_extension_error_quark ()) + +GQuark gimp_extension_error_quark (void) G_GNUC_CONST; + + +#endif /* __GIMP_EXTENSION_ERROR_H__ */ + diff --git a/app/core/gimpextension.c b/app/core/gimpextension.c new file mode 100644 index 0000000000..16f43aaf52 --- /dev/null +++ b/app/core/gimpextension.c @@ -0,0 +1,258 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimpextension.c + * Copyright (C) 2018 Jehan + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "config.h" + +#include +#include + +#include "core-types.h" + +#include "gimpextension.h" +#include "gimpextension-error.h" + +#include "gimp-intl.h" + + +enum +{ + PROP_0, + PROP_PATH, + PROP_WRITABLE +}; + +struct _GimpExtensionPrivate +{ + gchar *path; + + AsApp *app; + gboolean writable; +}; + + +static void gimp_extension_finalize (GObject *object); +static void gimp_extension_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void gimp_extension_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); + + +G_DEFINE_TYPE (GimpExtension, gimp_extension, GIMP_TYPE_OBJECT) + +#define parent_class gimp_extension_parent_class + + +static void +gimp_extension_class_init (GimpExtensionClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gimp_extension_finalize; + object_class->set_property = gimp_extension_set_property; + object_class->get_property = gimp_extension_get_property; + + g_object_class_install_property (object_class, PROP_PATH, + g_param_spec_string ("path", + NULL, NULL, NULL, + GIMP_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, PROP_WRITABLE, + g_param_spec_boolean ("writable", + NULL, NULL, FALSE, + GIMP_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + + g_type_class_add_private (klass, sizeof (GimpExtensionPrivate)); +} + +static void +gimp_extension_init (GimpExtension *extension) +{ + extension->p = G_TYPE_INSTANCE_GET_PRIVATE (extension, + GIMP_TYPE_EXTENSION, + GimpExtensionPrivate); +} + +static void +gimp_extension_finalize (GObject *object) +{ + GimpExtension *extension = GIMP_EXTENSION (object); + + g_free (extension->p->path); + if (extension->p->app) + g_object_unref (extension->p->app); +} + +static void +gimp_extension_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + GimpExtension *extension = GIMP_EXTENSION (object); + + switch (property_id) + { + case PROP_PATH: + g_free (extension->p->path); + extension->p->path = g_value_dup_string (value); + gimp_object_take_name (GIMP_OBJECT (object), + g_path_get_basename (extension->p->path)); + break; + case PROP_WRITABLE: + extension->p->writable = g_value_get_boolean (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gimp_extension_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + GimpExtension *extension = GIMP_EXTENSION (object); + + switch (property_id) + { + case PROP_PATH: + g_value_set_string (value, extension->p->path); + break; + case PROP_WRITABLE: + g_value_set_boolean (value, extension->p->writable); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +/* public functions */ + +GimpExtension * +gimp_extension_new (const gchar *dir, + gboolean writable) +{ + g_return_val_if_fail (dir && g_file_test (dir, G_FILE_TEST_IS_DIR), NULL); + + return g_object_new (GIMP_TYPE_EXTENSION, + "path", dir, + "writable", writable, + NULL); +} + +gboolean +gimp_extension_load (GimpExtension *extension, + GError **error) +{ + AsApp *app; + GPtrArray *extends; + AsRelease *release; + gchar *appdata_name; + gchar *path; + gboolean success = FALSE; + + g_clear_object (&extension->p->app); + + /* Search in subdirectory if a file with the same name as + * directory and ending with ".metainfo.xml" exists. + */ + appdata_name = g_strdup_printf ("%s.metainfo.xml", + gimp_object_get_name (GIMP_OBJECT (extension))); + path = g_build_filename (extension->p->path, appdata_name, NULL); + + app = as_app_new (); + success = as_app_parse_file (app, path, + AS_APP_PARSE_FLAG_USE_HEURISTICS, + error); + g_free (path); + if (success && as_app_get_kind (app) != AS_APP_KIND_ADDON) + { + /* Properly setting the type will allow extensions to be + * distributed appropriately through other means. + */ + if (error && *error == NULL) + *error = g_error_new (GIMP_EXTENSION_ERROR, + GIMP_EXTENSION_BAD_APPDATA, + _("Extension AppData must be of type \"addon\", found \"%s\" instead."), + as_app_kind_to_string (as_app_get_kind (app))); + success = FALSE; + } + + extends = as_app_get_extends (app); + if (success && + ! g_ptr_array_find_with_equal_func (extends, "org.gimp.GIMP", + g_str_equal, NULL)) + { + /* Properly setting the will allow extensions to be + * distributed appropriately through other means. + */ + if (error && *error == NULL) + *error = g_error_new (GIMP_EXTENSION_ERROR, + GIMP_EXTENSION_BAD_APPDATA, + _("Extension AppData must extend \"org.gimp.GIMP\".")); + success = FALSE; + } + + if (success && + g_strcmp0 (as_app_get_id (app), + gimp_object_get_name (extension)) != 0) + { + /* Extension IDs will be unique and we want therefore the + * installation folder to sync in order to avoid path clashes. + */ + if (error && *error == NULL) + *error = g_error_new (GIMP_EXTENSION_ERROR, + GIMP_EXTENSION_FAILED, + _("Extension AppData id (\"%s\") and directory (\"%s\") must be the same."), + as_app_get_id (app), gimp_object_get_name (extension)); + success = FALSE; + } + + release = as_app_get_release_default (app); + if (success && (! release || ! as_release_get_version (release))) + { + /* We don't need the detail, just to know that the extension has a + * release tag with a version. This is very important since it is + * the only way we can manage updates. + */ + if (error && *error == NULL) + *error = g_error_new (GIMP_EXTENSION_ERROR, + GIMP_EXTENSION_NO_VERSION, + _("Extension AppData must advertize a version in a tag.")); + success = FALSE; + } + + if (success) + extension->p->app = app; + else + g_object_unref (app); + + return success; +} diff --git a/app/core/gimpextension.h b/app/core/gimpextension.h new file mode 100644 index 0000000000..2b0123c9af --- /dev/null +++ b/app/core/gimpextension.h @@ -0,0 +1,60 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis + * + * gimpextension.h + * Copyright (C) 2018 Jehan + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __GIMP_EXTENSION_H__ +#define __GIMP_EXTENSION_H__ + + +#include "core/gimpobject.h" + + +#define GIMP_TYPE_EXTENSION (gimp_extension_get_type ()) +#define GIMP_EXTENSION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_EXTENSION, GimpExtension)) +#define GIMP_EXTENSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_EXTENSION, GimpExtensionClass)) +#define GIMP_IS_EXTENSION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_EXTENSION)) +#define GIMP_IS_EXTENSION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_EXTENSION)) +#define GIMP_EXTENSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_EXTENSION, GimpExtensionClass)) + +typedef struct _GimpExtensionPrivate GimpExtensionPrivate; +typedef struct _GimpExtensionClass GimpExtensionClass; + +struct _GimpExtension +{ + GimpObject parent_instance; + + GimpExtensionPrivate *p; +}; + +struct _GimpExtensionClass +{ + GimpObjectClass parent_class; +}; + + +GType gimp_extension_get_type (void) G_GNUC_CONST; + +GimpExtension * gimp_extension_new (const gchar *dir, + gboolean writable); + +gboolean gimp_extension_load (GimpExtension *extension, + GError **error); + +#endif /* __GIMP_EXTENSION_H__ */ + diff --git a/app/core/gimpextensionmanager.c b/app/core/gimpextensionmanager.c new file mode 100644 index 0000000000..9abff635a5 --- /dev/null +++ b/app/core/gimpextensionmanager.c @@ -0,0 +1,291 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995-2002 Spencer Kimball, Peter Mattis, and others + * + * gimpextensionmanager.c + * Copyright (C) 2018 Jehan + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "config.h" + +#include + +#include +#include + +#include "libgimpbase/gimpbase.h" +#include "libgimpconfig/gimpconfig.h" + +#include "core-types.h" + +#include "config/gimpcoreconfig.h" + +#include "gimp.h" +#include "gimpextension.h" +#include "gimpobject.h" +#include "gimpmarshal.h" + +#include "gimpextensionmanager.h" + +#include "gimp-intl.h" + + +enum +{ + PROP_0, + PROP_GIMP +}; + +struct _GimpExtensionManagerPrivate +{ + Gimp *gimp; + + /* Installed system (read-only) extensions. */ + GList *sys_extensions; + /* Self-installed (read-write) extensions. */ + GList *extensions; + + /* Running extensions */ + GHashTable *active_extensions; +}; + +static void gimp_extension_manager_finalize (GObject *object); +static void gimp_extension_manager_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void gimp_extension_manager_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); + +static void gimp_extension_manager_search_directory (GimpExtensionManager *manager, + GFile *directory, + gboolean system_dir); + +G_DEFINE_TYPE (GimpExtensionManager, gimp_extension_manager, GIMP_TYPE_OBJECT) + +#define parent_class gimp_extension_manager_parent_class + +static void +gimp_extension_manager_class_init (GimpExtensionManagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gimp_extension_manager_finalize; + object_class->set_property = gimp_extension_manager_set_property; + object_class->get_property = gimp_extension_manager_get_property; + + g_object_class_install_property (object_class, PROP_GIMP, + g_param_spec_object ("gimp", NULL, NULL, + GIMP_TYPE_GIMP, + GIMP_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + + g_type_class_add_private (klass, sizeof (GimpExtensionManagerPrivate)); +} + +static void +gimp_extension_manager_init (GimpExtensionManager *manager) +{ + manager->p = G_TYPE_INSTANCE_GET_PRIVATE (manager, + GIMP_TYPE_EXTENSION_MANAGER, + GimpExtensionManagerPrivate); +} + +static void +gimp_extension_manager_finalize (GObject *object) +{ + GimpExtensionManager *manager = GIMP_EXTENSION_MANAGER (object); + + g_list_free_full (manager->p->sys_extensions, g_object_unref); + g_list_free_full (manager->p->extensions, g_object_unref); + g_hash_table_unref (manager->p->active_extensions); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +gimp_extension_manager_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + GimpExtensionManager *manager = GIMP_EXTENSION_MANAGER (object); + + switch (property_id) + { + case PROP_GIMP: + manager->p->gimp = g_value_get_object (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gimp_extension_manager_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + GimpExtensionManager *manager = GIMP_EXTENSION_MANAGER (object); + + switch (property_id) + { + case PROP_GIMP: + g_value_set_object (value, manager->p->gimp); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +GimpExtensionManager * +gimp_extension_manager_new (Gimp *gimp) +{ + GimpExtensionManager *manager; + + manager = g_object_new (GIMP_TYPE_EXTENSION_MANAGER, + "gimp", gimp, + NULL); + + return manager; +} + +void +gimp_extension_manager_initialize (GimpExtensionManager *manager) +{ + gchar *path_str; + GList *path; + GList *list; + + /* List user-installed extensions. */ + path_str = gimp_config_build_writable_path ("extensions"); + path = gimp_config_path_expand_to_files (path_str, NULL); + for (list = path; list; list = g_list_next (list)) + gimp_extension_manager_search_directory (manager, list->data, FALSE); + g_list_free_full (path, (GDestroyNotify) g_object_unref); + + /* List system extensions. */ + path_str = gimp_config_build_system_path ("extensions"); + path = gimp_config_path_expand_to_files (path_str, NULL); + for (list = path; list; list = g_list_next (list)) + gimp_extension_manager_search_directory (manager, list->data, TRUE); + g_list_free_full (path, (GDestroyNotify) g_object_unref); + + /* Actually load the extensions. */ + if (manager->p->active_extensions) + g_hash_table_unref (manager->p->active_extensions); + manager->p->active_extensions = g_hash_table_new (g_str_hash, + g_str_equal); + for (list = manager->p->extensions; list; list = g_list_next (list)) + { + if (! g_hash_table_contains (manager->p->active_extensions, + gimp_object_get_name (list->data))) + { + g_hash_table_insert (manager->p->active_extensions, + (gpointer) gimp_object_get_name (list->data), + list->data); + /* TODO: do whatever is needed to make extension "active". */ + + } + } + for (list = manager->p->sys_extensions; list; list = g_list_next (list)) + { + if (! g_hash_table_contains (manager->p->active_extensions, + gimp_object_get_name (list->data))) + { + g_hash_table_insert (manager->p->active_extensions, + (gpointer) gimp_object_get_name (list->data), + list->data); + /* TODO: do whatever is needed to make extension "active". */ + } + } +} + +static void +gimp_extension_manager_search_directory (GimpExtensionManager *manager, + GFile *directory, + gboolean system_dir) +{ + GFileEnumerator *enumerator; + + enumerator = g_file_enumerate_children (directory, + G_FILE_ATTRIBUTE_STANDARD_NAME "," + G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN "," + G_FILE_ATTRIBUTE_TIME_MODIFIED, + G_FILE_QUERY_INFO_NONE, + NULL, NULL); + if (enumerator) + { + GFileInfo *info; + + while ((info = g_file_enumerator_next_file (enumerator, NULL, NULL))) + { + GFile *subdir; + + if (g_file_info_get_is_hidden (info)) + { + g_object_unref (info); + continue; + } + + subdir = g_file_enumerator_get_child (enumerator, info); + + if (g_file_query_file_type (subdir, + G_FILE_QUERY_INFO_NONE, + NULL) == G_FILE_TYPE_DIRECTORY) + { + GimpExtension *extension; + GError *error = NULL; + + extension = gimp_extension_new (g_file_peek_path (subdir), + ! system_dir); + + if (gimp_extension_load (extension, &error)) + { + if (system_dir) + manager->p->sys_extensions = g_list_prepend (manager->p->sys_extensions, + extension); + else + manager->p->extensions = g_list_prepend (manager->p->extensions, + extension); + } + else + { + g_object_unref (extension); + if (error) + g_printerr (_("Skipping extension '%s': %s\n"), + g_file_peek_path (subdir), error->message); + } + } + else + { + g_printerr (_("Skipping unknown file '%s' in extension directory.\n"), + g_file_peek_path (subdir)); + } + + g_object_unref (subdir); + g_object_unref (info); + } + + g_object_unref (enumerator); + } +} diff --git a/app/core/gimpextensionmanager.h b/app/core/gimpextensionmanager.h new file mode 100644 index 0000000000..625b0bfc25 --- /dev/null +++ b/app/core/gimpextensionmanager.h @@ -0,0 +1,58 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis + * + * gimpextensionmanager.h + * Copyright (C) 2018 Jehan + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __GIMP_EXTENSION_MANAGER_H__ +#define __GIMP_EXTENSION_MANAGER_H__ + + +#include "core/gimpobject.h" + + +#define GIMP_TYPE_EXTENSION_MANAGER (gimp_extension_manager_get_type ()) +#define GIMP_EXTENSION_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_EXTENSION_MANAGER, GimpExtensionManager)) +#define GIMP_EXTENSION_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_EXTENSION_MANAGER, GimpExtensionManagerClass)) +#define GIMP_IS_EXTENSION_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_EXTENSION_MANAGER)) +#define GIMP_IS_EXTENSION_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_EXTENSION_MANAGER)) +#define GIMP_EXTENSION_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_EXTENSION_MANAGER, GimpExtensionManagerClass)) + + +typedef struct _GimpExtensionManagerClass GimpExtensionManagerClass; +typedef struct _GimpExtensionManagerPrivate GimpExtensionManagerPrivate; + +struct _GimpExtensionManager +{ + GimpObject parent_instance; + + GimpExtensionManagerPrivate *p; +}; + +struct _GimpExtensionManagerClass +{ + GimpObjectClass parent_class; +}; + + +GType gimp_extension_manager_get_type (void) G_GNUC_CONST; + +GimpExtensionManager * gimp_extension_manager_new (Gimp *gimp); + +void gimp_extension_manager_initialize (GimpExtensionManager *manager); + +#endif /* __GIMP_EXTENSION_MANAGER_H__ */ diff --git a/configure.ac b/configure.ac index d6783d4998..36807e091c 100644 --- a/configure.ac +++ b/configure.ac @@ -73,6 +73,7 @@ m4_define([libmypaint_required_version], [1.3.0]) m4_define([lcms_required_version], [2.8]) m4_define([libpng_required_version], [1.6.25]) m4_define([liblzma_required_version], [5.0.0]) +m4_define([appstream_glib_required_version], [0.7.7]) m4_define([openexr_required_version], [1.6.1]) m4_define([openjpeg_required_version], [2.1.0]) m4_define([gtk_mac_integration_required_version], [2.0.0]) @@ -1504,6 +1505,14 @@ PKG_CHECK_MODULES(LZMA, liblzma >= liblzma_required_version,, [add_deps_error([liblzma >= liblzma_required_version])]) +########################## +# Check for appstream-glib +########################## + +PKG_CHECK_MODULES(APPSTREAM_GLIB, appstream-glib >= appstream_glib_required_version,, + [add_deps_error([appstream-glib >= appstream_glib_required_version])]) + + ############################### # Check for Ghostscript library ###############################