diff --git a/app/core/gimpparamspecs.c b/app/core/gimpparamspecs.c
index 79dc7463e1..ef576394e0 100644
--- a/app/core/gimpparamspecs.c
+++ b/app/core/gimpparamspecs.c
@@ -36,6 +36,7 @@
#include "gimpimage.h"
#include "gimplayer.h"
#include "gimplayermask.h"
+#include "gimplinklayer.h"
#include "gimppalette.h"
#include "gimpparamspecs.h"
#include "gimppattern.h"
diff --git a/app/pdb/internal-procs.c b/app/pdb/internal-procs.c
index 9b1805c86a..091d8900f6 100644
--- a/app/pdb/internal-procs.c
+++ b/app/pdb/internal-procs.c
@@ -30,26 +30,26 @@
#include "internal-procs.h"
-/* 752 procedures registered total */
+/* 758 procedures registered total */
void
internal_procs_init (GimpPDB *pdb)
{
g_return_if_fail (GIMP_IS_PDB (pdb));
- register_brush_procs (pdb);
register_brush_select_procs (pdb);
+ register_brush_procs (pdb);
register_brushes_procs (pdb);
register_buffer_procs (pdb);
register_channel_procs (pdb);
register_context_procs (pdb);
register_debug_procs (pdb);
register_display_procs (pdb);
- register_drawable_procs (pdb);
register_drawable_color_procs (pdb);
register_drawable_edit_procs (pdb);
register_drawable_filter_procs (pdb);
register_drawable_select_procs (pdb);
+ register_drawable_procs (pdb);
register_dynamics_procs (pdb);
register_edit_procs (pdb);
register_file_procs (pdb);
@@ -59,12 +59,11 @@ internal_procs_init (GimpPDB *pdb)
register_fonts_procs (pdb);
register_gimp_procs (pdb);
register_gimprc_procs (pdb);
- register_gradient_procs (pdb);
register_gradient_select_procs (pdb);
+ register_gradient_procs (pdb);
register_gradients_procs (pdb);
register_group_layer_procs (pdb);
register_help_procs (pdb);
- register_image_procs (pdb);
register_image_autocrop_procs (pdb);
register_image_color_profile_procs (pdb);
register_image_convert_procs (pdb);
@@ -74,17 +73,19 @@ internal_procs_init (GimpPDB *pdb)
register_image_select_procs (pdb);
register_image_transform_procs (pdb);
register_image_undo_procs (pdb);
- register_item_procs (pdb);
+ register_image_procs (pdb);
register_item_transform_procs (pdb);
+ register_item_procs (pdb);
register_layer_procs (pdb);
+ register_link_layer_procs (pdb);
register_message_procs (pdb);
register_paint_tools_procs (pdb);
- register_palette_procs (pdb);
register_palette_select_procs (pdb);
+ register_palette_procs (pdb);
register_palettes_procs (pdb);
register_path_procs (pdb);
- register_pattern_procs (pdb);
register_pattern_select_procs (pdb);
+ register_pattern_procs (pdb);
register_patterns_procs (pdb);
register_pdb_procs (pdb);
register_plug_in_procs (pdb);
diff --git a/app/pdb/internal-procs.h b/app/pdb/internal-procs.h
index 2bddfd3bd7..b2c82651d0 100644
--- a/app/pdb/internal-procs.h
+++ b/app/pdb/internal-procs.h
@@ -24,19 +24,19 @@ void internal_procs_init (GimpPDB *pdb);
/* Forward declarations for registering PDB procs */
-void register_brush_procs (GimpPDB *pdb);
void register_brush_select_procs (GimpPDB *pdb);
+void register_brush_procs (GimpPDB *pdb);
void register_brushes_procs (GimpPDB *pdb);
void register_buffer_procs (GimpPDB *pdb);
void register_channel_procs (GimpPDB *pdb);
void register_context_procs (GimpPDB *pdb);
void register_debug_procs (GimpPDB *pdb);
void register_display_procs (GimpPDB *pdb);
-void register_drawable_procs (GimpPDB *pdb);
void register_drawable_color_procs (GimpPDB *pdb);
void register_drawable_edit_procs (GimpPDB *pdb);
void register_drawable_filter_procs (GimpPDB *pdb);
void register_drawable_select_procs (GimpPDB *pdb);
+void register_drawable_procs (GimpPDB *pdb);
void register_dynamics_procs (GimpPDB *pdb);
void register_edit_procs (GimpPDB *pdb);
void register_file_procs (GimpPDB *pdb);
@@ -46,12 +46,11 @@ void register_font_select_procs (GimpPDB *pdb);
void register_fonts_procs (GimpPDB *pdb);
void register_gimp_procs (GimpPDB *pdb);
void register_gimprc_procs (GimpPDB *pdb);
-void register_gradient_procs (GimpPDB *pdb);
void register_gradient_select_procs (GimpPDB *pdb);
+void register_gradient_procs (GimpPDB *pdb);
void register_gradients_procs (GimpPDB *pdb);
void register_group_layer_procs (GimpPDB *pdb);
void register_help_procs (GimpPDB *pdb);
-void register_image_procs (GimpPDB *pdb);
void register_image_autocrop_procs (GimpPDB *pdb);
void register_image_color_profile_procs (GimpPDB *pdb);
void register_image_convert_procs (GimpPDB *pdb);
@@ -61,17 +60,19 @@ void register_image_sample_points_procs (GimpPDB *pdb);
void register_image_select_procs (GimpPDB *pdb);
void register_image_transform_procs (GimpPDB *pdb);
void register_image_undo_procs (GimpPDB *pdb);
-void register_item_procs (GimpPDB *pdb);
+void register_image_procs (GimpPDB *pdb);
void register_item_transform_procs (GimpPDB *pdb);
+void register_item_procs (GimpPDB *pdb);
void register_layer_procs (GimpPDB *pdb);
+void register_link_layer_procs (GimpPDB *pdb);
void register_message_procs (GimpPDB *pdb);
void register_paint_tools_procs (GimpPDB *pdb);
-void register_palette_procs (GimpPDB *pdb);
void register_palette_select_procs (GimpPDB *pdb);
+void register_palette_procs (GimpPDB *pdb);
void register_palettes_procs (GimpPDB *pdb);
void register_path_procs (GimpPDB *pdb);
-void register_pattern_procs (GimpPDB *pdb);
void register_pattern_select_procs (GimpPDB *pdb);
+void register_pattern_procs (GimpPDB *pdb);
void register_patterns_procs (GimpPDB *pdb);
void register_pdb_procs (GimpPDB *pdb);
void register_plug_in_procs (GimpPDB *pdb);
diff --git a/app/pdb/item-cmds.c b/app/pdb/item-cmds.c
index 3c4ee01ac1..1ca3505db6 100644
--- a/app/pdb/item-cmds.c
+++ b/app/pdb/item-cmds.c
@@ -35,6 +35,7 @@
#include "core/gimpimage.h"
#include "core/gimpitem.h"
#include "core/gimplayermask.h"
+#include "core/gimplinklayer.h"
#include "core/gimplist.h"
#include "core/gimpparamspecs.h"
#include "core/gimpselection.h"
@@ -244,6 +245,39 @@ item_id_is_group_layer_invoker (GimpProcedure *procedure,
return return_vals;
}
+static GimpValueArray *
+item_id_is_link_layer_invoker (GimpProcedure *procedure,
+ Gimp *gimp,
+ GimpContext *context,
+ GimpProgress *progress,
+ const GimpValueArray *args,
+ GError **error)
+{
+ gboolean success = TRUE;
+ GimpValueArray *return_vals;
+ gint item_id;
+ gboolean text_layer = FALSE;
+
+ item_id = g_value_get_int (gimp_value_array_index (args, 0));
+
+ if (success)
+ {
+ GimpItem *item = gimp_item_get_by_id (gimp, item_id);
+
+ text_layer = (GIMP_IS_LAYER (item) &&
+ ! gimp_item_is_removed (item) &&
+ gimp_item_is_link_layer (item));
+ }
+
+ return_vals = gimp_procedure_get_return_values (procedure, success,
+ error ? *error : NULL);
+
+ if (success)
+ g_value_set_boolean (gimp_value_array_index (return_vals, 1), text_layer);
+
+ return return_vals;
+}
+
static GimpValueArray *
item_id_is_channel_invoker (GimpProcedure *procedure,
Gimp *gimp,
@@ -1287,6 +1321,37 @@ register_item_procs (GimpPDB *pdb)
gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure);
+ /*
+ * gimp-item-id-is-link-layer
+ */
+ procedure = gimp_procedure_new (item_id_is_link_layer_invoker, FALSE);
+ gimp_object_set_static_name (GIMP_OBJECT (procedure),
+ "gimp-item-id-is-link-layer");
+ gimp_procedure_set_static_help (procedure,
+ "Returns whether the item ID is a link layer.",
+ "This procedure returns %TRUE if the specified item ID is a link layer.\n"
+ "\n"
+ "*Note*: in most use cases, you should not use this function. See [func@Gimp.Item.id_is_layer] for a discussion on alternatives.",
+ NULL);
+ gimp_procedure_set_static_attribution (procedure,
+ "Jehan",
+ "Jehan",
+ "2025");
+ gimp_procedure_add_argument (procedure,
+ g_param_spec_int ("item-id",
+ "item id",
+ "The item ID",
+ G_MININT32, G_MAXINT32, 0,
+ GIMP_PARAM_READWRITE));
+ gimp_procedure_add_return_value (procedure,
+ g_param_spec_boolean ("text-layer",
+ "text layer",
+ "TRUE if the item is a text layer, FALSE otherwise.",
+ FALSE,
+ GIMP_PARAM_READWRITE));
+ gimp_pdb_register_procedure (pdb, procedure);
+ g_object_unref (procedure);
+
/*
* gimp-item-id-is-channel
*/
diff --git a/app/pdb/link-layer-cmds.c b/app/pdb/link-layer-cmds.c
new file mode 100644
index 0000000000..8c1a65b4b4
--- /dev/null
+++ b/app/pdb/link-layer-cmds.c
@@ -0,0 +1,364 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995-2003 Spencer Kimball and Peter Mattis
+ *
+ * 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 .
+ */
+
+/* NOTE: This file is auto-generated by pdbgen.pl. */
+
+#include "config.h"
+
+#include "stamp-pdbgen.h"
+
+#include
+
+#include
+
+#include "libgimpbase/gimpbase.h"
+
+#include "pdb-types.h"
+
+#include "core/gimpimage.h"
+#include "core/gimplink.h"
+#include "core/gimplinklayer.h"
+#include "core/gimpparamspecs.h"
+
+#include "gimppdb.h"
+#include "gimppdberror.h"
+#include "gimpprocedure.h"
+#include "internal-procs.h"
+
+#include "gimp-intl.h"
+
+
+static GimpValueArray *
+link_layer_new_invoker (GimpProcedure *procedure,
+ Gimp *gimp,
+ GimpContext *context,
+ GimpProgress *progress,
+ const GimpValueArray *args,
+ GError **error)
+{
+ gboolean success = TRUE;
+ GimpValueArray *return_vals;
+ GimpImage *image;
+ GFile *file;
+ GimpLinkLayer *layer = NULL;
+
+ image = g_value_get_object (gimp_value_array_index (args, 0));
+ file = g_value_get_object (gimp_value_array_index (args, 1));
+
+ if (success)
+ {
+ if (file == NULL)
+ {
+ g_set_error (error, GIMP_PDB_ERROR, GIMP_PDB_ERROR_INVALID_ARGUMENT,
+ _("Failed to create link layer"));
+
+ success = FALSE;
+ }
+
+ if (success)
+ {
+ GimpLink *link;
+
+ link = gimp_link_new (gimp, file, 0, 0, TRUE, NULL, error);
+
+ if (link == NULL)
+ {
+ success = FALSE;
+ }
+ else
+ {
+ layer = GIMP_LINK_LAYER (gimp_link_layer_new (image, link));
+
+ if (! layer)
+ {
+ g_set_error (error, GIMP_PDB_ERROR, GIMP_PDB_ERROR_INVALID_ARGUMENT,
+ _("Failed to create link layer"));
+
+ success = FALSE;
+ }
+ }
+
+ g_clear_object (&link);
+ }
+ }
+
+ return_vals = gimp_procedure_get_return_values (procedure, success,
+ error ? *error : NULL);
+
+ if (success)
+ g_value_set_object (gimp_value_array_index (return_vals, 1), layer);
+
+ return return_vals;
+}
+
+static GimpValueArray *
+link_layer_discard_invoker (GimpProcedure *procedure,
+ Gimp *gimp,
+ GimpContext *context,
+ GimpProgress *progress,
+ const GimpValueArray *args,
+ GError **error)
+{
+ gboolean success = TRUE;
+ GimpLinkLayer *layer;
+
+ layer = g_value_get_object (gimp_value_array_index (args, 0));
+
+ if (success)
+ {
+ gimp_link_layer_discard (layer);
+ }
+
+ return gimp_procedure_get_return_values (procedure, success,
+ error ? *error : NULL);
+}
+
+static GimpValueArray *
+link_layer_monitor_invoker (GimpProcedure *procedure,
+ Gimp *gimp,
+ GimpContext *context,
+ GimpProgress *progress,
+ const GimpValueArray *args,
+ GError **error)
+{
+ gboolean success = TRUE;
+ GimpLinkLayer *layer;
+
+ layer = g_value_get_object (gimp_value_array_index (args, 0));
+
+ if (success)
+ {
+ gimp_link_layer_monitor (layer);
+ }
+
+ return gimp_procedure_get_return_values (procedure, success,
+ error ? *error : NULL);
+}
+
+static GimpValueArray *
+link_layer_get_file_invoker (GimpProcedure *procedure,
+ Gimp *gimp,
+ GimpContext *context,
+ GimpProgress *progress,
+ const GimpValueArray *args,
+ GError **error)
+{
+ gboolean success = TRUE;
+ GimpValueArray *return_vals;
+ GimpLinkLayer *layer;
+ GFile *file = NULL;
+
+ layer = g_value_get_object (gimp_value_array_index (args, 0));
+
+ if (success)
+ {
+ file = gimp_link_get_file (gimp_link_layer_get_link (layer), NULL, NULL);
+ }
+
+ return_vals = gimp_procedure_get_return_values (procedure, success,
+ error ? *error : NULL);
+
+ if (success)
+ g_value_set_object (gimp_value_array_index (return_vals, 1), file);
+
+ return return_vals;
+}
+
+static GimpValueArray *
+link_layer_set_file_invoker (GimpProcedure *procedure,
+ Gimp *gimp,
+ GimpContext *context,
+ GimpProgress *progress,
+ const GimpValueArray *args,
+ GError **error)
+{
+ gboolean success = TRUE;
+ GimpLinkLayer *layer;
+ GFile *file;
+
+ layer = g_value_get_object (gimp_value_array_index (args, 0));
+ file = g_value_get_object (gimp_value_array_index (args, 1));
+
+ if (success)
+ {
+ GimpLink *link = gimp_link_new (gimp, file, 0, 0, TRUE, NULL, error);
+
+ if (link)
+ {
+ gimp_link_layer_set_link (layer, link, TRUE);
+ }
+ else
+ {
+ success = FALSE;
+ }
+
+ g_clear_object (&link);
+ }
+
+ return gimp_procedure_get_return_values (procedure, success,
+ error ? *error : NULL);
+}
+
+void
+register_link_layer_procs (GimpPDB *pdb)
+{
+ GimpProcedure *procedure;
+
+ /*
+ * gimp-link-layer-new
+ */
+ procedure = gimp_procedure_new (link_layer_new_invoker, FALSE);
+ gimp_object_set_static_name (GIMP_OBJECT (procedure),
+ "gimp-link-layer-new");
+ gimp_procedure_set_static_help (procedure,
+ "Creates a new link layer.",
+ "This procedure creates a link layer monitoring the specified @file.\n"
+ "\n"
+ "The new layer still needs to be added to the image as this is not automatic. Add the new layer with the [method@Image.insert_layer] method.\n"
+ "\n"
+ "The arguments are kept as simple as necessary for the basic case. All link attributes, however, can be modified with the appropriate `gimp_link_layer_set_*()` procedures.",
+ NULL);
+ gimp_procedure_set_static_attribution (procedure,
+ "Jehan",
+ "Jehan",
+ "2025");
+ gimp_procedure_add_argument (procedure,
+ gimp_param_spec_image ("image",
+ "image",
+ "The image",
+ FALSE,
+ GIMP_PARAM_READWRITE));
+ gimp_procedure_add_argument (procedure,
+ g_param_spec_object ("file",
+ "file",
+ "The file this link layer will monitor",
+ G_TYPE_FILE,
+ GIMP_PARAM_READWRITE));
+ gimp_procedure_add_return_value (procedure,
+ gimp_param_spec_link_layer ("layer",
+ "layer",
+ "The new link layer. The object belongs to libgimp and you should not free it.",
+ FALSE,
+ GIMP_PARAM_READWRITE));
+ gimp_pdb_register_procedure (pdb, procedure);
+ g_object_unref (procedure);
+
+ /*
+ * gimp-link-layer-discard
+ */
+ procedure = gimp_procedure_new (link_layer_discard_invoker, FALSE);
+ gimp_object_set_static_name (GIMP_OBJECT (procedure),
+ "gimp-link-layer-discard");
+ gimp_procedure_set_static_help (procedure,
+ "Discard the link layer information.",
+ "Discards the link information. This makes the layer behave like a normal layer.",
+ NULL);
+ gimp_procedure_set_static_attribution (procedure,
+ "Jehan",
+ "Jehan",
+ "2025");
+ gimp_procedure_add_argument (procedure,
+ gimp_param_spec_link_layer ("layer",
+ "layer",
+ "The link layer",
+ FALSE,
+ GIMP_PARAM_READWRITE));
+ gimp_pdb_register_procedure (pdb, procedure);
+ g_object_unref (procedure);
+
+ /*
+ * gimp-link-layer-monitor
+ */
+ procedure = gimp_procedure_new (link_layer_monitor_invoker, FALSE);
+ gimp_object_set_static_name (GIMP_OBJECT (procedure),
+ "gimp-link-layer-monitor");
+ gimp_procedure_set_static_help (procedure,
+ "Retrieve the link layer information.",
+ "Retrieve the link information. This makes the layer behave like a link layer after the link information has been discarded.\n"
+ "Since the source file will be monitored again, it may change the layer's render.",
+ NULL);
+ gimp_procedure_set_static_attribution (procedure,
+ "Jehan",
+ "Jehan",
+ "2025");
+ gimp_procedure_add_argument (procedure,
+ gimp_param_spec_link_layer ("layer",
+ "layer",
+ "The link layer",
+ FALSE,
+ GIMP_PARAM_READWRITE));
+ gimp_pdb_register_procedure (pdb, procedure);
+ g_object_unref (procedure);
+
+ /*
+ * gimp-link-layer-get-file
+ */
+ procedure = gimp_procedure_new (link_layer_get_file_invoker, FALSE);
+ gimp_object_set_static_name (GIMP_OBJECT (procedure),
+ "gimp-link-layer-get-file");
+ gimp_procedure_set_static_help (procedure,
+ "Get the monitored file.",
+ "This procedure returns the file which is being monitored.",
+ NULL);
+ gimp_procedure_set_static_attribution (procedure,
+ "Jehan",
+ "Jehan",
+ "2025");
+ gimp_procedure_add_argument (procedure,
+ gimp_param_spec_link_layer ("layer",
+ "layer",
+ "The link layer",
+ FALSE,
+ GIMP_PARAM_READWRITE));
+ gimp_procedure_add_return_value (procedure,
+ g_param_spec_object ("file",
+ "file",
+ "The monitored file",
+ G_TYPE_FILE,
+ GIMP_PARAM_READWRITE));
+ gimp_pdb_register_procedure (pdb, procedure);
+ g_object_unref (procedure);
+
+ /*
+ * gimp-link-layer-set-file
+ */
+ procedure = gimp_procedure_new (link_layer_set_file_invoker, FALSE);
+ gimp_object_set_static_name (GIMP_OBJECT (procedure),
+ "gimp-link-layer-set-file");
+ gimp_procedure_set_static_help (procedure,
+ "Set the monitored file.",
+ "This procedure sets the file to be monitored. It may change the layer's render.",
+ NULL);
+ gimp_procedure_set_static_attribution (procedure,
+ "Jehan",
+ "Jehan",
+ "2025");
+ gimp_procedure_add_argument (procedure,
+ gimp_param_spec_link_layer ("layer",
+ "layer",
+ "The link layer",
+ FALSE,
+ GIMP_PARAM_READWRITE));
+ gimp_procedure_add_argument (procedure,
+ g_param_spec_object ("file",
+ "file",
+ "The file to monitor",
+ G_TYPE_FILE,
+ GIMP_PARAM_READWRITE));
+ gimp_pdb_register_procedure (pdb, procedure);
+ g_object_unref (procedure);
+}
diff --git a/app/pdb/meson.build b/app/pdb/meson.build
index 3b8fb0500b..e72bdb6d24 100644
--- a/app/pdb/meson.build
+++ b/app/pdb/meson.build
@@ -49,6 +49,7 @@ libappinternalprocs_sources = [
'item-cmds.c',
'item-transform-cmds.c',
'layer-cmds.c',
+ 'link-layer-cmds.c',
'message-cmds.c',
'paint-tools-cmds.c',
'palette-cmds.c',
diff --git a/app/plug-in/gimpgpparams.c b/app/plug-in/gimpgpparams.c
index 292580b566..bb778a4b1c 100644
--- a/app/plug-in/gimpgpparams.c
+++ b/app/plug-in/gimpgpparams.c
@@ -40,6 +40,7 @@
#include "core/gimpimage.h"
#include "core/gimplayer.h"
#include "core/gimplayermask.h"
+#include "core/gimplinklayer.h"
#include "core/gimppalette.h"
#include "core/gimppattern.h"
#include "core/gimpselection.h"
diff --git a/libgimp/gimp.def b/libgimp/gimp.def
index ff8647aafc..fd064241d2 100644
--- a/libgimp/gimp.def
+++ b/libgimp/gimp.def
@@ -601,6 +601,7 @@ EXPORTS
gimp_item_id_is_group_layer
gimp_item_id_is_layer
gimp_item_id_is_layer_mask
+ gimp_item_id_is_link_layer
gimp_item_id_is_path
gimp_item_id_is_selection
gimp_item_id_is_text_layer
@@ -612,6 +613,7 @@ EXPORTS
gimp_item_is_group_layer
gimp_item_is_layer
gimp_item_is_layer_mask
+ gimp_item_is_link_layer
gimp_item_is_path
gimp_item_is_selection
gimp_item_is_text_layer
@@ -679,6 +681,13 @@ EXPORTS
gimp_layer_set_offsets
gimp_layer_set_opacity
gimp_layer_set_show_mask
+ gimp_link_layer_discard
+ gimp_link_layer_get_by_id
+ gimp_link_layer_get_file
+ gimp_link_layer_get_type
+ gimp_link_layer_monitor
+ gimp_link_layer_new
+ gimp_link_layer_set_file
gimp_list_images
gimp_load_procedure_get_handles_raw
gimp_load_procedure_get_thumbnail_loader
@@ -725,6 +734,7 @@ EXPORTS
gimp_param_item_get_type
gimp_param_layer_get_type
gimp_param_layer_mask_get_type
+ gimp_param_link_layer_get_type
gimp_param_palette_get_type
gimp_param_path_get_type
gimp_param_pattern_get_type
@@ -747,6 +757,7 @@ EXPORTS
gimp_param_spec_item_none_allowed
gimp_param_spec_layer
gimp_param_spec_layer_mask
+ gimp_param_spec_link_layer
gimp_param_spec_palette
gimp_param_spec_path
gimp_param_spec_pattern
@@ -883,6 +894,9 @@ EXPORTS
gimp_procedure_add_layer_mask_aux_argument
gimp_procedure_add_layer_mask_return_value
gimp_procedure_add_layer_return_value
+ gimp_procedure_add_link_layer_argument
+ gimp_procedure_add_link_layer_aux_argument
+ gimp_procedure_add_link_layer_return_value
gimp_procedure_add_menu_path
gimp_procedure_add_palette_argument
gimp_procedure_add_palette_aux_argument
diff --git a/libgimp/gimp.h b/libgimp/gimp.h
index 9b9abfcc00..adba2a8377 100644
--- a/libgimp/gimp.h
+++ b/libgimp/gimp.h
@@ -57,6 +57,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff --git a/libgimp/gimp_pdb_headers.h b/libgimp/gimp_pdb_headers.h
index 7e4bb5322b..5fc08b21de 100644
--- a/libgimp/gimp_pdb_headers.h
+++ b/libgimp/gimp_pdb_headers.h
@@ -67,6 +67,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff --git a/libgimp/gimpgpparams-body.c b/libgimp/gimpgpparams-body.c
index f2b10ace67..39cbb8ec57 100644
--- a/libgimp/gimpgpparams-body.c
+++ b/libgimp/gimpgpparams-body.c
@@ -289,6 +289,11 @@ _gimp_gp_param_def_to_param_spec (const GPParamDef *param_def)
param_def->meta.m_id.none_ok,
flags);
+ if (! strcmp (param_def->type_name, "GimpParamLinkLayer"))
+ return gimp_param_spec_link_layer (name, nick, blurb,
+ param_def->meta.m_id.none_ok,
+ flags);
+
if (! strcmp (param_def->type_name, "GimpParamGroupLayer"))
return gimp_param_spec_group_layer (name, nick, blurb,
param_def->meta.m_id.none_ok,
@@ -725,6 +730,10 @@ _gimp_param_spec_to_gp_param_def (GParamSpec *pspec,
{
type_name = "GimpParamVectorLayer";
}
+ else if (value_type == GIMP_TYPE_LINK_LAYER)
+ {
+ type_name = "GimpParamLinkLayer";
+ }
else if (value_type == GIMP_TYPE_GROUP_LAYER)
{
type_name = "GimpParamGroupLayer";
diff --git a/libgimp/gimpitem.c b/libgimp/gimpitem.c
index 12be1ce730..528cdd6361 100644
--- a/libgimp/gimpitem.c
+++ b/libgimp/gimpitem.c
@@ -280,6 +280,25 @@ gimp_item_is_vector_layer (GimpItem *item)
return gimp_item_id_is_vector_layer (gimp_item_get_id (item));
}
+/**
+ * gimp_item_is_link_layer:
+ * @item: The item.
+ *
+ * Returns whether the item is a link layer.
+ *
+ * This procedure returns TRUE if the specified item is a link
+ * layer.
+ *
+ * Returns: TRUE if the item is a link layer, FALSE otherwise.
+ *
+ * Since: 3.2
+ **/
+gboolean
+gimp_item_is_link_layer (GimpItem *item)
+{
+ return gimp_item_id_is_link_layer (gimp_item_get_id (item));
+}
+
/**
* gimp_item_is_group_layer:
* @item: The item.
diff --git a/libgimp/gimpitem.h b/libgimp/gimpitem.h
index 91108051d9..ad0c6df082 100644
--- a/libgimp/gimpitem.h
+++ b/libgimp/gimpitem.h
@@ -61,6 +61,7 @@ gboolean gimp_item_is_drawable (GimpItem *item);
gboolean gimp_item_is_layer (GimpItem *item);
gboolean gimp_item_is_text_layer (GimpItem *item);
gboolean gimp_item_is_vector_layer (GimpItem *item);
+gboolean gimp_item_is_link_layer (GimpItem *item);
gboolean gimp_item_is_group_layer (GimpItem *item);
gboolean gimp_item_is_channel (GimpItem *item);
gboolean gimp_item_is_layer_mask (GimpItem *item);
diff --git a/libgimp/gimpitem_pdb.c b/libgimp/gimpitem_pdb.c
index e7672d22f7..577a3fb246 100644
--- a/libgimp/gimpitem_pdb.c
+++ b/libgimp/gimpitem_pdb.c
@@ -291,6 +291,46 @@ gimp_item_id_is_group_layer (gint item_id)
return group_layer;
}
+/**
+ * gimp_item_id_is_link_layer:
+ * @item_id: The item ID.
+ *
+ * Returns whether the item ID is a link layer.
+ *
+ * This procedure returns %TRUE if the specified item ID is a link
+ * layer.
+ *
+ * *Note*: in most use cases, you should not use this function. See
+ * [func@Gimp.Item.id_is_layer] for a discussion on alternatives.
+ *
+ * Returns: TRUE if the item is a text layer, FALSE otherwise.
+ *
+ * Since: 3.2
+ **/
+gboolean
+gimp_item_id_is_link_layer (gint item_id)
+{
+ GimpValueArray *args;
+ GimpValueArray *return_vals;
+ gboolean text_layer = FALSE;
+
+ args = gimp_value_array_new_from_types (NULL,
+ G_TYPE_INT, item_id,
+ G_TYPE_NONE);
+
+ return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
+ "gimp-item-id-is-link-layer",
+ args);
+ gimp_value_array_unref (args);
+
+ if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
+ text_layer = GIMP_VALUES_GET_BOOLEAN (return_vals, 1);
+
+ gimp_value_array_unref (return_vals);
+
+ return text_layer;
+}
+
/**
* gimp_item_id_is_channel:
* @item_id: The item ID.
diff --git a/libgimp/gimpitem_pdb.h b/libgimp/gimpitem_pdb.h
index 0b1bb166c7..a4801f6565 100644
--- a/libgimp/gimpitem_pdb.h
+++ b/libgimp/gimpitem_pdb.h
@@ -38,6 +38,7 @@ gboolean gimp_item_id_is_layer (gint item_id);
gboolean gimp_item_id_is_text_layer (gint item_id);
gboolean gimp_item_id_is_vector_layer (gint item_id);
gboolean gimp_item_id_is_group_layer (gint item_id);
+gboolean gimp_item_id_is_link_layer (gint item_id);
gboolean gimp_item_id_is_channel (gint item_id);
gboolean gimp_item_id_is_layer_mask (gint item_id);
gboolean gimp_item_id_is_path (gint item_id);
diff --git a/libgimp/gimplinklayer.c b/libgimp/gimplinklayer.c
new file mode 100644
index 0000000000..45e4a74708
--- /dev/null
+++ b/libgimp/gimplinklayer.c
@@ -0,0 +1,76 @@
+/* LIBGIMP - The GIMP Library
+ * Copyright (C) 1995-2000 Peter Mattis and Spencer Kimball
+ *
+ * gimplinklayer.c
+ * Copyright (C) 2025 Jehan
+ *
+ * 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 3 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, see
+ * .
+ */
+
+#include "config.h"
+
+#include "gimp.h"
+
+
+struct _GimpLinkLayer
+{
+ GimpLayer parent_instance;
+};
+
+
+
+G_DEFINE_TYPE (GimpLinkLayer, gimp_link_layer, GIMP_TYPE_LAYER)
+
+#define parent_class gimp_link_layer_parent_class
+
+
+static void
+gimp_link_layer_class_init (GimpLinkLayerClass *klass)
+{
+}
+
+static void
+gimp_link_layer_init (GimpLinkLayer *layer)
+{
+}
+
+
+/* Public API. */
+
+/**
+ * gimp_link_layer_get_by_id:
+ * @layer_id: The layer id.
+ *
+ * Returns a #GimpLinkLayer representing @layer_id. This function calls
+ * [func@Gimp.Item.get_by_id] and returns the item if it is a link
+ * layer or %NULL otherwise.
+ *
+ * Returns: (nullable) (transfer none): a #GimpLinkLayer for @layer_id or
+ * %NULL if @layer_id does not represent a valid link layer. The
+ * object belongs to libgimp and you must not modify or unref
+ * it.
+ *
+ * Since: 3.2
+ **/
+GimpLinkLayer *
+gimp_link_layer_get_by_id (gint32 layer_id)
+{
+ GimpItem *item = gimp_item_get_by_id (layer_id);
+
+ if (GIMP_IS_LINK_LAYER (item))
+ return (GimpLinkLayer *) item;
+
+ return NULL;
+}
diff --git a/libgimp/gimplinklayer.h b/libgimp/gimplinklayer.h
new file mode 100644
index 0000000000..7df9a703b9
--- /dev/null
+++ b/libgimp/gimplinklayer.h
@@ -0,0 +1,46 @@
+/* LIBGIMP - The GIMP Library
+ * Copyright (C) 1995-2000 Peter Mattis and Spencer Kimball
+ *
+ * gimplinklayer.h
+ * Copyright (C) 2025 Jehan
+ *
+ * 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 3 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, see
+ * .
+ */
+
+#if !defined (__GIMP_H_INSIDE__) && !defined (GIMP_COMPILATION)
+#error "Only can be included directly."
+#endif
+
+#ifndef __GIMP_LINK_LAYER_H__
+#define __GIMP_LINK_LAYER_H__
+
+G_BEGIN_DECLS
+
+/* For information look into the C source or the html documentation */
+
+
+#include
+
+
+#define GIMP_TYPE_LINK_LAYER (gimp_link_layer_get_type ())
+G_DECLARE_FINAL_TYPE (GimpLinkLayer, gimp_link_layer, GIMP, LINK_LAYER, GimpLayer)
+
+
+GimpLinkLayer * gimp_link_layer_get_by_id (gint32 layer_id);
+
+
+G_END_DECLS
+
+#endif /* __GIMP_LINK_LAYER_H__ */
diff --git a/libgimp/gimplinklayer_pdb.c b/libgimp/gimplinklayer_pdb.c
new file mode 100644
index 0000000000..5fb2b897af
--- /dev/null
+++ b/libgimp/gimplinklayer_pdb.c
@@ -0,0 +1,234 @@
+/* LIBGIMP - The GIMP Library
+ * Copyright (C) 1995-2003 Peter Mattis and Spencer Kimball
+ *
+ * gimplinklayer_pdb.c
+ *
+ * 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 3 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, see
+ * .
+ */
+
+/* NOTE: This file is auto-generated by pdbgen.pl */
+
+#include "config.h"
+
+#include "stamp-pdbgen.h"
+
+#include "gimp.h"
+
+
+/**
+ * SECTION: gimplinklayer
+ * @title: gimplinklayer
+ * @short_description: Functions for querying and manipulating link layers.
+ *
+ * Functions for querying and manipulating link layers.
+ **/
+
+
+/**
+ * gimp_link_layer_new:
+ * @image: The image.
+ * @file: The file this link layer will monitor.
+ *
+ * Creates a new link layer.
+ *
+ * This procedure creates a link layer monitoring the specified @file.
+ *
+ * The new layer still needs to be added to the image as this is not
+ * automatic. Add the new layer with the [method@Image.insert_layer]
+ * method.
+ *
+ * The arguments are kept as simple as necessary for the basic case.
+ * All link attributes, however, can be modified with the appropriate
+ * `gimp_link_layer_set_*()` procedures.
+ *
+ * Returns: (transfer none):
+ * The new link layer. The object belongs to libgimp and you should not free it.
+ *
+ * Since: 3.2
+ **/
+GimpLinkLayer *
+gimp_link_layer_new (GimpImage *image,
+ GFile *file)
+{
+ GimpValueArray *args;
+ GimpValueArray *return_vals;
+ GimpLinkLayer *layer = NULL;
+
+ args = gimp_value_array_new_from_types (NULL,
+ GIMP_TYPE_IMAGE, image,
+ G_TYPE_FILE, file,
+ G_TYPE_NONE);
+
+ return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
+ "gimp-link-layer-new",
+ args);
+ gimp_value_array_unref (args);
+
+ if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
+ layer = GIMP_VALUES_GET_LINK_LAYER (return_vals, 1);
+
+ gimp_value_array_unref (return_vals);
+
+ return layer;
+}
+
+/**
+ * gimp_link_layer_discard:
+ * @layer: The link layer.
+ *
+ * Discard the link layer information.
+ *
+ * Discards the link information. This makes the layer behave like a
+ * normal layer.
+ *
+ * Returns: TRUE on success.
+ *
+ * Since: 3.2
+ **/
+gboolean
+gimp_link_layer_discard (GimpLinkLayer *layer)
+{
+ GimpValueArray *args;
+ GimpValueArray *return_vals;
+ gboolean success = TRUE;
+
+ args = gimp_value_array_new_from_types (NULL,
+ GIMP_TYPE_LINK_LAYER, layer,
+ G_TYPE_NONE);
+
+ return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
+ "gimp-link-layer-discard",
+ args);
+ gimp_value_array_unref (args);
+
+ success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;
+
+ gimp_value_array_unref (return_vals);
+
+ return success;
+}
+
+/**
+ * gimp_link_layer_monitor:
+ * @layer: The link layer.
+ *
+ * Retrieve the link layer information.
+ *
+ * Retrieve the link information. This makes the layer behave like a
+ * link layer after the link information has been discarded.
+ * Since the source file will be monitored again, it may change the
+ * layer's render.
+ *
+ * Returns: TRUE on success.
+ *
+ * Since: 3.2
+ **/
+gboolean
+gimp_link_layer_monitor (GimpLinkLayer *layer)
+{
+ GimpValueArray *args;
+ GimpValueArray *return_vals;
+ gboolean success = TRUE;
+
+ args = gimp_value_array_new_from_types (NULL,
+ GIMP_TYPE_LINK_LAYER, layer,
+ G_TYPE_NONE);
+
+ return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
+ "gimp-link-layer-monitor",
+ args);
+ gimp_value_array_unref (args);
+
+ success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;
+
+ gimp_value_array_unref (return_vals);
+
+ return success;
+}
+
+/**
+ * gimp_link_layer_get_file:
+ * @layer: The link layer.
+ *
+ * Get the monitored file.
+ *
+ * This procedure returns the file which is being monitored.
+ *
+ * Returns: (transfer full): The monitored file.
+ *
+ * Since: 3.2
+ **/
+GFile *
+gimp_link_layer_get_file (GimpLinkLayer *layer)
+{
+ GimpValueArray *args;
+ GimpValueArray *return_vals;
+ GFile *file = NULL;
+
+ args = gimp_value_array_new_from_types (NULL,
+ GIMP_TYPE_LINK_LAYER, layer,
+ G_TYPE_NONE);
+
+ return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
+ "gimp-link-layer-get-file",
+ args);
+ gimp_value_array_unref (args);
+
+ if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
+ file = GIMP_VALUES_DUP_FILE (return_vals, 1);
+
+ gimp_value_array_unref (return_vals);
+
+ return file;
+}
+
+/**
+ * gimp_link_layer_set_file:
+ * @layer: The link layer.
+ * @file: The file to monitor.
+ *
+ * Set the monitored file.
+ *
+ * This procedure sets the file to be monitored. It may change the
+ * layer's render.
+ *
+ * Returns: TRUE on success.
+ *
+ * Since: 3.2
+ **/
+gboolean
+gimp_link_layer_set_file (GimpLinkLayer *layer,
+ GFile *file)
+{
+ GimpValueArray *args;
+ GimpValueArray *return_vals;
+ gboolean success = TRUE;
+
+ args = gimp_value_array_new_from_types (NULL,
+ GIMP_TYPE_LINK_LAYER, layer,
+ G_TYPE_FILE, file,
+ G_TYPE_NONE);
+
+ return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
+ "gimp-link-layer-set-file",
+ args);
+ gimp_value_array_unref (args);
+
+ success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;
+
+ gimp_value_array_unref (return_vals);
+
+ return success;
+}
diff --git a/libgimp/gimplinklayer_pdb.h b/libgimp/gimplinklayer_pdb.h
new file mode 100644
index 0000000000..482834bc60
--- /dev/null
+++ b/libgimp/gimplinklayer_pdb.h
@@ -0,0 +1,46 @@
+/* LIBGIMP - The GIMP Library
+ * Copyright (C) 1995-2003 Peter Mattis and Spencer Kimball
+ *
+ * gimplinklayer_pdb.h
+ *
+ * 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 3 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, see
+ * .
+ */
+
+/* NOTE: This file is auto-generated by pdbgen.pl */
+
+#if !defined (__GIMP_H_INSIDE__) && !defined (GIMP_COMPILATION)
+#error "Only can be included directly."
+#endif
+
+#ifndef __GIMP_LINK_LAYER_PDB_H__
+#define __GIMP_LINK_LAYER_PDB_H__
+
+G_BEGIN_DECLS
+
+/* For information look into the C source or the html documentation */
+
+
+GimpLinkLayer* gimp_link_layer_new (GimpImage *image,
+ GFile *file);
+gboolean gimp_link_layer_discard (GimpLinkLayer *layer);
+gboolean gimp_link_layer_monitor (GimpLinkLayer *layer);
+GFile* gimp_link_layer_get_file (GimpLinkLayer *layer);
+gboolean gimp_link_layer_set_file (GimpLinkLayer *layer,
+ GFile *file);
+
+
+G_END_DECLS
+
+#endif /* __GIMP_LINK_LAYER_PDB_H__ */
diff --git a/libgimp/gimpparamspecs-body.c b/libgimp/gimpparamspecs-body.c
index 1f388dbd49..80f79b8ca8 100644
--- a/libgimp/gimpparamspecs-body.c
+++ b/libgimp/gimpparamspecs-body.c
@@ -612,6 +612,86 @@ gimp_param_spec_vector_layer (const gchar *name,
}
+/*
+ * GIMP_TYPE_PARAM_LINK_LAYER
+ */
+
+static void gimp_param_link_layer_class_init (GParamSpecClass *klass);
+static void gimp_param_link_layer_init (GParamSpec *pspec);
+
+GType
+gimp_param_link_layer_get_type (void)
+{
+ static GType type = 0;
+
+ if (! type)
+ {
+ const GTypeInfo info =
+ {
+ sizeof (GParamSpecClass),
+ NULL, NULL,
+ (GClassInitFunc) gimp_param_link_layer_class_init,
+ NULL, NULL,
+ sizeof (GimpParamSpecItem),
+ 0,
+ (GInstanceInitFunc) gimp_param_link_layer_init
+ };
+
+ type = g_type_register_static (GIMP_TYPE_PARAM_LAYER,
+ "GimpParamLinkLayer", &info, 0);
+ }
+
+ return type;
+}
+
+static void
+gimp_param_link_layer_class_init (GParamSpecClass *klass)
+{
+ klass->value_type = GIMP_TYPE_LINK_LAYER;
+}
+
+static void
+gimp_param_link_layer_init (GParamSpec *pspec)
+{
+}
+
+/**
+ * gimp_param_spec_link_layer:
+ * @name: Canonical name of the property specified.
+ * @nick: Nick name of the property specified.
+ * @blurb: Description of the property specified.
+ * @none_ok: Whether no is a valid value.
+ * @flags: Flags for the property specified.
+ *
+ * Creates a new #GimpParamSpecLinkLayer specifying a
+ * [type@LinkLayer] property.
+ *
+ * See g_param_spec_internal() for details on property names.
+ *
+ * Returns: (transfer floating): The newly created #GimpParamSpecLinkLayer.
+ *
+ * Since: 3.2
+ **/
+GParamSpec *
+gimp_param_spec_link_layer (const gchar *name,
+ const gchar *nick,
+ const gchar *blurb,
+ gboolean none_ok,
+ GParamFlags flags)
+{
+ GimpParamSpecItem *ispec;
+
+ ispec = g_param_spec_internal (GIMP_TYPE_PARAM_LINK_LAYER,
+ name, nick, blurb, flags);
+
+ g_return_val_if_fail (ispec, NULL);
+
+ ispec->none_ok = none_ok ? TRUE : FALSE;
+
+ return G_PARAM_SPEC (ispec);
+}
+
+
/*
* GIMP_TYPE_PARAM_GROUP_LAYER
*/
diff --git a/libgimp/gimpparamspecs.h b/libgimp/gimpparamspecs.h
index 1d9b2f2679..b3c99b4a7b 100644
--- a/libgimp/gimpparamspecs.h
+++ b/libgimp/gimpparamspecs.h
@@ -148,6 +148,22 @@ GParamSpec * gimp_param_spec_vector_layer (const gchar *name,
GParamFlags flags);
+/*
+ * GIMP_TYPE_PARAM_LINK_LAYER
+ */
+
+#define GIMP_VALUE_HOLDS_LINK_LAYER(value) (G_TYPE_CHECK_VALUE_TYPE ((value), GIMP_TYPE_LINK_LAYER))
+#define GIMP_TYPE_PARAM_LINK_LAYER (gimp_param_link_layer_get_type ())
+#define GIMP_IS_PARAM_SPEC_LINK_LAYER(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), GIMP_TYPE_PARAM_LINK_LAYER))
+
+GType gimp_param_link_layer_get_type (void) G_GNUC_CONST;
+
+GParamSpec * gimp_param_spec_link_layer (const gchar *name,
+ const gchar *nick,
+ const gchar *blurb,
+ gboolean none_ok,
+ GParamFlags flags);
+
/*
* GIMP_TYPE_PARAM_GROUP_LAYER
*/
diff --git a/libgimp/gimpplugin.c b/libgimp/gimpplugin.c
index 21c3d7295e..a05c0ed37e 100644
--- a/libgimp/gimpplugin.c
+++ b/libgimp/gimpplugin.c
@@ -1807,6 +1807,12 @@ _gimp_plug_in_get_item (GimpPlugIn *plug_in,
"id", item_id,
NULL);
}
+ else if (gimp_item_id_is_link_layer (item_id))
+ {
+ item = g_object_new (GIMP_TYPE_LINK_LAYER,
+ "id", item_id,
+ NULL);
+ }
else if (gimp_item_id_is_group_layer (item_id))
{
item = g_object_new (GIMP_TYPE_GROUP_LAYER,
diff --git a/libgimp/gimpprocedure-params.c b/libgimp/gimpprocedure-params.c
index 46ae276fbc..859d39aaac 100644
--- a/libgimp/gimpprocedure-params.c
+++ b/libgimp/gimpprocedure-params.c
@@ -1962,6 +1962,84 @@ gimp_procedure_add_vector_layer_return_value (GimpProcedure *procedure,
none_ok, flags));
}
+/**
+ * gimp_procedure_add_link_layer_argument:
+ * @procedure: the #GimpProcedure.
+ * @name: the name of the argument to be created.
+ * @nick: the label used in #GimpProcedureDialog.
+ * @blurb: (nullable): a more detailed help description.
+ * @none_ok: Whether no is a valid value.
+ * @flags: argument flags.
+ *
+ * Add a new #GimpLinkLayer argument to @procedure.
+ *
+ * Since: 3.2
+ **/
+void
+gimp_procedure_add_link_layer_argument (GimpProcedure *procedure,
+ const gchar *name,
+ const gchar *nick,
+ const gchar *blurb,
+ gboolean none_ok,
+ GParamFlags flags)
+{
+ _gimp_procedure_add_argument (procedure,
+ gimp_param_spec_link_layer (name, nick, blurb,
+ none_ok, flags));
+}
+
+/**
+ * gimp_procedure_add_link_layer_aux_argument:
+ * @procedure: the #GimpProcedure.
+ * @name: the name of the argument to be created.
+ * @nick: the label used in #GimpProcedureDialog.
+ * @blurb: (nullable): a more detailed help description.
+ * @none_ok: Whether no is a valid value.
+ * @flags: argument flags.
+ *
+ * Add a new #GimpLinkLayer auxiliary argument to @procedure.
+ *
+ * Since: 3.2
+ **/
+void
+ gimp_procedure_add_link_layer_aux_argument (GimpProcedure *procedure,
+ const gchar *name,
+ const gchar *nick,
+ const gchar *blurb,
+ gboolean none_ok,
+ GParamFlags flags)
+{
+ _gimp_procedure_add_aux_argument (procedure,
+ gimp_param_spec_link_layer (name, nick, blurb,
+ none_ok, flags));
+}
+
+/**
+ * gimp_procedure_add_link_layer_return_value:
+ * @procedure: the #GimpProcedure.
+ * @name: the name of the argument to be created.
+ * @nick: the label used in #GimpProcedureDialog.
+ * @blurb: (nullable): a more detailed help description.
+ * @none_ok: Whether no is a valid value.
+ * @flags: argument flags.
+ *
+ * Add a new #GimpLinkLayer return value to @procedure.
+ *
+ * Since: 3.2
+ **/
+void
+gimp_procedure_add_link_layer_return_value (GimpProcedure *procedure,
+ const gchar *name,
+ const gchar *nick,
+ const gchar *blurb,
+ gboolean none_ok,
+ GParamFlags flags)
+{
+ _gimp_procedure_add_return_value (procedure,
+ gimp_param_spec_link_layer (name, nick, blurb,
+ none_ok, flags));
+}
+
/**
* gimp_procedure_add_group_layer_argument:
* @procedure: the #GimpProcedure.
diff --git a/libgimp/gimpprocedure-params.h b/libgimp/gimpprocedure-params.h
index 899d8c5f2f..ef0ab9fc70 100644
--- a/libgimp/gimpprocedure-params.h
+++ b/libgimp/gimpprocedure-params.h
@@ -325,6 +325,18 @@ G_BEGIN_DECLS
g_value_set_object (gimp_value_array_index (args, n), value)
+/* link layer */
+
+#define GIMP_VALUES_GET_LINK_LAYER(args, n) \
+ g_value_get_object (gimp_value_array_index (args, n))
+
+#define GIMP_VALUES_GET_LINK_LAYER_ID(args, n) \
+ gimp_item_get_id (g_value_get_object (gimp_value_array_index (args, n)))
+
+#define GIMP_VALUES_SET_LINK_LAYER(args, n, value) \
+ g_value_set_object (gimp_value_array_index (args, n), value)
+
+
/* group layer */
#define GIMP_VALUES_GET_GROUP_LAYER(args, n) \
@@ -930,6 +942,25 @@ void gimp_procedure_add_vector_layer_return_value (GimpProcedure *procedure
gboolean none_ok,
GParamFlags flags);
+void gimp_procedure_add_link_layer_argument (GimpProcedure *procedure,
+ const gchar *name,
+ const gchar *nick,
+ const gchar *blurb,
+ gboolean none_ok,
+ GParamFlags flags);
+void gimp_procedure_add_link_layer_aux_argument (GimpProcedure *procedure,
+ const gchar *name,
+ const gchar *nick,
+ const gchar *blurb,
+ gboolean none_ok,
+ GParamFlags flags);
+void gimp_procedure_add_link_layer_return_value (GimpProcedure *procedure,
+ const gchar *name,
+ const gchar *nick,
+ const gchar *blurb,
+ gboolean none_ok,
+ GParamFlags flags);
+
void gimp_procedure_add_group_layer_argument (GimpProcedure *procedure,
const gchar *name,
const gchar *nick,
diff --git a/libgimp/gimptypes.h b/libgimp/gimptypes.h
index 23da350321..57121b58a6 100644
--- a/libgimp/gimptypes.h
+++ b/libgimp/gimptypes.h
@@ -47,6 +47,7 @@ typedef struct _GimpGroupLayer GimpGroupLayer;
typedef struct _GimpLayer GimpLayer;
typedef struct _GimpChannel GimpChannel;
typedef struct _GimpLayerMask GimpLayerMask;
+typedef struct _GimpLinkLayer GimpLinkLayer;
typedef struct _GimpSelection GimpSelection;
typedef struct _GimpTextLayer GimpTextLayer;
typedef struct _GimpPath GimpPath;
diff --git a/libgimp/meson.build b/libgimp/meson.build
index aa953c2790..0503ae4d16 100644
--- a/libgimp/meson.build
+++ b/libgimp/meson.build
@@ -99,6 +99,7 @@ pdb_wrappers_sources = [
'gimpitem_pdb.c',
'gimpitemtransform_pdb.c',
'gimplayer_pdb.c',
+ 'gimplinklayer_pdb.c',
'gimpmessage_pdb.c',
'gimppainttools_pdb.c',
'gimppalette_pdb.c',
@@ -159,6 +160,7 @@ pdb_wrappers_headers = [
'gimpitem_pdb.h',
'gimpitemtransform_pdb.h',
'gimplayer_pdb.h',
+ 'gimplinklayer_pdb.h',
'gimpmessage_pdb.h',
'gimppainttools_pdb.h',
'gimppalette_pdb.h',
@@ -200,6 +202,7 @@ libgimp_sources_introspectable = [
'gimpitem.c',
'gimplayer.c',
'gimplayermask.c',
+ 'gimplinklayer.c',
'gimploadprocedure.c',
'gimppalette.c',
'gimpparamspecs.c',
@@ -263,6 +266,7 @@ libgimp_headers_introspectable = [
'gimpitem.h',
'gimplayer.h',
'gimplayermask.h',
+ 'gimplinklayer.h',
'gimploadprocedure.h',
'gimppalette.h',
'gimpparamspecs.h',
diff --git a/pdb/app.pl b/pdb/app.pl
index 133bc70ab1..316d52598a 100644
--- a/pdb/app.pl
+++ b/pdb/app.pl
@@ -391,6 +391,16 @@ gimp_param_spec_vector_layer ("$name",
"$blurb",
$none_ok,
$flags)
+CODE
+ }
+ elsif ($pdbtype eq 'link_layer') {
+ $none_ok = exists $arg->{none_ok} ? 'TRUE' : 'FALSE';
+ $pspec = < 'item_id', type => 'int32',
+ desc => 'The item ID' }
+ );
+
+ @outargs = (
+ { name => 'text_layer', type => 'boolean',
+ desc => 'TRUE if the item is a text layer, FALSE otherwise.' }
+ );
+
+ %invoke = (
+ code => <<'CODE'
+{
+ GimpItem *item = gimp_item_get_by_id (gimp, item_id);
+
+ text_layer = (GIMP_IS_LAYER (item) &&
+ ! gimp_item_is_removed (item) &&
+ gimp_item_is_link_layer (item));
+}
+CODE
+ );
+}
+
sub item_id_is_channel {
$blurb = 'Returns whether the item ID is a channel.';
@@ -1090,6 +1126,7 @@ CODE
@headers = qw("core/gimpgrouplayer.h"
"core/gimplayermask.h"
+ "core/gimplinklayer.h"
"core/gimplist.h"
"core/gimpselection.h"
"path/gimppath.h"
@@ -1105,6 +1142,7 @@ CODE
item_id_is_text_layer
item_id_is_vector_layer
item_id_is_group_layer
+ item_id_is_link_layer
item_id_is_channel
item_id_is_layer_mask
item_id_is_path
diff --git a/pdb/groups/link_layer.pdb b/pdb/groups/link_layer.pdb
new file mode 100644
index 0000000000..6fde88cfc2
--- /dev/null
+++ b/pdb/groups/link_layer.pdb
@@ -0,0 +1,225 @@
+# GIMP - The GNU Image Manipulation Program
+# Copyright (C) 1995 Spencer Kimball and Peter Mattis
+
+# New Link Layer PDB API
+# Copyright (C) 2025 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 .
+
+
+sub link_layer_new {
+ $blurb = 'Creates a new link layer.';
+
+ $help = <<'HELP';
+This procedure creates a link layer monitoring the specified @file.
+
+
+The new layer still needs to be added to the image as this is not
+automatic. Add the new layer with the [method@Image.insert_layer]
+method.
+
+
+The arguments are kept as simple as necessary for the basic case. All
+link attributes, however, can be modified with the appropriate
+`gimp_link_layer_set_*()` procedures.
+HELP
+
+ &jehan_pdb_misc('2025', '3.2');
+
+ @inargs = (
+ { name => 'image', type => 'image',
+ desc => 'The image' },
+ { name => 'file', type => 'file',
+ desc => 'The file this link layer will monitor' }
+ );
+
+ @outargs = (
+ { name => 'layer', type => 'link_layer',
+ desc => 'The new link layer. The object belongs to libgimp and you should not free it.' }
+ );
+
+ %invoke = (
+ code => <<'CODE'
+{
+ if (file == NULL)
+ {
+ g_set_error (error, GIMP_PDB_ERROR, GIMP_PDB_ERROR_INVALID_ARGUMENT,
+ _("Failed to create link layer"));
+
+ success = FALSE;
+ }
+
+ if (success)
+ {
+ GimpLink *link;
+
+ link = gimp_link_new (gimp, file, 0, 0, TRUE, NULL, error);
+
+ if (link == NULL)
+ {
+ success = FALSE;
+ }
+ else
+ {
+ layer = GIMP_LINK_LAYER (gimp_link_layer_new (image, link));
+
+ if (! layer)
+ {
+ g_set_error (error, GIMP_PDB_ERROR, GIMP_PDB_ERROR_INVALID_ARGUMENT,
+ _("Failed to create link layer"));
+
+ success = FALSE;
+ }
+ }
+
+ g_clear_object (&link);
+ }
+}
+CODE
+ );
+}
+
+sub link_layer_discard {
+ $blurb = 'Discard the link layer information.';
+
+ $help = <<'HELP';
+Discards the link information. This makes the layer behave like a normal layer.
+HELP
+
+ &jehan_pdb_misc('2025', '3.2');
+
+ @inargs = (
+ { name => 'layer', type => 'link_layer',
+ desc => 'The link layer' }
+ );
+
+ %invoke = (
+ code => <<'CODE'
+{
+ gimp_link_layer_discard (layer);
+}
+CODE
+ );
+}
+
+sub link_layer_monitor {
+ $blurb = 'Retrieve the link layer information.';
+
+ $help = <<'HELP';
+Retrieve the link information. This makes the layer behave like a link
+layer after the link information has been discarded.
+
+Since the source file will be monitored again, it may change the layer's render.
+HELP
+
+ &jehan_pdb_misc('2025', '3.2');
+
+ @inargs = (
+ { name => 'layer', type => 'link_layer',
+ desc => 'The link layer' }
+ );
+
+ %invoke = (
+ code => <<'CODE'
+{
+ gimp_link_layer_monitor (layer);
+}
+CODE
+ );
+}
+
+sub link_layer_get_file {
+ $blurb = 'Get the monitored file.';
+
+ $help = <<'HELP';
+This procedure returns the file which is being monitored.
+HELP
+
+ &jehan_pdb_misc('2025', '3.2');
+
+ @inargs = (
+ { name => 'layer', type => 'link_layer',
+ desc => 'The link layer' }
+ );
+
+ @outargs = (
+ { name => 'file', type => 'file',
+ desc => 'The monitored file' }
+ );
+
+ %invoke = (
+ code => <<'CODE'
+{
+ file = gimp_link_get_file (gimp_link_layer_get_link (layer), NULL, NULL);
+}
+CODE
+ );
+}
+
+sub link_layer_set_file {
+ $blurb = 'Set the monitored file.';
+
+ $help = <<'HELP';
+This procedure sets the file to be monitored.
+It may change the layer's render.
+HELP
+
+ &jehan_pdb_misc('2025', '3.2');
+
+ @inargs = (
+ { name => 'layer', type => 'link_layer',
+ desc => 'The link layer' },
+ { name => 'file', type => 'file',
+ desc => 'The file to monitor' }
+ );
+
+ %invoke = (
+ code => <<'CODE'
+{
+ GimpLink *link = gimp_link_new (gimp, file, 0, 0, TRUE, NULL, error);
+
+ if (link)
+ {
+ gimp_link_layer_set_link (layer, link, TRUE);
+ }
+ else
+ {
+ success = FALSE;
+ }
+
+ g_clear_object (&link);
+}
+CODE
+ );
+}
+
+@headers = qw("core/gimplink.h"
+ "core/gimplinklayer.h"
+ "gimppdberror.h"
+ "gimp-intl.h");
+
+@procs = qw(link_layer_new
+ link_layer_discard
+ link_layer_monitor
+ link_layer_get_file
+ link_layer_set_file);
+
+%exports = (app => [@procs], lib => [@procs]);
+
+$desc = 'Link layer procedures';
+$doc_title = 'gimplinklayer';
+$doc_short_desc = 'Functions for querying and manipulating link layers.';
+$doc_long_desc = 'Functions for querying and manipulating link layers.';
+
+1;
diff --git a/pdb/meson.build b/pdb/meson.build
index d0c0a5f20c..682de2492c 100644
--- a/pdb/meson.build
+++ b/pdb/meson.build
@@ -42,6 +42,7 @@ pdb_names = [
'item_transform',
'item',
'layer',
+ 'link_layer',
'message',
'paint_tools',
'palette_select',
diff --git a/pdb/pdb.pl b/pdb/pdb.pl
index aa8591d575..a1a108cadb 100644
--- a/pdb/pdb.pl
+++ b/pdb/pdb.pl
@@ -383,6 +383,18 @@ package Gimp::CodeGen::pdb;
take_value_func => 'g_value_set_object ($value, $var)',
headers => [ qw("path/gimpvectorlayer.h") ] },
+ link_layer => { name => 'LINK_LAYER',
+ gtype => 'GIMP_TYPE_LINK_LAYER',
+ type => 'GimpLinkLayer *',
+ const_type => 'GimpLinkLayer *',
+ init_value => 'NULL',
+ out_annotate => '(transfer none)',
+ get_value_func => '$var = g_value_get_object ($value)',
+ dup_value_func => '$var = GIMP_VALUES_GET_LINK_LAYER ($value)',
+ set_value_func => 'g_value_set_object ($value, $var)',
+ take_value_func => 'g_value_set_object ($value, $var)',
+ headers => [ qw("core/gimplinklayer.h") ] },
+
group_layer => { name => 'GROUP_LAYER',
gtype => 'GIMP_TYPE_GROUP_LAYER',
type => 'GimpGroupLayer *',
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 2800ce9687..f749b5db3d 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -390,6 +390,7 @@ app/pdb/image-transform-cmds.c
app/pdb/image-undo-cmds.c
app/pdb/item-transform-cmds.c
app/pdb/layer-cmds.c
+app/pdb/link-layer-cmds.c
app/pdb/path-cmds.c
app/pdb/pdb-cmds.c
app/pdb/resource-cmds.c