[gimp] plug-ins: port script-fu to GimpPlugIn



commit 103a7e4fc38d667aa035ef6cad8218c4b03edab2
Author: Michael Natterer <mitch gimp org>
Date:   Mon Aug 12 20:11:45 2019 +0200

    plug-ins: port script-fu to GimpPlugIn
    
    This probably has some bugs, but worked flawlessly in my tests...

 plug-ins/script-fu/scheme-wrapper.c         | 853 ++++++++++++++--------------
 plug-ins/script-fu/script-fu-console.c      |  82 +--
 plug-ins/script-fu/script-fu-console.h      |   7 +-
 plug-ins/script-fu/script-fu-eval.c         |  38 +-
 plug-ins/script-fu/script-fu-eval.h         |   7 +-
 plug-ins/script-fu/script-fu-interface.c    |   6 +-
 plug-ins/script-fu/script-fu-script.c       | 309 ++++++----
 plug-ins/script-fu/script-fu-script.h       |  51 +-
 plug-ins/script-fu/script-fu-scripts.c      | 224 ++++----
 plug-ins/script-fu/script-fu-scripts.h      |  11 +-
 plug-ins/script-fu/script-fu-server.c       |  33 +-
 plug-ins/script-fu/script-fu-server.h       |  13 +-
 plug-ins/script-fu/script-fu-text-console.c |  23 +-
 plug-ins/script-fu/script-fu-text-console.h |   7 +-
 plug-ins/script-fu/script-fu.c              | 529 ++++++++++-------
 15 files changed, 1132 insertions(+), 1061 deletions(-)
---
diff --git a/plug-ins/script-fu/scheme-wrapper.c b/plug-ins/script-fu/scheme-wrapper.c
index 8860b4c882..f57471a452 100644
--- a/plug-ins/script-fu/scheme-wrapper.c
+++ b/plug-ins/script-fu/scheme-wrapper.c
@@ -62,8 +62,6 @@ static pointer  script_fu_marshal_procedure_call_strict     (scheme    *sc,
                                                              pointer    a);
 static pointer  script_fu_marshal_procedure_call_permissive (scheme    *sc,
                                                              pointer    a);
-static void     script_fu_marshal_destroy_args              (GimpParam *params,
-                                                             gint       n_params);
 
 static pointer  script_fu_register_call                     (scheme    *sc,
                                                              pointer    a);
@@ -448,8 +446,10 @@ ts_init_procedures (scheme   *sc,
                                                       script_fu_marshal_procedure_call_permissive));
   sc->vptr->setimmutable (symbol);
 
-  gimp_pdb_query (".*", ".*", ".*", ".*", ".*", ".*", ".*",
-                  &num_procs, &proc_list);
+  proc_list = gimp_pdb_query_procedures (gimp_get_pdb (),
+                                         ".*", ".*", ".*", ".*",
+                                         ".*", ".*", ".*", ".*",
+                                         &num_procs);
 
   /*  Register each procedure as a scheme func  */
   for (i = 0; i < num_procs; i++)
