1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389
|
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <libgimp/gimp.h>
#include "script-fu-lib.h"
#include "script-fu-types.h" /* SFScript */
#include "scheme-wrapper.h" /* tinyscheme_init etc, */
#include "script-fu-scripts.h" /* script_fu_find_scripts */
#include "script-fu-script.h" /* script_fu_script_get_i18n */
#include "script-fu-interface.h" /* script_fu_interface_is_active */
#include "script-fu-proc-factory.h"
/*
* The purpose here is a small, clean API to the exported functions of the library,
* hiding internal types of the library
* and hiding functions not static but not exported.
*
* Some are simple delegation to scheme_wrapper functions,
* but others adapt
* and some call functions not in scheme_wrapper.c
*/
static gboolean _script_fu_report_progress = FALSE;
/**
* script_fu_report_progress:
*
* Returns: whether we should report progress status automatically
* (normally only within the "extension-script-fu" persistent plug-in).
*/
gboolean
script_fu_report_progress (void)
{
return _script_fu_report_progress;
}
/*
* Return whether extension-script-fu has an open dialog.
* extension-script-fu is a single process.
* It cannot have concurrent dialogs open in the GIMP app.
*
* Other plugins implementing PLUGIN type PDB procedures
* in their own process (e.g. gimp-scheme-interpreter) do not need this.
*/
gboolean
script_fu_extension_is_busy (void)
{
return script_fu_interface_is_active ();
}
/*
* Find files at given paths, load them into the interpreter,
* and register them as PDB procs of type TEMPORARY,
* owned by the PDB proc of type PLUGIN for the given plugin.
*/
void
script_fu_find_and_register_scripts ( GimpPlugIn *plugin,
GList *paths)
{
script_fu_find_scripts (plugin, paths);
}
/*
* Init the embedded interpreter.
*
* allow_register:
* TRUE: allow loaded scripts to register PDB procedures.
* The scheme functions script-fu-register and script-fu-menu-register are
* defined to do something.
* FALSE: The scheme functions script-fu-register and script-fu-menu-register are
* defined but do nothing.
*
* Note that the embedded interpreter always defines scheme functions
* for all PDB procedures already existing when the interpreter starts
* (currently bound at startup, but its possible to lazy bind.)
* allow_register doesn't affect that.
*/
void
script_fu_init_embedded_interpreter (GList *paths,
gboolean allow_register,
GimpRunMode run_mode,
gboolean report_progress)
{
g_debug ("script_fu_init_embedded_interpreter");
_script_fu_report_progress = report_progress;
tinyscheme_init (paths, allow_register);
ts_set_run_mode (run_mode);
/*
* Ensure the embedded interpreter is running and:
* loaded its internal Scheme scripts e.g. init.scm
* defined existing PDB procs as Scheme foreign functions
* (is ready to interpret PDB-like function calls in scheme scripts.)
* has loaded other init and compat scripts in /scripts/init
* e.g. script-fu-compat.scm
*
* The .scm file(s) for plugins in /scripts are NOT loaded.
* Any util scripts in /scripts are NOT loaded, e.g. script-fu-utils.scm.
*/
}
/* Load script files at paths.
* Side effect: create state script_tree.
* Requires interpreter initialized.
*/
void
script_fu_load_scripts_into_tree (GimpPlugIn *plugin,
GList *paths)
{
script_fu_scripts_load_into_tree (plugin, paths);
}
/* Has the interpreter been initialized and a script loaded
* i.e. interpreted for registration into interpreter state: script_tree.
*/
gboolean
script_fu_is_scripts_loaded (void)
{
return script_fu_scripts_are_loaded ();
}
void
script_fu_set_print_flag (gboolean should_print)
{
ts_set_print_flag (should_print);
}
/*
* Make tinyscheme begin writing output to given gstring.
*/
void
script_fu_redirect_output_to_gstr (GString *output)
{
ts_register_output_func (ts_gstring_output_func, output);
}
void
script_fu_redirect_output_to_stdout (void)
{
ts_register_output_func (ts_stdout_output_func, NULL);
}
void
script_fu_print_welcome (void)
{
ts_print_welcome ();
}
gboolean
script_fu_interpret_string (const gchar *text)
{
/*converting from enum to boolean */
return (gboolean) ts_interpret_string (text);
}
void
script_fu_set_run_mode (GimpRunMode run_mode)
{
ts_set_run_mode (run_mode);
}
const gchar *
script_fu_get_success_msg (void)
{
return ts_get_success_msg ();
}
/* Return an error message string for recent failure of script.
*
* Requires an interpretation just returned an error, else returns "Unknown".
* Should be called exactly once per error, else second calls return "Unknown".
*
* Transfer ownership to caller, the string must be freed.
*/
const gchar *
script_fu_get_error_msg (void)
{
return ts_get_error_msg ();
}
/* Return a GError for recent failure of script.
*
* Requires an interpretation just returned an error,
* else returns a GError with message "Unknown".
* Should be called exactly once per error
*
* You should call either get_error_msg, or get_gerror, but not both.
*
* Transfers ownership, caller must free the GError.
*/
GError *
script_fu_get_gerror (void)
{
const gchar *error_message;
GError *result;
error_message = script_fu_get_error_msg ();
result = g_error_new_literal (g_quark_from_string ("scriptfu"), 0, error_message);
g_free ((gpointer) error_message);
return result;
}
void
script_fu_run_read_eval_print_loop (void)
{
ts_interpret_stdin ();
}
void
script_fu_register_quit_callback (void (*func) (void))
{
ts_register_quit_callback (func);
}
void
script_fu_register_post_command_callback (void (*func) (void))
{
ts_register_post_command_callback (func);
}
/*
* Return list of paths to directories containing .scm and .init scripts.
*
* List has two elements, in this order:
* directory for user scripts
* directory for system-wide scripts, distributed with GIMP
* The dirs usually contain: plugins, init scripts, and utility scripts.
*
* The returned type is GList of GFile.
* Caller must free the returned list.
*/
GList *
script_fu_search_path (void)
{
gchar *path_str;
GList *path = NULL;
path_str = gimp_gimprc_query ("script-fu-path");
if (path_str)
{
GError *error = NULL;
path = gimp_config_path_expand_to_files (path_str, &error);
g_free (path_str);
if (! path)
{
g_warning ("Can't convert script-fu-path to filesystem encoding: %s",
error->message);
g_clear_error (&error);
}
}
return path;
}
/* Returns path to a subdirectory of the given path,
* the subdirectory containing init scripts.
*
* SF keeps init scripts segregated in a subdirectory, since 3.0.
* This lets them have the proper suffix ".scm"
* without being confused with plugin scripts.
* Also lets other scripts in that directory not be loaded at startup.
*
* This hides the name "init".
*
* Caller must free the result.
*/
gchar *
script_fu_get_init_subdirectory (GFile *dir)
{
GFile *subdirectory = g_file_get_child (dir, "scriptfu-init");
gchar *result_path = g_file_get_path (subdirectory);
g_object_unref (subdirectory);
/* result is a string path to a directory which might not exist. */
return result_path;
}
/* The directory containing init scripts installed with GIMP.
* Caller must free the result string.
*/
gchar *
script_fu_sys_init_directory (void)
{
GList *paths = script_fu_search_path ();
GList *list_element;
gchar *result_path;
/* The second list element is the sys scripts dir. */
list_element = g_list_next (paths);
result_path = script_fu_get_init_subdirectory (list_element->data);
g_list_free_full (paths, (GDestroyNotify) g_object_unref);
return result_path;
}
/* The directory containing user init scripts.
* Caller must free the result string.
*/
gchar *
script_fu_user_init_directory (void)
{
GList *paths = script_fu_search_path ();
GList *list_element;
gchar *result_path;
/* The first list element is the user scripts dir. */
list_element = paths;
result_path = script_fu_get_init_subdirectory (list_element->data);
g_list_free_full (paths, (GDestroyNotify) g_object_unref);
return result_path;
}
gboolean
/* Is the given dir named like an init dir for SF?
*
* This is lax, and doesn't check the dir is in one of
* the two locations for SF's init directories.
* Users should not use the name in their own directories
* in the tree of script directories.
*/
script_fu_is_init_directory (GFile *dir)
{
char *basename = g_file_get_basename (dir);
gboolean result;
result = g_strcmp0 (basename, "scriptfu-init") == 0;
g_free (basename);
return result;
}
/* Create a PDB procedure from the SFScript for the given proc name.
* Does not register into the PDB.
* Requires scripts already loaded i.e. SFScript exist.
*/
GimpProcedure *
script_fu_create_PDB_proc_plugin (GimpPlugIn *plug_in,
const gchar *name)
{
/* Delegate to factory. */
return script_fu_proc_factory_make_PLUGIN (plug_in, name);
}
GList *
script_fu_find_scripts_list_proc_names (GimpPlugIn *plug_in,
GList *paths)
{
/* Delegate to factory. */
return script_fu_proc_factory_list_names (plug_in, paths);
}
/* Requires scripts already loaded. */
void
script_fu_get_i18n_for_proc (const gchar *proc_name,
gchar **declared_i18n_domain,
gchar **declared_i18n_catalog)
{
SFScript *script = script_fu_find_script (proc_name);
if (script != NULL)
script_fu_script_get_i18n (script, declared_i18n_domain,
declared_i18n_catalog);
}
|