Exemple #1
0
GimpValueArray *
procedure_commands_get_item_args (GimpProcedure *procedure,
                                  GimpImage     *image,
                                  GimpItem      *item)
{
    GimpValueArray *args;
    gint            n_args = 0;

    args = gimp_procedure_get_arguments (procedure);

    /* initialize the first argument  */
    g_value_set_int (gimp_value_array_index (args, n_args),
                     GIMP_RUN_INTERACTIVE);
    n_args++;

    if (gimp_value_array_length (args) > n_args &&
            GIMP_IS_PARAM_SPEC_IMAGE_ID (procedure->args[n_args]))
    {
        if (image)
        {
            gimp_value_set_image (gimp_value_array_index (args, n_args), image);
            n_args++;

            if (gimp_value_array_length (args) > n_args &&
                    GIMP_IS_PARAM_SPEC_ITEM_ID (procedure->args[n_args]))
            {
                if (item &&
                        g_type_is_a (G_TYPE_FROM_INSTANCE (item),
                                     GIMP_PARAM_SPEC_ITEM_ID (procedure->args[n_args])->item_type))
                {
                    gimp_value_set_item (gimp_value_array_index (args, n_args),
                                         item);
                    n_args++;
                }
                else
                {
                    g_warning ("Uh-oh, no active item for the plug-in!");
                    gimp_value_array_unref (args);
                    return NULL;
                }
            }
        }
    }

    gimp_value_array_truncate (args, n_args);

    return args;
}
GimpValueArray *
procedure_commands_get_data_args (GimpProcedure *procedure,
                                  GimpObject    *object)
{
  GimpValueArray *args;
  gint            n_args = 0;

  args = gimp_procedure_get_arguments (procedure);

  /* initialize the first argument  */
  g_value_set_int (gimp_value_array_index (args, n_args),
                   GIMP_RUN_INTERACTIVE);
  n_args++;

  if (gimp_value_array_length (args) > n_args &&
      GIMP_IS_PARAM_SPEC_STRING (procedure->args[n_args]))
    {
      if (object)
        {
          g_value_set_string (gimp_value_array_index (args, n_args),
                              gimp_object_get_name (object));
          n_args++;
        }
      else
        {
          g_warning ("Uh-oh, no active data object for the plug-in!");
          gimp_value_array_unref (args);
          return NULL;
        }
    }

  gimp_value_array_truncate (args, n_args);

  return args;
}
static gint
plug_in_collect_data_args (GtkAction       *action,
                           GimpObject      *object,
                           GParamSpec     **pspecs,
                           GimpValueArray  *args,
                           gint             n_args)
{
  if (gimp_value_array_length (args) > n_args &&
      GIMP_IS_PARAM_SPEC_STRING (pspecs[n_args]))
    {
      if (object)
        {
          g_value_set_string (gimp_value_array_index (args, n_args),
                              gimp_object_get_name (object));
          n_args++;
        }
      else
        {
          g_warning ("Uh-oh, no active data object for the plug-in!");
          return -1;
        }
    }

  return n_args;
}
Exemple #4
0
static void
gimp_procedure_real_execute_async (GimpProcedure  *procedure,
                                   Gimp           *gimp,
                                   GimpContext    *context,
                                   GimpProgress   *progress,
                                   GimpValueArray *args,
                                   GimpObject     *display)
{
  GimpValueArray *return_vals;
  GError         *error = NULL;

  g_return_if_fail (gimp_value_array_length (args) >= procedure->num_args);

  return_vals = GIMP_PROCEDURE_GET_CLASS (procedure)->execute (procedure,
                                                               gimp,
                                                               context,
                                                               progress,
                                                               args,
                                                               &error);

  gimp_value_array_unref (return_vals);

  if (error)
    {
      gimp_message_literal (gimp, G_OBJECT (progress), GIMP_MESSAGE_ERROR,
                            error->message);
      g_error_free (error);
    }
}
void
gimp_plug_in_procedure_handle_return_values (GimpPlugInProcedure *proc,
                                             Gimp                *gimp,
                                             GimpProgress        *progress,
                                             GimpValueArray      *return_vals)
{
  g_return_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc));
  g_return_if_fail (return_vals != NULL);

  if (! gimp_value_array_length (return_vals) > 0 ||
      G_VALUE_TYPE (gimp_value_array_index (return_vals, 0)) !=
      GIMP_TYPE_PDB_STATUS_TYPE)
    {
      return;
    }

  switch (g_value_get_enum (gimp_value_array_index (return_vals, 0)))
    {
    case GIMP_PDB_SUCCESS:
      break;

    case GIMP_PDB_CALLING_ERROR:
      if (gimp_value_array_length (return_vals) > 1 &&
          G_VALUE_HOLDS_STRING (gimp_value_array_index (return_vals, 1)))
        {
          gimp_message (gimp, G_OBJECT (progress), GIMP_MESSAGE_ERROR,
                        _("Calling error for '%s':\n"
                          "%s"),
                        gimp_plug_in_procedure_get_label (proc),
                        g_value_get_string (gimp_value_array_index (return_vals, 1)));
        }
      break;

    case GIMP_PDB_EXECUTION_ERROR:
      if (gimp_value_array_length (return_vals) > 1 &&
          G_VALUE_HOLDS_STRING (gimp_value_array_index (return_vals, 1)))
        {
          gimp_message (gimp, G_OBJECT (progress), GIMP_MESSAGE_ERROR,
                        _("Execution error for '%s':\n"
                          "%s"),
                        gimp_plug_in_procedure_get_label (proc),
                        g_value_get_string (gimp_value_array_index (return_vals, 1)));
        }
      break;
    }
}
static gint
plug_in_collect_item_args (GtkAction       *action,
                           GimpImage       *image,
                           GimpItem        *item,
                           GParamSpec     **pspecs,
                           GimpValueArray  *args,
                           gint             n_args)
{
  if (gimp_value_array_length (args) > n_args &&
      GIMP_IS_PARAM_SPEC_IMAGE_ID (pspecs[n_args]))
    {
      if (image)
        {
          gimp_value_set_image (gimp_value_array_index (args, n_args), image);
          n_args++;

          if (gimp_value_array_length (args) > n_args &&
              GIMP_IS_PARAM_SPEC_ITEM_ID (pspecs[n_args]))
            {
              if (item &&
                  g_type_is_a (G_TYPE_FROM_INSTANCE (item),
                               GIMP_PARAM_SPEC_ITEM_ID (pspecs[n_args])->item_type))
                {
                  gimp_value_set_item (gimp_value_array_index (args, n_args),
                                       item);
                  n_args++;
                }
              else
                {
                  g_warning ("Uh-oh, no active item for the plug-in!");
                  return -1;
                }
            }
        }
    }

  return n_args;
}
Exemple #7
0
static GimpValueArray *
gimp_procedure_real_execute (GimpProcedure   *procedure,
                             Gimp            *gimp,
                             GimpContext     *context,
                             GimpProgress    *progress,
                             GimpValueArray  *args,
                             GError         **error)
{
  g_return_val_if_fail (gimp_value_array_length (args) >=
                        procedure->num_args, NULL);

  return procedure->marshal_func (procedure, gimp,
                                  context, progress,
                                  args, error);
}
static gdouble
gimp_pdb_progress_run_callback (GimpPdbProgress     *progress,
                                GimpProgressCommand  command,
                                const gchar         *text,
                                gdouble              value)
{
  gdouble retval = 0;

  if (progress->callback_name && ! progress->callback_busy)
    {
      GimpValueArray *return_vals;

      progress->callback_busy = TRUE;

      return_vals =
        gimp_pdb_execute_procedure_by_name (progress->pdb,
                                            progress->context,
                                            NULL, NULL,
                                            progress->callback_name,
                                            GIMP_TYPE_INT32, command,
                                            G_TYPE_STRING,   text,
                                            G_TYPE_DOUBLE,   value,
                                            G_TYPE_NONE);

      if (g_value_get_enum (gimp_value_array_index (return_vals, 0)) !=
          GIMP_PDB_SUCCESS)
        {
          gimp_message (progress->context->gimp, NULL, GIMP_MESSAGE_ERROR,
                        _("Unable to run %s callback. "
                          "The corresponding plug-in may have crashed."),
                        g_type_name (G_TYPE_FROM_INSTANCE (progress)));
        }
      else if (gimp_value_array_length (return_vals) >= 2 &&
               G_VALUE_HOLDS_DOUBLE (gimp_value_array_index (return_vals, 1)))
        {
          retval = g_value_get_double (gimp_value_array_index (return_vals, 1));
        }

      gimp_value_array_unref (return_vals);

      progress->callback_busy = FALSE;
    }

  return retval;
}
Exemple #9
0
GimpValueArray *
procedure_commands_get_run_mode_arg (GimpProcedure *procedure)
{
    GimpValueArray *args;
    gint            n_args = 0;

    args = gimp_procedure_get_arguments (procedure);

    /* initialize the first argument  */
    if (gimp_value_array_length (args) > n_args &&
            GIMP_IS_PARAM_SPEC_INT32 (procedure->args[n_args]))
    {
        g_value_set_int (gimp_value_array_index (args, n_args),
                         GIMP_RUN_INTERACTIVE);
        n_args++;
    }

    gimp_value_array_truncate (args, n_args);

    return args;
}
static gint
plug_in_collect_image_args (GtkAction       *action,
                            GimpImage       *image,
                            GParamSpec     **pspecs,
                            GimpValueArray  *args,
                            gint             n_args)
{
  if (gimp_value_array_length (args) > n_args &&
      GIMP_IS_PARAM_SPEC_IMAGE_ID (pspecs[n_args]))
    {
      if (image)
        {
          gimp_value_set_image (gimp_value_array_index (args, n_args), image);
          n_args++;
        }
      else
        {
          g_warning ("Uh-oh, no active image for the plug-in!");
          return -1;
        }
    }

  return n_args;
}
gboolean
plug_in_icc_profile_apply_rgb (GimpImage     *image,
                               GimpContext   *context,
                               GimpProgress  *progress,
                               GimpRunMode    run_mode,
                               GError       **error)
{
  Gimp          *gimp;
  GimpProcedure *procedure;

  g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
  g_return_val_if_fail (GIMP_IS_CONTEXT (context), FALSE);
  g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  gimp = image->gimp;

  if (gimp_image_get_base_type (image) == GIMP_GRAY)
    {
      g_set_error (error, GIMP_PLUG_IN_ERROR, GIMP_PLUG_IN_EXECUTION_FAILED,
                   _("Can't apply color profile to grayscale image (%s)"),
                   ICC_PROFILE_APPLY_RGB_PROC);
      return FALSE;
    }

  procedure = gimp_pdb_lookup_procedure (gimp->pdb, ICC_PROFILE_APPLY_RGB_PROC);

  if (procedure &&
      procedure->num_args >= 2 &&
      GIMP_IS_PARAM_SPEC_INT32 (procedure->args[0]) &&
      GIMP_IS_PARAM_SPEC_IMAGE_ID (procedure->args[1]))
    {
      GimpValueArray         *return_vals;
      GimpPDBStatusType       status;
      GimpColorProfilePolicy  policy = GIMP_COLOR_PROFILE_POLICY_ASK;
      gboolean                success;

      return_vals =
        gimp_pdb_execute_procedure_by_name (gimp->pdb, context, progress, error,
                                            ICC_PROFILE_APPLY_RGB_PROC,
                                            GIMP_TYPE_INT32, run_mode,
                                            GIMP_TYPE_IMAGE_ID,
                                            gimp_image_get_ID (image),
                                            G_TYPE_NONE);

      status = g_value_get_enum (gimp_value_array_index (return_vals, 0));

      switch (status)
        {
        case GIMP_PDB_SUCCESS:
          policy = GIMP_COLOR_PROFILE_POLICY_CONVERT;
          success = TRUE;
          break;

        case GIMP_PDB_CANCEL:
          policy = GIMP_COLOR_PROFILE_POLICY_KEEP;
          success = TRUE;
          break;

        default:
          if (error && *error == NULL)
            g_set_error (error,
                         GIMP_PLUG_IN_ERROR, GIMP_PLUG_IN_EXECUTION_FAILED,
                         _("Error running '%s'"), ICC_PROFILE_APPLY_RGB_PROC);
          success = FALSE;
          break;
        }

      if (success && gimp_value_array_length (return_vals) > 1)
        {
          GValue *value = gimp_value_array_index (return_vals, 1);

          if (GIMP_VALUE_HOLDS_INT32 (value) && g_value_get_int (value))
            {
              g_object_set (G_OBJECT (gimp->config),
                            "color-profile-policy", policy,
                            NULL);
            }
        }

      gimp_value_array_unref (return_vals);

      return success;
    }

  g_set_error (error,
               GIMP_PLUG_IN_ERROR, GIMP_PLUG_IN_NOT_FOUND,
               _("Plug-In missing (%s)"), ICC_PROFILE_APPLY_RGB_PROC);

  return FALSE;
}
Exemple #12
0
/**
 * file_open_thumbnail:
 * @gimp:
 * @context:
 * @progress:
 * @file:         an image file
 * @size:         requested size of the thumbnail
 * @mime_type:    return location for image MIME type
 * @image_width:  return location for image width
 * @image_height: return location for image height
 * @format:       return location for image format (set to NULL if unknown)
 * @num_layers:   return location for number of layers
 *                (set to -1 if the number of layers is not known)
 * @error:
 *
 * Attempts to load a thumbnail by using a registered thumbnail loader.
 *
 * Return value: the thumbnail image
 */