@@ -517,20 +517,12 @@ script_fu_marshal_procedure_call (scheme   *sc,
                                   pointer   a,
                                   gboolean  permissive)
 {
-  GimpParam       *args;
-  GimpParam       *values = NULL;
-  gint             nvalues;
+  GimpProcedure   *procedure;
+  GimpValueArray  *args;
+  GimpValueArray  *values = NULL;
   gchar           *proc_name;
-  gchar           *proc_blurb;
-  gchar           *proc_help;
-  gchar           *proc_author;
-  gchar           *proc_copyright;
-  gchar           *proc_date;
-  GimpPDBProcType  proc_type;
-  gint             nparams;
-  gint             nreturn_vals;
-  GimpParamDef    *params;
-  GimpParamDef    *return_vals;
+  GParamSpec     **arg_specs;
+  gint             n_arg_specs;
   gchar            error_str[1024];
   gint             i;
   gint             success = TRUE;
@@ -576,15 +568,9 @@ script_fu_marshal_procedure_call (scheme   *sc,
   script_fu_interface_report_cc (proc_name);
 
   /*  Attempt to fetch the procedure from the database  */
-  if (! gimp_pdb_proc_info (proc_name,
-                            &proc_blurb,
-                            &proc_help,
-                            &proc_author,
-                            &proc_copyright,
-                            &proc_date,
-                            &proc_type,
-                            &nparams, &nreturn_vals,
-                            &params, &return_vals))
+  procedure = gimp_pdb_lookup_procedure (gimp_get_pdb (), proc_name);
+
+  if (! procedure)
     {
 #ifdef DEBUG_MARSHALL
       g_printerr ("  Invalid procedure name\n");
@@ -594,21 +580,11 @@ script_fu_marshal_procedure_call (scheme   *sc,
       return foreign_error (sc, error_str, 0);
     }
 
-  /* Free the name and the description which are of no use here.  */
-  for (i = 0; i < nparams; i++)
-    {
-      g_free (params[i].name);
-      g_free (params[i].description);
-    }
-  for (i = 0; i < nreturn_vals; i++)
-    {
-      g_free (return_vals[i].name);
-      g_free (return_vals[i].description);
-    }
+  arg_specs = gimp_procedure_get_arguments (procedure, &n_arg_specs);
 
   /*  Check the supplied number of arguments  */
-  if ((nparams > 0 || ! permissive) &&
-      (sc->vptr->list_length (sc, a) - 1) != nparams)
+  if ((n_arg_specs > 0 || ! permissive) &&
+      (sc->vptr->list_length (sc, a) - 1) != n_arg_specs)
     {
 #if DEBUG_MARSHALL
       g_printerr ("  Invalid number of arguments (expected %d but received %d)",
@@ -616,21 +592,20 @@ script_fu_marshal_procedure_call (scheme   *sc,
 #endif
       g_snprintf (error_str, sizeof (error_str),
                   "Invalid number of arguments for %s (expected %d but received %d)",
-                  proc_name, nparams, (sc->vptr->list_length (sc, a) - 1));
+                  proc_name, n_arg_specs, (sc->vptr->list_length (sc, a) - 1));
       return foreign_error (sc, error_str, 0);
     }
 
   /*  Marshall the supplied arguments  */
-  if (nparams)
-    args = g_new (GimpParam, nparams);
-  else
-    args = NULL;
+  args = gimp_value_array_new (n_arg_specs);
 
-  for (i = 0; i < nparams; i++)
+  for (i = 0; i < n_arg_specs; i++)
     {
-      gint32  n_elements;
-      pointer vector;
-      gint    j;
+      GParamSpec *arg_spec = arg_specs[i];
+      GValue      value    = G_VALUE_INIT;
+      gint32      n_elements;
+      pointer     vector;
+      gint        j;
 
       a = sc->vptr->pair_cdr (a);
 
@@ -650,85 +625,104 @@ script_fu_marshal_procedure_call (scheme   *sc,
       }
 #endif
 
-      args[i].type = params[i].type;
+      g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (arg_spec));
 
-      switch (params[i].type)
+      if (G_VALUE_HOLDS_INT (&value))
         {
-        case GIMP_PDB_INT32:
-        case GIMP_PDB_DISPLAY:
-        case GIMP_PDB_IMAGE:
-        case GIMP_PDB_ITEM:
-        case GIMP_PDB_LAYER:
-        case GIMP_PDB_CHANNEL:
-        case GIMP_PDB_DRAWABLE:
-        case GIMP_PDB_SELECTION:
-        case GIMP_PDB_VECTORS:
-          if (!sc->vptr->is_number (sc->vptr->pair_car (a)))
+          if (! sc->vptr->is_number (sc->vptr->pair_car (a)))
             success = FALSE;
+
           if (success)
             {
-              args[i].data.d_int32 = sc->vptr->ivalue (sc->vptr->pair_car (a));
+              g_value_set_int (&value,
+                               sc->vptr->ivalue (sc->vptr->pair_car (a)));
 #if DEBUG_MARSHALL
               g_printerr ("      int32 arg is '%d'\n", args[i].data.d_int32);
 #endif
             }
-          break;
-
-        case GIMP_PDB_INT16:
-          if (!sc->vptr->is_number (sc->vptr->pair_car (a)))
+        }
+      else if (G_VALUE_HOLDS_UINT (&value))
+        {
+          if (! sc->vptr->is_number (sc->vptr->pair_car (a)))
             success = FALSE;
+
           if (success)
             {
-              args[i].data.d_int16 = (gint16) sc->vptr->ivalue (sc->vptr->pair_car (a));
+              g_value_set_uint (&value,
+                                sc->vptr->ivalue (sc->vptr->pair_car (a)));
 #if DEBUG_MARSHALL
-              g_printerr ("      int16 arg is '%d'\n", args[i].data.d_int16);
+              g_printerr ("      int8 arg is '%u'\n", args[i].data.d_int8);
 #endif
             }
-          break;
-
-        case GIMP_PDB_INT8:
-          if (!sc->vptr->is_number (sc->vptr->pair_car (a)))
+        }
+      else if (G_VALUE_HOLDS_DOUBLE (&value))
+        {
+          if (! sc->vptr->is_number (sc->vptr->pair_car (a)))
             success = FALSE;
+
           if (success)
             {
-              args[i].data.d_int8 = (guint8) sc->vptr->ivalue (sc->vptr->pair_car (a));
+              g_value_set_double (&value,
+                                  sc->vptr->rvalue (sc->vptr->pair_car (a)));
 #if DEBUG_MARSHALL
-              g_printerr ("      int8 arg is '%u'\n", args[i].data.d_int8);
+              g_printerr ("      float arg is '%f'\n", args[i].data.d_float);
 #endif
             }
-          break;
-
-        case GIMP_PDB_FLOAT:
-          if (!sc->vptr->is_number (sc->vptr->pair_car (a)))
+        }
+      else if (G_VALUE_HOLDS_ENUM (&value))
+        {
+          if (! sc->vptr->is_number (sc->vptr->pair_car (a)))
             success = FALSE;
+
           if (success)
             {
-              args[i].data.d_float = sc->vptr->rvalue (sc->vptr->pair_car (a));
+              g_value_set_enum (&value,
+                                sc->vptr->ivalue (sc->vptr->pair_car (a)));
 #if DEBUG_MARSHALL
-              g_printerr ("      float arg is '%f'\n", args[i].data.d_float);
+              g_printerr ("      enum arg is '%d'\n", args[i].data.d_int32);
 #endif
             }
-          break;
+        }
+      else if (G_VALUE_HOLDS_BOOLEAN (&value))
+        {
+          if (! sc->vptr->is_number (sc->vptr->pair_car (a)))
+            success = FALSE;
 
-        case GIMP_PDB_STRING:
-          if (!sc->vptr->is_string (sc->vptr->pair_car (a)))
+          if (success)
+            {
+              g_value_set_boolean (&value,
+                                   sc->vptr->ivalue (sc->vptr->pair_car (a)));
+#if DEBUG_MARSHALL
+              g_printerr ("      bool arg is '%d'\n", args[i].data.d_int32);
+#endif
+            }
+        }
+      else if (G_VALUE_HOLDS_STRING (&value))
+        {
+          if (! sc->vptr->is_string (sc->vptr->pair_car (a)))
             success = FALSE;
+
           if (success)
             {
-              args[i].data.d_string = sc->vptr->string_value (sc->vptr->pair_car (a));
+              g_value_set_string (&value,
+                                  sc->vptr->string_value (sc->vptr->pair_car (a)));
 #if DEBUG_MARSHALL
               g_printerr ("      string arg is '%s'\n", args[i].data.d_string);
 #endif
             }
-          break;
-
-        case GIMP_PDB_INT32ARRAY:
+        }
+      else if (GIMP_VALUE_HOLDS_INT32_ARRAY (&value))
+        {
           vector = sc->vptr->pair_car (a);
-          if (!sc->vptr->is_vector (vector))
+          if (! sc->vptr->is_vector (vector))
             success = FALSE;
+
           if (success)
             {
-              n_elements = args[i-1].data.d_int32;
+              gint32 *array;
+
+              n_elements = g_value_get_int (gimp_value_array_index (args, i - 1));
+
               if (n_elements < 0 ||
                   n_elements > sc->vptr->vector_length (vector))
                 {
@@ -740,25 +734,27 @@ script_fu_marshal_procedure_call (scheme   *sc,
                   return foreign_error (sc, error_str, 0);
                 }
 
-              args[i].data.d_int32array = g_new (gint32, n_elements);
+              array = g_new0 (gint32, n_elements);
 
               for (j = 0; j < n_elements; j++)
                 {
                   pointer v_element = sc->vptr->vector_elem (vector, j);
 
                   /* FIXME: Check values in vector stay within range for each type. */
-                  if (!sc->vptr->is_number (v_element))
+                  if (! sc->vptr->is_number (v_element))
                     {
                       g_snprintf (error_str, sizeof (error_str),
                                   "Item %d in vector is not a number (argument %d for function %s)",
                                   j+1, i+1, proc_name);
+                      g_free (array);
                       return foreign_error (sc, error_str, vector);
                     }
 
-                  args[i].data.d_int32array[j] =
-                      (gint32) sc->vptr->ivalue (v_element);
+                  array[j] = (gint32) sc->vptr->ivalue (v_element);
                 }
 
+              gimp_value_take_int32_array (&value, array, n_elements);
+
 #if DEBUG_MARSHALL
               {
                 glong count = sc->vptr->vector_length (vector);
@@ -774,16 +770,21 @@ script_fu_marshal_procedure_call (scheme   *sc,
               }
 #endif
             }
-          break;
-
-        case GIMP_PDB_INT16ARRAY:
+        }
+      else if (GIMP_VALUE_HOLDS_INT16_ARRAY (&value))
+        {
           vector = sc->vptr->pair_car (a);
-          if (!sc->vptr->is_vector (vector))
+          if (! sc->vptr->is_vector (vector))
             success = FALSE;
+
           if (success)
             {
-              n_elements = args[i-1].data.d_int32;
-              if (n_elements < 0 || n_elements > sc->vptr->vector_length (vector))
+              gint16 *array;
+
+              n_elements = g_value_get_int (gimp_value_array_index (args, i - 1));
+
+              if (n_elements < 0 ||
+                  n_elements > sc->vptr->vector_length (vector))
                 {
                   g_snprintf (error_str, sizeof (error_str),
                               "INT16 vector (argument %d) for function %s has "
@@ -792,24 +793,26 @@ script_fu_marshal_procedure_call (scheme   *sc,
                   return foreign_error (sc, error_str, 0);
                 }
 
-              args[i].data.d_int16array = g_new (gint16, n_elements);
+              array = g_new0 (gint16, n_elements);
 
               for (j = 0; j < n_elements; j++)
                 {
                   pointer v_element = sc->vptr->vector_elem (vector, j);
 
-                  if (!sc->vptr->is_number (v_element))
+                  if (! sc->vptr->is_number (v_element))
                     {
                       g_snprintf (error_str, sizeof (error_str),
                                   "Item %d in vector is not a number (argument %d for function %s)",
                                   j+1, i+1, proc_name);
+                      g_free (array);
                       return foreign_error (sc, error_str, vector);
                     }
 
-                  args[i].data.d_int16array[j] =
-                      (gint16) sc->vptr->ivalue (v_element);
+                  array[j] = (gint16) sc->vptr->ivalue (v_element);
                 }
 
+              gimp_value_take_int16_array (&value, array, n_elements);
+
 #if DEBUG_MARSHALL
               {
                 glong count = sc->vptr->vector_length (vector);
@@ -825,15 +828,19 @@ script_fu_marshal_procedure_call (scheme   *sc,
               }
 #endif
             }
-          break;
-
-        case GIMP_PDB_INT8ARRAY:
+        }
+      else if (GIMP_VALUE_HOLDS_INT8_ARRAY (&value))
+        {
           vector = sc->vptr->pair_car (a);
-          if (!sc->vptr->is_vector (vector))
+          if (! sc->vptr->is_vector (vector))
             success = FALSE;
+
           if (success)
             {
-              n_elements = args[i-1].data.d_int32;
+              guint8 *array;
+
+              n_elements = g_value_get_int (gimp_value_array_index (args, i - 1));
+
               if (n_elements < 0 ||
                   n_elements > sc->vptr->vector_length (vector))
                 {
@@ -845,7 +852,7 @@ script_fu_marshal_procedure_call (scheme   *sc,
                   return foreign_error (sc, error_str, 0);
                 }
 
-              args[i].data.d_int8array = g_new (guint8, n_elements);
+              array = g_new0 (guint8, n_elements);
 
               for (j = 0; j < n_elements; j++)
                 {
@@ -856,13 +863,15 @@ script_fu_marshal_procedure_call (scheme   *sc,
                       g_snprintf (error_str, sizeof (error_str),
                                   "Item %d in vector is not a number (argument %d for function %s)",
                                   j+1, i+1, proc_name);
+                      g_free (array);
                       return foreign_error (sc, error_str, vector);
                     }
 
-                  args[i].data.d_int8array[j] =
-                      (guint8) sc->vptr->ivalue (v_element);
+                  array[j] = (guint8) sc->vptr->ivalue (v_element);
                 }
 
+              gimp_value_take_int8_array (&value, array, n_elements);
+
 #if DEBUG_MARSHALL
               {
                 glong count = sc->vptr->vector_length (vector);
@@ -878,15 +887,19 @@ script_fu_marshal_procedure_call (scheme   *sc,
               }
 #endif
             }
-          break;
-
-        case GIMP_PDB_FLOATARRAY:
+        }
+      else if (GIMP_VALUE_HOLDS_FLOAT_ARRAY (&value))
+        {
           vector = sc->vptr->pair_car (a);
-          if (!sc->vptr->is_vector (vector))
+          if (! sc->vptr->is_vector (vector))
             success = FALSE;
+
           if (success)
             {
-              n_elements = args[i-1].data.d_int32;
+              gdouble *array;
+
+              n_elements = g_value_get_int (gimp_value_array_index (args, i - 1));
+
               if (n_elements < 0 ||
                   n_elements > sc->vptr->vector_length (vector))
                 {
@@ -898,7 +911,7 @@ script_fu_marshal_procedure_call (scheme   *sc,
                   return foreign_error (sc, error_str, 0);
                 }
 
-              args[i].data.d_floatarray = g_new (gdouble, n_elements);
+              array = g_new0 (gdouble, n_elements);
 
               for (j = 0; j < n_elements; j++)
                 {
@@ -909,13 +922,15 @@ script_fu_marshal_procedure_call (scheme   *sc,
                       g_snprintf (error_str, sizeof (error_str),
                                   "Item %d in vector is not a number (argument %d for function %s)",
                                   j+1, i+1, proc_name);
+                      g_free (array);
                       return foreign_error (sc, error_str, vector);
                     }
 
-                  args[i].data.d_floatarray[j] =
-                      (gfloat) sc->vptr->rvalue (v_element);
+                  array[j] = (gfloat) sc->vptr->rvalue (v_element);
                 }
 
+              gimp_value_take_float_array (&value, array, n_elements);
+
 #if DEBUG_MARSHALL
               {
                 glong count = sc->vptr->vector_length (vector);
@@ -931,15 +946,19 @@ script_fu_marshal_procedure_call (scheme   *sc,
               }
 #endif
             }
-          break;
-
-        case GIMP_PDB_STRINGARRAY:
+        }
+      else if (GIMP_VALUE_HOLDS_STRING_ARRAY (&value))
+        {
           vector = sc->vptr->pair_car (a);  /* vector is pointing to a list */
-          if (!sc->vptr->is_list (sc, vector))
+          if (! sc->vptr->is_list (sc, vector))
             success = FALSE;
+
           if (success)
             {
-              n_elements = args[i - 1].data.d_int32;
+              gchar **array;
+
+              n_elements = g_value_get_int (gimp_value_array_index (args, i - 1));
+
               if (n_elements < 0 ||
                   n_elements > sc->vptr->list_length (sc, vector))
                 {
@@ -951,7 +970,7 @@ script_fu_marshal_procedure_call (scheme   *sc,
                   return foreign_error (sc, error_str, 0);
                 }
 
-              args[i].data.d_stringarray = g_new (gchar *, n_elements);
+              array = g_new0 (gchar *, n_elements + 1);
 
               for (j = 0; j < n_elements; j++)
                 {
@@ -962,15 +981,17 @@ script_fu_marshal_procedure_call (scheme   *sc,
                       g_snprintf (error_str, sizeof (error_str),
                                   "Item %d in vector is not a string (argument %d for function %s)",
                                   j+1, i+1, proc_name);
+                      g_strfreev (array);
                       return foreign_error (sc, error_str, vector);
                     }
 
-                  args[i].data.d_stringarray[j] =
-                      (gchar *) sc->vptr->string_value (v_element);
+                  array[j] = g_strdup (sc->vptr->string_value (v_element));
 
                   vector = sc->vptr->pair_cdr (vector);
                 }
 
+              gimp_value_take_string_array (&value, array, n_elements);
+
 #if DEBUG_MARSHALL
               {
                 glong count = sc->vptr->list_length ( sc, sc->vptr->pair_car (a) );
@@ -986,17 +1007,19 @@ script_fu_marshal_procedure_call (scheme   *sc,
               }
 #endif
             }
-          break;
+        }
+      else if (GIMP_VALUE_HOLDS_RGB (&value))
+        {
+          GimpRGB color;
 
-        case GIMP_PDB_COLOR:
           if (sc->vptr->is_string (sc->vptr->pair_car (a)))
             {
-              if (! gimp_rgb_parse_css (&args[i].data.d_color,
+              if (! gimp_rgb_parse_css (&color,
                                         sc->vptr->string_value (sc->vptr->pair_car (a)),
                                         -1))
                 success = FALSE;
 
-              gimp_rgb_set_alpha (&args[i].data.d_color, 1.0);
+              gimp_rgb_set_alpha (&color, 1.0);
 #if DEBUG_MARSHALL
               g_printerr ("      (%s)\n",
                           sc->vptr->string_value (sc->vptr->pair_car (a)));
@@ -1030,7 +1053,10 @@ script_fu_marshal_procedure_call (scheme   *sc,
                 success = FALSE;
 
               if (success)
-                gimp_rgba_set_uchar (&args[i].data.d_color, r, g, b, 255);
+                {
+                  gimp_rgba_set_uchar (&color, r, g, b, 255);
+                  gimp_value_set_rgb (&value, &color);
+                }
 #if DEBUG_MARSHALL
               if (success)
                 g_printerr ("      (%d %d %d)\n", r, g, b);
@@ -1042,15 +1068,19 @@ script_fu_marshal_procedure_call (scheme   *sc,
             {
               success = FALSE;
             }
-          break;
-
-        case GIMP_PDB_COLORARRAY:
+        }
+      else if (GIMP_VALUE_HOLDS_RGB_ARRAY (&value))
+        {
           vector = sc->vptr->pair_car (a);
-          if (!sc->vptr->is_vector (vector))
+          if (! sc->vptr->is_vector (vector))
             success = FALSE;
+
           if (success)
             {
-              n_elements = args[i-1].data.d_int32;
+              GimpRGB *array;
+
+              n_elements = g_value_get_int (gimp_value_array_index (args, i - 1));
+
               if (n_elements < 0 ||
                   n_elements > sc->vptr->vector_length (vector))
                 {
@@ -1062,7 +1092,7 @@ script_fu_marshal_procedure_call (scheme   *sc,
                   return foreign_error (sc, error_str, 0);
                 }
 
-              args[i].data.d_colorarray = g_new (GimpRGB, n_elements);
+              array = g_new0 (GimpRGB, n_elements);
 
               for (j = 0; j < n_elements; j++)
                 {
@@ -1079,6 +1109,7 @@ script_fu_marshal_procedure_call (scheme   *sc,
                                   "Item %d in vector is not a color "
                                   "(argument %d for function %s)",
                                   j+1, i+1, proc_name);
+                      g_free (array);
                       return foreign_error (sc, error_str, vector);
                     }
 
@@ -1092,9 +1123,11 @@ script_fu_marshal_procedure_call (scheme   *sc,
                   b = CLAMP (sc->vptr->ivalue (sc->vptr->pair_car (color_list)),
                              0, 255);
 
-                  gimp_rgba_set_uchar (&args[i].data.d_colorarray[j],
-                                       r, g, b, 255);
+                  gimp_rgba_set_uchar (&array[i], r, g, b, 255);
                 }
+
+              gimp_value_take_rgb_array (&value, array, n_elements);
+
 #if DEBUG_MARSHALL
               {
                 glong count = sc->vptr->vector_length (vector);
@@ -1102,26 +1135,28 @@ script_fu_marshal_procedure_call (scheme   *sc,
               }
 #endif
             }
-          break;
-
-        case GIMP_PDB_PARASITE:
-          if (!sc->vptr->is_list (sc, sc->vptr->pair_car (a)) ||
+        }
+      else if (GIMP_VALUE_HOLDS_PARASITE (&value))
+        {
+          if (! sc->vptr->is_list (sc, sc->vptr->pair_car (a)) ||
               sc->vptr->list_length (sc, sc->vptr->pair_car (a)) != 3)
             success = FALSE;
+
           if (success)
             {
-              pointer temp_val;
+              GimpParasite parasite;
+              pointer      temp_val;
 
               /* parasite->name */
               temp_val = sc->vptr->pair_car (a);
 
-              if (!sc->vptr->is_string (sc->vptr->pair_car (temp_val)))
+              if (! sc->vptr->is_string (sc->vptr->pair_car (temp_val)))
                 {
                   success = FALSE;
                   break;
                 }
 
-              args[i].data.d_parasite.name =
+              parasite.name =
                 sc->vptr->string_value (sc->vptr->pair_car (temp_val));
 #if DEBUG_MARSHALL
               g_printerr ("      name '%s'\n", args[i].data.d_parasite.name);
@@ -1130,13 +1165,13 @@ script_fu_marshal_procedure_call (scheme   *sc,
               /* parasite->flags */
               temp_val = sc->vptr->pair_cdr (temp_val);
 
-              if (!sc->vptr->is_number (sc->vptr->pair_car (temp_val)))
+              if (! sc->vptr->is_number (sc->vptr->pair_car (temp_val)))
                 {
                   success = FALSE;
                   break;
                 }
 
-              args[i].data.d_parasite.flags =
+              parasite.flags =
                 sc->vptr->ivalue (sc->vptr->pair_car (temp_val));
 #if DEBUG_MARSHALL
               g_printerr ("      flags %d", args[i].data.d_parasite.flags);
@@ -1151,33 +1186,38 @@ script_fu_marshal_procedure_call (scheme   *sc,
                   break;
                 }
 
-              args[i].data.d_parasite.data =
+              parasite.data =
                 sc->vptr->string_value (sc->vptr->pair_car (temp_val));
-              args[i].data.d_parasite.size = strlen (args[i].data.d_parasite.data);
+              parasite.size = strlen (parasite.data);
 
 #if DEBUG_MARSHALL
               g_printerr (", size %d\n", args[i].data.d_parasite.size);
               g_printerr ("      data '%s'\n", (char *)args[i].data.d_parasite.data);
 #endif
-            }
-          break;
 
-        case GIMP_PDB_STATUS:
+              g_value_set_boxed (&value, &parasite);
+            }
+        }
+      else if (G_VALUE_TYPE (&value) == GIMP_TYPE_PDB_STATUS_TYPE)
+        {
           return foreign_error (sc,
                                 "Status is for return types, not arguments",
                                 sc->vptr->pair_car (a));
-          break;
-
-        default:
+        }
+      else
+        {
           g_snprintf (error_str, sizeof (error_str),
-                      "Argument %d for %s is an unknown type",
-                      i+1, proc_name);
+                      "Argument %d for %s is an unknown type %s",
+                      i+1, proc_name, g_type_name (G_VALUE_TYPE (&value)));
           return foreign_error (sc, error_str, 0);
         }
 
       /* Break out of loop before i gets updated when error was detected */
       if (! success)
         break;
+
+      gimp_value_array_append (args, &value);
+      g_value_unset (&value);
     }
 
   if (success)
@@ -1190,7 +1230,8 @@ script_fu_marshal_procedure_call (scheme   *sc,
 #if DEBUG_MARSHALL
           g_printerr ("    calling %s...", proc_name);
 #endif
-          values = gimp_run_procedure2 (proc_name, &nvalues, nparams, args);
+          values = gimp_pdb_run_procedure_array (gimp_get_pdb (),
+                                                 proc_name, args);
 #if DEBUG_MARSHALL
           g_printerr ("  done.\n");
 #endif
@@ -1231,14 +1272,16 @@ script_fu_marshal_procedure_call (scheme   *sc,
   }
 #endif
 
-  switch (values[0].data.d_status)
+  switch (g_value_get_enum (gimp_value_array_index (values, 0)))
     {
     case GIMP_PDB_EXECUTION_ERROR:
-      if (nvalues > 1 && values[1].type == GIMP_PDB_STRING)
+      if (gimp_value_array_length (values) > 1 &&
+          G_VALUE_HOLDS_STRING (gimp_value_array_index (values, 1)))
         {
           g_snprintf (error_str, sizeof (error_str),
                       "Procedure execution of %s failed: %s",
-                      proc_name, values[1].data.d_string);
+                      proc_name,
+                      g_value_get_string (gimp_value_array_index (values, 1)));
         }
       else
         {
@@ -1250,11 +1293,13 @@ script_fu_marshal_procedure_call (scheme   *sc,
       break;
 
     case GIMP_PDB_CALLING_ERROR:
-      if (nvalues > 1 && values[1].type == GIMP_PDB_STRING)
+      if (gimp_value_array_length (values) > 1 &&
+          G_VALUE_HOLDS_STRING (gimp_value_array_index (values, 1)))
         {
           g_snprintf (error_str, sizeof (error_str),
                       "Procedure execution of %s failed on invalid input arguments: %s",
-                      proc_name, values[1].data.d_string);
+                      proc_name,
+                      g_value_get_string (gimp_value_array_index (values, 1)));
         }
       else
         {
@@ -1269,10 +1314,10 @@ script_fu_marshal_procedure_call (scheme   *sc,
 #if DEBUG_MARSHALL
       g_printerr ("    values returned: %d\n", nvalues-1);
 #endif
-      for (i = nvalues - 2; i >= 0; --i)
+      for (i = gimp_value_array_length (values) - 2; i >= 0; --i)
         {
-          const gchar *string;
-          gint         j;
+          GValue *value = gimp_value_array_index (values, i + 1);
+          gint    j;
 
 #if DEBUG_MARSHALL
           {
@@ -1286,234 +1331,236 @@ script_fu_marshal_procedure_call (scheme   *sc,
                         i, type_name, return_vals[i].type);
           }
 #endif
-          switch (return_vals[i].type)
+          if (G_VALUE_HOLDS_INT (value))
             {
-            case GIMP_PDB_INT32:
-            case GIMP_PDB_DISPLAY:
-            case GIMP_PDB_IMAGE:
-            case GIMP_PDB_ITEM:
-            case GIMP_PDB_LAYER:
-            case GIMP_PDB_CHANNEL:
-            case GIMP_PDB_DRAWABLE:
-            case GIMP_PDB_SELECTION:
-            case GIMP_PDB_VECTORS:
-              return_val = sc->vptr->cons (sc,
-                             sc->vptr->mk_integer (sc,
-                                                   values[i + 1].data.d_int32),
-                             return_val);
-              break;
-
-            case GIMP_PDB_INT16:
-              return_val = sc->vptr->cons (sc,
-                             sc->vptr->mk_integer (sc,
-                                                   values[i + 1].data.d_int16),
-                             return_val);
-              break;
-
-            case GIMP_PDB_INT8:
-              return_val = sc->vptr->cons (sc,
-                             sc->vptr->mk_integer (sc,
-                                                   values[i + 1].data.d_int8),
-                             return_val);
-              break;
-
-            case GIMP_PDB_FLOAT:
-              return_val = sc->vptr->cons (sc,
-                             sc->vptr->mk_real (sc,
-                                                values[i + 1].data.d_float),
-                             return_val);
-              break;
+              gint v = g_value_get_int (value);
 
-            case GIMP_PDB_STRING:
-              string = values[i + 1].data.d_string;
-              if (! string)
-                string = "";
-              return_val = sc->vptr->cons (sc,
-                             sc->vptr->mk_string (sc, string),
-                             return_val);
-              break;
-
-            case GIMP_PDB_INT32ARRAY:
-              {
-                gint32  num_int32s = values[i].data.d_int32;
-                gint32 *array      = (gint32 *) values[i + 1].data.d_int32array;
-                pointer vector     = sc->vptr->mk_vector (sc, num_int32s);
-
-                for (j = 0; j < num_int32s; j++)
-                  {
-                    sc->vptr->set_vector_elem (vector, j,
-                                               sc->vptr->mk_integer (sc,
-                                                                     array[j]));
-                  }
+              return_val = sc->vptr->cons (sc, sc->vptr->mk_integer (sc, v),
+                                           return_val);
+            }
+          else if (G_VALUE_HOLDS_UINT (value))
+            {
+              guint v = g_value_get_uint (value);
 
-                return_val = sc->vptr->cons (sc, vector, return_val);
-              }
-              break;
+              return_val = sc->vptr->cons (sc, sc->vptr->mk_integer (sc, v),
+                                           return_val);
+            }
+          else if (G_VALUE_HOLDS_DOUBLE (value))
+            {
+              gdouble v = g_value_get_double (value);
 
-            case GIMP_PDB_INT16ARRAY:
-              {
-                gint32  num_int16s = values[i].data.d_int32;
-                gint16 *array      = (gint16 *) values[i + 1].data.d_int16array;
-                pointer vector     = sc->vptr->mk_vector (sc, num_int16s);
+              return_val = sc->vptr->cons (sc, sc->vptr->mk_real (sc, v),
+                                           return_val);
+            }
+          else if (G_VALUE_HOLDS_ENUM (value))
+            {
+              gint v = g_value_get_enum (value);
 
-                for (j = 0; j < num_int16s; j++)
-                  {
-                    sc->vptr->set_vector_elem (vector, j,
-                                               sc->vptr->mk_integer (sc,
-                                                                     array[j]));
-                  }
+              return_val = sc->vptr->cons (sc, sc->vptr->mk_integer (sc, v),
+                                           return_val);
+            }
+          else if (G_VALUE_HOLDS_BOOLEAN (value))
+            {
+              gboolean v = g_value_get_boolean (value);
 
-                return_val = sc->vptr->cons (sc, vector, return_val);
-              }
-              break;
+              return_val = sc->vptr->cons (sc, sc->vptr->mk_integer (sc, v),
+                                           return_val);
+            }
+          else if (G_VALUE_HOLDS_STRING (value))
+            {
+              const gchar *v = g_value_get_string (value);
 
-            case GIMP_PDB_INT8ARRAY:
-              {
-                gint32  num_int8s = values[i].data.d_int32;
-                guint8 *array     = (guint8 *) values[i + 1].data.d_int8array;
-                pointer vector    = sc->vptr->mk_vector (sc, num_int8s);
+              if (! v)
+                v = "";
 
-                for (j = 0; j < num_int8s; j++)
-                  {
-                    sc->vptr->set_vector_elem (vector, j,
-                                               sc->vptr->mk_integer (sc,
-                                                                     array[j]));
-                  }
+              return_val = sc->vptr->cons (sc, sc->vptr->mk_string (sc, v),
+                                           return_val);
+            }
+          else if (GIMP_VALUE_HOLDS_INT32_ARRAY (value))
+            {
+              gint32        n      = g_value_get_int
+                                       (gimp_value_array_index (values, i));
+              const gint32 *v      = gimp_value_get_int32_array (value);
+              pointer       vector = sc->vptr->mk_vector (sc, n);
 
-                return_val = sc->vptr->cons (sc, vector, return_val);
-              }
-              break;
+              for (j = 0; j < n; j++)
+                {
+                  sc->vptr->set_vector_elem (vector, j,
+                                             sc->vptr->mk_integer (sc, v[j]));
+                }
 
-            case GIMP_PDB_FLOATARRAY:
-              {
-                gint32   num_floats = values[i].data.d_int32;
-                gdouble *array      = (gdouble *) values[i + 1].data.d_floatarray;
-                pointer  vector     = sc->vptr->mk_vector (sc, num_floats);
+              return_val = sc->vptr->cons (sc, vector, return_val);
+            }
+          else if (GIMP_VALUE_HOLDS_INT16_ARRAY (value))
+            {
+              gint32        n      = g_value_get_int
+                                       (gimp_value_array_index (values, i));
+              const gint16 *v      = gimp_value_get_int16_array (value);
+              pointer       vector = sc->vptr->mk_vector (sc, n);
 
-                for (j = 0; j < num_floats; j++)
-                  {
-                    sc->vptr->set_vector_elem (vector, j,
-                                               sc->vptr->mk_real (sc,
-                                                                  array[j]));
-                  }
+              for (j = 0; j < n; j++)
+                {
+                  sc->vptr->set_vector_elem (vector, j,
+                                             sc->vptr->mk_integer (sc, v[j]));
+                }
 
-                return_val = sc->vptr->cons (sc, vector, return_val);
-              }
-              break;
+              return_val = sc->vptr->cons (sc, vector, return_val);
+            }
+          else if (GIMP_VALUE_HOLDS_INT8_ARRAY (value))
+            {
+              gint32        n      = g_value_get_int
+                                       (gimp_value_array_index (values, i));
+              const guint8 *v      = gimp_value_get_int8_array (value);
+              pointer       vector = sc->vptr->mk_vector (sc, n);
 
-            case GIMP_PDB_STRINGARRAY:
-              {
-                gint    num_strings = values[i].data.d_int32;
-                gchar **array       = (gchar **) values[i + 1].data.d_stringarray;
-                pointer list        = sc->NIL;
+              for (j = 0; j < n; j++)
+                {
+                  sc->vptr->set_vector_elem (vector, j,
+                                             sc->vptr->mk_integer (sc, v[j]));
+                }
 
-                for (j = num_strings - 1; j >= 0; j--)
-                  {
-                    list = sc->vptr->cons (sc,
-                                           sc->vptr->mk_string (sc,
-                                                                array[j] ?
-                                                                array[j] : ""),
-                                           list);
-                  }
+              return_val = sc->vptr->cons (sc, vector, return_val);
+            }
+          else if (GIMP_VALUE_HOLDS_FLOAT_ARRAY (value))
+            {
+              gint32         n      = g_value_get_int
+                                        (gimp_value_array_index (values, i));
+              const gdouble *v      = gimp_value_get_float_array (value);
+              pointer        vector = sc->vptr->mk_vector (sc, n);
 
-                return_val = sc->vptr->cons (sc, list, return_val);
-              }
-              break;
+              for (j = 0; j < n; j++)
+                {
+                  sc->vptr->set_vector_elem (vector, j,
+                                             sc->vptr->mk_real (sc, v[j]));
+                }
 
-            case GIMP_PDB_COLOR:
-              {
-                guchar   r, g, b;
-                gpointer temp_val;
+              return_val = sc->vptr->cons (sc, vector, return_val);
+            }
+          else if (GIMP_VALUE_HOLDS_STRING_ARRAY (value))
+            {
+              gint32         n    = g_value_get_int
+                                      (gimp_value_array_index (values, i));
+              const gchar  **v    = gimp_value_get_string_array (value);
+              pointer        list = sc->NIL;
 
-                gimp_rgb_get_uchar (&values[i + 1].data.d_color, &r, &g, &b);
+              for (j = n - 1; j >= 0; j--)
+                {
+                  list = sc->vptr->cons (sc,
+                                         sc->vptr->mk_string (sc,
+                                                              v[j] ?
+                                                              v[j] : ""),
+                                         list);
+                }
 
-                temp_val = sc->vptr->cons (sc,
-                             sc->vptr->mk_integer (sc, r),
-                             sc->vptr->cons (sc,
+              return_val = sc->vptr->cons (sc, list, return_val);
+            }
+          else if (GIMP_VALUE_HOLDS_RGB (value))
+            {
+              GimpRGB  v;
+              guchar   r, g, b;
+              gpointer temp_val;
+
+              gimp_value_get_rgb (value, &v);
+              gimp_rgb_get_uchar (&v, &r, &g, &b);
+
+              temp_val = sc->vptr->cons
+                           (sc,
+                            sc->vptr->mk_integer (sc, r),
+                            sc->vptr->cons
+                              (sc,
                                sc->vptr->mk_integer (sc, g),
-                               sc->vptr->cons (sc,
-                                 sc->vptr->mk_integer (sc, b),
-                                 sc->NIL)));
-                return_val = sc->vptr->cons (sc,
-                                             temp_val,
-                                             return_val);
-                break;
-              }
-
-            case GIMP_PDB_COLORARRAY:
-              {
-                gint32   num_colors = values[i].data.d_int32;
-                GimpRGB *array      = (GimpRGB *) values[i + 1].data.d_colorarray;
-                pointer  vector     = sc->vptr->mk_vector (sc, num_colors);
+                               sc->vptr->cons
+                                 (sc,
+                                  sc->vptr->mk_integer (sc, b),
+                                  sc->NIL)));
 
-                for (j = 0; j < num_colors; j++)
-                  {
-                    guchar  r, g, b;
-                    pointer temp_val;
-
-                    gimp_rgb_get_uchar (&array[j], &r, &g, &b);
+              return_val = sc->vptr->cons (sc,
+                                           temp_val,
+                                           return_val);
+            }
+          else if (GIMP_VALUE_HOLDS_RGB_ARRAY (value))
+            {
+              gint32          n    = g_value_get_int
+                                       (gimp_value_array_index (values, i));
+              const GimpRGB  *v = gimp_value_get_rgb_array (value);
+              pointer  vector   = sc->vptr->mk_vector (sc, n);
 
-                    temp_val = sc->vptr->cons (sc,
-                                 sc->vptr->mk_integer (sc, r),
-                                 sc->vptr->cons (sc,
-                                   sc->vptr->mk_integer (sc, g),
-                                   sc->vptr->cons (sc,
+              for (j = 0; j < n; j++)
+                {
+                  guchar  r, g, b;
+                  pointer temp_val;
+
+                  gimp_rgb_get_uchar (&v[j], &r, &g, &b);
+
+                  temp_val = sc->vptr->cons
+                              (sc,
+                               sc->vptr->mk_integer (sc, r),
+                               sc->vptr->cons
+                                 (sc,
+                                  sc->vptr->mk_integer (sc, g),
+                                  sc->vptr->cons
+                                    (sc,
                                      sc->vptr->mk_integer (sc, b),
                                      sc->NIL)));
-                    sc->vptr->set_vector_elem (vector, j, temp_val);
-                  }
+                  sc->vptr->set_vector_elem (vector, j, temp_val);
+                }
 
-                return_val = sc->vptr->cons (sc, vector, return_val);
-              }
-              break;
+              return_val = sc->vptr->cons (sc, vector, return_val);
+            }
+          else if (GIMP_VALUE_HOLDS_PARASITE (value))
+            {
+              GimpParasite *v = g_value_get_boxed (value);
 
-            case GIMP_PDB_PARASITE:
-              {
-                if (values[i + 1].data.d_parasite.name == NULL)
-                  {
-                    return_val = foreign_error (sc, "Error: null parasite", 0);
-                  }
-                else
-                  {
-                    GimpParasite *p = &values[i + 1].data.d_parasite;
-                    gchar        *data = g_strndup (p->data, p->size);
-                    gint          char_cnt = g_utf8_strlen (data, p->size);
-                    pointer       temp_val;
-
-                    /* don't move the mk_foo() calls outside this function call,
-                     * otherwise they might be garbage collected away!
-                     */
-                    temp_val = sc->vptr->cons (sc,
-                                 sc->vptr->mk_string (sc, p->name),
-                                 sc->vptr->cons (sc,
-                                   sc->vptr->mk_integer (sc, p->flags),
-                                   sc->vptr->cons (sc,
-                                     sc->vptr->mk_counted_string (sc,
-                                                                  data,
-                                                                  char_cnt),
-                                     sc->NIL)));
-                    return_val = sc->vptr->cons (sc,
-                                                 temp_val,
-                                                 return_val);
-                    g_free (data);
+              if (v->name == NULL)
+                {
+                  return_val = foreign_error (sc, "Error: null parasite", 0);
+                }
+              else
+                {
+                  gchar   *data = g_strndup (v->data, v->size);
+                  gint     char_cnt = g_utf8_strlen (data, v->size);
+                  pointer  temp_val;
+
+                  /* don't move the mk_foo() calls outside this function call,
+                   * otherwise they might be garbage collected away!
+                   */
+                  temp_val = sc->vptr->cons
+                               (sc,
+                                sc->vptr->mk_string (sc, v->name),
+                                sc->vptr->cons
+                                  (sc,
+                                   sc->vptr->mk_integer (sc, v->flags),
+                                   sc->vptr->cons
+                                     (sc,
+                                      sc->vptr->mk_counted_string (sc,
+                                                                   data,
+                                                                   char_cnt),
+                                      sc->NIL)));
+
+                  return_val = sc->vptr->cons (sc,
+                                               temp_val,
+                                               return_val);
+                  g_free (data);
 
 #if DEBUG_MARSHALL
-                    g_printerr ("      name '%s'\n", p->name);
-                    g_printerr ("      flags %d", p->flags);
-                    g_printerr (", size %d\n", p->size);
-                    g_printerr ("      data '%.*s'\n",
+                  g_printerr ("      name '%s'\n", p->name);
+                  g_printerr ("      flags %d", p->flags);
+                  g_printerr (", size %d\n", p->size);
+                  g_printerr ("      data '%.*s'\n",
                                 p->size, (gchar *) p->data);
 #endif
-                  }
-              }
-              break;
-
-            case GIMP_PDB_STATUS:
+                }
+            }
+          else if (G_VALUE_TYPE (&value) == GIMP_TYPE_PDB_STATUS_TYPE)
+            {
               return foreign_error (sc, "Procedure execution returned multiple status values", 0);
-              break;
-
-            default:
-              return foreign_error (sc, "Unknown return type", 0);
+            }
+          else
+            {
+              g_snprintf (error_str, sizeof (error_str),
+                          "Unknown return type %s",
+                          g_type_name (G_VALUE_TYPE (value)));
+              return foreign_error (sc, error_str, 0);
             }
         }
 
@@ -1527,7 +1574,8 @@ script_fu_marshal_procedure_call (scheme   *sc,
    */
   if (return_val == sc->NIL)
     {
-      if (values[0].data.d_status == GIMP_PDB_SUCCESS)
+      if (g_value_get_enum (gimp_value_array_index (values, 0)) ==
+          GIMP_PDB_SUCCESS)
         return_val = sc->vptr->cons (sc, sc->T, sc->NIL);
       else
         return_val = sc->vptr->cons (sc, sc->F, sc->NIL);
@@ -1537,19 +1585,10 @@ script_fu_marshal_procedure_call (scheme   *sc,
   g_free (proc_name);
 
   /*  free up the executed procedure return values  */
-  gimp_destroy_params (values, nvalues);
+  gimp_value_array_unref (values);
 
   /*  free up arguments and values  */
-  script_fu_marshal_destroy_args (args, nparams);
-
-  /*  free the query information  */
-  g_free (proc_blurb);
-  g_free (proc_help);
-  g_free (proc_author);
-  g_free (proc_copyright);
-  g_free (proc_date);
-  g_free (params);
-  g_free (return_vals);
+  gimp_value_array_unref (args);
 
   /*  if we're in server mode, listen for additional commands for 10 ms  */
   if (script_fu_server_get_mode ())
@@ -1578,66 +1617,6 @@ script_fu_marshal_procedure_call_permissive (scheme  *sc,
   return script_fu_marshal_procedure_call (sc, a, TRUE);
 }
 
-static void
-script_fu_marshal_destroy_args (GimpParam *params,
-                                gint       n_params)
-{
-  gint i;
-
-  for (i = 0; i < n_params; i++)
-    {
-      switch (params[i].type)
-        {
-        case GIMP_PDB_INT32:
-        case GIMP_PDB_INT16:
-        case GIMP_PDB_INT8:
-        case GIMP_PDB_FLOAT:
-        case GIMP_PDB_STRING:
-          break;
-
-        case GIMP_PDB_INT32ARRAY:
-          g_free (params[i].data.d_int32array);
-          break;
-
-        case GIMP_PDB_INT16ARRAY:
-          g_free (params[i].data.d_int16array);
-          break;
-
-        case GIMP_PDB_INT8ARRAY:
-          g_free (params[i].data.d_int8array);
-          break;
-
-        case GIMP_PDB_FLOATARRAY:
-          g_free (params[i].data.d_floatarray);
-          break;
-
-        case GIMP_PDB_STRINGARRAY:
-          g_free (params[i].data.d_stringarray);
-          break;
-
-        case GIMP_PDB_COLORARRAY:
-          g_free (params[i].data.d_colorarray);
-          break;
-
-        case GIMP_PDB_COLOR:
-        case GIMP_PDB_DISPLAY:
-        case GIMP_PDB_IMAGE:
-        case GIMP_PDB_ITEM:
-        case GIMP_PDB_LAYER:
-        case GIMP_PDB_CHANNEL:
-        case GIMP_PDB_DRAWABLE:
-        case GIMP_PDB_SELECTION:
-        case GIMP_PDB_VECTORS:
-        case GIMP_PDB_PARASITE:
-        case GIMP_PDB_STATUS:
-        case GIMP_PDB_END:
-          break;
-        }
-    }
-
-  g_free (params);
-}
-
 static pointer
 script_fu_register_call (scheme  *sc,
                          pointer  a)
diff --git a/plug-ins/script-fu/script-fu-console.c b/plug-ins/script-fu/script-fu-console.c
index 17358810db..baa2827f0d 100644
--- a/plug-ins/script-fu/script-fu-console.c
+++ b/plug-ins/script-fu/script-fu-console.c
@@ -62,7 +62,6 @@ enum
 /*
  *  Local Functions
  */
-static void      script_fu_console_interface     (void);
 static void      script_fu_console_response      (GtkWidget        *widget,
                                                   gint              response_id,
                                                   ConsoleInterface *console);
@@ -92,27 +91,9 @@ static void      script_fu_output_to_console     (TsOutputType      type,
  *  Function definitions
  */
 
-void
-script_fu_console_run (const gchar      *name,
-                       gint              nparams,
-                       const GimpParam  *params,
-                       gint             *nreturn_vals,
-                       GimpParam       **return_vals)
-{
-  static GimpParam  values[1];
-
-  ts_set_print_flag (1);
-  script_fu_console_interface ();
-
-  *nreturn_vals = 1;
-  *return_vals  = values;
-
-  values[0].type          = GIMP_PDB_STATUS;
-  values[0].data.d_status = GIMP_PDB_SUCCESS;
-}
-
-static void
-script_fu_console_interface (void)
+GimpValueArray *
+script_fu_console_run (GimpProcedure        *procedure,
+                       const GimpValueArray *args)
 {
   ConsoleInterface  console = { 0, };
   GtkWidget        *vbox;
@@ -120,6 +101,8 @@ script_fu_console_interface (void)
   GtkWidget        *scrolled_window;
   GtkWidget        *hbox;
 
+  ts_set_print_flag (1);
+
   gimp_ui_init ("script-fu", FALSE);
 
   console.history_max = 50;
@@ -254,6 +237,8 @@ script_fu_console_interface (void)
 
   if (console.dialog)
     gtk_widget_destroy (console.dialog);
+
+  return gimp_procedure_new_return_values (procedure, GIMP_PDB_SUCCESS, NULL);
 }
 
 static void
@@ -401,20 +386,13 @@ script_fu_browse_response (GtkWidget        *widget,
                            gint              response_id,
                            ConsoleInterface *console)
 {
-  GimpProcBrowserDialog *dialog = GIMP_PROC_BROWSER_DIALOG (widget);
-  gchar                 *proc_name;
-  gchar                 *proc_blurb;
-  gchar                 *proc_help;
-  gchar                 *proc_author;
-  gchar                 *proc_copyright;
-  gchar                 *proc_date;
-  GimpPDBProcType        proc_type;
-  gint                   n_params;
-  gint                   n_return_vals;
-  GimpParamDef          *params;
-  GimpParamDef          *return_vals;
-  gint                   i;
-  GString               *text;
+  GimpProcBrowserDialog  *dialog = GIMP_PROC_BROWSER_DIALOG (widget);
+  GimpProcedure          *procedure;
+  gchar                  *proc_name;
+  GParamSpec            **pspecs;
+  gint                    n_pspecs;
+  gint                    i;
+  GString                *text;
 
   if (response_id != GTK_RESPONSE_APPLY)
     {
@@ -427,25 +405,17 @@ script_fu_browse_response (GtkWidget        *widget,
   if (proc_name == NULL)
     return;
 
-  gimp_pdb_proc_info (proc_name,
-                      &proc_blurb,
-                      &proc_help,
-                      &proc_author,
-                      &proc_copyright,
-                      &proc_date,
-                      &proc_type,
-                      &n_params,
-                      &n_return_vals,
-                      &params,
-                      &return_vals);
+  procedure = gimp_pdb_lookup_procedure (gimp_get_pdb (), proc_name);
+
+  pspecs = gimp_procedure_get_arguments (procedure, &n_pspecs);
 
   text = g_string_new ("(");
   text = g_string_append (text, proc_name);
 
-  for (i = 0; i < n_params; i++)
+  for (i = 0; i < n_pspecs; i++)
     {
       text = g_string_append_c (text, ' ');
-      text = g_string_append (text, params[i].name);
+      text = g_string_append (text, pspecs[i]->name);
     }
 
   text = g_string_append_c (text, ')');
@@ -463,14 +433,6 @@ script_fu_browse_response (GtkWidget        *widget,
   gtk_window_present (GTK_WINDOW (console->dialog));
 
   g_free (proc_name);
-  g_free (proc_blurb);
-  g_free (proc_help);
-  g_free (proc_author);
-  g_free (proc_copyright);
-  g_free (proc_date);
-
-  gimp_destroy_paramdefs (params,      n_params);
-  gimp_destroy_paramdefs (return_vals, n_return_vals);
 }
 
 static void
@@ -606,7 +568,8 @@ script_fu_cc_key_function (GtkWidget        *widget,
       output = g_string_new (NULL);
       ts_register_output_func (ts_gstring_output_func, output);
 
-      gimp_plugin_set_pdb_error_handler (GIMP_PDB_ERROR_HANDLER_PLUGIN);
+      gimp_plug_in_set_pdb_error_handler (gimp_get_plug_in (),
+                                          GIMP_PDB_ERROR_HANDLER_PLUGIN);
 
       if (ts_interpret_string (list->data) != 0)
         {
@@ -623,7 +586,8 @@ script_fu_cc_key_function (GtkWidget        *widget,
                                        console);
         }
 
-      gimp_plugin_set_pdb_error_handler (GIMP_PDB_ERROR_HANDLER_INTERNAL);
+      gimp_plug_in_set_pdb_error_handler (gimp_get_plug_in (),
+                                          GIMP_PDB_ERROR_HANDLER_INTERNAL);
 
       g_string_free (output, TRUE);
 
diff --git a/plug-ins/script-fu/script-fu-console.h b/plug-ins/script-fu/script-fu-console.h
index 8410a61dc5..2f4b31a74d 100644
--- a/plug-ins/script-fu/script-fu-console.h
+++ b/plug-ins/script-fu/script-fu-console.h
@@ -19,11 +19,8 @@
 #define __SCRIPT_FU_CONSOLE_H__
 
 
-void  script_fu_console_run (const gchar      *name,
-                             gint              nparams,
-                             const GimpParam  *params,
-                             gint             *nreturn_vals,
-                             GimpParam       **return_vals);
+GimpValueArray * script_fu_console_run (GimpProcedure        *procedure,
+                                        const GimpValueArray *args);
 
 
 #endif /*  __SCRIPT_FU_CONSOLE_H__  */
diff --git a/plug-ins/script-fu/script-fu-eval.c b/plug-ins/script-fu/script-fu-eval.c
index 6f2e354af3..b89dc4c416 100644
--- a/plug-ins/script-fu/script-fu-eval.c
+++ b/plug-ins/script-fu/script-fu-eval.c
@@ -25,24 +25,17 @@
 #include "script-fu-intl.h"
 
 
-void
-script_fu_eval_run (const gchar      *name,
-                    gint              nparams,
-                    const GimpParam  *params,
-                    gint             *nreturn_vals,
-                    GimpParam       **return_vals)
+GimpValueArray *
+script_fu_eval_run (GimpProcedure        *procedure,
+                    const GimpValueArray *args)
 {
-  static GimpParam   values[2];
   GString           *output = g_string_new (NULL);
   GimpPDBStatusType  status = GIMP_PDB_SUCCESS;
   GimpRunMode        run_mode;
+  const gchar       *code;
 
-  *nreturn_vals = 1;
-  *return_vals  = values;
-
-  values[0].type = GIMP_PDB_STATUS;
-
-  run_mode = params[0].data.d_int32;
+  run_mode = g_value_get_enum   (gimp_value_array_index (args, 0));
+  code     = g_value_get_string (gimp_value_array_index (args, 1));
 
   ts_set_run_mode (run_mode);
   ts_register_output_func (ts_gstring_output_func, output);
@@ -50,7 +43,7 @@ script_fu_eval_run (const gchar      *name,
   switch (run_mode)
     {
     case GIMP_RUN_NONINTERACTIVE:
-      if (ts_interpret_string (params[1].data.d_string) != 0)
+      if (ts_interpret_string (code) != 0)
         status = GIMP_PDB_EXECUTION_ERROR;
       break;
 
@@ -65,16 +58,15 @@ script_fu_eval_run (const gchar      *name,
       break;
     }
 
-  values[0].data.d_status = status;
-
   if (status != GIMP_PDB_SUCCESS && output->len > 0)
     {
-      *nreturn_vals = 2;
-      values[1].type          = GIMP_PDB_STRING;
-      values[1].data.d_string = g_string_free (output, FALSE);
-    }
-  else
-    {
-      g_string_free (output, TRUE);
+      GError *error = g_error_new_literal (0, 0,
+                                           g_string_free (output, FALSE));
+
+      return gimp_procedure_new_return_values (procedure, status, error);
     }
+
+  g_string_free (output, TRUE);
+
+  return gimp_procedure_new_return_values (procedure, status, NULL);
 }
diff --git a/plug-ins/script-fu/script-fu-eval.h b/plug-ins/script-fu/script-fu-eval.h
index 83ec9c4ab3..0288efe0c0 100644
--- a/plug-ins/script-fu/script-fu-eval.h
+++ b/plug-ins/script-fu/script-fu-eval.h
@@ -19,11 +19,8 @@
 #define __SCRIPT_FU_EVAL_H__
 
 
-void  script_fu_eval_run (const gchar      *name,
-                          gint              nparams,
-                          const GimpParam  *params,
-                          gint             *nreturn_vals,
-                          GimpParam       **return_vals);
+GimpValueArray * script_fu_eval_run (GimpProcedure        *procedure,
+                                     const GimpValueArray *args);
 
 
 #endif /*  __SCRIPT_FU_EVAL_H__  */
diff --git a/plug-ins/script-fu/script-fu-interface.c b/plug-ins/script-fu/script-fu-interface.c
index 687373cf7a..fe9fdaca18 100644
--- a/plug-ins/script-fu/script-fu-interface.c
+++ b/plug-ins/script-fu/script-fu-interface.c
@@ -880,7 +880,8 @@ script_fu_ok (SFScript *script)
   output = g_string_new (NULL);
   ts_register_output_func (ts_gstring_output_func, output);
 
-  gimp_plugin_set_pdb_error_handler (GIMP_PDB_ERROR_HANDLER_PLUGIN);
+  gimp_plug_in_set_pdb_error_handler (gimp_get_plug_in (),
+                                      GIMP_PDB_ERROR_HANDLER_PLUGIN);
 
   if (ts_interpret_string (command))
     {
@@ -891,7 +892,8 @@ script_fu_ok (SFScript *script)
       g_free (message);
     }
 
-  gimp_plugin_set_pdb_error_handler (GIMP_PDB_ERROR_HANDLER_INTERNAL);
+  gimp_plug_in_set_pdb_error_handler (gimp_get_plug_in (),
+                                      GIMP_PDB_ERROR_HANDLER_INTERNAL);
 
   g_string_free (output, TRUE);
 
diff --git a/plug-ins/script-fu/script-fu-script.c b/plug-ins/script-fu/script-fu-script.c
index cd37163d0d..5e67c50831 100644
--- a/plug-ins/script-fu/script-fu-script.c
+++ b/plug-ins/script-fu/script-fu-script.c
@@ -37,11 +37,10 @@
  *  Local Functions
  */
 
-static gboolean   script_fu_script_param_init (SFScript        *script,
-                                               gint             nparams,
-                                               const GimpParam *params,
-                                               SFArgType        type,
-                                               gint             n);
+static gboolean   script_fu_script_param_init (SFScript             *script,
+                                               const GimpValueArray *args,
+                                               SFArgType             type,
+                                               gint                  n);
 
 
 /*
@@ -167,162 +166,237 @@ script_fu_script_free (SFScript *script)
 }
 
 void
-script_fu_script_install_proc (SFScript    *script,
-                               GimpRunProc  run_proc)
+script_fu_script_install_proc (GimpPlugIn  *plug_in,
+                               SFScript    *script,
+                               GimpRunFunc  run_func)
 {
-  const gchar  *menu_label = NULL;
-  GimpParamDef *args;
-  gint          i;
+  GimpProcedure *procedure;
+  const gchar   *menu_label = NULL;
+  gint           i;
 
+  g_return_if_fail (GIMP_IS_PLUG_IN (plug_in));
   g_return_if_fail (script != NULL);
-  g_return_if_fail (run_proc != NULL);
+  g_return_if_fail (run_func != NULL);
 
   /* Allow scripts with no menus */
   if (strncmp (script->menu_label, "<None>", 6) != 0)
     menu_label = script->menu_label;
 
-  args = g_new0 (GimpParamDef, script->n_args + 1);
+  procedure = gimp_procedure_new (plug_in, script->name,
+                                  GIMP_TEMPORARY,
+                                  run_func, script, NULL);
 
-  args[0].type        = GIMP_PDB_INT32;
-  args[0].name        = "run-mode";
-  args[0].description = "The run mode { RUN-INTERACTIVE (0), RUN-NONINTERACTIVE (1) }";
+  gimp_procedure_set_image_types (procedure, script->image_types);
+
+  gimp_procedure_set_menu_label (procedure, menu_label);
+
+  gimp_procedure_set_documentation (procedure,
+                                    script->blurb,
+                                    NULL,
+                                    script->name);
+  gimp_procedure_set_attribution (procedure,
+                                  script->author,
+                                  script->copyright,
+                                  script->date);
+
+  gimp_procedure_add_argument (procedure,
+                               g_param_spec_enum ("run-mode",
+                                                  "Run mode",
+                                                  "The run mode",
+                                                  GIMP_TYPE_RUN_MODE,
+                                                  GIMP_RUN_INTERACTIVE,
+                                                  G_PARAM_READWRITE));
 
   for (i = 0; i < script->n_args; i++)
     {
-      GimpPDBArgType  type = 0;
-      const gchar    *name = NULL;
+      GParamSpec *pspec = NULL;
 
       switch (script->args[i].type)
         {
         case SF_IMAGE:
-          type = GIMP_PDB_IMAGE;
-          name = "image";
+          pspec = gimp_param_spec_image_id ("image",
+                                            "Image",
+                                            script->args[i].label,
+                                            TRUE,
+                                            G_PARAM_READWRITE);
           break;
 
         case SF_DRAWABLE:
-          type = GIMP_PDB_DRAWABLE;
-          name = "drawable";
+          pspec = gimp_param_spec_drawable_id ("drawable",
+                                               "Drawable",
+                                               script->args[i].label,
+                                               TRUE,
+                                               G_PARAM_READWRITE);
           break;
 
         case SF_LAYER:
-          type = GIMP_PDB_LAYER;
-          name = "layer";
+          pspec = gimp_param_spec_layer_id ("layer",
+                                            "Layer",
+                                            script->args[i].label,
+                                            TRUE,
+                                            G_PARAM_READWRITE);
           break;
 
         case SF_CHANNEL:
-          type = GIMP_PDB_CHANNEL;
-          name = "channel";
+          pspec = gimp_param_spec_channel_id ("channel",
+                                              "Channel",
+                                              script->args[i].label,
+                                              TRUE,
+                                              G_PARAM_READWRITE);
           break;
 
         case SF_VECTORS:
-          type = GIMP_PDB_VECTORS;
-          name = "vectors";
+          pspec = gimp_param_spec_vectors_id ("vectors",
+                                              "Vectors",
+                                              script->args[i].label,
+                                              TRUE,
+                                              G_PARAM_READWRITE);
           break;
 
         case SF_DISPLAY:
-          type = GIMP_PDB_DISPLAY;
-          name = "display";
+          pspec = gimp_param_spec_display_id ("display",
+                                              "Display",
+                                              script->args[i].label,
+                                              TRUE,
+                                              G_PARAM_READWRITE);
           break;
 
         case SF_COLOR:
-          type = GIMP_PDB_COLOR;
-          name = "color";
+          pspec = gimp_param_spec_rgb ("color",
+                                       "Color",
+                                       script->args[i].label,
+                                       TRUE, NULL,
+                                       G_PARAM_READWRITE);
           break;
 
         case SF_TOGGLE:
-          type = GIMP_PDB_INT32;
-          name = "toggle";
+          pspec = g_param_spec_boolean ("toggle",
+                                        "Toggle",
+                                        script->args[i].label,
+                                        FALSE,
+                                        G_PARAM_READWRITE);
           break;
 
         case SF_VALUE:
-          type = GIMP_PDB_STRING;
-          name = "value";
+          pspec = g_param_spec_string ("value",
+                                       "Value",
+                                       script->args[i].label,
+                                       NULL,
+                                       G_PARAM_READWRITE);
           break;
 
         case SF_STRING:
         case SF_TEXT:
-          type = GIMP_PDB_STRING;
-          name = "string";
+          pspec = g_param_spec_string ("string",
+                                       "String",
+                                       script->args[i].label,
+                                       NULL,
+                                       G_PARAM_READWRITE);
           break;
 
         case SF_ADJUSTMENT:
-          type = GIMP_PDB_FLOAT;
-          name = "value";
+          pspec = g_param_spec_double ("value",
+                                       "Value",
+                                       script->args[i].label,
+                                       -G_MAXDOUBLE, G_MAXDOUBLE, 0,
+                                       G_PARAM_READWRITE);
           break;
 
         case SF_FILENAME:
-          type = GIMP_PDB_STRING;
-          name = "filename";
+          pspec = gimp_param_spec_string ("filename",
+                                          "Filename",
+                                          script->args[i].label,
+                                          TRUE, TRUE, FALSE,
+                                          NULL,
+                                          G_PARAM_READWRITE);
           break;
 
         case SF_DIRNAME:
-          type = GIMP_PDB_STRING;
-          name = "dirname";
+          pspec = gimp_param_spec_string ("dirname",
+                                          "Dirname",
+                                          script->args[i].label,
+                                          TRUE, TRUE, FALSE,
+                                          NULL,
+                                          G_PARAM_READWRITE);
           break;
 
         case SF_FONT:
-          type = GIMP_PDB_STRING;
-          name = "font";
+          pspec = gimp_param_spec_string ("Font",
+                                          "font",
+                                          script->args[i].label,
+                                          FALSE, TRUE, FALSE,
+                                          NULL,
+                                          G_PARAM_READWRITE);
           break;
 
         case SF_PALETTE:
-          type = GIMP_PDB_STRING;
-          name = "palette";
+          pspec = gimp_param_spec_string ("palette",
+                                          "Palette",
+                                          script->args[i].label,
+                                          FALSE, TRUE, FALSE,
+                                          NULL,
+                                          G_PARAM_READWRITE);
           break;
 
         case SF_PATTERN:
-          type = GIMP_PDB_STRING;
-          name = "pattern";
+          pspec = gimp_param_spec_string ("pattern",
+                                          "Pattern",
+                                          script->args[i].label,
+                                          FALSE, TRUE, FALSE,
+                                          NULL,
+                                          G_PARAM_READWRITE);
           break;
 
         case SF_BRUSH:
-          type = GIMP_PDB_STRING;
-          name = "brush";
+          pspec = gimp_param_spec_string ("brush",
+                                          "Brush",
+                                          script->args[i].label,
+                                          FALSE, TRUE, FALSE,
+                                          NULL,
+                                          G_PARAM_READWRITE);
           break;
 
         case SF_GRADIENT:
-          type = GIMP_PDB_STRING;
-          name = "gradient";
+          pspec = gimp_param_spec_string ("gradient",
+                                          "Gradient",
+                                          script->args[i].label,
+                                          FALSE, TRUE, FALSE,
+                                          NULL,
+                                          G_PARAM_READWRITE);
           break;
 
         case SF_OPTION:
-          type = GIMP_PDB_INT32;
-          name = "option";
+          pspec = g_param_spec_int ("option",
+                                    "Option",
+                                    script->args[i].label,
+                                    G_MININT, G_MAXINT, 0,
+                                    G_PARAM_READWRITE);
           break;
 
         case SF_ENUM:
-          type = GIMP_PDB_INT32;
-          name = "enum";
+          pspec = g_param_spec_int ("enum",
+                                    "Enum",
+                                    script->args[i].label,
+                                    G_MININT, G_MAXINT, 0,
+                                    G_PARAM_READWRITE);
           break;
         }
 
-      args[i + 1].type        = type;
-      args[i + 1].name        = (gchar *) name;
-      args[i + 1].description = script->args[i].label;
+      gimp_procedure_add_argument (procedure, pspec);
     }
 
-  gimp_install_temp_proc (script->name,
-                          script->blurb,
-                          "",
-                          script->author,
-                          script->copyright,
-                          script->date,
-                          menu_label,
-                          script->image_types,
-                          GIMP_TEMPORARY,
-                          script->n_args + 1, 0,
-                          args, NULL,
-                          run_proc);
-
-  g_free (args);
+  gimp_plug_in_add_temp_procedure (plug_in, procedure);
+  g_object_unref (procedure);
 }
 
 void
-script_fu_script_uninstall_proc (SFScript *script)
+script_fu_script_uninstall_proc (GimpPlugIn *plug_in,
+                                 SFScript   *script)
 {
+  g_return_if_fail (GIMP_IS_PLUG_IN (plug_in));
   g_return_if_fail (script != NULL);
 
-  gimp_uninstall_temp_proc (script->name);
+  gimp_plug_in_remove_temp_procedure (plug_in, script->name);
 }
 
 gchar *
@@ -447,9 +521,8 @@ script_fu_script_reset (SFScript *script,
 }
 
 gint
-script_fu_script_collect_standard_args (SFScript        *script,
-                                        gint             n_params,
-                                        const GimpParam *params)
+script_fu_script_collect_standard_args (SFScript             *script,
+                                        const GimpValueArray *args)
 {
   gint params_consumed = 0;
 
@@ -457,7 +530,7 @@ script_fu_script_collect_standard_args (SFScript        *script,
 
   /*  the first parameter may be a DISPLAY id  */
   if (script_fu_script_param_init (script,
-                                   n_params, params, SF_DISPLAY,
+                                   args, SF_DISPLAY,
                                    params_consumed))
     {
       params_consumed++;
@@ -465,7 +538,7 @@ script_fu_script_collect_standard_args (SFScript        *script,
 
   /*  an IMAGE id may come first or after the DISPLAY id  */
   if (script_fu_script_param_init (script,
-                                   n_params, params, SF_IMAGE,
+                                   args, SF_IMAGE,
                                    params_consumed))
     {
       params_consumed++;
@@ -474,16 +547,16 @@ script_fu_script_collect_standard_args (SFScript        *script,
        *  VECTORS id
        */
       if (script_fu_script_param_init (script,
-                                       n_params, params, SF_DRAWABLE,
+                                       args, SF_DRAWABLE,
                                        params_consumed) ||
           script_fu_script_param_init (script,
-                                       n_params, params, SF_LAYER,
+                                       args, SF_LAYER,
                                        params_consumed) ||
           script_fu_script_param_init (script,
-                                       n_params, params, SF_CHANNEL,
+                                       args, SF_CHANNEL,
                                        params_consumed) ||
           script_fu_script_param_init (script,
-                                       n_params, params, SF_VECTORS,
+                                       args, SF_VECTORS,
                                        params_consumed))
         {
           params_consumed++;
@@ -617,8 +690,8 @@ script_fu_script_get_command (SFScript *script)
 }
 
 gchar *
-script_fu_script_get_command_from_params (SFScript        *script,
-                                          const GimpParam *params)
+script_fu_script_get_command_from_params (SFScript             *script,
+                                          const GimpValueArray *args)
 {
   GString *s;
   gint     i;
@@ -630,7 +703,7 @@ script_fu_script_get_command_from_params (SFScript        *script,
 
   for (i = 0; i < script->n_args; i++)
     {
-      const GimpParam *param = &params[i + 1];
+      GValue *value = gimp_value_array_index (args, i + 1);
 
       g_string_append_c (s, ' ');
 
@@ -642,25 +715,28 @@ script_fu_script_get_command_from_params (SFScript        *script,
         case SF_CHANNEL:
         case SF_VECTORS:
         case SF_DISPLAY:
-          g_string_append_printf (s, "%d", param->data.d_int32);
+          g_string_append_printf (s, "%d", g_value_get_int (value));
           break;
 
         case SF_COLOR:
           {
-            guchar r, g, b;
+            GimpRGB color;
+            guchar  r, g, b;
 
-            gimp_rgb_get_uchar (&param->data.d_color, &r, &g, &b);
+            gimp_value_get_rgb (value, &color);
+            gimp_rgb_get_uchar (&color, &r, &g, &b);
             g_string_append_printf (s, "'(%d %d %d)",
                                     (gint) r, (gint) g, (gint) b);
           }
           break;
 
         case SF_TOGGLE:
-          g_string_append_printf (s, (param->data.d_int32 ? "TRUE" : "FALSE"));
+          g_string_append_printf (s, (g_value_get_boolean (value) ?
+                                      "TRUE" : "FALSE"));
           break;
 
         case SF_VALUE:
-          g_string_append (s, param->data.d_string);
+          g_string_append (s, g_value_get_string (value));
           break;
 
         case SF_STRING:
@@ -670,7 +746,7 @@ script_fu_script_get_command_from_params (SFScript        *script,
           {
             gchar *tmp;
 
-            tmp = script_fu_strescape (param->data.d_string);
+            tmp = script_fu_strescape (g_value_get_string (value));
             g_string_append_printf (s, "\"%s\"", tmp);
             g_free (tmp);
           }
@@ -680,7 +756,7 @@ script_fu_script_get_command_from_params (SFScript        *script,
           {
             gchar buffer[G_ASCII_DTOSTR_BUF_SIZE];
 
-            g_ascii_dtostr (buffer, sizeof (buffer), param->data.d_float);
+            g_ascii_dtostr (buffer, sizeof (buffer), g_value_get_double (value));
             g_string_append (s, buffer);
           }
           break;
@@ -690,12 +766,12 @@ script_fu_script_get_command_from_params (SFScript        *script,
         case SF_PATTERN:
         case SF_GRADIENT:
         case SF_BRUSH:
-          g_string_append_printf (s, "\"%s\"", param->data.d_string);
+          g_string_append_printf (s, "\"%s\"", g_value_get_string (value));
           break;
 
         case SF_OPTION:
         case SF_ENUM:
-          g_string_append_printf (s, "%d", param->data.d_int32);
+          g_string_append_printf (s, "%d", g_value_get_int (value));
           break;
         }
     }
@@ -711,62 +787,65 @@ script_fu_script_get_command_from_params (SFScript        *script,
  */
 
 static gboolean
-script_fu_script_param_init (SFScript        *script,
-                             gint             nparams,
-                             const GimpParam *params,
-                             SFArgType        type,
-                             gint             n)
+script_fu_script_param_init (SFScript             *script,
+                             const GimpValueArray *args,
+                             SFArgType             type,
+                             gint                  n)
 {
   SFArg *arg = &script->args[n];
 
-  if (script->n_args > n && arg->type == type && nparams > n + 1)
+  if (script->n_args > n &&
+      arg->type == type  &&
+      gimp_value_array_length (args) > n + 1)
     {
+      GValue *value = gimp_value_array_index (args, n + 1);
+
       switch (type)
         {
         case SF_IMAGE:
-          if (params[n + 1].type == GIMP_PDB_IMAGE)
+          if (GIMP_VALUE_HOLDS_IMAGE_ID (value))
             {
-              arg->value.sfa_image = params[n + 1].data.d_image;
+              arg->value.sfa_image = gimp_value_get_image_id (value);
               return TRUE;
             }
           break;
 
         case SF_DRAWABLE:
-          if (params[n + 1].type == GIMP_PDB_DRAWABLE)
+          if (GIMP_VALUE_HOLDS_DRAWABLE_ID (value))
             {
-              arg->value.sfa_drawable = params[n + 1].data.d_drawable;
+              arg->value.sfa_drawable = gimp_value_get_drawable_id (value);
               return TRUE;
             }
           break;
 
         case SF_LAYER:
-          if (params[n + 1].type == GIMP_PDB_LAYER)
+          if (GIMP_VALUE_HOLDS_LAYER_ID (value))
             {
-              arg->value.sfa_layer = params[n + 1].data.d_layer;
+              arg->value.sfa_layer = gimp_value_get_layer_id (value);
               return TRUE;
             }
           break;
 
         case SF_CHANNEL:
-          if (params[n + 1].type == GIMP_PDB_CHANNEL)
+          if (GIMP_VALUE_HOLDS_CHANNEL_ID (value))
             {
-              arg->value.sfa_channel = params[n + 1].data.d_channel;
+              arg->value.sfa_channel = gimp_value_get_channel_id (value);
               return TRUE;
             }
           break;
 
         case SF_VECTORS:
-          if (params[n + 1].type == GIMP_PDB_VECTORS)
+          if (GIMP_VALUE_HOLDS_VECTORS_ID (value))
             {
-              arg->value.sfa_vectors = params[n + 1].data.d_vectors;
+              arg->value.sfa_vectors = gimp_value_get_vectors_id (value);
               return TRUE;
             }
           break;
 
         case SF_DISPLAY:
-          if (params[n + 1].type == GIMP_PDB_DISPLAY)
+          if (GIMP_VALUE_HOLDS_DISPLAY_ID (value))
             {
-              arg->value.sfa_display = params[n + 1].data.d_display;
+              arg->value.sfa_display = gimp_value_get_display_id (value);
               return TRUE;
             }
           break;
diff --git a/plug-ins/script-fu/script-fu-script.h b/plug-ins/script-fu/script-fu-script.h
index 86b318f237..c9a16f607a 100644
--- a/plug-ins/script-fu/script-fu-script.h
+++ b/plug-ins/script-fu/script-fu-script.h
@@ -19,31 +19,32 @@
 #define __SCRIPT_FU_SCRIPT_H__
 
 
-SFScript * script_fu_script_new                     (const gchar     *name,
-                                                     const gchar     *menu_label,
-                                                     const gchar     *blurb,
-                                                     const gchar     *author,
-                                                     const gchar     *copyright,
-                                                     const gchar     *date,
-                                                     const gchar     *image_types,
-                                                     gint             n_args);
-void       script_fu_script_free                    (SFScript        *script);
-
-void       script_fu_script_install_proc            (SFScript        *script,
-                                                     GimpRunProc      run_proc);
-void       script_fu_script_uninstall_proc          (SFScript        *script);
-
-gchar    * script_fu_script_get_title               (SFScript        *script);
-void       script_fu_script_reset                   (SFScript        *script,
-                                                     gboolean         reset_ids);
-
-gint       script_fu_script_collect_standard_args   (SFScript        *script,
-                                                     gint             n_params,
-                                                     const GimpParam *params);
-
-gchar    * script_fu_script_get_command             (SFScript        *script);
-gchar    * script_fu_script_get_command_from_params (SFScript        *script,
-                                                     const GimpParam *params);
+SFScript * script_fu_script_new                     (const gchar          *name,
+                                                     const gchar          *menu_label,
+                                                     const gchar          *blurb,
+                                                     const gchar          *authors,
+                                                     const gchar          *copyright,
+                                                     const gchar          *date,
+                                                     const gchar          *image_types,
+                                                     gint                  n_args);
+void       script_fu_script_free                    (SFScript             *script);
+
+void       script_fu_script_install_proc            (GimpPlugIn           *plug_in,
+                                                     SFScript             *script,
+                                                     GimpRunFunc           run_func);
+void       script_fu_script_uninstall_proc          (GimpPlugIn           *plug_in,
+                                                     SFScript             *script);
+
+gchar    * script_fu_script_get_title               (SFScript             *script);
+void       script_fu_script_reset                   (SFScript             *script,
+                                                     gboolean              reset_ids);
+
+gint       script_fu_script_collect_standard_args   (SFScript             *script,
+                                                     const GimpValueArray *args);
+
+gchar    * script_fu_script_get_command             (SFScript             *script);
+gchar    * script_fu_script_get_command_from_params (SFScript             *script,
+                                                     const GimpValueArray *args);
 
 
 #endif /*  __SCRIPT_FU_SCRIPT__  */
diff --git a/plug-ins/script-fu/script-fu-scripts.c b/plug-ins/script-fu/script-fu-scripts.c
index bf56edb60f..b54d770a42 100644
--- a/plug-ins/script-fu/script-fu-scripts.c
+++ b/plug-ins/script-fu/script-fu-scripts.c
@@ -54,28 +54,26 @@ typedef struct
  *  Local Functions
  */
 
-static gboolean  script_fu_run_command    (const gchar      *command,
-                                           GError          **error);
-static void      script_fu_load_directory (GFile            *directory);
-static void      script_fu_load_script    (GFile            *file);
-static gboolean  script_fu_install_script (gpointer          foo,
-                                           GList            *scripts,
-                                           gpointer          bar);
-static void      script_fu_install_menu   (SFMenu           *menu);
-static gboolean  script_fu_remove_script  (gpointer          foo,
-                                           GList            *scripts,
-                                           gpointer          bar);
-static void      script_fu_script_proc    (const gchar      *name,
-                                           gint              nparams,
-                                           const GimpParam  *params,
-                                           gint             *nreturn_vals,
-                                           GimpParam       **return_vals);
-
-static SFScript *script_fu_find_script    (const gchar      *name);
-
-static gchar *   script_fu_menu_map       (const gchar      *menu_path);
-static gint      script_fu_menu_compare   (gconstpointer     a,
-                                           gconstpointer     b);
+static gboolean         script_fu_run_command    (const gchar          *command,
+                                                  GError              **error);
+static void             script_fu_load_directory (GFile                *directory);
+static void             script_fu_load_script    (GFile                *file);
+static gboolean         script_fu_install_script (gpointer              foo,
+                                                  GList                *scripts,
+                                                  gpointer              data);
+static void             script_fu_install_menu   (SFMenu               *menu);
+static gboolean         script_fu_remove_script  (gpointer              foo,
+                                                  GList                *scripts,
+                                                  gpointer              data);
+static GimpValueArray * script_fu_script_proc    (GimpProcedure        *procedure,
+                                                  const GimpValueArray *args,
+                                                  gpointer              data);
+
+static SFScript       * script_fu_find_script    (const gchar          *name);
+
+static gchar          * script_fu_menu_map       (const gchar          *menu_path);
+static gint             script_fu_menu_compare   (gconstpointer         a,
+                                                  gconstpointer         b);
 
 
 /*
@@ -91,7 +89,8 @@ static GList *script_menu_list = NULL;
  */
 
 void
-script_fu_find_scripts (GList *path)
+script_fu_find_scripts (GimpPlugIn *plug_in,
+                        GList      *path)
 {
   GList *list;
 
@@ -100,7 +99,7 @@ script_fu_find_scripts (GList *path)
     {
       g_tree_foreach (script_tree,
                       (GTraverseFunc) script_fu_remove_script,
-                      NULL);
+                      plug_in);
       g_tree_destroy (script_tree);
     }
 
@@ -117,7 +116,7 @@ script_fu_find_scripts (GList *path)
   /*  Now that all scripts are read in and sorted, tell gimp about them  */
   g_tree_foreach (script_tree,
                   (GTraverseFunc) script_fu_install_script,
-                  NULL);
+                  plug_in);
 
   script_menu_list = g_list_sort (script_menu_list,
                                   (GCompareFunc) script_fu_menu_compare);
@@ -672,15 +671,17 @@ script_fu_load_script (GFile *file)
 static gboolean
 script_fu_install_script (gpointer  foo G_GNUC_UNUSED,
                           GList    *scripts,
-                          gpointer  bar G_GNUC_UNUSED)
+                          gpointer  data)
 {
-  GList *list;
+  GimpPlugIn *plug_in = data;
+  GList      *list;
 
   for (list = scripts; list; list = g_list_next (list))
     {
       SFScript *script = list->data;
 
-      script_fu_script_install_proc (script, script_fu_script_proc);
+      script_fu_script_install_proc (plug_in, script,
+                                     script_fu_script_proc);
     }
 
   return FALSE;
@@ -689,7 +690,13 @@ script_fu_install_script (gpointer  foo G_GNUC_UNUSED,
 static void
 script_fu_install_menu (SFMenu *menu)
 {
-  gimp_plugin_menu_register (menu->script->name, menu->menu_path);
+  GimpPlugIn    *plug_in = gimp_get_plug_in ();
+  GimpProcedure *procedure;
+
+  procedure = gimp_plug_in_get_temp_procedure (plug_in,
+                                               menu->script->name);
+
+  gimp_procedure_add_menu_path (procedure, menu->menu_path);
 
   g_free (menu->menu_path);
   g_slice_free (SFMenu, menu);
@@ -701,15 +708,16 @@ script_fu_install_menu (SFMenu *menu)
 static gboolean
 script_fu_remove_script (gpointer  foo G_GNUC_UNUSED,
                          GList    *scripts,
-                         gpointer  bar G_GNUC_UNUSED)
+                         gpointer  data)
 {
-  GList *list;
+  GimpPlugIn *plug_in = data;
+  GList      *list;
 
   for (list = scripts; list; list = g_list_next (list))
     {
       SFScript *script = list->data;
 
-      script_fu_script_uninstall_proc (script);
+      script_fu_script_uninstall_proc (plug_in, script);
       script_fu_script_free (script);
     }
 
@@ -718,120 +726,96 @@ script_fu_remove_script (gpointer  foo G_GNUC_UNUSED,
   return FALSE;
 }
 
-static void
-script_fu_script_proc (const gchar      *name,
-                       gint              nparams,
-                       const GimpParam  *params,
-                       gint             *nreturn_vals,
-                       GimpParam       **return_vals)
+static GimpValueArray *
+script_fu_script_proc (GimpProcedure        *procedure,
+                       const GimpValueArray *args,
+                       gpointer              data)
 {
-  static GimpParam   values[2] = { { 0, }, { 0, } };
-  GimpPDBStatusType  status    = GIMP_PDB_SUCCESS;
+  GimpPDBStatusType  status = GIMP_PDB_SUCCESS;
   SFScript          *script;
-  GError            *error     = NULL;
-
-  if (values[1].type == GIMP_PDB_STRING && values[1].data.d_string)
-    {
-      g_free (values[1].data.d_string);
-      values[1].data.d_string = NULL;
-    }
+  GimpRunMode        run_mode;
+  GError            *error = NULL;
 
-  *nreturn_vals = 1;
-  *return_vals  = values;
+  script = script_fu_find_script (gimp_procedure_get_name (procedure));
 
-  values[0].type = GIMP_PDB_STATUS;
+  if (! script)
+    return gimp_procedure_new_return_values (procedure,
+                                             GIMP_PDB_CALLING_ERROR,
+                                             NULL);
 
-  script = script_fu_find_script (name);
+  run_mode = g_value_get_enum (gimp_value_array_index (args, 0));
 
-  if (! script)
-    status = GIMP_PDB_CALLING_ERROR;
+  ts_set_run_mode (run_mode);
 
-  if (status == GIMP_PDB_SUCCESS)
+  switch (run_mode)
     {
-      GimpRunMode run_mode = params[0].data.d_int32;
+    case GIMP_RUN_INTERACTIVE:
+      {
+        gint min_args = 0;
 
-      ts_set_run_mode (run_mode);
+        /*  First, try to collect the standard script arguments...  */
+        min_args = script_fu_script_collect_standard_args (script, args);
 
-      switch (run_mode)
-        {
-        case GIMP_RUN_INTERACTIVE:
+        /*  ...then acquire the rest of arguments (if any) with a dialog  */
+        if (script->n_args > min_args)
           {
-            gint min_args = 0;
-
-            /*  First, try to collect the standard script arguments...  */
-            min_args = script_fu_script_collect_standard_args (script,
-                                                               nparams, params);
-
-            /*  ...then acquire the rest of arguments (if any) with a dialog  */
-            if (script->n_args > min_args)
-              {
-                status = script_fu_interface (script, min_args);
-                break;
-              }
-            /*  otherwise (if the script takes no more arguments), skip
-             *  this part and run the script directly (fallthrough)
-             */
+            status = script_fu_interface (script, min_args);
+            break;
           }
+        /*  otherwise (if the script takes no more arguments), skip
+         *  this part and run the script directly (fallthrough)
+         */
+      }
 
-        case GIMP_RUN_NONINTERACTIVE:
-          /*  Make sure all the arguments are there  */
-          if (nparams != (script->n_args + 1))
-            status = GIMP_PDB_CALLING_ERROR;
+    case GIMP_RUN_NONINTERACTIVE:
+      /*  Make sure all the arguments are there  */
+      if (gimp_value_array_length (args) != (script->n_args + 1))
+        status = GIMP_PDB_CALLING_ERROR;
 
-          if (status == GIMP_PDB_SUCCESS)
-            {
-              gchar *command;
-
-              command = script_fu_script_get_command_from_params (script,
-                                                                  params);
-
-              /*  run the command through the interpreter  */
-              if (! script_fu_run_command (command, &error))
-                {
-                  status                  = GIMP_PDB_EXECUTION_ERROR;
-                  *nreturn_vals           = 2;
-                  values[1].type          = GIMP_PDB_STRING;
-                  values[1].data.d_string = error->message;
+      if (status == GIMP_PDB_SUCCESS)
+        {
+          gchar *command;
 
-                  error->message = NULL;
-                  g_error_free (error);
-                }
+          command = script_fu_script_get_command_from_params (script, args);
 
-              g_free (command);
+          /*  run the command through the interpreter  */
+          if (! script_fu_run_command (command, &error))
+            {
+              return gimp_procedure_new_return_values (procedure,
+                                                       GIMP_PDB_EXECUTION_ERROR,
+                                                       error);
             }
-          break;
 
-        case GIMP_RUN_WITH_LAST_VALS:
-          {
-            gchar *command;
-
-            /*  First, try to collect the standard script arguments  */
-            script_fu_script_collect_standard_args (script, nparams, params);
+          g_free (command);
+        }
+      break;
 
-            command = script_fu_script_get_command (script);
+    case GIMP_RUN_WITH_LAST_VALS:
+      {
+        gchar *command;
 
-            /*  run the command through the interpreter  */
-            if (! script_fu_run_command (command, &error))
-              {
-                status                  = GIMP_PDB_EXECUTION_ERROR;
-                *nreturn_vals           = 2;
-                values[1].type          = GIMP_PDB_STRING;
-                values[1].data.d_string = error->message;
+        /*  First, try to collect the standard script arguments  */
+        script_fu_script_collect_standard_args (script, args);
 
-                error->message = NULL;
-                g_error_free (error);
-              }
+        command = script_fu_script_get_command (script);
 
-            g_free (command);
+        /*  run the command through the interpreter  */
+        if (! script_fu_run_command (command, &error))
+          {
+            return gimp_procedure_new_return_values (procedure,
+                                                     GIMP_PDB_EXECUTION_ERROR,
+                                                     error);
           }
-          break;
 
-        default:
-          break;
-        }
+        g_free (command);
+      }
+      break;
+
+    default:
+      break;
     }
 
-  values[0].data.d_status = status;
+  return gimp_procedure_new_return_values (procedure, status, NULL);
 }
 
 /* this is a GTraverseFunction */
diff --git a/plug-ins/script-fu/script-fu-scripts.h b/plug-ins/script-fu/script-fu-scripts.h
index ef6387093d..b0079a39d3 100644
--- a/plug-ins/script-fu/script-fu-scripts.h
+++ b/plug-ins/script-fu/script-fu-scripts.h
@@ -19,11 +19,12 @@
 #define __SCRIPT_FU_SCRIPTS_H__
 
 
-void      script_fu_find_scripts  (GList   *path);
-pointer   script_fu_add_script    (scheme  *sc,
-                                   pointer  a);
-pointer   script_fu_add_menu      (scheme  *sc,
-                                   pointer  a);
+void      script_fu_find_scripts  (GimpPlugIn *plug_in,
+                                   GList      *path);
+pointer   script_fu_add_script    (scheme     *sc,
+                                   pointer     a);
+pointer   script_fu_add_menu      (scheme     *sc,
+                                   pointer     a);
 
 
 #endif /*  __SCRIPT_FU_SCRIPTS__  */
diff --git a/plug-ins/script-fu/script-fu-server.c b/plug-ins/script-fu/script-fu-server.c
index 5bb7c499ce..7341dd7c9e 100644
--- a/plug-ins/script-fu/script-fu-server.c
+++ b/plug-ins/script-fu/script-fu-server.c
@@ -219,18 +219,20 @@ script_fu_server_get_mode (void)
   return server_mode;
 }
 
-void
-script_fu_server_run (const gchar      *name,
-                      gint              nparams,
-                      const GimpParam  *params,
-                      gint             *nreturn_vals,
-                      GimpParam       **return_vals)
+GimpValueArray *
+script_fu_server_run (GimpProcedure        *procedure,
+                      const GimpValueArray *args)
 {
-  static GimpParam   values[1];
   GimpPDBStatusType  status = GIMP_PDB_SUCCESS;
   GimpRunMode        run_mode;
+  const gchar       *ip;
+  gint               port;
+  const gchar       *logfile;
 
-  run_mode = params[0].data.d_int32;
+  run_mode = g_value_get_enum   (gimp_value_array_index (args, 0));
+  ip       = g_value_get_string (gimp_value_array_index (args, 1));
+  port     = g_value_get_int    (gimp_value_array_index (args, 2));
+  logfile  = g_value_get_string (gimp_value_array_index (args, 3));
 
   ts_set_run_mode (run_mode);
   ts_set_print_flag (1);
@@ -252,26 +254,19 @@ script_fu_server_run (const gchar      *name,
       server_mode = TRUE;
 
       /*  Start the server  */
-      server_start ((params[1].data.d_string &&
-                     strlen (params[1].data.d_string)) ?
-                    params[1].data.d_string : "127.0.0.1",
-                    params[2].data.d_int32,
-                    params[3].data.d_string);
+      server_start (ip ? ip : "127.0.0.1", port, logfile);
       break;
 
     case GIMP_RUN_WITH_LAST_VALS:
       status = GIMP_PDB_CALLING_ERROR;
-      g_warning ("Script-Fu server does not handle \"GIMP_RUN_WITH_LAST_VALS\"");
+      g_printerr ("Script-Fu server does not handle "
+                  "\"GIMP_RUN_WITH_LAST_VALS\"\n");
 
     default:
       break;
     }
 
-  *nreturn_vals = 1;
-  *return_vals = values;
-
-  values[0].type = GIMP_PDB_STATUS;
-  values[0].data.d_status = status;
+  return gimp_procedure_new_return_values (procedure, status, NULL);
 }
 
 static void
diff --git a/plug-ins/script-fu/script-fu-server.h b/plug-ins/script-fu/script-fu-server.h
index 96b88ee036..5f07ea5001 100644
--- a/plug-ins/script-fu/script-fu-server.h
+++ b/plug-ins/script-fu/script-fu-server.h
@@ -19,14 +19,11 @@
 #define __SCRIPT_FU_SERVER_H__
 
 
-void  script_fu_server_run      (const gchar      *name,
-                                gint              nparams,
-                                const GimpParam  *params,
-                                gint             *nreturn_vals,
-                                GimpParam       **return_vals);
-void  script_fu_server_listen   (gint              timeout);
-gint  script_fu_server_get_mode (void);
-void  script_fu_server_quit     (void);
+GimpValueArray * script_fu_server_run      (GimpProcedure        *procedure,
+                                            const GimpValueArray *args);
+void             script_fu_server_listen   (gint                  timeout);
+gint             script_fu_server_get_mode (void);
+void             script_fu_server_quit     (void);
 
 
 #endif /*  __SCRIPT_FU_SERVER__  */
diff --git a/plug-ins/script-fu/script-fu-text-console.c b/plug-ins/script-fu/script-fu-text-console.c
index 94c8d7c1e5..4747bee960 100644
--- a/plug-ins/script-fu/script-fu-text-console.c
+++ b/plug-ins/script-fu/script-fu-text-console.c
@@ -31,30 +31,23 @@
 
 #include "script-fu-intl.h"
 
-void
-script_fu_text_console_run (const gchar      *name,
-                            gint              nparams,
-                            const GimpParam  *params,
-                            gint             *nreturn_vals,
-                            GimpParam       **return_vals)
+GimpValueArray *
+script_fu_text_console_run (GimpProcedure        *procedure,
+                            const GimpValueArray *args)
 {
-  static GimpParam  values[1];
-
   /*  Enable Script-Fu output  */
   ts_register_output_func (ts_stdout_output_func, NULL);
 
   ts_print_welcome ();
 
-  gimp_plugin_set_pdb_error_handler (GIMP_PDB_ERROR_HANDLER_PLUGIN);
+  gimp_plug_in_set_pdb_error_handler (gimp_procedure_get_plug_in (procedure),
+                                      GIMP_PDB_ERROR_HANDLER_PLUGIN);
 
   /*  Run the interface  */
   ts_interpret_stdin ();
 
-  gimp_plugin_set_pdb_error_handler (GIMP_PDB_ERROR_HANDLER_INTERNAL);
-
-  values[0].type          = GIMP_PDB_STATUS;
-  values[0].data.d_status = GIMP_PDB_SUCCESS;
+  gimp_plug_in_set_pdb_error_handler (gimp_procedure_get_plug_in (procedure),
+                                      GIMP_PDB_ERROR_HANDLER_INTERNAL);
 
-  *nreturn_vals = 1;
-  *return_vals  = values;
+  return gimp_procedure_new_return_values (procedure, GIMP_PDB_SUCCESS, NULL);
 }
diff --git a/plug-ins/script-fu/script-fu-text-console.h b/plug-ins/script-fu/script-fu-text-console.h
index 83c98606f8..b714207dbb 100644
--- a/plug-ins/script-fu/script-fu-text-console.h
+++ b/plug-ins/script-fu/script-fu-text-console.h
@@ -19,11 +19,8 @@
 #define __SCRIPT_FU_TEXT_CONSOLE_H__
 
 
-void  script_fu_text_console_run (const gchar      *name,
-                                  gint              nparams,
-                                  const GimpParam  *params,
-                                  gint             *nreturn_vals,
-                                  GimpParam       **return_vals);
+GimpValueArray * script_fu_text_console_run (GimpProcedure        *procedure,
+                                             const GimpValueArray *args);
 
 
 #endif /*  __SCRIPT_FU_TEXT_CONSOLE_H__  */
diff --git a/plug-ins/script-fu/script-fu.c b/plug-ins/script-fu/script-fu.c
index d7d4073bc9..0a1d5fc844 100644
--- a/plug-ins/script-fu/script-fu.c
+++ b/plug-ins/script-fu/script-fu.c
@@ -38,147 +38,246 @@
 #include "script-fu-intl.h"
 
 
-/* Declare local functions. */
-
-static void    script_fu_query          (void);
-static void    script_fu_run            (const gchar      *name,
-                                         gint              nparams,
-                                         const GimpParam  *params,
-                                         gint             *nreturn_vals,
-                                         GimpParam       **return_vals);
-static GList * script_fu_search_path    (void);
-static void    script_fu_extension_init (void);
-static void    script_fu_refresh_proc   (const gchar      *name,
-                                         gint              nparams,
-                                         const GimpParam  *params,
-                                         gint             *nreturn_vals,
-                                         GimpParam       **return_vals);
-
-
-const GimpPlugInInfo PLUG_IN_INFO =
+typedef struct _ScriptFu      ScriptFu;
+typedef struct _ScriptFuClass ScriptFuClass;
+
+struct _ScriptFu
+{
+  GimpPlugIn      parent_instance;
+};
+
+struct _ScriptFuClass
 {
-  NULL,             /* init_proc  */
-  NULL,             /* quit_proc  */
-  script_fu_query,  /* query_proc */
-  script_fu_run     /* run_proc   */
+  GimpPlugInClass parent_class;
 };
 
 
-MAIN ()
+#define SCRIPT_FU_TYPE  (script_fu_get_type ())
+#define SCRIPT_FU (obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SCRIPT_FU_TYPE, ScriptFu))
+
+GType                   script_fu_get_type         (void) G_GNUC_CONST;
+
+static GList          * script_fu_query_procedures (GimpPlugIn           *plug_in);
+static GimpProcedure  * script_fu_create_procedure (GimpPlugIn           *plug_in,
+                                                    const gchar          *name);
+
+static GimpValueArray * script_fu_run              (GimpProcedure        *procedure,
+                                                    const GimpValueArray *args,
+                                                    gpointer              run_data);
+static GList *          script_fu_search_path      (void);
+static void             script_fu_extension_init   (GimpPlugIn           *plug_in);
+static GimpValueArray * script_fu_refresh_proc     (GimpProcedure        *procedure,
+                                                    const GimpValueArray *args,
+                                                    gpointer              run_data);
+
+
+G_DEFINE_TYPE (ScriptFu, script_fu, GIMP_TYPE_PLUG_IN)
+
+GIMP_MAIN (SCRIPT_FU_TYPE)
 
 
 static void
-script_fu_query (void)
+script_fu_class_init (ScriptFuClass *klass)
 {
-  static const GimpParamDef console_args[] =
-  {
-    { GIMP_PDB_INT32,  "run-mode", "The run mode { RUN-INTERACTIVE (0) }" }
-  };
-
-  static const GimpParamDef textconsole_args[] =
-  {
-    { GIMP_PDB_INT32,  "run-mode", "The run mode { RUN-INTERACTIVE (0) }" }
-  };
-
-  static const GimpParamDef eval_args[] =
-  {
-    { GIMP_PDB_INT32,  "run-mode", "The run mode { RUN-NONINTERACTIVE (1) }" },
-    { GIMP_PDB_STRING, "code",     "The code to evaluate"                    }
-  };
-
-  static const GimpParamDef server_args[] =
-  {
-    { GIMP_PDB_INT32,  "run-mode", "The run mode { RUN-NONINTERACTIVE (1) }"  },
-    { GIMP_PDB_STRING, "ip",       "The ip on which to listen for requests"   },
-    { GIMP_PDB_INT32,  "port",     "The port on which to listen for requests" },
-    { GIMP_PDB_STRING, "logfile",  "The file to log server activity to"       }
-  };
-
-  gimp_plugin_domain_register (GETTEXT_PACKAGE "-script-fu", NULL);
-
-  gimp_install_procedure ("extension-script-fu",
-                          "A scheme interpreter for scripting GIMP operations",
-                          "More help here later",
-                          "Spencer Kimball & Peter Mattis",
-                          "Spencer Kimball & Peter Mattis",
-                          "1997",
-                          NULL,
-                          NULL,
-                          GIMP_EXTENSION,
-                          0, 0, NULL, NULL);
-
-  gimp_install_procedure ("plug-in-script-fu-console",
-                          N_("Interactive console for Script-Fu development"),
-                          "Provides an interface which allows interactive "
-                                      "scheme development.",
-                          "Spencer Kimball & Peter Mattis",
-                          "Spencer Kimball & Peter Mattis",
-                          "1997",
-                          N_("_Console"),
-                          NULL,
-                          GIMP_PLUGIN,
-                          G_N_ELEMENTS (console_args), 0,
-                          console_args, NULL);
-
-  gimp_plugin_menu_register ("plug-in-script-fu-console",
-                             "<Image>/Filters/Development/Script-Fu");
-
-  gimp_install_procedure ("plug-in-script-fu-text-console",
-                          "Provides a text console mode for script-fu "
-                          "development",
-                          "Provides an interface which allows interactive "
-                          "scheme development.",
-                          "Spencer Kimball & Peter Mattis",
-                          "Spencer Kimball & Peter Mattis",
-                          "1997",
-                          NULL,
-                          NULL,
-                          GIMP_PLUGIN,
-                          G_N_ELEMENTS (textconsole_args), 0,
-                          textconsole_args, NULL);
-
-  gimp_install_procedure ("plug-in-script-fu-server",
-                          N_("Server for remote Script-Fu operation"),
-                          "Provides a server for remote script-fu operation. "
-                          "NOTE that for security reasons this procedure's "
-                          "API was changed in an incompatible way since "
-                          "GIMP 2.8.12. You now have to pass the IP to listen "
-                          "on as first parameter. Calling this procedure with "
-                          "the old API will fail on purpose.",
-                          "Spencer Kimball & Peter Mattis",
-                          "Spencer Kimball & Peter Mattis",
-                          "1997",
-                          N_("_Start Server..."),
-                          NULL,
-                          GIMP_PLUGIN,
-                          G_N_ELEMENTS (server_args), 0,
-                          server_args, NULL);
-
-  gimp_plugin_menu_register ("plug-in-script-fu-server",
-                             "<Image>/Filters/Development/Script-Fu");
-
-  gimp_install_procedure ("plug-in-script-fu-eval",
-                          "Evaluate scheme code",
-                          "Evaluate the code under the scheme interpreter "
-                                      "(primarily for batch mode)",
-                          "Manish Singh",
-                          "Manish Singh",
-                          "1998",
-                          NULL,
-                          NULL,
-                          GIMP_PLUGIN,
-                          G_N_ELEMENTS (eval_args), 0,
-                          eval_args, NULL);
+  GimpPlugInClass *plug_in_class = GIMP_PLUG_IN_CLASS (klass);
+
+  plug_in_class->query_procedures = script_fu_query_procedures;
+  plug_in_class->create_procedure = script_fu_create_procedure;
 }
 
 static void
-script_fu_run (const gchar      *name,
-               gint              nparams,
-               const GimpParam  *param,
-               gint             *nreturn_vals,
-               GimpParam       **return_vals)
+script_fu_init (ScriptFu *script_fu)
 {
-  GList *path;
+}
+
+static GList *
+script_fu_query_procedures (GimpPlugIn *plug_in)
+{
+  GList *list = NULL;
+
+  gimp_plug_in_set_translation_domain (plug_in,
+                                       GETTEXT_PACKAGE "-script-fu", NULL);
+
+  list = g_list_append (list, g_strdup ("extension-script-fu"));
+  list = g_list_append (list, g_strdup ("plug-in-script-fu-console"));
+  list = g_list_append (list, g_strdup ("plug-in-script-fu-text-console"));
+  list = g_list_append (list, g_strdup ("plug-in-script-fu-server"));
+  list = g_list_append (list, g_strdup ("plug-in-script-fu-eval"));
+
+  return list;
+}
+
+static GimpProcedure *
+script_fu_create_procedure (GimpPlugIn  *plug_in,
+                            const gchar *name)
+{
+  GimpProcedure *procedure = NULL;
+
+  if (! strcmp (name, "extension-script-fu"))
+    {
+      procedure = gimp_procedure_new (plug_in, name, GIMP_EXTENSION,
+                                      script_fu_run, NULL, NULL);
+
+      gimp_procedure_set_documentation (procedure,
+                                        "A scheme interpreter for scripting "
+                                        "GIMP operations",
+                                        "More help here later",
+                                        NULL);
+      gimp_procedure_set_attribution (procedure,
+                                      "Spencer Kimball & Peter Mattis",
+                                      "Spencer Kimball & Peter Mattis",
+                                      "1997");
+    }
+  else if (! strcmp (name, "plug-in-script-fu-console"))
+    {
+      procedure = gimp_procedure_new (plug_in, name, GIMP_PLUGIN,
+                                      script_fu_run, NULL, NULL);
+
+      gimp_procedure_set_menu_label (procedure, N_("_Console"));
+      gimp_procedure_add_menu_path (procedure,
+                                    "<Image>/Filters/Development/Script-Fu");
+
+      gimp_procedure_set_documentation (procedure,
+                                        N_("Interactive console for Script-Fu "
+                                           "development"),
+                                        "Provides an interface which allows "
+                                        "interactive scheme development.",
+                                        name);
+      gimp_procedure_set_attribution (procedure,
+                                      "Spencer Kimball & Peter Mattis",
+                                      "Spencer Kimball & Peter Mattis",
+                                      "1997");
+
+      gimp_procedure_add_argument (procedure,
+                                   g_param_spec_enum ("run-mode",
+                                                      "Run mode",
+                                                      "The run mode",
+                                                      GIMP_TYPE_RUN_MODE,
+                                                      GIMP_RUN_INTERACTIVE,
+                                                      G_PARAM_READWRITE));
+    }
+  else if (! strcmp (name, "plug-in-script-fu-text-console"))
+    {
+      procedure = gimp_procedure_new (plug_in, name, GIMP_PLUGIN,
+                                      script_fu_run, NULL, NULL);
+
+      gimp_procedure_set_documentation (procedure,
+                                        "Provides a text console mode for "
+                                        "script-fu development",
+                                        "Provides an interface which allows "
+                                        "interactive scheme development.",
+                                        name);
+      gimp_procedure_set_attribution (procedure,
+                                      "Spencer Kimball & Peter Mattis",
+                                      "Spencer Kimball & Peter Mattis",
+                                      "1997");
+
+      gimp_procedure_add_argument (procedure,
+                                   g_param_spec_enum ("run-mode",
+                                                      "Run mode",
+                                                      "The run mode",
+                                                      GIMP_TYPE_RUN_MODE,
+                                                      GIMP_RUN_INTERACTIVE,
+                                                      G_PARAM_READWRITE));
+    }
+  else if (! strcmp (name, "plug-in-script-fu-server"))
+    {
+      procedure = gimp_procedure_new (plug_in, name, GIMP_PLUGIN,
+                                      script_fu_run, NULL, NULL);
+
+      gimp_procedure_set_menu_label (procedure, N_("_Start Server..."));
+      gimp_procedure_add_menu_path (procedure,
+                                    "<Image>/Filters/Development/Script-Fu");
+
+      gimp_procedure_set_documentation (procedure,
+                                        N_("Server for remote Script-Fu "
+                                           "operation"),
+                                        "Provides a server for remote "
+                                        "script-fu operation. NOTE that for "
+                                        "security reasons this procedure's "
+                                        "API was changed in an incompatible "
+                                        "way since GIMP 2.8.12. You now have "
+                                        "to pass the IP to listen on as "
+                                        "first parameter. Calling this "
+                                        "procedure with the old API will "
+                                        "fail on purpose.",
+                                        name);
+      gimp_procedure_set_attribution (procedure,
+                                      "Spencer Kimball & Peter Mattis",
+                                      "Spencer Kimball & Peter Mattis",
+                                      "1997");
+
+      gimp_procedure_add_argument (procedure,
+                                   g_param_spec_enum ("run-mode",
+                                                      "Run mode",
+                                                      "The run mode",
+                                                      GIMP_TYPE_RUN_MODE,
+                                                      GIMP_RUN_INTERACTIVE,
+                                                      G_PARAM_READWRITE));
+      gimp_procedure_add_argument (procedure,
+                                   g_param_spec_string ("ip",
+                                                        "IP",
+                                                        "The IP on which to "
+                                                        "listen for requests",
+                                                        NULL,
+                                                        G_PARAM_READWRITE));
+      gimp_procedure_add_argument (procedure,
+                                   g_param_spec_int ("port",
+                                                     "Port",
+                                                     "The port on which to "
+                                                     "listen for requests",
+                                                     0, G_MAXINT, 0,
+                                                     G_PARAM_READWRITE));
+      gimp_procedure_add_argument (procedure,
+                                   g_param_spec_string ("logfile",
+                                                        "Log File",
+                                                        "The file to log "
+                                                        "activity to",
+                                                        NULL,
+                                                        G_PARAM_READWRITE));
+    }
+  else if (! strcmp (name, "plug-in-script-fu-eval"))
+    {
+      procedure = gimp_procedure_new (plug_in, name, GIMP_PLUGIN,
+                                      script_fu_run, NULL, NULL);
+
+      gimp_procedure_set_documentation (procedure,
+                                        "Evaluate scheme code",
+                                        "Evaluate the code under the scheme "
+                                        "interpreter (primarily for batch mode)",
+                                        name);
+      gimp_procedure_set_attribution (procedure,
+                                      "Manish Singh",
+                                      "Manish Singh",
+                                      "1998");
+
+      gimp_procedure_add_argument (procedure,
+                                   g_param_spec_enum ("run-mode",
+                                                      "Run mode",
+                                                      "The run mode",
+                                                      GIMP_TYPE_RUN_MODE,
+                                                      GIMP_RUN_INTERACTIVE,
+                                                      G_PARAM_READWRITE));
+      gimp_procedure_add_argument (procedure,
+                                   g_param_spec_string ("code",
+                                                        "Code",
+                                                        "The code to run",
+                                                        NULL,
+                                                        G_PARAM_READWRITE));
+    }
+
+  return procedure;
+}
+
+static GimpValueArray *
+script_fu_run (GimpProcedure        *procedure,
+               const GimpValueArray *args,
+               gpointer              run_data)
+{
+  GimpPlugIn     *plug_in     = gimp_procedure_get_plug_in (procedure);
+  const gchar    *name        = gimp_procedure_get_name (procedure);
+  GimpValueArray *return_vals = NULL;
+  GList          *path;
 
   INIT_I18N();
 
@@ -190,7 +289,7 @@ script_fu_run (const gchar      *name,
   if (strcmp (name, "extension-script-fu") == 0)
     {
       /*  Setup auxiliary temporary procedures for the base extension  */
-      script_fu_extension_init ();
+      script_fu_extension_init (plug_in);
 
       /*  Init the interpreter and register scripts */
       tinyscheme_init (path, TRUE);
@@ -201,11 +300,11 @@ script_fu_run (const gchar      *name,
       tinyscheme_init (path, FALSE);
     }
 
-  if (param != NULL)
-    ts_set_run_mode ((GimpRunMode) param[0].data.d_int32);
+  if (gimp_value_array_length (args) > 0)
+    ts_set_run_mode (g_value_get_enum (gimp_value_array_index (args, 0)));
 
   /*  Load all of the available scripts  */
-  script_fu_find_scripts (path);
+  script_fu_find_scripts (plug_in, path);
 
   g_list_free_full (path, (GDestroyNotify) g_object_unref);
 
@@ -215,21 +314,12 @@ script_fu_run (const gchar      *name,
        *  The main script-fu extension.
        */
 
-      static GimpParam  values[1];
-
       /*  Acknowledge that the extension is properly initialized  */
-      gimp_extension_ack ();
+      gimp_procedure_extension_ready (procedure);
 
       /*  Go into an endless loop  */
       while (TRUE)
-        gimp_extension_process (0);
-
-      /*  Set return values; pointless because we never get out of the loop  */
-      *nreturn_vals = 1;
-      *return_vals  = values;
-
-      values[0].type          = GIMP_PDB_STATUS;
-      values[0].data.d_status = GIMP_PDB_SUCCESS;
+        gimp_plug_in_extension_process (plug_in, 0);
     }
   else if (strcmp (name, "plug-in-script-fu-text-console") == 0)
     {
@@ -237,8 +327,7 @@ script_fu_run (const gchar      *name,
        *  The script-fu text console for interactive Scheme development
        */
 
-      script_fu_text_console_run (name, nparams, param,
-                                  nreturn_vals, return_vals);
+      return_vals = script_fu_text_console_run (procedure, args);
     }
   else if (strcmp (name, "plug-in-script-fu-console") == 0)
     {
@@ -246,8 +335,7 @@ script_fu_run (const gchar      *name,
        *  The script-fu console for interactive Scheme development
        */
 
-      script_fu_console_run (name, nparams, param,
-                             nreturn_vals, return_vals);
+      return_vals = script_fu_console_run (procedure, args);
     }
   else if (strcmp (name, "plug-in-script-fu-server") == 0)
     {
@@ -255,8 +343,7 @@ script_fu_run (const gchar      *name,
        *  The script-fu server for remote operation
        */
 
-      script_fu_server_run (name, nparams, param,
-                            nreturn_vals, return_vals);
+      return_vals = script_fu_server_run (procedure, args);
     }
   else if (strcmp (name, "plug-in-script-fu-eval") == 0)
     {
@@ -264,9 +351,15 @@ script_fu_run (const gchar      *name,
        *  A non-interactive "console" (for batch mode)
        */
 
-      script_fu_eval_run (name, nparams, param,
-                          nreturn_vals, return_vals);
+      return_vals = script_fu_eval_run (procedure, args);
     }
+
+  if (! return_vals)
+    return_vals = gimp_procedure_new_return_values (procedure,
+                                                    GIMP_PDB_SUCCESS,
+                                                    NULL);
+
+  return return_vals;
 }
 
 static GList *
@@ -296,90 +389,90 @@ script_fu_search_path (void)
 }
 
 static void
-script_fu_extension_init (void)
+script_fu_extension_init (GimpPlugIn *plug_in)
 {
-  static const GimpParamDef args[] =
-  {
-    { GIMP_PDB_INT32, "run-mode", "[Interactive], non-interactive" }
-  };
-
-  gimp_plugin_menu_branch_register ("<Image>/Help", N_("_GIMP Online"));
-  gimp_plugin_menu_branch_register ("<Image>/Help", N_("_User Manual"));
-
-  gimp_plugin_menu_branch_register ("<Image>/Filters/Development",
-                                    N_("_Script-Fu"));
-  gimp_plugin_menu_branch_register ("<Image>/Filters/Development/Script-Fu",
-                                    N_("_Test"));
-
-  gimp_plugin_menu_branch_register ("<Image>/File/Create",
-                                    N_("_Buttons"));
-  gimp_plugin_menu_branch_register ("<Image>/File/Create",
-                                    N_("_Logos"));
-  gimp_plugin_menu_branch_register ("<Image>/File/Create",
-                                    N_("_Patterns"));
-
-  gimp_plugin_menu_branch_register ("<Image>/File/Create",
-                                    N_("_Web Page Themes"));
-  gimp_plugin_menu_branch_register ("<Image>/File/Create/Web Page Themes",
-                                    N_("_Alien Glow"));
-  gimp_plugin_menu_branch_register ("<Image>/File/Create/Web Page Themes",
-                                    N_("_Beveled Pattern"));
-  gimp_plugin_menu_branch_register ("<Image>/File/Create/Web Page Themes",
-                                    N_("_Classic.Gimp.Org"));
-
-  gimp_plugin_menu_branch_register ("<Image>/Filters",
-                                    N_("Alpha to _Logo"));
-
-  gimp_install_temp_proc ("script-fu-refresh",
-                          N_("Re-read all available Script-Fu scripts"),
-                          "Re-read all available Script-Fu scripts",
-                          "Spencer Kimball & Peter Mattis",
-                          "Spencer Kimball & Peter Mattis",
-                          "1997",
-                          N_("_Refresh Scripts"),
-                          NULL,
-                          GIMP_TEMPORARY,
-                          G_N_ELEMENTS (args), 0,
-                          args, NULL,
-                          script_fu_refresh_proc);
-
-  gimp_plugin_menu_register ("script-fu-refresh",
-                             "<Image>/Filters/Development/Script-Fu");
+  GimpProcedure *procedure;
+
+  gimp_plug_in_add_menu_branch (plug_in, "<Image>/Help", N_("_GIMP Online"));
+  gimp_plug_in_add_menu_branch (plug_in, "<Image>/Help", N_("_User Manual"));
+
+  gimp_plug_in_add_menu_branch (plug_in, "<Image>/Filters/Development",
+                                N_("_Script-Fu"));
+  gimp_plug_in_add_menu_branch (plug_in, "<Image>/Filters/Development/Script-Fu",
+                                N_("_Test"));
+
+  gimp_plug_in_add_menu_branch (plug_in, "<Image>/File/Create",
+                                N_("_Buttons"));
+  gimp_plug_in_add_menu_branch (plug_in, "<Image>/File/Create",
+                                N_("_Logos"));
+  gimp_plug_in_add_menu_branch (plug_in, "<Image>/File/Create",
+                                N_("_Patterns"));
+
+  gimp_plug_in_add_menu_branch (plug_in, "<Image>/File/Create",
+                                N_("_Web Page Themes"));
+  gimp_plug_in_add_menu_branch (plug_in, "<Image>/File/Create/Web Page Themes",
+                                N_("_Alien Glow"));
+  gimp_plug_in_add_menu_branch (plug_in, "<Image>/File/Create/Web Page Themes",
+                                N_("_Beveled Pattern"));
+  gimp_plug_in_add_menu_branch (plug_in, "<Image>/File/Create/Web Page Themes",
+                                N_("_Classic.Gimp.Org"));
+
+  gimp_plug_in_add_menu_branch (plug_in, "<Image>/Filters",
+                                N_("Alpha to _Logo"));
+
+  procedure = gimp_procedure_new (plug_in, "script-fu-refresh",
+                                  GIMP_TEMPORARY,
+                                  script_fu_refresh_proc, NULL, NULL);
+
+  gimp_procedure_set_menu_label (procedure, N_("_Refresh Scripts"));
+  gimp_procedure_add_menu_path (procedure,
+                                "<Image>/Filters/Development/Script-Fu");
+
+  gimp_procedure_set_documentation (procedure,
+                                    N_("Re-read all available Script-Fu scripts"),
+                                    "Re-read all available Script-Fu scripts",
+                                    "script-fu-refresh");
+  gimp_procedure_set_attribution (procedure,
+                                  "Spencer Kimball & Peter Mattis",
+                                  "Spencer Kimball & Peter Mattis",
+                                  "1997");
+
+  gimp_procedure_add_argument (procedure,
+                               g_param_spec_enum ("run-mode",
+                                                  "Run mode",
+                                                  "The run mode",
+                                                  GIMP_TYPE_RUN_MODE,
+                                                  GIMP_RUN_INTERACTIVE,
+                                                  G_PARAM_READWRITE));
+
+  gimp_plug_in_add_temp_procedure (plug_in, procedure);
+  g_object_unref (procedure);
 }
 
-static void
-script_fu_refresh_proc (const gchar      *name,
-                        gint              nparams,
-                        const GimpParam  *params,
-                        gint             *nreturn_vals,
-                        GimpParam       **return_vals)
+static GimpValueArray *
+script_fu_refresh_proc (GimpProcedure        *procedure,
+                        const GimpValueArray *args,
+                        gpointer              run_data)
 {
-  static GimpParam  values[1];
-  GimpPDBStatusType status;
-
   if (script_fu_interface_is_active ())
     {
       g_message (_("You can not use \"Refresh Scripts\" while a "
                    "Script-Fu dialog box is open.  Please close "
                    "all Script-Fu windows and try again."));
 
-      status = GIMP_PDB_EXECUTION_ERROR;
+      return gimp_procedure_new_return_values (procedure,
+                                               GIMP_PDB_EXECUTION_ERROR,
+                                               NULL);
     }
   else
     {
       /*  Reload all of the available scripts  */
       GList *path = script_fu_search_path ();
 
-      script_fu_find_scripts (path);
+      script_fu_find_scripts (gimp_procedure_get_plug_in (procedure), path);
 
       g_list_free_full (path, (GDestroyNotify) g_object_unref);
-
-      status = GIMP_PDB_SUCCESS;
     }
 
-  *nreturn_vals = 1;
-  *return_vals  = values;
-
-  values[0].type          = GIMP_PDB_STATUS;
-  values[0].data.d_status = status;
+  return gimp_procedure_new_return_values (procedure, GIMP_PDB_SUCCESS, NULL);
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]