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; }
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; }
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; }
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; }
/** * 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; }
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); } }
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; } }
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; }
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; }
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, ¶ms[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); }