GimpImage *
file_open_thumbnail (Gimp           *gimp,
                     GimpContext    *context,
                     GimpProgress   *progress,
                     GFile          *file,
                     gint            size,
                     const gchar   **mime_type,
                     gint           *image_width,
                     gint           *image_height,
                     const Babl    **format,
                     gint           *num_layers,
                     GError        **error)
{
  GimpPlugInProcedure *file_proc;
  GimpProcedure       *procedure;

  g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
  g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
  g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), NULL);
  g_return_val_if_fail (G_IS_FILE (file), NULL);
  g_return_val_if_fail (mime_type != NULL, NULL);
  g_return_val_if_fail (image_width != NULL, NULL);
  g_return_val_if_fail (image_height != NULL, NULL);
  g_return_val_if_fail (format != NULL, NULL);
  g_return_val_if_fail (num_layers != NULL, NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

  *image_width  = 0;
  *image_height = 0;
  *format       = NULL;
  *num_layers   = -1;

  file_proc = file_procedure_find (gimp->plug_in_manager->load_procs, file,
                                   NULL);

  if (! file_proc || ! file_proc->thumb_loader)
    return NULL;

  procedure = gimp_pdb_lookup_procedure (gimp->pdb, file_proc->thumb_loader);

  if (procedure && procedure->num_args >= 2 && procedure->num_values >= 1)
    {
      GimpPDBStatusType  status;
      GimpValueArray    *return_vals;
      GimpImage         *image = NULL;
      gchar             *path  = NULL;

      if (! file_proc->handles_uri)
        path = g_file_get_path (file);

      if (! path)
        path = g_file_get_uri (file);

      return_vals =
        gimp_pdb_execute_procedure_by_name (gimp->pdb,
                                            context, progress, error,
                                            gimp_object_get_name (procedure),
                                            G_TYPE_STRING,   path,
                                            GIMP_TYPE_INT32, size,
                                            G_TYPE_NONE);

      g_free (path);

      status = g_value_get_enum (gimp_value_array_index (return_vals, 0));

      if (status == GIMP_PDB_SUCCESS &&
          GIMP_VALUE_HOLDS_IMAGE_ID (gimp_value_array_index (return_vals, 1)))
        {
          image = gimp_value_get_image (gimp_value_array_index (return_vals, 1),
                                        gimp);

          if (gimp_value_array_length (return_vals) >= 3 &&
              G_VALUE_HOLDS_INT (gimp_value_array_index (return_vals, 2)) &&
              G_VALUE_HOLDS_INT (gimp_value_array_index (return_vals, 3)))
            {
              *image_width =
                MAX (0, g_value_get_int (gimp_value_array_index (return_vals, 2)));

              *image_height =
                MAX (0, g_value_get_int (gimp_value_array_index (return_vals, 3)));

              if (gimp_value_array_length (return_vals) >= 5 &&
                  G_VALUE_HOLDS_INT (gimp_value_array_index (return_vals, 4)))
                {
                  gint value = g_value_get_int (gimp_value_array_index (return_vals, 4));

                  switch (value)
                    {
                    case GIMP_RGB_IMAGE:
                      *format = gimp_babl_format (GIMP_RGB,
                                                  GIMP_PRECISION_U8_GAMMA,
                                                  FALSE);
                      break;

                    case GIMP_RGBA_IMAGE:
                      *format = gimp_babl_format (GIMP_RGB,
                                                  GIMP_PRECISION_U8_GAMMA,
                                                  TRUE);
                      break;

                    case GIMP_GRAY_IMAGE:
                      *format = gimp_babl_format (GIMP_GRAY,
                                                  GIMP_PRECISION_U8_GAMMA,
                                                  FALSE);
                      break;

                    case GIMP_GRAYA_IMAGE:
                      *format = gimp_babl_format (GIMP_GRAY,
                                                  GIMP_PRECISION_U8_GAMMA,
                                                  TRUE);
                      break;

                    case GIMP_INDEXED_IMAGE:
                    case GIMP_INDEXEDA_IMAGE:
                      {
                        const Babl *rgb;
                        const Babl *rgba;

                        babl_new_palette ("-gimp-indexed-format-dummy",
                                          &rgb, &rgba);

                        if (value == GIMP_INDEXED_IMAGE)
                          *format = rgb;
                        else
                          *format = rgba;
                      }
                      break;

                    default:
                      break;
                    }
                }

              if (gimp_value_array_length (return_vals) >= 6 &&
                  G_VALUE_HOLDS_INT (gimp_value_array_index (return_vals, 5)))
                {
                  *num_layers =
                    MAX (0, g_value_get_int (gimp_value_array_index (return_vals, 5)));
                }
            }

          if (image)
            {
              file_open_sanitize_image (image, FALSE);

              *mime_type = file_proc->mime_type;

#ifdef GIMP_UNSTABLE
              g_printerr ("opened thumbnail at %d x %d\n",
                          gimp_image_get_width  (image),
                          gimp_image_get_height (image));
#endif
            }
        }

      gimp_value_array_unref (return_vals);

      return image;
    }

  return NULL;
}
Exemple #13
0
static void
gimp_device_info_set_property (GObject      *object,
                               guint         property_id,
                               const GValue *value,
                               GParamSpec   *pspec)
{
  GimpDeviceInfo *info       = GIMP_DEVICE_INFO (object);
  GdkDevice      *device     = info->device;
  GimpCurve      *src_curve  = NULL;
  GimpCurve      *dest_curve = NULL;

  switch (property_id)
    {
    case PROP_DEVICE:
      info->device = g_value_get_object (value);
      break;

    case PROP_DISPLAY:
      info->display = g_value_get_object (value);
      break;

    case PROP_MODE:
      gimp_device_info_set_mode (info, g_value_get_enum (value));
      break;

    case PROP_AXES:
      {
        GimpValueArray *array = g_value_get_boxed (value);

        if (array)
          {
            gint i;
            gint n_device_values;

            if (device)
              {
                n_device_values = MIN (gimp_value_array_length (array),
                                       device->num_axes);
              }
            else
              {
                n_device_values = gimp_value_array_length (array);

                info->n_axes = n_device_values;
                info->axes   = g_renew (GdkAxisUse, info->axes, info->n_axes);
                memset (info->axes, 0, info->n_axes * sizeof (GdkAxisUse));
              }

            for (i = 0; i < n_device_values; i++)
              {
                GdkAxisUse axis_use;

                axis_use = g_value_get_enum (gimp_value_array_index (array, i));

                gimp_device_info_set_axis_use (info, i, axis_use);
              }
          }
      }
      break;

    case PROP_KEYS:
      {
        GimpValueArray *array = g_value_get_boxed (value);

        if (array)
          {
            gint i;
            gint n_device_values;

            if (device)
              {
                n_device_values = MIN (gimp_value_array_length (array),
                                       device->num_keys);
              }
            else
              {
                n_device_values = gimp_value_array_length (array);

                info->n_keys = n_device_values;
                info->keys   = g_renew (GdkDeviceKey, info->keys, info->n_keys);
                memset (info->keys, 0, info->n_keys * sizeof (GdkDeviceKey));
              }

            for (i = 0; i < n_device_values; i++)
              {
                const gchar     *accel;
                guint            keyval;
                GdkModifierType  modifiers;

                accel = g_value_get_string (gimp_value_array_index (array, i));

                gtk_accelerator_parse (accel, &keyval, &modifiers);

                gimp_device_info_set_key (info, i, keyval, modifiers);
              }
          }
      }
      break;

    case PROP_PRESSURE_CURVE:
      src_curve  = g_value_get_object (value);
      dest_curve = info->pressure_curve;
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
    }

  if (src_curve && dest_curve)
    {
      gimp_config_copy (GIMP_CONFIG (src_curve),
                        GIMP_CONFIG (dest_curve),
                        GIMP_CONFIG_PARAM_SERIALIZE);
    }
}
Exemple #14
0
static void
gimp_curve_set_property (GObject      *object,
                         guint         property_id,
                         const GValue *value,
                         GParamSpec   *pspec)
{
  GimpCurve *curve = GIMP_CURVE (object);

  switch (property_id)
    {
    case PROP_CURVE_TYPE:
      gimp_curve_set_curve_type (curve, g_value_get_enum (value));
      break;

    case PROP_N_POINTS:
      gimp_curve_set_n_points (curve, g_value_get_int (value));
      break;

    case PROP_POINTS:
      {
        GimpValueArray *array = g_value_get_boxed (value);
        gint            length;
        gint            i;

        if (! array)
          break;

        length = gimp_value_array_length (array);

        for (i = 0; i < curve->n_points && i * 2 < length; i++)
          {
            GValue *x = gimp_value_array_index (array, i * 2);
            GValue *y = gimp_value_array_index (array, i * 2 + 1);

            curve->points[i].x = g_value_get_double (x);
            curve->points[i].y = g_value_get_double (y);
          }
      }
      break;

    case PROP_N_SAMPLES:
      gimp_curve_set_n_samples (curve, g_value_get_int (value));
      break;

    case PROP_SAMPLES:
      {
        GimpValueArray *array = g_value_get_boxed (value);
        gint            length;
        gint            i;

        if (! array)
          break;

        length = gimp_value_array_length (array);

        for (i = 0; i < curve->n_samples && i < length; i++)
          {
            GValue *v = gimp_value_array_index (array, i);

            curve->samples[i] = g_value_get_double (v);
          }
      }
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
    }
}
Exemple #15
0
static gboolean
gimp_procedure_validate_args (GimpProcedure  *procedure,
                              GParamSpec    **param_specs,
                              gint            n_param_specs,
                              GimpValueArray *args,
                              gboolean        return_vals,
                              GError        **error)
{
  gint i;

  for (i = 0; i < MIN (gimp_value_array_length (args), n_param_specs); i++)
    {
      GValue     *arg       = gimp_value_array_index (args, i);
      GParamSpec *pspec     = param_specs[i];
      GType       arg_type  = G_VALUE_TYPE (arg);
      GType       spec_type = G_PARAM_SPEC_VALUE_TYPE (pspec);

      if (arg_type != spec_type)
        {
          if (return_vals)
            {
              g_set_error (error,
                           GIMP_PDB_ERROR, GIMP_PDB_ERROR_INVALID_RETURN_VALUE,
                           _("Procedure '%s' returned a wrong value type "
                             "for return value '%s' (#%d). "
                             "Expected %s, got %s."),
                           gimp_object_get_name (procedure),
                           g_param_spec_get_name (pspec),
                           i + 1, g_type_name (spec_type),
                           g_type_name (arg_type));
            }
          else
            {
              g_set_error (error,
                           GIMP_PDB_ERROR, GIMP_PDB_ERROR_INVALID_ARGUMENT,
                           _("Procedure '%s' has been called with a "
                             "wrong value type for argument '%s' (#%d). "
                             "Expected %s, got %s."),
                           gimp_object_get_name (procedure),
                           g_param_spec_get_name (pspec),
                           i + 1, g_type_name (spec_type),
                           g_type_name (arg_type));
            }

          return FALSE;
        }
      else if (! (pspec->flags & GIMP_PARAM_NO_VALIDATE))
        {
          GValue string_value = { 0, };

          g_value_init (&string_value, G_TYPE_STRING);

          if (g_value_type_transformable (arg_type, G_TYPE_STRING))
            g_value_transform (arg, &string_value);
          else
            g_value_set_static_string (&string_value,
                                       "<not transformable to string>");

          if (g_param_value_validate (pspec, arg))
            {
              if (GIMP_IS_PARAM_SPEC_DRAWABLE_ID (pspec) &&
                  g_value_get_int (arg) == -1)
                {
                  if (return_vals)
                    {
                      g_set_error (error,
                                   GIMP_PDB_ERROR,
                                   GIMP_PDB_ERROR_INVALID_RETURN_VALUE,
                                   _("Procedure '%s' returned an "
                                     "invalid ID for argument '%s'. "
                                     "Most likely a plug-in is trying "
                                     "to work on a layer that doesn't "
                                     "exist any longer."),
                                   gimp_object_get_name (procedure),
                                   g_param_spec_get_name (pspec));
                    }
                  else
                    {
                      g_set_error (error,
                                   GIMP_PDB_ERROR,
                                   GIMP_PDB_ERROR_INVALID_ARGUMENT,
                                   _("Procedure '%s' has been called with an "
                                     "invalid ID for argument '%s'. "
                                     "Most likely a plug-in is trying "
                                     "to work on a layer that doesn't "
                                     "exist any longer."),
                                   gimp_object_get_name (procedure),
                                   g_param_spec_get_name (pspec));
                    }
                }
              else if (GIMP_IS_PARAM_SPEC_IMAGE_ID (pspec) &&
                       g_value_get_int (arg) == -1)
                {
                  if (return_vals)
                    {
                      g_set_error (error,
                                   GIMP_PDB_ERROR,
                                   GIMP_PDB_ERROR_INVALID_RETURN_VALUE,
                                   _("Procedure '%s' returned an "
                                     "invalid ID for argument '%s'. "
                                     "Most likely a plug-in is trying "
                                     "to work on an image that doesn't "
                                     "exist any longer."),
                                   gimp_object_get_name (procedure),
                                   g_param_spec_get_name (pspec));
                    }
                  else
                    {
                      g_set_error (error,
                                   GIMP_PDB_ERROR,
                                   GIMP_PDB_ERROR_INVALID_ARGUMENT,
                                   _("Procedure '%s' has been called with an "
                                     "invalid ID for argument '%s'. "
                                     "Most likely a plug-in is trying "
                                     "to work on an image that doesn't "
                                     "exist any longer."),
                                   gimp_object_get_name (procedure),
                                   g_param_spec_get_name (pspec));
                    }
                }
              else
                {
                  const gchar *value = g_value_get_string (&string_value);

                  if (value == NULL)
                    value = "(null)";

                  if (return_vals)
                    {
                      g_set_error (error,
                                   GIMP_PDB_ERROR,
                                   GIMP_PDB_ERROR_INVALID_RETURN_VALUE,
                                   _("Procedure '%s' returned "
                                     "'%s' as return value '%s' "
                                     "(#%d, type %s). "
                                     "This value is out of range."),
                                   gimp_object_get_name (procedure),
                                   value,
                                   g_param_spec_get_name (pspec),
                                   i + 1, g_type_name (spec_type));
                    }
                  else
                    {
                      g_set_error (error,
                                   GIMP_PDB_ERROR,
                                   GIMP_PDB_ERROR_INVALID_ARGUMENT,
                                   _("Procedure '%s' has been called with "
                                     "value '%s' for argument '%s' "
                                     "(#%d, type %s). "
                                     "This value is out of range."),
                                   gimp_object_get_name (procedure),
                                   value,
                                   g_param_spec_get_name (pspec),
                                   i + 1, g_type_name (spec_type));
                    }
                }

              g_value_unset (&string_value);

              return FALSE;
            }

          g_value_unset (&string_value);
        }
    }

  return TRUE;
}
Exemple #16
0
static GimpValueArray *
file_load_invoker (GimpProcedure         *procedure,
                   Gimp                  *gimp,
                   GimpContext           *context,
                   GimpProgress          *progress,
                   const GimpValueArray  *args,
                   GError               **error)
{
  GimpValueArray      *new_args;
  GimpValueArray      *return_vals;
  GimpPlugInProcedure *file_proc;
  GimpProcedure       *proc;
  gchar               *uri;
  gint                 i;

  uri = file_utils_filename_to_uri (gimp,
                                    g_value_get_string (gimp_value_array_index (args, 1)),
                                    error);

  if (! uri)
    return gimp_procedure_get_return_values (procedure, FALSE,
                                             error ? *error : NULL);

  file_proc =
    file_procedure_find (gimp->plug_in_manager->load_procs, uri, error);

  g_free (uri);

  if (! file_proc)
    return gimp_procedure_get_return_values (procedure, FALSE,
                                             error ? *error : NULL);

  proc = GIMP_PROCEDURE (file_proc);

  new_args = gimp_procedure_get_arguments (proc);

  for (i = 0; i < 3; i++)
    g_value_transform (gimp_value_array_index (args, i),
                       gimp_value_array_index (new_args, i));

  for (i = 3; i < proc->num_args; i++)
    if (G_IS_PARAM_SPEC_STRING (proc->args[i]))
      g_value_set_static_string (gimp_value_array_index (new_args, i), "");

  return_vals =
    gimp_pdb_execute_procedure_by_name_args (gimp->pdb,
                                             context, progress, error,
                                             gimp_object_get_name (proc),
                                             new_args);

  gimp_value_array_unref (new_args);

  if (g_value_get_enum (gimp_value_array_index (return_vals, 0)) ==
      GIMP_PDB_SUCCESS)
    {
      if (gimp_value_array_length (return_vals) > 1 &&
          GIMP_VALUE_HOLDS_IMAGE_ID (gimp_value_array_index (return_vals, 1)))
        {
          GimpImage *image =
            gimp_value_get_image (gimp_value_array_index (return_vals, 1),
                                  gimp);
          gimp_image_set_load_proc (image, file_proc);
        }
    }

  return return_vals;
}
Exemple #17
0
GimpValueArray *
gimp_procedure_execute (GimpProcedure   *procedure,
                        Gimp            *gimp,
                        GimpContext     *context,
                        GimpProgress    *progress,
                        GimpValueArray  *args,
                        GError         **error)
{
  GimpValueArray *return_vals;
  GError         *pdb_error = NULL;

  g_return_val_if_fail (GIMP_IS_PROCEDURE (procedure), NULL);
  g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
  g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
  g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), NULL);
  g_return_val_if_fail (args != NULL, NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

  if (! gimp_procedure_validate_args (procedure,
                                      procedure->args, procedure->num_args,
                                      args, FALSE, &pdb_error))
    {
      return_vals = gimp_procedure_get_return_values (procedure, FALSE,
                                                      pdb_error);
      g_propagate_error (error, pdb_error);

      return return_vals;
    }

  if (GIMP_IS_PDB_CONTEXT (context))
    context = g_object_ref (context);
  else
    context = gimp_pdb_context_new (gimp, context, TRUE);

  /*  call the procedure  */
  return_vals = GIMP_PROCEDURE_GET_CLASS (procedure)->execute (procedure,
                                                               gimp,
                                                               context,
                                                               progress,
                                                               args,
                                                               error);

  g_object_unref (context);

  if (return_vals)
    {
      switch (g_value_get_enum (gimp_value_array_index (return_vals, 0)))
        {
        case GIMP_PDB_CALLING_ERROR:
        case GIMP_PDB_EXECUTION_ERROR:
          /*  If the error has not already been set, construct one
           *  from the error message that is optionally passed with
           *  the return values.
           */
          if (error && *error == NULL &&
              gimp_value_array_length (return_vals) > 1 &&
              G_VALUE_HOLDS_STRING (gimp_value_array_index (return_vals, 1)))
            {
              GValue      *value   = gimp_value_array_index (return_vals, 1);
              const gchar *message = g_value_get_string (value);

              if (message)
                g_set_error_literal (error, GIMP_PDB_ERROR,
                                     GIMP_PDB_ERROR_FAILED,
                                     message);
            }
          break;

        default:
          break;
        }
    }
  else
    {
      g_warning ("%s: no return values, shouldn't happen", G_STRFUNC);

      pdb_error = g_error_new (GIMP_PDB_ERROR,
                               GIMP_PDB_ERROR_INVALID_RETURN_VALUE,
                               _("Procedure '%s' returned no return values"),
                               gimp_object_get_name (procedure));

      return_vals = gimp_procedure_get_return_values (procedure, FALSE,
                                                      pdb_error);
      if (error && *error == NULL)
        g_propagate_error (error, pdb_error);
      else
        g_error_free (pdb_error);

    }

  return return_vals;
}
GimpValueArray *
gimp_plug_in_manager_call_run (GimpPlugInManager   *manager,
                               GimpContext         *context,
                               GimpProgress        *progress,
                               GimpPlugInProcedure *procedure,
                               GimpValueArray      *args,
                               gboolean             synchronous,
                               GimpObject          *display)
{
  GimpValueArray *return_vals = NULL;
  GimpPlugIn     *plug_in;

  g_return_val_if_fail (GIMP_IS_PLUG_IN_MANAGER (manager), NULL);
  g_return_val_if_fail (GIMP_IS_PDB_CONTEXT (context), NULL);
  g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), NULL);
  g_return_val_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (procedure), NULL);
  g_return_val_if_fail (args != NULL, NULL);
  g_return_val_if_fail (display == NULL || GIMP_IS_OBJECT (display), NULL);

  plug_in = gimp_plug_in_new (manager, context, progress, procedure, NULL);

  if (plug_in)
    {
      GimpCoreConfig    *core_config    = manager->gimp->config;
      GimpGeglConfig    *gegl_config    = GIMP_GEGL_CONFIG (core_config);
      GimpDisplayConfig *display_config = GIMP_DISPLAY_CONFIG (core_config);
      GimpGuiConfig     *gui_config     = GIMP_GUI_CONFIG (core_config);
      GPConfig           config;
      GPProcRun          proc_run;
      gint               display_ID;
      GObject           *screen;
      gint               monitor;

      if (! gimp_plug_in_open (plug_in, GIMP_PLUG_IN_CALL_RUN, FALSE))
        {
          const gchar *name  = gimp_object_get_name (plug_in);
          GError      *error = g_error_new (GIMP_PLUG_IN_ERROR,
                                            GIMP_PLUG_IN_EXECUTION_FAILED,
                                            _("Failed to run plug-in \"%s\""),
                                            name);

          g_object_unref (plug_in);

          return_vals = gimp_procedure_get_return_values (GIMP_PROCEDURE (procedure),
                                                          FALSE, error);
          g_error_free (error);

          return return_vals;
        }

      display_ID = display ? gimp_get_display_ID (manager->gimp, display) : -1;

      config.version          = GIMP_PROTOCOL_VERSION;
      config.tile_width       = GIMP_PLUG_IN_TILE_WIDTH;
      config.tile_height      = GIMP_PLUG_IN_TILE_HEIGHT;
      config.shm_ID           = (manager->shm ?
                                 gimp_plug_in_shm_get_ID (manager->shm) : -1);
      config.check_size       = display_config->transparency_size;
      config.check_type       = display_config->transparency_type;
      config.show_help_button = (gui_config->use_help &&
                                 gui_config->show_help_button);
      config.use_cpu_accel    = manager->gimp->use_cpu_accel;
      config.use_opencl       = gegl_config->use_opencl;
      config.gimp_reserved_6  = 0;
      config.gimp_reserved_7  = 0;
      config.gimp_reserved_8  = 0;
      config.install_cmap     = FALSE;
      config.show_tooltips    = gui_config->show_tooltips;
      config.min_colors       = 144;
      config.gdisp_ID         = display_ID;
      config.app_name         = (gchar *) g_get_application_name ();
      config.wm_class         = (gchar *) gimp_get_program_class (manager->gimp);
      config.display_name     = gimp_get_display_name (manager->gimp,
                                                       display_ID,
                                                       &screen, &monitor);
      config.monitor_number   = monitor;
      config.timestamp        = gimp_get_user_time (manager->gimp);

      proc_run.name    = GIMP_PROCEDURE (procedure)->original_name;
      proc_run.nparams = gimp_value_array_length (args);
      proc_run.params  = plug_in_args_to_params (args, FALSE);

      if (! gp_config_write (plug_in->my_write, &config, plug_in)     ||
          ! gp_proc_run_write (plug_in->my_write, &proc_run, plug_in) ||
          ! gimp_wire_flush (plug_in->my_write, plug_in))
        {
          const gchar *name  = gimp_object_get_name (plug_in);
          GError      *error = g_error_new (GIMP_PLUG_IN_ERROR,
                                            GIMP_PLUG_IN_EXECUTION_FAILED,
                                            _("Failed to run plug-in \"%s\""),
                                            name);

          g_free (config.display_name);
          g_free (proc_run.params);

          g_object_unref (plug_in);

          return_vals = gimp_procedure_get_return_values (GIMP_PROCEDURE (procedure),
                                                          FALSE, error);
          g_error_free (error);

          return return_vals;
        }

      g_free (config.display_name);
      g_free (proc_run.params);

      /* If this is an extension,
       * wait for an installation-confirmation message
       */
      if (GIMP_PROCEDURE (procedure)->proc_type == GIMP_EXTENSION)
        {
          plug_in->ext_main_loop = g_main_loop_new (NULL, FALSE);

          gimp_threads_leave (manager->gimp);
          g_main_loop_run (plug_in->ext_main_loop);
          gimp_threads_enter (manager->gimp);

          /*  main_loop is quit in gimp_plug_in_handle_extension_ack()  */

          g_main_loop_unref (plug_in->ext_main_loop);
          plug_in->ext_main_loop = NULL;
        }

      /* If this plug-in is requested to run synchronously,
       * wait for its return values
       */
      if (synchronous)
        {
          GimpPlugInProcFrame *proc_frame = &plug_in->main_proc_frame;

          proc_frame->main_loop = g_main_loop_new (NULL, FALSE);

          gimp_threads_leave (manager->gimp);
          g_main_loop_run (proc_frame->main_loop);
          gimp_threads_enter (manager->gimp);

          /*  main_loop is quit in gimp_plug_in_handle_proc_return()  */

          g_main_loop_unref (proc_frame->main_loop);
          proc_frame->main_loop = NULL;

          return_vals = gimp_plug_in_proc_frame_get_return_values (proc_frame);
        }

      g_object_unref (plug_in);
    }

  return return_vals;
}
GimpValueArray *
procedure_commands_get_display_args (GimpProcedure *procedure,
                                     GimpDisplay   *display)
{
  GimpValueArray *args;
  gint            n_args = 0;

  args = gimp_procedure_get_arguments (procedure);

  /* initialize the first argument  */
  g_value_set_int (gimp_value_array_index (args, n_args),
                   GIMP_RUN_INTERACTIVE);
  n_args++;

  if (gimp_value_array_length (args) > n_args &&
      GIMP_IS_PARAM_SPEC_DISPLAY_ID (procedure->args[n_args]))
    {
      if (display)
        {
          gimp_value_set_display (gimp_value_array_index (args, n_args),
                                  GIMP_OBJECT (display));
          n_args++;
        }
      else
        {
          g_warning ("Uh-oh, no active display for the plug-in!");
          gimp_value_array_unref (args);
          return NULL;
        }
    }

  if (gimp_value_array_length (args) > n_args &&
      GIMP_IS_PARAM_SPEC_IMAGE_ID (procedure->args[n_args]))
    {
      GimpImage *image = display ? gimp_display_get_image (display) : NULL;

      if (image)
        {
          gimp_value_set_image (gimp_value_array_index (args, n_args),
                                image);
          n_args++;

          if (gimp_value_array_length (args) > n_args &&
              GIMP_IS_PARAM_SPEC_DRAWABLE_ID (procedure->args[n_args]))
            {
              GimpDrawable *drawable = gimp_image_get_active_drawable (image);

              if (drawable)
                {
                  gimp_value_set_drawable (gimp_value_array_index (args, n_args),
                                           drawable);
                  n_args++;
                }
              else
                {
                  g_warning ("Uh-oh, no active drawable for the plug-in!");
                  gimp_value_array_unref (args);
                  return NULL;
                }
            }
        }
    }

  gimp_value_array_truncate (args, n_args);

  return args;
}
GimpValueArray *
gimp_plug_in_manager_call_run_temp (GimpPlugInManager      *manager,
                                    GimpContext            *context,
                                    GimpProgress           *progress,
                                    GimpTemporaryProcedure *procedure,
                                    GimpValueArray         *args)
{
  GimpValueArray *return_vals = NULL;
  GimpPlugIn     *plug_in;

  g_return_val_if_fail (GIMP_IS_PLUG_IN_MANAGER (manager), NULL);
  g_return_val_if_fail (GIMP_IS_PDB_CONTEXT (context), NULL);
  g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), NULL);
  g_return_val_if_fail (GIMP_IS_TEMPORARY_PROCEDURE (procedure), NULL);
  g_return_val_if_fail (args != NULL, NULL);

  plug_in = procedure->plug_in;

  if (plug_in)
    {
      GimpPlugInProcFrame *proc_frame;
      GPProcRun            proc_run;

      proc_frame = gimp_plug_in_proc_frame_push (plug_in, context, progress,
                                                 procedure);

      proc_run.name    = GIMP_PROCEDURE (procedure)->original_name;
      proc_run.nparams = gimp_value_array_length (args);
      proc_run.params  = plug_in_args_to_params (args, FALSE);

      if (! gp_temp_proc_run_write (plug_in->my_write, &proc_run, plug_in) ||
          ! gimp_wire_flush (plug_in->my_write, plug_in))
        {
          const gchar *name  = gimp_object_get_name (plug_in);
          GError      *error = g_error_new (GIMP_PLUG_IN_ERROR,
                                            GIMP_PLUG_IN_EXECUTION_FAILED,
                                            _("Failed to run plug-in \"%s\""),
                                            name);

          g_free (proc_run.params);
          gimp_plug_in_proc_frame_pop (plug_in);

          return_vals = gimp_procedure_get_return_values (GIMP_PROCEDURE (procedure),
                                                          FALSE, error);
          g_error_free (error);

          return return_vals;
        }

      g_free (proc_run.params);

      g_object_ref (plug_in);
      gimp_plug_in_proc_frame_ref (proc_frame);

      gimp_plug_in_main_loop (plug_in);

      /*  main_loop is quit and proc_frame is popped in
       *  gimp_plug_in_handle_temp_proc_return()
       */

      return_vals = gimp_plug_in_proc_frame_get_return_values (proc_frame);

      gimp_plug_in_proc_frame_unref (proc_frame, plug_in);
      g_object_unref (plug_in);
    }

  return return_vals;
}
GPParam *
plug_in_args_to_params (GimpValueArray *args,
                        gboolean        full_copy)
{
  GPParam *params;
  gint     length;
  gint     i;

  g_return_val_if_fail (args != NULL, NULL);

  params = g_new0 (GPParam, gimp_value_array_length (args));

  length = gimp_value_array_length (args);

  for (i = 0; i < length; i++)
    {
      GValue *value = gimp_value_array_index (args, i);

      params[i].type =
        gimp_pdb_compat_arg_type_from_gtype (G_VALUE_TYPE (value));

      switch (params[i].type)
        {
        case GIMP_PDB_INT32:
          if (G_VALUE_HOLDS_INT (value))
            params[i].data.d_int32 = g_value_get_int (value);
          else if (G_VALUE_HOLDS_UINT (value))
            params[i].data.d_int32 = g_value_get_uint (value);
          else if (G_VALUE_HOLDS_ENUM (value))
            params[i].data.d_int32 = g_value_get_enum (value);
          else if (G_VALUE_HOLDS_BOOLEAN (value))
            params[i].data.d_int32 = g_value_get_boolean (value);
          else
            {
              g_printerr ("%s: unhandled GIMP_PDB_INT32 type: %s\n",
                          G_STRFUNC, g_type_name (G_VALUE_TYPE (value)));
              g_return_val_if_reached (params);
            }
          break;

        case GIMP_PDB_INT16:
          params[i].data.d_int16 = g_value_get_int (value);
          break;

        case GIMP_PDB_INT8:
          params[i].data.d_int8 = g_value_get_uint (value);
          break;

        case GIMP_PDB_FLOAT:
          params[i].data.d_float = g_value_get_double (value);
          break;

        case GIMP_PDB_STRING:
          if (full_copy)
            params[i].data.d_string = g_value_dup_string (value);
          else
            params[i].data.d_string = (gchar *) g_value_get_string (value);
          break;

        case GIMP_PDB_INT32ARRAY:
          if (full_copy)
            params[i].data.d_int32array = gimp_value_dup_int32array (value);
          else
            params[i].data.d_int32array = (gint32 *) gimp_value_get_int32array (value);
          break;

        case GIMP_PDB_INT16ARRAY:
          if (full_copy)
            params[i].data.d_int16array = gimp_value_dup_int16array (value);
          else
            params[i].data.d_int16array = (gint16 *) gimp_value_get_int16array (value);
          break;

        case GIMP_PDB_INT8ARRAY:
          if (full_copy)
            params[i].data.d_int8array = gimp_value_dup_int8array (value);
          else
            params[i].data.d_int8array = (guint8 *) gimp_value_get_int8array (value);
          break;

        case GIMP_PDB_FLOATARRAY:
          if (full_copy)
            params[i].data.d_floatarray = gimp_value_dup_floatarray (value);
          else
            params[i].data.d_floatarray = (gdouble *) gimp_value_get_floatarray (value);
          break;

        case GIMP_PDB_STRINGARRAY:
          if (full_copy)
            params[i].data.d_stringarray = gimp_value_dup_stringarray (value);
          else
            params[i].data.d_stringarray = (gchar **) gimp_value_get_stringarray (value);
          break;

        case GIMP_PDB_COLOR:
          gimp_value_get_rgb (value, &params[i].data.d_color);
          break;

        case GIMP_PDB_ITEM:
          params[i].data.d_item = g_value_get_int (value);
          break;

        case GIMP_PDB_DISPLAY:
          params[i].data.d_display = g_value_get_int (value);
          break;

        case GIMP_PDB_IMAGE:
          params[i].data.d_image = g_value_get_int (value);
          break;

        case GIMP_PDB_LAYER:
          params[i].data.d_layer = g_value_get_int (value);
          break;

        case GIMP_PDB_CHANNEL:
          params[i].data.d_channel = g_value_get_int (value);
          break;

        case GIMP_PDB_DRAWABLE:
          params[i].data.d_drawable = g_value_get_int (value);
          break;

        case GIMP_PDB_SELECTION:
          params[i].data.d_selection = g_value_get_int (value);
          break;

        case GIMP_PDB_COLORARRAY:
          if (full_copy)
            params[i].data.d_colorarray = gimp_value_dup_colorarray (value);
          else
            params[i].data.d_colorarray = (GimpRGB *) gimp_value_get_colorarray (value);
          break;

        case GIMP_PDB_VECTORS:
          params[i].data.d_vectors = g_value_get_int (value);
          break;

        case GIMP_PDB_PARASITE:
          {
            GimpParasite *parasite = (full_copy ?
                                      g_value_dup_boxed (value) :
                                      g_value_get_boxed (value));

            if (parasite)
              {
                params[i].data.d_parasite.name  = parasite->name;
                params[i].data.d_parasite.flags = parasite->flags;
                params[i].data.d_parasite.size  = parasite->size;
                params[i].data.d_parasite.data  = parasite->data;

                if (full_copy)
                  {
                    parasite->name  = NULL;
                    parasite->flags = 0;
                    parasite->size  = 0;
                    parasite->data  = NULL;

                    gimp_parasite_free (parasite);
                  }
              }
            else
              {
                params[i].data.d_parasite.name  = NULL;
                params[i].data.d_parasite.flags = 0;
                params[i].data.d_parasite.size  = 0;
                params[i].data.d_parasite.data  = NULL;
              }
          }
          break;

        case GIMP_PDB_STATUS:
          params[i].data.d_status = g_value_get_enum (value);
          break;

        case GIMP_PDB_END:
          break;
        }
    }

  return params;
}
static void
gimp_plug_in_handle_proc_run (GimpPlugIn *plug_in,
                              GPProcRun  *proc_run)
{
  GimpPlugInProcFrame *proc_frame;
  gchar               *canonical;
  const gchar         *proc_name   = NULL;
  GimpProcedure       *procedure;
  GimpValueArray      *args        = NULL;
  GimpValueArray      *return_vals = NULL;
  GError              *error       = NULL;

  g_return_if_fail (proc_run != NULL);
  g_return_if_fail (proc_run->name != NULL);

  canonical = gimp_canonicalize_identifier (proc_run->name);

  proc_frame = gimp_plug_in_get_proc_frame (plug_in);

  procedure = gimp_pdb_lookup_procedure (plug_in->manager->gimp->pdb,
                                         canonical);

  if (! procedure)
    {
      proc_name = gimp_pdb_lookup_compat_proc_name (plug_in->manager->gimp->pdb,
                                                    canonical);

      if (proc_name)
        {
          procedure = gimp_pdb_lookup_procedure (plug_in->manager->gimp->pdb,
                                                 proc_name);

          if (plug_in->manager->gimp->pdb_compat_mode == GIMP_PDB_COMPAT_WARN)
            {
              gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_WARNING,
                            "Plug-In \"%s\"\n(%s)\n"
                            "called deprecated procedure '%s'.\n"
                            "It should call '%s' instead!",
                            gimp_object_get_name (plug_in),
                            gimp_file_get_utf8_name (plug_in->file),
                            canonical, proc_name);
            }
        }
    }
  else if (procedure->deprecated)
    {
      if (plug_in->manager->gimp->pdb_compat_mode == GIMP_PDB_COMPAT_WARN)
        {
          if (! strcmp (procedure->deprecated, "NONE"))
            {
              gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_WARNING,
                            "Plug-In \"%s\"\n(%s)\n"
                            "called deprecated procedure '%s'.",
                            gimp_object_get_name (plug_in),
                            gimp_file_get_utf8_name (plug_in->file),
                            canonical);
            }
          else
            {
              gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_WARNING,
                            "WARNING: Plug-In \"%s\"\n(%s)\n"
                            "called deprecated procedure '%s'.\n"
                            "It should call '%s' instead!",
                            gimp_object_get_name (plug_in),
                            gimp_file_get_utf8_name (plug_in->file),
                            canonical, procedure->deprecated);
            }
        }
    }

  if (! proc_name)
    proc_name = canonical;

  args = plug_in_params_to_args (procedure ? procedure->args     : NULL,
                                 procedure ? procedure->num_args : 0,
                                 proc_run->params, proc_run->nparams,
                                 FALSE, FALSE);

  /*  Execute the procedure even if gimp_pdb_lookup_procedure()
   *  returned NULL, gimp_pdb_execute_procedure_by_name_args() will
   *  return appropriate error return_vals.
   */
  gimp_plug_in_manager_plug_in_push (plug_in->manager, plug_in);
  return_vals = gimp_pdb_execute_procedure_by_name_args (plug_in->manager->gimp->pdb,
                                                         proc_frame->context_stack ?
                                                         proc_frame->context_stack->data :
                                                         proc_frame->main_context,
                                                         proc_frame->progress,
                                                         &error,
                                                         proc_name,
                                                         args);
  gimp_plug_in_manager_plug_in_pop (plug_in->manager);

  gimp_value_array_unref (args);

  if (error)
    {
      gimp_plug_in_handle_proc_error (plug_in, proc_frame,
                                      canonical, error);
      g_error_free (error);
    }

  g_free (canonical);

  /*  Don't bother to send the return value if executing the procedure
   *  closed the plug-in (e.g. if the procedure is gimp-quit)
   */
  if (plug_in->open)
    {
      GPProcReturn proc_return;

      /*  Return the name we got called with, *not* proc_name or canonical,
       *  since proc_name may have been remapped by gimp->procedural_compat_ht
       *  and canonical may be different too.
       */
      proc_return.name    = proc_run->name;
      proc_return.nparams = gimp_value_array_length (return_vals);
      proc_return.params  = plug_in_args_to_params (return_vals, FALSE);

      if (! gp_proc_return_write (plug_in->my_write, &proc_return, plug_in))
        {
          gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR,
                        "%s: ERROR", G_STRFUNC);
          gimp_plug_in_close (plug_in, TRUE);
        }

      g_free (proc_return.params);
    }

  gimp_value_array_unref (return_vals);
}