gboolean gimp_plug_in_manager_register_load_handler (GimpPlugInManager *manager, const gchar *name, const gchar *extensions, const gchar *prefixes, const gchar *magics) { GimpPlugInProcedure *file_proc; GimpProcedure *procedure; GSList *list; g_return_val_if_fail (GIMP_IS_PLUG_IN_MANAGER (manager), FALSE); g_return_val_if_fail (name != NULL, FALSE); if (manager->current_plug_in && manager->current_plug_in->plug_in_def) list = manager->current_plug_in->plug_in_def->procedures; else list = manager->plug_in_procedures; file_proc = gimp_plug_in_procedure_find (list, name); if (! file_proc) { gimp_message (manager->gimp, NULL, GIMP_MESSAGE_ERROR, "attempt to register nonexistent load handler \"%s\"", name); return FALSE; } procedure = GIMP_PROCEDURE (file_proc); if ((procedure->num_args < 3) || (procedure->num_values < 1) || ! GIMP_IS_PARAM_SPEC_INT32 (procedure->args[0]) || ! G_IS_PARAM_SPEC_STRING (procedure->args[1]) || ! G_IS_PARAM_SPEC_STRING (procedure->args[2]) || ! GIMP_IS_PARAM_SPEC_IMAGE_ID (procedure->values[0])) { gimp_message (manager->gimp, NULL, GIMP_MESSAGE_ERROR, "load handler \"%s\" does not take the standard " "load handler args", name); return FALSE; } gimp_plug_in_procedure_set_file_proc (file_proc, extensions, prefixes, magics); if (! g_slist_find (manager->load_procs, file_proc)) manager->load_procs = g_slist_prepend (manager->load_procs, file_proc); return TRUE; }
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; }
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 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; }
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; }
static gboolean gimp_procedure_validate_args (GimpProcedure *procedure, GParamSpec **param_specs, gint n_param_specs, GValueArray *args, gboolean return_vals, GError **error) { gint i; for (i = 0; i < MIN (args->n_values, n_param_specs); i++) { GValue *arg = &args->values[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_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_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_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_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_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_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_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_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)); } } return FALSE; } g_value_unset (&string_value); } } return TRUE; }
gboolean gimp_plug_in_procedure_add_menu_path (GimpPlugInProcedure *proc, const gchar *menu_path, GError **error) { GimpProcedure *procedure; gchar *basename = NULL; const gchar *required = NULL; gchar *p; gchar *mapped_path; g_return_val_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc), FALSE); g_return_val_if_fail (menu_path != NULL, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); procedure = GIMP_PROCEDURE (proc); p = strchr (menu_path, '>'); if (p == NULL || (*(++p) && *p != '/')) { basename = g_filename_display_basename (proc->prog); g_set_error (error, GIMP_PLUG_IN_ERROR, GIMP_PLUG_IN_FAILED, "Plug-In \"%s\"\n(%s)\n" "attempted to install procedure \"%s\"\n" "in the invalid menu location \"%s\".\n" "The menu path must look like either \"<Prefix>\" " "or \"<Prefix>/path/to/item\".", basename, gimp_filename_to_utf8 (proc->prog), gimp_object_get_name (proc), menu_path); goto failure; } if (g_str_has_prefix (menu_path, "<Toolbox>") || g_str_has_prefix (menu_path, "<Image>")) { if ((procedure->num_args < 1) || ! GIMP_IS_PARAM_SPEC_INT32 (procedure->args[0])) { required = "INT32"; goto failure; } } else if (g_str_has_prefix (menu_path, "<Layers>")) { if ((procedure->num_args < 3) || ! GIMP_IS_PARAM_SPEC_INT32 (procedure->args[0]) || ! GIMP_IS_PARAM_SPEC_IMAGE_ID (procedure->args[1]) || ! (G_TYPE_FROM_INSTANCE (procedure->args[2]) == GIMP_TYPE_PARAM_LAYER_ID || G_TYPE_FROM_INSTANCE (procedure->args[2]) == GIMP_TYPE_PARAM_DRAWABLE_ID)) { required = "INT32, IMAGE, (LAYER | DRAWABLE)"; goto failure; } } else if (g_str_has_prefix (menu_path, "<Channels>")) { if ((procedure->num_args < 3) || ! GIMP_IS_PARAM_SPEC_INT32 (procedure->args[0]) || ! GIMP_IS_PARAM_SPEC_IMAGE_ID (procedure->args[1]) || ! (G_TYPE_FROM_INSTANCE (procedure->args[2]) == GIMP_TYPE_PARAM_CHANNEL_ID || G_TYPE_FROM_INSTANCE (procedure->args[2]) == GIMP_TYPE_PARAM_DRAWABLE_ID)) { required = "INT32, IMAGE, (CHANNEL | DRAWABLE)"; goto failure; } } else if (g_str_has_prefix (menu_path, "<Vectors>")) { if ((procedure->num_args < 3) || ! GIMP_IS_PARAM_SPEC_INT32 (procedure->args[0]) || ! GIMP_IS_PARAM_SPEC_IMAGE_ID (procedure->args[1]) || ! GIMP_IS_PARAM_SPEC_VECTORS_ID (procedure->args[2])) { required = "INT32, IMAGE, VECTORS"; goto failure; } } else if (g_str_has_prefix (menu_path, "<Colormap>")) { if ((procedure->num_args < 2) || ! GIMP_IS_PARAM_SPEC_INT32 (procedure->args[0]) || ! GIMP_IS_PARAM_SPEC_IMAGE_ID (procedure->args[1])) { required = "INT32, IMAGE"; goto failure; } } else if (g_str_has_prefix (menu_path, "<Load>")) { if ((procedure->num_args < 3) || ! GIMP_IS_PARAM_SPEC_INT32 (procedure->args[0]) || ! G_IS_PARAM_SPEC_STRING (procedure->args[1]) || ! G_IS_PARAM_SPEC_STRING (procedure->args[2])) { required = "INT32, STRING, STRING"; goto failure; } if ((procedure->num_values < 1) || ! GIMP_IS_PARAM_SPEC_IMAGE_ID (procedure->values[0])) { required = "IMAGE"; goto failure; } } else if (g_str_has_prefix (menu_path, "<Save>")) { if ((procedure->num_args < 5) || ! GIMP_IS_PARAM_SPEC_INT32 (procedure->args[0]) || ! GIMP_IS_PARAM_SPEC_IMAGE_ID (procedure->args[1]) || ! GIMP_IS_PARAM_SPEC_DRAWABLE_ID (procedure->args[2]) || ! G_IS_PARAM_SPEC_STRING (procedure->args[3]) || ! G_IS_PARAM_SPEC_STRING (procedure->args[4])) { required = "INT32, IMAGE, DRAWABLE, STRING, STRING"; goto failure; } } else if (g_str_has_prefix (menu_path, "<Brushes>") || g_str_has_prefix (menu_path, "<Gradients>") || g_str_has_prefix (menu_path, "<Palettes>") || g_str_has_prefix (menu_path, "<Patterns>") || g_str_has_prefix (menu_path, "<Fonts>") || g_str_has_prefix (menu_path, "<Buffers>")) { if ((procedure->num_args < 1) || ! GIMP_IS_PARAM_SPEC_INT32 (procedure->args[0])) { required = "INT32"; goto failure; } } else { basename = g_filename_display_basename (proc->prog); g_set_error (error, GIMP_PLUG_IN_ERROR, GIMP_PLUG_IN_FAILED, "Plug-In \"%s\"\n(%s)\n" "attempted to install procedure \"%s\" " "in the invalid menu location \"%s\".\n" "Use either \"<Toolbox>\", \"<Image>\", " "\"<Layers>\", \"<Channels>\", \"<Vectors>\", " "\"<Colormap>\", \"<Load>\", \"<Save>\", " "\"<Brushes>\", \"<Gradients>\", \"<Palettes>\", " "\"<Patterns>\" or \"<Buffers>\".", basename, gimp_filename_to_utf8 (proc->prog), gimp_object_get_name (proc), menu_path); goto failure; } g_free (basename); mapped_path = plug_in_menu_path_map (menu_path, NULL); proc->menu_paths = g_list_append (proc->menu_paths, mapped_path); g_signal_emit (proc, gimp_plug_in_procedure_signals[MENU_PATH_ADDED], 0, mapped_path); return TRUE; failure: if (required) { gchar *prefix = g_strdup (menu_path); p = strchr (prefix, '>') + 1; *p = '\0'; basename = g_filename_display_basename (proc->prog); g_set_error (error, GIMP_PLUG_IN_ERROR, GIMP_PLUG_IN_FAILED, "Plug-In \"%s\"\n(%s)\n\n" "attempted to install %s procedure \"%s\" " "which does not take the standard %s Plug-In " "arguments: (%s).", basename, gimp_filename_to_utf8 (proc->prog), prefix, gimp_object_get_name (proc), prefix, required); g_free (prefix); } g_free (basename); return FALSE; }
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; }