diff --git a/app/pdb/internal-procs.c b/app/pdb/internal-procs.c index 113c95cae2..3db3f2bff3 100644 --- a/app/pdb/internal-procs.c +++ b/app/pdb/internal-procs.c @@ -28,7 +28,7 @@ #include "internal-procs.h" -/* 743 procedures registered total */ +/* 745 procedures registered total */ void internal_procs_init (GimpPDB *pdb) diff --git a/app/pdb/procedural-db-cmds.c b/app/pdb/procedural-db-cmds.c index ef3eb53e23..540d99473e 100644 --- a/app/pdb/procedural-db-cmds.c +++ b/app/pdb/procedural-db-cmds.c @@ -370,6 +370,116 @@ procedural_db_proc_val_invoker (GimpProcedure *procedure, return return_vals; } +static GimpValueArray * +procedural_db_proc_argument_invoker (GimpProcedure *procedure, + Gimp *gimp, + GimpContext *context, + GimpProgress *progress, + const GimpValueArray *args, + GError **error) +{ + gboolean success = TRUE; + GimpValueArray *return_vals; + const gchar *procedure_name; + gint32 arg_num; + GParamSpec *param_spec = NULL; + + procedure_name = g_value_get_string (gimp_value_array_index (args, 0)); + arg_num = g_value_get_int (gimp_value_array_index (args, 1)); + + if (success) + { + GimpProcedure *proc; + gchar *canonical; + + canonical = gimp_canonicalize_identifier (procedure_name); + + proc = gimp_pdb_lookup_procedure (gimp->pdb, canonical); + + if (! proc) + { + const gchar *compat_name; + + compat_name = gimp_pdb_lookup_compat_proc_name (gimp->pdb, canonical); + + if (compat_name) + proc = gimp_pdb_lookup_procedure (gimp->pdb, compat_name); + } + + g_free (canonical); + + if (proc && (arg_num >= 0 && arg_num < proc->num_args)) + { + param_spec = g_param_spec_ref (proc->args[arg_num]); + } + else + success = FALSE; + } + + return_vals = gimp_procedure_get_return_values (procedure, success, + error ? *error : NULL); + + if (success) + g_value_take_param (gimp_value_array_index (return_vals, 1), param_spec); + + return return_vals; +} + +static GimpValueArray * +procedural_db_proc_return_value_invoker (GimpProcedure *procedure, + Gimp *gimp, + GimpContext *context, + GimpProgress *progress, + const GimpValueArray *args, + GError **error) +{ + gboolean success = TRUE; + GimpValueArray *return_vals; + const gchar *procedure_name; + gint32 val_num; + GParamSpec *param_spec = NULL; + + procedure_name = g_value_get_string (gimp_value_array_index (args, 0)); + val_num = g_value_get_int (gimp_value_array_index (args, 1)); + + if (success) + { + GimpProcedure *proc; + gchar *canonical; + + canonical = gimp_canonicalize_identifier (procedure_name); + + proc = gimp_pdb_lookup_procedure (gimp->pdb, canonical); + + if (! proc) + { + const gchar *compat_name; + + compat_name = gimp_pdb_lookup_compat_proc_name (gimp->pdb, canonical); + + if (compat_name) + proc = gimp_pdb_lookup_procedure (gimp->pdb, compat_name); + } + + g_free (canonical); + + if (proc && (val_num >= 0 && val_num < proc->num_values)) + { + param_spec = g_param_spec_ref (proc->values[val_num]); + } + else + success = FALSE; + } + + return_vals = gimp_procedure_get_return_values (procedure, success, + error ? *error : NULL); + + if (success) + g_value_take_param (gimp_value_array_index (return_vals, 1), param_spec); + + return return_vals; +} + static GimpValueArray * procedural_db_get_data_invoker (GimpProcedure *procedure, Gimp *gimp, @@ -824,6 +934,78 @@ register_procedural_db_procs (GimpPDB *pdb) gimp_pdb_register_procedure (pdb, procedure); g_object_unref (procedure); + /* + * gimp-procedural-db-proc-argument + */ + procedure = gimp_procedure_new (procedural_db_proc_argument_invoker); + gimp_object_set_static_name (GIMP_OBJECT (procedure), + "gimp-procedural-db-proc-argument"); + gimp_procedure_set_static_strings (procedure, + "gimp-procedural-db-proc-argument", + "Queries the procedural database for information on the specified procedure's argument.", + "This procedure returns the #GParamSpec of procedure_name's argument.", + "Michael Natterer ", + "Michael Natterer", + "2019", + NULL); + gimp_procedure_add_argument (procedure, + gimp_param_spec_string ("procedure-name", + "procedure name", + "The procedure name", + FALSE, FALSE, TRUE, + NULL, + GIMP_PARAM_READWRITE)); + gimp_procedure_add_argument (procedure, + gimp_param_spec_int32 ("arg-num", + "arg num", + "The argument number", + G_MININT32, G_MAXINT32, 0, + GIMP_PARAM_READWRITE)); + gimp_procedure_add_return_value (procedure, + g_param_spec_param ("param-spec", + "param spec", + "The GParamSpec of the argument", + G_TYPE_PARAM, + GIMP_PARAM_READWRITE)); + gimp_pdb_register_procedure (pdb, procedure); + g_object_unref (procedure); + + /* + * gimp-procedural-db-proc-return-value + */ + procedure = gimp_procedure_new (procedural_db_proc_return_value_invoker); + gimp_object_set_static_name (GIMP_OBJECT (procedure), + "gimp-procedural-db-proc-return-value"); + gimp_procedure_set_static_strings (procedure, + "gimp-procedural-db-proc-return-value", + "Queries the procedural database for information on the specified procedure's return value.", + "This procedure returns the #GParamSpec of procedure_name's return value.", + "Michael Natterer ", + "Michael Natterer", + "2019", + NULL); + gimp_procedure_add_argument (procedure, + gimp_param_spec_string ("procedure-name", + "procedure name", + "The procedure name", + FALSE, FALSE, TRUE, + NULL, + GIMP_PARAM_READWRITE)); + gimp_procedure_add_argument (procedure, + gimp_param_spec_int32 ("val-num", + "val num", + "The return value number", + G_MININT32, G_MAXINT32, 0, + GIMP_PARAM_READWRITE)); + gimp_procedure_add_return_value (procedure, + g_param_spec_param ("param-spec", + "param spec", + "The GParamSpec of the return value", + G_TYPE_PARAM, + GIMP_PARAM_READWRITE)); + gimp_pdb_register_procedure (pdb, procedure); + g_object_unref (procedure); + /* * gimp-procedural-db-get-data */ diff --git a/libgimp/gimpproceduraldb.c b/libgimp/gimpproceduraldb.c index 4605af18cd..ae5caaef6c 100644 --- a/libgimp/gimpproceduraldb.c +++ b/libgimp/gimpproceduraldb.c @@ -82,6 +82,8 @@ gimp_procedural_db_proc_info (const gchar *procedure, for (i = 0; i < *num_args; i++) { + GParamSpec *pspec; + if (! gimp_procedural_db_proc_arg (procedure, i, &(*args)[i].type, @@ -93,10 +95,21 @@ gimp_procedural_db_proc_info (const gchar *procedure, return FALSE; } + + pspec = gimp_procedural_db_proc_argument (procedure, i); + + if (pspec) + { + g_printerr ("Arg %i of %s: %s\n", i, procedure, + G_PARAM_SPEC_TYPE_NAME (pspec)); + g_param_spec_unref (pspec); + } } for (i = 0; i < *num_values; i++) { + GParamSpec *pspec; + if (! gimp_procedural_db_proc_val (procedure, i, &(*return_vals)[i].type, @@ -108,6 +121,15 @@ gimp_procedural_db_proc_info (const gchar *procedure, return FALSE; } + + pspec = gimp_procedural_db_proc_return_value (procedure, i); + + if (pspec) + { + g_printerr ("Value %i of %s: %s\n", i, procedure, + G_PARAM_SPEC_TYPE_NAME (pspec)); + g_param_spec_unref (pspec); + } } } diff --git a/libgimp/gimpproceduraldb_pdb.c b/libgimp/gimpproceduraldb_pdb.c index e80f6eb9b4..4bf5a06091 100644 --- a/libgimp/gimpproceduraldb_pdb.c +++ b/libgimp/gimpproceduraldb_pdb.c @@ -404,6 +404,89 @@ gimp_procedural_db_proc_val (const gchar *procedure_name, return success; } +/** + * gimp_procedural_db_proc_argument: + * @procedure_name: The procedure name. + * @arg_num: The argument number. + * + * Queries the procedural database for information on the specified + * procedure's argument. + * + * This procedure returns the #GParamSpec of procedure_name's argument. + * + * Returns: (transfer full): The GParamSpec of the argument. + * The returned value must be freed with g_param_spec_unref(). + * + * Since: 3.0 + **/ +GParamSpec * +gimp_procedural_db_proc_argument (const gchar *procedure_name, + gint arg_num) +{ + GimpValueArray *args; + GimpValueArray *return_vals; + GParamSpec *param_spec = NULL; + + args = gimp_value_array_new_from_types (G_TYPE_STRING, + GIMP_TYPE_INT32, + G_TYPE_NONE); + g_value_set_string (gimp_value_array_index (args, 0), procedure_name); + g_value_set_int (gimp_value_array_index (args, 1), arg_num); + + return_vals = gimp_run_procedure_with_array ("gimp-procedural-db-proc-argument", + args); + gimp_value_array_unref (args); + + if (g_value_get_enum (gimp_value_array_index (return_vals, 0)) == GIMP_PDB_SUCCESS) + param_spec = g_value_dup_param (gimp_value_array_index (return_vals, 1)); + + gimp_value_array_unref (return_vals); + + return param_spec; +} + +/** + * gimp_procedural_db_proc_return_value: + * @procedure_name: The procedure name. + * @val_num: The return value number. + * + * Queries the procedural database for information on the specified + * procedure's return value. + * + * This procedure returns the #GParamSpec of procedure_name's return + * value. + * + * Returns: (transfer full): The GParamSpec of the return value. + * The returned value must be freed with g_param_spec_unref(). + * + * Since: 3.0 + **/ +GParamSpec * +gimp_procedural_db_proc_return_value (const gchar *procedure_name, + gint val_num) +{ + GimpValueArray *args; + GimpValueArray *return_vals; + GParamSpec *param_spec = NULL; + + args = gimp_value_array_new_from_types (G_TYPE_STRING, + GIMP_TYPE_INT32, + G_TYPE_NONE); + g_value_set_string (gimp_value_array_index (args, 0), procedure_name); + g_value_set_int (gimp_value_array_index (args, 1), val_num); + + return_vals = gimp_run_procedure_with_array ("gimp-procedural-db-proc-return-value", + args); + gimp_value_array_unref (args); + + if (g_value_get_enum (gimp_value_array_index (return_vals, 0)) == GIMP_PDB_SUCCESS) + param_spec = g_value_dup_param (gimp_value_array_index (return_vals, 1)); + + gimp_value_array_unref (return_vals); + + return param_spec; +} + /** * _gimp_procedural_db_get_data: * @identifier: The identifier associated with data. diff --git a/libgimp/gimpproceduraldb_pdb.h b/libgimp/gimpproceduraldb_pdb.h index 45b4c7bbe1..5ce28b7d2f 100644 --- a/libgimp/gimpproceduraldb_pdb.h +++ b/libgimp/gimpproceduraldb_pdb.h @@ -32,44 +32,48 @@ G_BEGIN_DECLS /* For information look into the C source or the html documentation */ -gchar* gimp_procedural_db_temp_name (void); -gboolean gimp_procedural_db_dump (const gchar *filename); -gboolean gimp_procedural_db_query (const gchar *name, - const gchar *blurb, - const gchar *help, - const gchar *author, - const gchar *copyright, - const gchar *date, - const gchar *proc_type, - gint *num_matches, - gchar ***procedure_names); -gboolean gimp_procedural_db_proc_exists (const gchar *procedure_name); -G_GNUC_INTERNAL gboolean _gimp_procedural_db_proc_info (const gchar *procedure_name, - gchar **blurb, - gchar **help, - gchar **author, - gchar **copyright, - gchar **date, - GimpPDBProcType *proc_type, - gint *num_args, - gint *num_values); -gboolean gimp_procedural_db_proc_arg (const gchar *procedure_name, - gint arg_num, - GimpPDBArgType *arg_type, - gchar **arg_name, - gchar **arg_desc); -gboolean gimp_procedural_db_proc_val (const gchar *procedure_name, - gint val_num, - GimpPDBArgType *val_type, - gchar **val_name, - gchar **val_desc); -G_GNUC_INTERNAL gboolean _gimp_procedural_db_get_data (const gchar *identifier, - gint *bytes, - guint8 **data); -gint gimp_procedural_db_get_data_size (const gchar *identifier); -G_GNUC_INTERNAL gboolean _gimp_procedural_db_set_data (const gchar *identifier, - gint bytes, - const guint8 *data); +gchar* gimp_procedural_db_temp_name (void); +gboolean gimp_procedural_db_dump (const gchar *filename); +gboolean gimp_procedural_db_query (const gchar *name, + const gchar *blurb, + const gchar *help, + const gchar *author, + const gchar *copyright, + const gchar *date, + const gchar *proc_type, + gint *num_matches, + gchar ***procedure_names); +gboolean gimp_procedural_db_proc_exists (const gchar *procedure_name); +G_GNUC_INTERNAL gboolean _gimp_procedural_db_proc_info (const gchar *procedure_name, + gchar **blurb, + gchar **help, + gchar **author, + gchar **copyright, + gchar **date, + GimpPDBProcType *proc_type, + gint *num_args, + gint *num_values); +gboolean gimp_procedural_db_proc_arg (const gchar *procedure_name, + gint arg_num, + GimpPDBArgType *arg_type, + gchar **arg_name, + gchar **arg_desc); +gboolean gimp_procedural_db_proc_val (const gchar *procedure_name, + gint val_num, + GimpPDBArgType *val_type, + gchar **val_name, + gchar **val_desc); +GParamSpec* gimp_procedural_db_proc_argument (const gchar *procedure_name, + gint arg_num); +GParamSpec* gimp_procedural_db_proc_return_value (const gchar *procedure_name, + gint val_num); +G_GNUC_INTERNAL gboolean _gimp_procedural_db_get_data (const gchar *identifier, + gint *bytes, + guint8 **data); +gint gimp_procedural_db_get_data_size (const gchar *identifier); +G_GNUC_INTERNAL gboolean _gimp_procedural_db_set_data (const gchar *identifier, + gint bytes, + const guint8 *data); G_END_DECLS diff --git a/pdb/app.pl b/pdb/app.pl index e5417d1dbf..61b9b9aa1a 100644 --- a/pdb/app.pl +++ b/pdb/app.pl @@ -508,6 +508,15 @@ gimp_param_spec_parasite ("$name", "$nick", "$blurb", $flags) +CODE + } + elsif ($pdbtype eq 'param') { + $pspec = < 'procedure_name', type => 'string', non_empty => 1, + desc => 'The procedure name' }, + { name => 'arg_num', type => 'int32', + desc => 'The argument number' } + ); + + @outargs = ( + { name => 'param_spec', type => 'param', + desc => "The GParamSpec of the argument" } + ); + + %invoke = ( + code => <pdb, canonical); + + if (! proc) + { + const gchar *compat_name; + + compat_name = gimp_pdb_lookup_compat_proc_name (gimp->pdb, canonical); + + if (compat_name) + proc = gimp_pdb_lookup_procedure (gimp->pdb, compat_name); + } + + g_free (canonical); + + if (proc && (arg_num >= 0 && arg_num < proc->num_args)) + { + param_spec = g_param_spec_ref (proc->args[arg_num]); + } + else + success = FALSE; +} +CODE + ); +} + +sub procedural_db_proc_return_value { + $blurb = < 'procedure_name', type => 'string', non_empty => 1, + desc => 'The procedure name' }, + { name => 'val_num', type => 'int32', + desc => 'The return value number' } + ); + + @outargs = ( + { name => 'param_spec', type => 'param', + desc => "The GParamSpec of the return value" } + ); + + %invoke = ( + code => <pdb, canonical); + + if (! proc) + { + const gchar *compat_name; + + compat_name = gimp_pdb_lookup_compat_proc_name (gimp->pdb, canonical); + + if (compat_name) + proc = gimp_pdb_lookup_procedure (gimp->pdb, compat_name); + } + + g_free (canonical); + + if (proc && (val_num >= 0 && val_num < proc->num_values)) + { + param_spec = g_param_spec_ref (proc->values[val_num]); + } + else + success = FALSE; +} +CODE + ); +} + sub procedural_db_proc_arg { $blurb = <{type} eq 'stringarray') { $retdesc .= "\n * The returned value must be freed with g_strfreev()."; } + elsif ($retarg->{type} eq 'param') { + $retdesc .= "\n * The returned value must be freed with g_param_spec_unref()."; + } elsif (exists $argtype->{array}) { $retdesc .= "\n * The returned value must be freed with g_free()."; } diff --git a/pdb/pdb.pl b/pdb/pdb.pl index e82cc9fdb0..20e8c9b96d 100644 --- a/pdb/pdb.pl +++ b/pdb/pdb.pl @@ -277,6 +277,17 @@ package Gimp::CodeGen::pdb; take_value_func => 'g_value_take_boxed ($value, $var)', headers => [ qw("libgimpbase/gimpbase.h") ] }, + param => { name => 'PARAM', + gtype => 'G_TYPE_PARAM_SPEC', + type => 'GParamSpec *', + const_type => 'GParamSpec *', + init_value => 'NULL', + out_annotate => '(transfer full)', + get_value_func => '$var = g_value_get_param ($value)', + dup_value_func => '$var = g_value_dup_param ($value)', + set_value_func => 'g_value_set_param ($value, $var)', + take_value_func => 'g_value_take_param ($value, $var)' }, + # Special cases enum => { name => 'INT32', gtype => 'G_TYPE_ENUM',