diff --git a/ChangeLog b/ChangeLog index d375363e22..6205d3c299 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,53 @@ +2001-07-17 Mathieu Lacage + + * app/batch.c: new code to call the script_fuc_text_console pdb function. + * app/main.c: (main): remove batch command code. + + * plug-ins/script-fu/Makefile.am: add siod-wrapper.h/c + * plug-ins/script-fu/script-fu-console.c: + (script_fu_cc_key_function), + (script_fu_open_siod_console), + (script_fu_close_siod_console): + * plug-ins/script-fu/script-fu-scripts.h: + * plug-ins/script-fu/script-fu-server.c: + (script_fu_server_quit), + (script_fu_server_get_mode), + (execute_command): + Replace all direct calls to the scheme interpreter with calls to the siod-wrapper. + * plug-ins/script-fu/script-fu-console.h: remove run_eval. + * plug-ins/script-fu/script-fu-server.h: + * plug-ins/script-fu/script-fu-text-console.c: + (script_fu_text_console_run), + (read_command), + (script_fu_text_console_interface): + The actual new text console. + * plug-ins/script-fu/script-fu-text-console.h: header. + * plug-ins/script-fu/script-fu.c: + (script_fu_quit), + (script_fu_query), + (script_fu_run): rename to better words. + move most of the code to siod-wrapper.c/h + * plug-ins/script-fu/siod-wrapper.c: + (siod_get_output_file), + (siod_set_output_file), + (siod_get_verbose_level), + (siod_set_verbose_level), + (siod_print_welcome), + (siod_interpret_string), + (siod_get_error_msg), + (siod_get_success_msg), + (siod_init), + (init_procedures), + (init_constants), + (convert_string), + (sputs_fcn), + (lprin1s), + (marshall_proc_db_call), + (script_fu_register_call), + (script_fu_quit_call): + All the funcitons dealing with the internals of the scheme interpreter. + * plug-ins/script-fu/siod-wrapper.h: the header. + 2001-07-17 Michael Natterer * app/path.[ch]: removed path_to_beziersel() so this file can be diff --git a/app/batch.c b/app/batch.c deleted file mode 100644 index 2e46877c55..0000000000 --- a/app/batch.c +++ /dev/null @@ -1,265 +0,0 @@ -/* The GIMP -- an 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 2 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, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "config.h" - -#include -#include -#include -#include -#include -#ifdef HAVE_UNISTD_H -#include -#endif - -#include - -#include "core/core-types.h" - -#include "appenv.h" -#include "app_procs.h" -#include "batch.h" - -#include "pdb/procedural_db.h" - - -static void batch_run_cmd (Gimp *gimp, - gchar *cmd); -static void batch_read (gpointer data, - gint source, - GdkInputCondition condition); -static void batch_pserver (Gimp *gimp, - gint run_mode, - gint flags, - gint extra); - - -static ProcRecord *eval_proc; - - -void -batch_init (Gimp *gimp) -{ - gboolean read_from_stdin; - gboolean perl_server_already_running = FALSE; - gint i; - - eval_proc = procedural_db_lookup (gimp, "extension_script_fu_eval"); - - read_from_stdin = FALSE; - for (i = 0; batch_cmds[i]; i++) - { - - /* until --batch-interp=xxx or something similar is implemented - * and gimp-1.0 is not extinct use a shortcut to speed up starting the - * perl-server tremendously. This is also fully compatible with 1.0. - */ - { - gint run_mode, flags, extra; - - if (sscanf (batch_cmds[i], "(extension%*[-_]perl%*[-_]server %i %i %i)", &run_mode, &flags, &extra) == 3) - { - if (!perl_server_already_running) - { - batch_pserver (gimp, run_mode, flags, extra); - perl_server_already_running = 1; - } - continue; - } - } - - if (!eval_proc) - { - g_message ("script-fu not available: batch mode disabled\n"); - return; - } - - if (strcmp (batch_cmds[i], "-") == 0) - { - if (!read_from_stdin) - { -#ifndef G_OS_WIN32 /* for now */ - g_print ("reading batch commands from stdin\n"); - gdk_input_add (STDIN_FILENO, GDK_INPUT_READ, batch_read, gimp); - read_from_stdin = TRUE; -#else - g_error ("Batch mode from standard input not implemented on Win32"); -#endif - } - } - else - { - batch_run_cmd (gimp, batch_cmds[i]); - } - } -} - - -static void -batch_run_cmd (Gimp *gimp, - gchar *cmd) -{ - Argument *args; - Argument *vals; - gint i; - - if (g_strcasecmp (cmd, "(gimp-quit 0)") == 0) - { - app_exit (FALSE); - exit (0); - } - - args = g_new0 (Argument, eval_proc->num_args); - for (i = 0; i < eval_proc->num_args; i++) - args[i].arg_type = eval_proc->args[i].arg_type; - - args[0].value.pdb_int = 1; - args[1].value.pdb_pointer = cmd; - - vals = procedural_db_execute (gimp, "extension_script_fu_eval", args); - - switch (vals[0].value.pdb_int) - { - case GIMP_PDB_EXECUTION_ERROR: - g_print ("batch command: experienced an execution error.\n"); - break; - case GIMP_PDB_CALLING_ERROR: - g_print ("batch command: experienced a calling error.\n"); - break; - case GIMP_PDB_SUCCESS: - g_print ("batch command: executed successfully.\n"); - break; - default: - break; - } - - procedural_db_destroy_args (vals, eval_proc->num_values); - g_free(args); - - return; -} - -#ifndef G_OS_WIN32 - -static void -batch_read (gpointer data, - gint source, - GdkInputCondition condition) -{ - static GString *string; - gchar buf[32]; - gchar *t; - gint nread; - gboolean done; - - if (condition & GDK_INPUT_READ) - { - do { - nread = read (source, &buf, sizeof (char) * 31); - } while ((nread == -1) && ((errno == EAGAIN) || (errno == EINTR))); - - if ((nread == 0) && (!string || (string->len == 0))) - app_exit (FALSE); - - buf[nread] = '\0'; - - if (!string) - string = g_string_new (""); - - t = buf; - if (string->len == 0) - { - while (*t) - { - if (isspace (*t)) - t++; - else - break; - } - } - - g_string_append (string, t); - - done = FALSE; - - while (*t) - { - if ((*t == '\n') || (*t == '\r')) - done = TRUE; - t++; - } - - if (done) - { - batch_run_cmd ((Gimp *) data, string->str); - g_string_truncate (string, 0); - } - } -} - -#endif /* !G_OS_WIN32 */ - -static void -batch_pserver (Gimp *gimp, - gint run_mode, - gint flags, - gint extra) -{ - ProcRecord *pserver_proc; - Argument *args; - Argument *vals; - gint i; - - pserver_proc = procedural_db_lookup (gimp, "extension_perl_server"); - - if (!pserver_proc) - { - g_message ("extension_perl_server not available: unable to start the perl server\n"); - return; - } - - args = g_new0 (Argument, pserver_proc->num_args); - for (i = 0; i < pserver_proc->num_args; i++) - args[i].arg_type = pserver_proc->args[i].arg_type; - - args[0].value.pdb_int = run_mode; - args[1].value.pdb_int = flags; - args[2].value.pdb_int = extra; - - vals = procedural_db_execute (gimp, "extension_perl_server", args); - - switch (vals[0].value.pdb_int) - { - case GIMP_PDB_EXECUTION_ERROR: - g_print ("perl server: experienced an execution error.\n"); - break; - case GIMP_PDB_CALLING_ERROR: - g_print ("perl server: experienced a calling error.\n"); - break; - case GIMP_PDB_SUCCESS: - g_print ("perl server: executed successfully.\n"); - break; - default: - break; - } - - procedural_db_destroy_args (vals, pserver_proc->num_values); - g_free(args); - - return; -} diff --git a/app/main.c b/app/main.c index da32f8c205..8b8d58d8de 100644 --- a/app/main.c +++ b/app/main.c @@ -63,6 +63,7 @@ gboolean no_data = FALSE; gboolean no_splash = FALSE; gboolean no_splash_image = FALSE; gboolean be_verbose = FALSE; +gboolean use_stdin = FALSE; gboolean use_shm = FALSE; gboolean use_debug_handler = FALSE; gboolean console_messages = FALSE; @@ -70,7 +71,6 @@ gboolean restore_session = FALSE; StackTraceMode stack_trace_mode = STACK_TRACE_QUERY; gchar *alternate_gimprc = NULL; gchar *alternate_system_gimprc = NULL; -gchar **batch_cmds = NULL; /* other global variables */ gchar *prog_name = NULL; /* our executable name */ @@ -93,9 +93,6 @@ gboolean double_speed = FALSE; * left are assumed to be image files the GIMP should * display. * - * The exception is the batch switch. When this is - * encountered, all remaining args are treated as batch - * commands. */ int @@ -133,8 +130,6 @@ main (int argc, use_shm = TRUE; #endif - batch_cmds = g_new (char *, argc); - batch_cmds[0] = NULL; for (i = 1; i < argc; i++) { @@ -148,15 +143,7 @@ main (int argc, (strcmp (argv[i], "-b") == 0)) { argv[i] = NULL; - for (j = 0, i++ ; i < argc; j++, i++) - { - batch_cmds[j] = argv[i]; - argv[i] = NULL; - } - batch_cmds[j] = NULL; - - if (batch_cmds[0] == NULL) /* We need at least one batch command */ - show_help = TRUE; + use_stdin = TRUE; } else if (strcmp (argv[i], "--system-gimprc") == 0) { @@ -292,7 +279,7 @@ main (int argc, { g_print (_("\nUsage: %s [option ... ] [file ... ]\n\n"), argv[0]); g_print (_("Options:\n")); - g_print (_(" -b, --batch Run in batch mode.\n")); + g_print (_(" -b, --batch Read scheme statements from stdin.\n")); g_print (_(" -c, --console-messages Display warnings to console instead of a dialog box.\n")); g_print (_(" -d, --no-data Do not load brushes, gradients, palettes, patterns.\n")); g_print (_(" -i, --no-interface Run without a user interface.\n")); diff --git a/plug-ins/script-fu/Makefile.am b/plug-ins/script-fu/Makefile.am index 29a738b13b..efeb1e24ed 100644 --- a/plug-ins/script-fu/Makefile.am +++ b/plug-ins/script-fu/Makefile.am @@ -14,6 +14,8 @@ script_fu_SOURCES = @STRIP_BEGIN@ \ script-fu.c \ script-fu-console.c \ script-fu-console.h \ + script-fu-text-console.h \ + script-fu-text-console.c \ script-fu-constants.c \ script-fu-constants.h \ script-fu-intl.h \ @@ -24,6 +26,8 @@ script_fu_SOURCES = @STRIP_BEGIN@ \ script-fu-enums.h \ siod.h \ siodp.h \ + siod-wrapper.c \ + siod-wrapper.h \ @STRIP_END@ AM_CPPFLAGS = -DLOCALEDIR=\""$(localedir)"\" diff --git a/plug-ins/script-fu/scheme-wrapper.c b/plug-ins/script-fu/scheme-wrapper.c new file mode 100644 index 0000000000..fa6fbd62e6 --- /dev/null +++ b/plug-ins/script-fu/scheme-wrapper.c @@ -0,0 +1,946 @@ +#include "config.h" + +#include "siod.h" +#include "siod-wrapper.h" +#include +#include "libgimp/gimp.h" +#include "script-fu-constants.h" +#include "script-fu-enums.h" +#include "script-fu-scripts.h" +#include "script-fu-server.h" + +/* global variables declared by the scheme interpreter */ +extern FILE* siod_output; +extern int siod_verbose_level; +extern char siod_err_msg[]; +extern LISP repl_return_val; + + +/* defined in regex.c. not exported by regex.h */ +extern void init_regex (void); + +/* defined in siodp.h but this file cannot be imported... */ +extern long nlength (LISP obj); +extern LISP leval_define (LISP args, LISP env); + + +/* wrapper functions */ +FILE * +siod_get_output_file (void) +{ + return siod_output; +} + +void +siod_set_output_file (FILE *file) +{ + siod_output = file; +} + +int +siod_get_verbose_level (void) +{ + return siod_verbose_level; +} + + +void +siod_set_verbose_level (int verbose_level) +{ + siod_verbose_level = verbose_level; +} + + +void +siod_print_welcome (void) +{ + print_welcome (); +} + + +int +siod_interpret_string (const char *expr) +{ + return repl_c_string ((char *)expr, 0, 0, 1); +} + + +const char * +siod_get_error_msg (void) +{ + return siod_err_msg; +} + +const char * +siod_get_success_msg (void) +{ + char *response; + + if (TYPEP (repl_return_val, tc_string)) + response = get_c_string (repl_return_val); + else + response = "Success"; + + return (const char *) response; +} + + +static void init_constants (void); +static void init_procedures (void); + +static gboolean register_scripts = FALSE; + +void +siod_init (gint local_register_scripts) +{ + char *siod_argv[] = + { + "siod", + "-h100000:10", + "-g0", + "-o1000", + "-s200000", + "-n2048", + "-v0", + }; + + register_scripts = local_register_scripts; + + /* init the interpreter */ + process_cla (sizeof (siod_argv) / sizeof (char *), siod_argv, 1); + init_storage (); + init_subrs (); + init_trace (); + init_regex (); + + /* register in the interpreter the gimp functions and types. */ + init_procedures (); + init_constants (); + +} + +static void convert_string (char *str); +static gint sputs_fcn (char *st, + void *dest); +static LISP lprin1s (LISP exp, + char *dest); +static LISP marshall_proc_db_call (LISP a); +static LISP script_fu_register_call (LISP a); +static LISP script_fu_quit_call (LISP a); + + +/********* + + Below can be found the functions responsible for registering the gimp functions + and types against the scheme interpreter. + +********/ + + +static void +init_procedures (void) +{ + gchar **proc_list; + gchar *proc_name; + gchar *arg_name; + gchar *proc_blurb; + gchar *proc_help; + gchar *proc_author; + gchar *proc_copyright; + gchar *proc_date; + GimpPDBProcType proc_type; + gint nparams; + gint nreturn_vals; + GimpParamDef *params; + GimpParamDef *return_vals; + gint num_procs; + gint i; + + /* register the database execution procedure */ + init_lsubr ("gimp-proc-db-call", marshall_proc_db_call); + init_lsubr ("script-fu-register", script_fu_register_call); + init_lsubr ("script-fu-quit", script_fu_quit_call); + + gimp_procedural_db_query (".*", ".*", ".*", ".*", ".*", ".*", ".*", + &num_procs, &proc_list); + + /* Register each procedure as a scheme func */ + for (i = 0; i < num_procs; i++) + { + proc_name = g_strdup (proc_list[i]); + + /* lookup the procedure */ + if (gimp_procedural_db_proc_info (proc_name, + &proc_blurb, + &proc_help, + &proc_author, + &proc_copyright, + &proc_date, + &proc_type, + &nparams, &nreturn_vals, + ¶ms, &return_vals)) + { + LISP args = NIL; + LISP code = NIL; + gint j; + + /* convert the names to scheme-like naming conventions */ + convert_string (proc_name); + + /* create a new scheme func that calls gimp-proc-db-call */ + for (j = 0; j < nparams; j++) + { + arg_name = g_strdup (params[j].name); + convert_string (arg_name); + args = cons (cintern (arg_name), args); + code = cons (cintern (arg_name), code); + } + + /* reverse the list */ + args = nreverse (args); + code = nreverse (code); + + /* set the scheme-based procedure name */ + args = cons (cintern (proc_name), args); + + /* set the acture pdb procedure name */ + code = cons (cons (cintern ("quote"), + cons (cintern (proc_list[i]), NIL)), + code); + code = cons (cintern ("gimp-proc-db-call"), code); + + leval_define (cons (args, cons (code, NIL)), NIL); + + /* free the queried information */ + g_free (proc_blurb); + g_free (proc_help); + g_free (proc_author); + g_free (proc_copyright); + g_free (proc_date); + gimp_destroy_paramdefs (params, nparams); + gimp_destroy_paramdefs (return_vals, nreturn_vals); + } + } + + g_free (proc_list); +} + +static void +init_constants (void) +{ + gchar *gimp_plugin_dir; + + setvar (cintern ("gimp-data-dir"), + strcons (-1, (gchar *) gimp_data_directory ()), NIL); + + gimp_plugin_dir = gimp_gimprc_query ("gimp_plugin_dir"); + if (gimp_plugin_dir) + { + setvar (cintern ("gimp-plugin-dir"), + strcons (-1, gimp_plugin_dir), NIL); + g_free (gimp_plugin_dir); + } + + /* Generated constants */ + init_generated_constants (); + + /* These are for backwards compatibility; they should be removed sometime */ + setvar (cintern ("NORMAL"), flocons (GIMP_NORMAL_MODE), NIL); + setvar (cintern ("DISSOLVE"), flocons (GIMP_DISSOLVE_MODE), NIL); + setvar (cintern ("BEHIND"), flocons (GIMP_BEHIND_MODE), NIL); + setvar (cintern ("MULTIPLY"), flocons (GIMP_MULTIPLY_MODE), NIL); + setvar (cintern ("SCREEN"), flocons (GIMP_SCREEN_MODE), NIL); + setvar (cintern ("OVERLAY"), flocons (GIMP_OVERLAY_MODE), NIL); + setvar (cintern ("DIFFERENCE"), flocons (GIMP_DIFFERENCE_MODE), NIL); + setvar (cintern ("ADDITION"), flocons (GIMP_ADDITION_MODE), NIL); + setvar (cintern ("SUBTRACT"), flocons (GIMP_SUBTRACT_MODE), NIL); + setvar (cintern ("DARKEN-ONLY"), flocons (GIMP_DARKEN_ONLY_MODE), NIL); + setvar (cintern ("LIGHTEN-ONLY"), flocons (GIMP_LIGHTEN_ONLY_MODE), NIL); + setvar (cintern ("HUE"), flocons (GIMP_HUE_MODE), NIL); + setvar (cintern ("SATURATION"), flocons (GIMP_SATURATION_MODE), NIL); + setvar (cintern ("COLOR"), flocons (GIMP_COLOR_MODE), NIL); + setvar (cintern ("VALUE"), flocons (GIMP_VALUE_MODE), NIL); + setvar (cintern ("DIVIDE"), flocons (GIMP_DIVIDE_MODE), NIL); + + setvar (cintern ("BLUR"), flocons (GIMP_BLUR_CONVOLVE), NIL); + setvar (cintern ("SHARPEN"), flocons (GIMP_SHARPEN_CONVOLVE), NIL); + + setvar (cintern ("RGB_IMAGE"), flocons (GIMP_RGB_IMAGE), NIL); + setvar (cintern ("RGBA_IMAGE"), flocons (GIMP_RGBA_IMAGE), NIL); + setvar (cintern ("GRAY_IMAGE"), flocons (GIMP_GRAY_IMAGE), NIL); + setvar (cintern ("GRAYA_IMAGE"), flocons (GIMP_GRAYA_IMAGE), NIL); + setvar (cintern ("INDEXED_IMAGE"), flocons (GIMP_INDEXED_IMAGE), NIL); + setvar (cintern ("INDEXEDA_IMAGE"), flocons (GIMP_INDEXEDA_IMAGE), NIL); + + /* Useful misc stuff */ + setvar (cintern ("TRUE"), flocons (TRUE), NIL); + setvar (cintern ("FALSE"), flocons (FALSE), NIL); + + /* Script-fu types */ + setvar (cintern ("SF-IMAGE"), flocons (SF_IMAGE), NIL); + setvar (cintern ("SF-DRAWABLE"), flocons (SF_DRAWABLE), NIL); + setvar (cintern ("SF-LAYER"), flocons (SF_LAYER), NIL); + setvar (cintern ("SF-CHANNEL"), flocons (SF_CHANNEL), NIL); + setvar (cintern ("SF-COLOR"), flocons (SF_COLOR), NIL); + setvar (cintern ("SF-TOGGLE"), flocons (SF_TOGGLE), NIL); + setvar (cintern ("SF-VALUE"), flocons (SF_VALUE), NIL); + setvar (cintern ("SF-STRING"), flocons (SF_STRING), NIL); + setvar (cintern ("SF-FILENAME"), flocons (SF_FILENAME), NIL); + setvar (cintern ("SF-ADJUSTMENT"), flocons (SF_ADJUSTMENT), NIL); + setvar (cintern ("SF-FONT"), flocons (SF_FONT), NIL); + setvar (cintern ("SF-PATTERN"), flocons (SF_PATTERN), NIL); + setvar (cintern ("SF-BRUSH"), flocons (SF_BRUSH), NIL); + setvar (cintern ("SF-GRADIENT"), flocons (SF_GRADIENT), NIL); + setvar (cintern ("SF-OPTION"), flocons (SF_OPTION), NIL); + + /* for SF_ADJUSTMENT */ + setvar (cintern ("SF-SLIDER"), flocons (SF_SLIDER), NIL); + setvar (cintern ("SF-SPINNER"), flocons (SF_SPINNER), NIL); +} + +static void +convert_string (gchar *str) +{ + while (*str) + { + if (*str == '_') *str = '-'; + str++; + } +} + +static gboolean +sputs_fcn (gchar *st, + gpointer dest) +{ + strcpy (*((gchar**)dest), st); + *((gchar**)dest) += strlen (st); + + return TRUE; +} + +static LISP +lprin1s (LISP exp, + gchar *dest) +{ + struct gen_printio s; + + s.putc_fcn = NULL; + s.puts_fcn = sputs_fcn; + s.cb_argument = &dest; + + lprin1g (exp, &s); + + return (NIL); +} + + +static LISP +marshall_proc_db_call (LISP a) +{ + GimpParam *args; + GimpParam *values = NULL; + gint nvalues; + gchar *proc_name; + gchar *proc_blurb; + gchar *proc_help; + gchar *proc_author; + gchar *proc_copyright; + gchar *proc_date; + GimpPDBProcType proc_type; + gint nparams; + gint nreturn_vals; + GimpParamDef *params; + GimpParamDef *return_vals; + gchar error_str[256]; + gint i; + gint success = TRUE; + LISP color_list; + LISP intermediate_val; + LISP return_val = NIL; + gchar *string; + gint string_len; + LISP a_saved; + + /* Save a in case it is needed for an error message. */ + a_saved = a; + + /* Make sure there are arguments */ + if (a == NIL) + return my_err ("Procedure database argument marshaller was called with no arguments. " + "The procedure to be executed and the arguments it requires " + "(possibly none) must be specified.", NIL); + + /* Derive the pdb procedure name from the argument + or first argument of a list */ + if (TYPEP (a, tc_cons)) + proc_name = get_c_string (car (a)); + else + proc_name = get_c_string (a); + + /* report the current command */ + script_fu_report_cc (proc_name); + + /* Attempt to fetch the procedure from the database */ + if (! gimp_procedural_db_proc_info (proc_name, + &proc_blurb, + &proc_help, + &proc_author, + &proc_copyright, + &proc_date, + &proc_type, + &nparams, &nreturn_vals, + ¶ms, &return_vals)) + return my_err ("Invalid procedure name specified.", NIL); + + + /* Check the supplied number of arguments */ + if ((nlength (a) - 1) != nparams) + { + g_snprintf (error_str, sizeof (error_str), + "Invalid arguments supplied to %s--(# args: %ld, expecting: %d)", + proc_name, (nlength (a) - 1), nparams); + return my_err (error_str, NIL); + } + + /* Marshall the supplied arguments */ + if (nparams) + args = g_new (GimpParam, nparams); + else + args = NULL; + + a = cdr (a); + for (i = 0; i < nparams; i++) + { + switch (params[i].type) + { + case GIMP_PDB_INT32: + if (!TYPEP (car (a), tc_flonum)) + success = FALSE; + if (success) + { + args[i].type = GIMP_PDB_INT32; + args[i].data.d_int32 = get_c_long (car (a)); + } + break; + + case GIMP_PDB_INT16: + if (!TYPEP (car (a), tc_flonum)) + success = FALSE; + if (success) + { + args[i].type = GIMP_PDB_INT16; + args[i].data.d_int16 = (gint16) get_c_long (car (a)); + } + break; + + case GIMP_PDB_INT8: + if (!TYPEP (car (a), tc_flonum)) + success = FALSE; + if (success) + { + args[i].type = GIMP_PDB_INT8; + args[i].data.d_int8 = (gint8) get_c_long (car (a)); + } + break; + + case GIMP_PDB_FLOAT: + if (!TYPEP (car (a), tc_flonum)) + success = FALSE; + if (success) + { + args[i].type = GIMP_PDB_FLOAT; + args[i].data.d_float = get_c_double (car (a)); + } + break; + + case GIMP_PDB_STRING: + if (!TYPEP (car (a), tc_string)) + success = FALSE; + if (success) + { + args[i].type = GIMP_PDB_STRING; + args[i].data.d_string = get_c_string (car (a)); + } + break; + + case GIMP_PDB_INT32ARRAY: + if (!TYPEP (car (a), tc_long_array)) + success = FALSE; + if (success) + { + args[i].type = GIMP_PDB_INT32ARRAY; + args[i].data.d_int32array = + (gint32*) (car (a))->storage_as.long_array.data; + } + break; + + case GIMP_PDB_INT16ARRAY: + if (!TYPEP (car (a), tc_long_array)) + success = FALSE; + if (success) + { + args[i].type = GIMP_PDB_INT16ARRAY; + args[i].data.d_int16array = + (gint16*) (car (a))->storage_as.long_array.data; + } + break; + + case GIMP_PDB_INT8ARRAY: + if (!TYPEP (car (a), tc_byte_array)) + success = FALSE; + if (success) + { + args[i].type = GIMP_PDB_INT8ARRAY; + args[i].data.d_int8array = + (gint8*) (car (a))->storage_as.string.data; + } + break; + + case GIMP_PDB_FLOATARRAY: + if (!TYPEP (car (a), tc_double_array)) + success = FALSE; + if (success) + { + args[i].type = GIMP_PDB_FLOATARRAY; + args[i].data.d_floatarray = + (car (a))->storage_as.double_array.data; + } + break; + + case GIMP_PDB_STRINGARRAY: + if (!TYPEP (car (a), tc_cons)) + success = FALSE; + if (success) + { + args[i].type = GIMP_PDB_STRINGARRAY; + + /* Set the array */ + { + gint j; + gint num_strings; + gchar **array; + LISP list; + + list = car (a); + num_strings = args[i - 1].data.d_int32; + if (nlength (list) != num_strings) + return my_err ("String array argument has incorrectly specified length", NIL); + array = args[i].data.d_stringarray = + g_new (char *, num_strings); + + for (j = 0; j < num_strings; j++) + { + array[j] = get_c_string (car (list)); + list = cdr (list); + } + } + } + break; + + case GIMP_PDB_COLOR: + if (!TYPEP (car (a), tc_cons)) + success = FALSE; + if (success) + { + guchar color[3]; + + args[i].type = GIMP_PDB_COLOR; + color_list = car (a); + color[0] = get_c_long (car (color_list)); + color[1] = get_c_long (car (color_list)); + color[2] = get_c_long (car (color_list)); + + gimp_rgb_set_uchar (&args[i].data.d_color, + color[0], color[1], color[2]); + } + break; + + case GIMP_PDB_REGION: + return my_err ("Regions are currently unsupported as arguments", + car (a)); + break; + + case GIMP_PDB_DISPLAY: + if (!TYPEP (car (a), tc_flonum)) + success = FALSE; + if (success) + { + args[i].type = GIMP_PDB_DISPLAY; + args[i].data.d_int32 = get_c_long (car (a)); + } + break; + + case GIMP_PDB_IMAGE: + if (!TYPEP (car (a), tc_flonum)) + success = FALSE; + if (success) + { + args[i].type = GIMP_PDB_IMAGE; + args[i].data.d_int32 = get_c_long (car (a)); + } + break; + + case GIMP_PDB_LAYER: + if (!TYPEP (car (a), tc_flonum)) + success = FALSE; + if (success) + { + args[i].type = GIMP_PDB_LAYER; + args[i].data.d_int32 = get_c_long (car (a)); + } + break; + + case GIMP_PDB_CHANNEL: + if (!TYPEP (car (a), tc_flonum)) + success = FALSE; + if (success) + { + args[i].type = GIMP_PDB_CHANNEL; + args[i].data.d_int32 = get_c_long (car (a)); + } + break; + + case GIMP_PDB_DRAWABLE: + if (!TYPEP (car (a), tc_flonum)) + success = FALSE; + if (success) + { + args[i].type = GIMP_PDB_DRAWABLE; + args[i].data.d_int32 = get_c_long (car (a)); + } + break; + + case GIMP_PDB_SELECTION: + if (!TYPEP (car (a), tc_flonum)) + success = FALSE; + if (success) + { + args[i].type = GIMP_PDB_SELECTION; + args[i].data.d_int32 = get_c_long (car (a)); + } + break; + + case GIMP_PDB_BOUNDARY: + return my_err ("Boundaries are currently unsupported as arguments", + car (a)); + break; + + case GIMP_PDB_PATH: + return my_err ("Paths are currently unsupported as arguments", + car (a)); + break; + + case GIMP_PDB_PARASITE: + if (!TYPEP (car (a), tc_cons)) + success = FALSE; + if (success) + { + args[i].type = GIMP_PDB_PARASITE; + /* parasite->name */ + intermediate_val = car (a); + args[i].data.d_parasite.name = + get_c_string (car (intermediate_val)); + + /* parasite->flags */ + intermediate_val = cdr (intermediate_val); + args[i].data.d_parasite.flags = get_c_long (car(intermediate_val)); + + /* parasite->size */ + intermediate_val = cdr (intermediate_val); + args[i].data.d_parasite.size = + (car (intermediate_val))->storage_as.string.dim; + + /* parasite->data */ + args[i].data.d_parasite.data = + (void*) (car (intermediate_val))->storage_as.string.data; + } + break; + + case GIMP_PDB_STATUS: + return my_err ("Status is for return types, not arguments", car (a)); + break; + + default: + return my_err ("Unknown argument type", NIL); + } + + a = cdr (a); + } + + if (success) + values = gimp_run_procedure2 (proc_name, &nvalues, nparams, args); + else + return my_err ("Invalid types specified for arguments", NIL); + + /* Check the return status */ + if (! values) + { + strcpy (error_str, "Procedural database execution did not return a status:\n "); + lprin1s (a_saved, error_str + strlen(error_str)); + + return my_err (error_str, NIL); + } + + switch (values[0].data.d_status) + { + case GIMP_PDB_EXECUTION_ERROR: + strcpy (error_str, "Procedural database execution failed:\n "); + lprin1s (a_saved, error_str + strlen(error_str)); + return my_err (error_str, NIL); + break; + + case GIMP_PDB_CALLING_ERROR: + strcpy (error_str, "Procedural database execution failed on invalid input arguments:\n "); + lprin1s (a_saved, error_str + strlen(error_str)); + return my_err (error_str, NIL); + break; + + case GIMP_PDB_SUCCESS: + return_val = NIL; + + for (i = 0; i < nvalues - 1; i++) + { + switch (return_vals[i].type) + { + case GIMP_PDB_INT32: + return_val = cons (flocons (values[i + 1].data.d_int32), + return_val); + break; + + case GIMP_PDB_INT16: + return_val = cons (flocons (values[i + 1].data.d_int32), + return_val); + break; + + case GIMP_PDB_INT8: + return_val = cons (flocons (values[i + 1].data.d_int32), + return_val); + break; + + case GIMP_PDB_FLOAT: + return_val = cons (flocons (values[i + 1].data.d_float), + return_val); + break; + + case GIMP_PDB_STRING: + string = (gchar *) values[i + 1].data.d_string; + string_len = strlen (string); + return_val = cons (strcons (string_len, string), return_val); + break; + + case GIMP_PDB_INT32ARRAY: + { + LISP array; + gint j; + + array = arcons (tc_long_array, values[i].data.d_int32, 0); + for (j = 0; j < values[i].data.d_int32; j++) + { + array->storage_as.long_array.data[j] = + values[i + 1].data.d_int32array[j]; + } + return_val = cons (array, return_val); + } + break; + + case GIMP_PDB_INT16ARRAY: + return my_err ("Arrays are currently unsupported as return values", NIL); + break; + + case GIMP_PDB_INT8ARRAY: + { + LISP array; + gint j; + + array = arcons (tc_byte_array, values[i].data.d_int32, 0); + for (j = 0; j < values[i].data.d_int32; j++) + { + array->storage_as.string.data[j] = + values[i + 1].data.d_int8array[j]; + } + return_val = cons (array, return_val); + } + break; + + case GIMP_PDB_FLOATARRAY: + { + LISP array; + gint j; + + array = arcons (tc_double_array, values[i].data.d_int32, 0); + for (j = 0; j < values[i].data.d_int32; j++) + { + array->storage_as.double_array.data[j] = + values[i + 1].data.d_floatarray[j]; + } + return_val = cons (array, return_val); + } + break; + + case GIMP_PDB_STRINGARRAY: + /* string arrays are always implemented such that the previous + * return value contains the number of strings in the array + */ + { + gint j; + gint num_strings = values[i].data.d_int32; + LISP string_array = NIL; + gchar **array = (gchar **) values[i + 1].data.d_stringarray; + + for (j = 0; j < num_strings; j++) + { + string_len = strlen (array[j]); + string_array = cons (strcons (string_len, array[j]), + string_array); + } + + return_val = cons (nreverse (string_array), return_val); + } + break; + + case GIMP_PDB_COLOR: + { + guchar color[3]; + gimp_rgb_get_uchar (&values[i + 1].data.d_color, color, color + 1, color + 2); + intermediate_val = cons (flocons ((int) color[0]), + cons (flocons ((int) color[1]), + cons (flocons ((int) color[2]), + NIL))); + return_val = cons (intermediate_val, return_val); + break; + } + + case GIMP_PDB_REGION: + return my_err ("Regions are currently unsupported as return values", NIL); + break; + + case GIMP_PDB_DISPLAY: + return_val = cons (flocons (values[i + 1].data.d_int32), + return_val); + break; + + case GIMP_PDB_IMAGE: + return_val = cons (flocons (values[i + 1].data.d_int32), + return_val); + break; + + case GIMP_PDB_LAYER: + return_val = cons (flocons (values[i + 1].data.d_int32), + return_val); + break; + + case GIMP_PDB_CHANNEL: + return_val = cons (flocons (values[i + 1].data.d_int32), + return_val); + break; + + case GIMP_PDB_DRAWABLE: + return_val = cons (flocons (values[i + 1].data.d_int32), + return_val); + break; + + case GIMP_PDB_SELECTION: + return_val = cons (flocons (values[i + 1].data.d_int32), + return_val); + break; + + case GIMP_PDB_BOUNDARY: + return my_err ("Boundaries are currently unsupported as return values", NIL); + break; + + case GIMP_PDB_PATH: + return my_err ("Paths are currently unsupported as return values", NIL); + break; + + case GIMP_PDB_PARASITE: + { + LISP name, flags, data; + + if (values[i + 1].data.d_parasite.name == NULL) + { + return_val = my_err("Error: null parasite", NIL); + } + else + { + string_len = strlen (values[i + 1].data.d_parasite.name); + name = strcons (string_len, + values[i + 1].data.d_parasite.name); + + flags = flocons (values[i + 1].data.d_parasite.flags); + data = arcons (tc_byte_array, + values[i+1].data.d_parasite.size, 0); + memcpy(data->storage_as.string.data, + values[i+1].data.d_parasite.data, + values[i+1].data.d_parasite.size); + + intermediate_val = cons (name, + cons(flags, cons(data, NIL))); + return_val = cons (intermediate_val, return_val); + } + } + break; + + case GIMP_PDB_STATUS: + return my_err ("Procedural database execution returned multiple status values", NIL); + break; + + default: + return my_err ("Unknown return type", NIL); + } + } + break; + + case GIMP_PDB_PASS_THROUGH: + case GIMP_PDB_CANCEL: /* should we do something here? */ + break; + } + + /* free up the executed procedure return values */ + gimp_destroy_params (values, nvalues); + + /* free up arguments and values */ + g_free (args); + + /* free the query information */ + g_free (proc_blurb); + g_free (proc_help); + g_free (proc_author); + g_free (proc_copyright); + g_free (proc_date); + g_free (params); + g_free (return_vals); + + /* reverse the return values */ + return_val = nreverse (return_val); +#ifndef G_OS_WIN32 + /* if we're in server mode, listen for additional commands for 10 ms */ + if (script_fu_server_get_mode ()) + script_fu_server_listen (10); +#endif + +#ifdef GDK_WINDOWING_WIN32 + /* This seems to help a lot on Windoze. */ + while (gtk_events_pending ()) + gtk_main_iteration (); +#endif + + return return_val; +} + +static LISP +script_fu_register_call (LISP a) +{ + if (register_scripts) + return script_fu_add_script (a); + else + return NIL; +} + +static LISP +script_fu_quit_call (LISP a) +{ + script_fu_server_quit (); + + return NIL; +} + diff --git a/plug-ins/script-fu/scheme-wrapper.h b/plug-ins/script-fu/scheme-wrapper.h new file mode 100644 index 0000000000..4948a6c372 --- /dev/null +++ b/plug-ins/script-fu/scheme-wrapper.h @@ -0,0 +1,25 @@ + +#ifndef SIOD_WRAPPER_H +#define SIOD_WRAPPER_H + +#include +#include + +void siod_init (gboolean register_scripts); + +FILE *siod_get_output_file (void); +void siod_set_output_file (FILE *file); + +int siod_get_verbose_level (void); +void siod_set_verbose_level (int verbose_level); + +void siod_print_welcome (void); + +const char *siod_get_error_msg (void); +const char *siod_get_success_msg (void); + +/* if the return value is 0, success. error otherwise. */ +int siod_interpret_string (const char *expr); + + +#endif /* SIOD_WRAPPER_H */ diff --git a/plug-ins/script-fu/script-fu-console.c b/plug-ins/script-fu/script-fu-console.c index c49c10845c..b2e5189aaa 100644 --- a/plug-ins/script-fu/script-fu-console.c +++ b/plug-ins/script-fu/script-fu-console.c @@ -38,7 +38,7 @@ #include "script-fu-intl.h" -#include "siod.h" +#include "siod-wrapper.h" #include "script-fu-console.h" #include @@ -85,8 +85,8 @@ static gboolean script_fu_cc_key_function (GtkWidget *widget, GdkEventKey *event, gpointer data); -static FILE * script_fu_open_siod_console (void); -static void script_fu_close_siod_console (void); +static void script_fu_open_siod_console (void); +static void script_fu_close_siod_console(void); /* * Local variables @@ -113,9 +113,6 @@ static gint history_cur = 0; static gint history_max = 50; static gint siod_output_pipe[2]; -extern gint siod_verbose_level; -extern gchar siod_err_msg[]; -extern FILE *siod_output; #define message(string) printf("(%s): %d ::: %s\n", __PRETTY_FUNCTION__, __LINE__, string) @@ -498,7 +495,7 @@ script_fu_cc_key_function (GtkWidget *widget, gtk_entry_set_text (GTK_ENTRY (cint.cc), ""); gdk_flush (); - repl_c_string ((char *) list->data, 0, 0, 1); + siod_interpret_string ((char *) list->data); gimp_displays_flush (); history = g_list_append (history, NULL); @@ -575,36 +572,49 @@ script_fu_cc_key_function (GtkWidget *widget, return FALSE; } - -static FILE * +static void script_fu_open_siod_console (void) { + FILE *siod_output; + + siod_output = siod_get_output_file (); + if (siod_output == stdout) { - if (pipe (siod_output_pipe)) - { - gimp_message (_("Unable to open SIOD output pipe")); - } - else if ((siod_output = fdopen (siod_output_pipe [1], "w")) == NULL) - { - gimp_message (_("Unable to open a stream on the SIOD output pipe")); - siod_output = stdout; - } + if (pipe (siod_output_pipe) == 0) + { + siod_output = fdopen (siod_output_pipe [1], "w"); + if (siod_output != NULL) + { + siod_set_verbose_level (2); + siod_print_welcome (); + } + else + { + gimp_message (_("Unable to open a stream on the SIOD output pipe")); + siod_output = stdout; + } + } else - { - siod_verbose_level = 2; - print_welcome (); - } + { + gimp_message (_("Unable to open the SIOD output pipe")); + siod_output = stdout; + } } - return siod_output; + siod_set_output_file (siod_output); } static void script_fu_close_siod_console (void) { + FILE *siod_output; + + siod_output = siod_get_output_file (); + if (siod_output != stdout) fclose (siod_output); + close (siod_output_pipe[0]); close (siod_output_pipe[1]); } @@ -645,3 +655,4 @@ script_fu_eval_run (gchar *name, values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; } + diff --git a/plug-ins/script-fu/script-fu-scripts.h b/plug-ins/script-fu/script-fu-scripts.h index c5cf16cad5..65c4394d38 100644 --- a/plug-ins/script-fu/script-fu-scripts.h +++ b/plug-ins/script-fu/script-fu-scripts.h @@ -20,6 +20,7 @@ #define __SCRIPT_FU_SCRIPTS_H__ #include "script-fu-enums.h" +#include "siod.h" void script_fu_find_scripts (void); LISP script_fu_add_script (LISP a); diff --git a/plug-ins/script-fu/script-fu-server.c b/plug-ins/script-fu/script-fu-server.c index f9345fef74..171eb6a74b 100644 --- a/plug-ins/script-fu/script-fu-server.c +++ b/plug-ins/script-fu/script-fu-server.c @@ -42,7 +42,7 @@ #include "script-fu-intl.h" #include "gtk/gtk.h" -#include "siod.h" +#include "siod-wrapper.h" #include "script-fu-server.h" @@ -129,11 +129,6 @@ static void ok_callback (GtkWidget *widget, gpointer data); -/* - * Global variables - */ -gint server_mode = FALSE; - /* * Local variables */ @@ -145,6 +140,8 @@ static FILE *server_log_file = NULL; static GHashTable *clientname_ht = NULL; static SELECT_MASK server_active; static SELECT_MASK server_read; +static gboolean script_fu_done = FALSE; +static gboolean server_mode = FALSE; static ServerInterface sint = { @@ -157,14 +154,23 @@ static ServerInterface sint = FALSE /* run */ }; -extern gboolean script_fu_done; -extern gchar siod_err_msg[]; -extern LISP repl_return_val; - /* * Server interface functions */ +void +script_fu_server_quit (void) +{ + script_fu_done = TRUE; +} + +gint +script_fu_server_get_mode (void) +{ + return server_mode; +} + + void script_fu_server_run (gchar *name, gint nparams, @@ -355,36 +361,32 @@ server_start (gint port, static gboolean execute_command (SFCommand *cmd) { - guchar buffer[RESPONSE_HEADER]; - gchar *response; - time_t clock1; - time_t clock2; - gint response_len; - gboolean error; - gint i; + guchar buffer[RESPONSE_HEADER]; + const gchar *response; + time_t clock1; + time_t clock2; + gint response_len; + gboolean error; + gint i; /* Get the client address from the address/socket table */ server_log ("Processing request #%d\n", cmd->request_no); time (&clock1); /* run the command */ - if (repl_c_string (cmd->command, 0, 0, 1) != 0) + if (siod_interpret_string (cmd->command) != 0) { error = TRUE; - response_len = strlen (siod_err_msg); - response = siod_err_msg; + response = siod_get_error_msg (); + response_len = strlen (response); - server_log ("%s\n", siod_err_msg); + server_log ("%s\n", response); } else { error = FALSE; - if (TYPEP (repl_return_val, tc_string)) - response = get_c_string (repl_return_val); - else - response = "Success"; - + response = siod_get_success_msg (); response_len = strlen (response); time (&clock2); diff --git a/plug-ins/script-fu/script-fu-server.h b/plug-ins/script-fu/script-fu-server.h index 03139cb5c9..5d4988b53b 100644 --- a/plug-ins/script-fu/script-fu-server.h +++ b/plug-ins/script-fu/script-fu-server.h @@ -19,6 +19,13 @@ #ifndef __SCRIPT_FU_SERVER_H__ #define __SCRIPT_FU_SERVER_H__ +#include +#include + +gint script_fu_server_get_mode (void); + +void script_fu_server_quit (void); + void script_fu_server_run (gchar *name, gint nparams, GimpParam *params, diff --git a/plug-ins/script-fu/script-fu-text-console.c b/plug-ins/script-fu/script-fu-text-console.c new file mode 100644 index 0000000000..a5919a98ef --- /dev/null +++ b/plug-ins/script-fu/script-fu-text-console.c @@ -0,0 +1,121 @@ +/* The GIMP -- an 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "config.h" +#include "siod-wrapper.h" +#include "libgimp/gimp.h" +#include +#include "script-fu-intl.h" +#if HAVE_UNISTD_H +#include +#endif +#include + +static void script_fu_text_console_interface (void); + +void +script_fu_text_console_run (char *name, + int nparams, + GimpParam *params, + int *nreturn_vals, + GimpParam **return_vals) +{ + static GimpParam values[1]; + GimpPDBStatusType status = GIMP_PDB_SUCCESS; + GimpRunModeType run_mode; + + run_mode = params[0].data.d_int32; + + switch (run_mode) + { + case GIMP_RUN_INTERACTIVE: + /* Enable SIOD output */ + siod_set_output_file (stdout); + siod_set_verbose_level (2); + siod_print_welcome (); + + /* Run the interface */ + script_fu_text_console_interface (); + + break; + + case GIMP_RUN_WITH_LAST_VALS: + case GIMP_RUN_NONINTERACTIVE: + status = GIMP_PDB_CALLING_ERROR; + gimp_message (_("Script-Fu console mode allows only interactive invocation")); + break; + + default: + break; + } + + *nreturn_vals = 1; + *return_vals = values; + + values[0].type = GIMP_PDB_STATUS; + values[0].data.d_status = status; +} + +static char * +read_command (void) +{ + unsigned char c; + GString *string; + char *retval; + int left = 0, right = 0; + + string = g_string_new (""); + + c = (unsigned char )fgetc (stdin); + while (!((c == '\n') && (left == right))) + { + + if (c == '(') + left++; + else if (c == ')') + right++; + + if (c != '\n') + string = g_string_append_c (string, c); + else + string = g_string_append_c (string, ' '); + + c = (unsigned char )fgetc (stdin); + } + + retval = string->str; + g_string_free (string, 0); + + return retval; +} + +static void +script_fu_text_console_interface (void) +{ + char *command; + + while (1) + { + command = read_command (); + siod_interpret_string (command); + g_free (command); + } +} + + + diff --git a/app/batch.h b/plug-ins/script-fu/script-fu-text-console.h similarity index 74% rename from app/batch.h rename to plug-ins/script-fu/script-fu-text-console.h index 57da6e70cb..c2132383bd 100644 --- a/app/batch.h +++ b/plug-ins/script-fu/script-fu-text-console.h @@ -16,11 +16,13 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef __BATCH_H__ -#define __BATCH_H__ +#ifndef __SCRIPT_FU_TEXT_CONSOLE_H__ +#define __SCRIPT_FU_TEXT_CONSOLE_H__ +void script_fu_text_console_run (gchar *name, + gint nparams, + GimpParam *params, + gint *nreturn_vals, + GimpParam **return_vals); -void batch_init (Gimp *gimp); - - -#endif /* __BATCH_H__ */ +#endif /* __SCRIPT_FU_CONSOLE__ */ diff --git a/plug-ins/script-fu/script-fu.c b/plug-ins/script-fu/script-fu.c index 3d41ff185d..39333689a4 100644 --- a/plug-ins/script-fu/script-fu.c +++ b/plug-ins/script-fu/script-fu.c @@ -28,7 +28,7 @@ #include #include -#include "siod.h" +#include "siod-wrapper.h" #include "script-fu-console.h" #include "script-fu-constants.h" #include "script-fu-scripts.h" @@ -36,48 +36,22 @@ #include "script-fu-intl.h" -extern FILE *siod_output; - /* External functions */ extern void gimp_extension_process (guint timeout); extern void gimp_extension_ack (void); -extern void init_subrs (void); -extern void init_trace (void); -extern void init_regex (void); - -extern long nlength (LISP obj); -extern LISP leval_define (LISP args, - LISP env); - -extern void fput_st (FILE *f, - gchar *st); /* Declare local functions. */ -static void sfquit (void); -static void query (void); -static void run (gchar *name, - gint nparams, - GimpParam *param, - gint *nreturn_vals, - GimpParam **return_vals); +static void script_fu_quit (void); +static void script_fu_query (void); +static void script_fu_run (gchar *name, + gint nparams, + GimpParam *param, + gint *nreturn_vals, + GimpParam **return_vals); -static gint init_interp (void); -static void init_gimp (void); -static void init_procedures (void); -static void init_constants (void); -static void convert_string (gchar *str); - -static gboolean sputs_fcn (gchar *st, - gpointer dest); -static LISP lprin1s (LISP exp, - gchar *dest); - -static LISP marshall_proc_db_call (LISP a); -static LISP script_fu_register_call (LISP a); -static LISP script_fu_quit_call (LISP a); static void script_fu_auxillary_init (void); static void script_fu_refresh_proc (gchar *name, @@ -89,39 +63,23 @@ static void script_fu_refresh_proc (gchar *name, GimpPlugInInfo PLUG_IN_INFO = { - NULL, /* init_proc */ - sfquit, /* quit_proc */ - query, /* query_proc */ - run, /* run_proc */ + NULL, /* init_proc */ + script_fu_quit, /* quit_proc */ + script_fu_query, /* query_proc */ + script_fu_run, /* run_proc */ }; -static gchar *siod_argv[] = -{ - "siod", - "-h100000:10", - "-g0", - "-o1000", - "-s200000", - "-n2048", - "-v0", -}; - -static gint script_fu_base = TRUE; -extern gint server_mode; - -/* declared extern in script-fu-server.c */ -gboolean script_fu_done = FALSE; MAIN () static void -sfquit (void) +script_fu_quit (void) { } static void -query (void) +script_fu_query (void) { static GimpParamDef console_args[] = { @@ -129,6 +87,12 @@ query (void) }; static gint nconsole_args = sizeof (console_args) / sizeof (console_args[0]); + static GimpParamDef textconsole_args[] = + { + { GIMP_PDB_INT32, "run_mode", "Interactive, [non-interactive]" } + }; + static gint ntextconsole_args = sizeof (textconsole_args) / sizeof (textconsole_args[0]); + static GimpParamDef eval_args[] = { { GIMP_PDB_INT32, "run_mode", "[Interactive], non-interactive" }, @@ -169,6 +133,18 @@ query (void) nconsole_args, 0, console_args, NULL); + gimp_install_procedure ("extension_script_fu_text_console", + "Provides a text console mode for script-fu development", + "Provides an interface which allows interactive scheme development.", + "Spencer Kimball & Peter Mattis", + "Spencer Kimball & Peter Mattis", + "1997", + NULL, + NULL, + GIMP_EXTENSION, + ntextconsole_args, 0, + textconsole_args, NULL); + #ifndef G_OS_WIN32 gimp_install_procedure ("extension_script_fu_server", "Provides a server for remote script-fu operation", @@ -197,13 +173,13 @@ query (void) } static void -run (gchar *name, - gint nparams, - GimpParam *param, - gint *nreturn_vals, - GimpParam **return_vals) +script_fu_run (gchar *name, + gint nparams, + GimpParam *param, + gint *nreturn_vals, + GimpParam **return_vals) { - siod_output = stdout; + siod_set_output_file (stdout); /* Determine before we allow scripts to register themselves * whether this is the base, automatically installed script-fu extension @@ -213,13 +189,15 @@ run (gchar *name, /* Setup auxillary temporary procedures for the base extension */ script_fu_auxillary_init (); - script_fu_base = TRUE; + /* Init the interpreter */ + siod_init (TRUE); } else - script_fu_base = FALSE; + { + /* Init the interpreter */ + siod_init (FALSE); + } - /* Init the interpreter */ - init_interp (); /* Load all of the available scripts */ script_fu_find_scripts (); @@ -246,8 +224,12 @@ run (gchar *name, values[0].data.d_status = status; } /* - * The script-fu console for interactive SIOD development + * The script-fu consoles for interactive SIOD development */ + else if (strcmp (name, "extension_script_fu_text_console") == 0) + { + script_fu_text_console_run (name, nparams, param, nreturn_vals, return_vals); + } else if (strcmp (name, "extension_script_fu_console") == 0) { script_fu_console_run (name, nparams, param, nreturn_vals, return_vals); @@ -270,834 +252,6 @@ run (gchar *name, } } -static gint -init_interp (void) -{ - process_cla (sizeof (siod_argv) / sizeof (gchar *), siod_argv, 1); - - init_storage (); - - init_subrs (); - init_trace (); - init_regex (); - init_gimp (); - - return 0; -} - -static void -init_gimp (void) -{ - init_procedures (); - init_constants (); -} - -static void -init_procedures (void) -{ - gchar **proc_list; - gchar *proc_name; - gchar *arg_name; - gchar *proc_blurb; - gchar *proc_help; - gchar *proc_author; - gchar *proc_copyright; - gchar *proc_date; - GimpPDBProcType proc_type; - gint nparams; - gint nreturn_vals; - GimpParamDef *params; - GimpParamDef *return_vals; - gint num_procs; - gint i; - - /* register the database execution procedure */ - init_lsubr ("gimp-proc-db-call", marshall_proc_db_call); - init_lsubr ("script-fu-register", script_fu_register_call); - init_lsubr ("script-fu-quit", script_fu_quit_call); - - gimp_procedural_db_query (".*", ".*", ".*", ".*", ".*", ".*", ".*", - &num_procs, &proc_list); - - /* Register each procedure as a scheme func */ - for (i = 0; i < num_procs; i++) - { - proc_name = g_strdup (proc_list[i]); - - /* lookup the procedure */ - if (gimp_procedural_db_proc_info (proc_name, - &proc_blurb, - &proc_help, - &proc_author, - &proc_copyright, - &proc_date, - &proc_type, - &nparams, &nreturn_vals, - ¶ms, &return_vals)) - { - LISP args = NIL; - LISP code = NIL; - gint j; - - /* convert the names to scheme-like naming conventions */ - convert_string (proc_name); - - /* create a new scheme func that calls gimp-proc-db-call */ - for (j = 0; j < nparams; j++) - { - arg_name = g_strdup (params[j].name); - convert_string (arg_name); - args = cons (cintern (arg_name), args); - code = cons (cintern (arg_name), code); - } - - /* reverse the list */ - args = nreverse (args); - code = nreverse (code); - - /* set the scheme-based procedure name */ - args = cons (cintern (proc_name), args); - - /* set the acture pdb procedure name */ - code = cons (cons (cintern ("quote"), - cons (cintern (proc_list[i]), NIL)), - code); - code = cons (cintern ("gimp-proc-db-call"), code); - - leval_define (cons (args, cons (code, NIL)), NIL); - - /* free the queried information */ - g_free (proc_blurb); - g_free (proc_help); - g_free (proc_author); - g_free (proc_copyright); - g_free (proc_date); - gimp_destroy_paramdefs (params, nparams); - gimp_destroy_paramdefs (return_vals, nreturn_vals); - } - } - - g_free (proc_list); -} - -static void -init_constants (void) -{ - gchar *gimp_plugin_dir; - - setvar (cintern ("gimp-data-dir"), - strcons (-1, (gchar *) gimp_data_directory ()), NIL); - - gimp_plugin_dir = gimp_gimprc_query ("gimp_plugin_dir"); - if (gimp_plugin_dir) - { - setvar (cintern ("gimp-plugin-dir"), - strcons (-1, gimp_plugin_dir), NIL); - g_free (gimp_plugin_dir); - } - - /* Generated constants */ - init_generated_constants (); - - /* These are for backwards compatibility; they should be removed sometime */ - setvar (cintern ("NORMAL"), flocons (GIMP_NORMAL_MODE), NIL); - setvar (cintern ("DISSOLVE"), flocons (GIMP_DISSOLVE_MODE), NIL); - setvar (cintern ("BEHIND"), flocons (GIMP_BEHIND_MODE), NIL); - setvar (cintern ("MULTIPLY"), flocons (GIMP_MULTIPLY_MODE), NIL); - setvar (cintern ("SCREEN"), flocons (GIMP_SCREEN_MODE), NIL); - setvar (cintern ("OVERLAY"), flocons (GIMP_OVERLAY_MODE), NIL); - setvar (cintern ("DIFFERENCE"), flocons (GIMP_DIFFERENCE_MODE), NIL); - setvar (cintern ("ADDITION"), flocons (GIMP_ADDITION_MODE), NIL); - setvar (cintern ("SUBTRACT"), flocons (GIMP_SUBTRACT_MODE), NIL); - setvar (cintern ("DARKEN-ONLY"), flocons (GIMP_DARKEN_ONLY_MODE), NIL); - setvar (cintern ("LIGHTEN-ONLY"), flocons (GIMP_LIGHTEN_ONLY_MODE), NIL); - setvar (cintern ("HUE"), flocons (GIMP_HUE_MODE), NIL); - setvar (cintern ("SATURATION"), flocons (GIMP_SATURATION_MODE), NIL); - setvar (cintern ("COLOR"), flocons (GIMP_COLOR_MODE), NIL); - setvar (cintern ("VALUE"), flocons (GIMP_VALUE_MODE), NIL); - setvar (cintern ("DIVIDE"), flocons (GIMP_DIVIDE_MODE), NIL); - - setvar (cintern ("BLUR"), flocons (GIMP_BLUR_CONVOLVE), NIL); - setvar (cintern ("SHARPEN"), flocons (GIMP_SHARPEN_CONVOLVE), NIL); - - setvar (cintern ("RGB_IMAGE"), flocons (GIMP_RGB_IMAGE), NIL); - setvar (cintern ("RGBA_IMAGE"), flocons (GIMP_RGBA_IMAGE), NIL); - setvar (cintern ("GRAY_IMAGE"), flocons (GIMP_GRAY_IMAGE), NIL); - setvar (cintern ("GRAYA_IMAGE"), flocons (GIMP_GRAYA_IMAGE), NIL); - setvar (cintern ("INDEXED_IMAGE"), flocons (GIMP_INDEXED_IMAGE), NIL); - setvar (cintern ("INDEXEDA_IMAGE"), flocons (GIMP_INDEXEDA_IMAGE), NIL); - - /* Useful misc stuff */ - setvar (cintern ("TRUE"), flocons (TRUE), NIL); - setvar (cintern ("FALSE"), flocons (FALSE), NIL); - - /* Script-fu types */ - setvar (cintern ("SF-IMAGE"), flocons (SF_IMAGE), NIL); - setvar (cintern ("SF-DRAWABLE"), flocons (SF_DRAWABLE), NIL); - setvar (cintern ("SF-LAYER"), flocons (SF_LAYER), NIL); - setvar (cintern ("SF-CHANNEL"), flocons (SF_CHANNEL), NIL); - setvar (cintern ("SF-COLOR"), flocons (SF_COLOR), NIL); - setvar (cintern ("SF-TOGGLE"), flocons (SF_TOGGLE), NIL); - setvar (cintern ("SF-VALUE"), flocons (SF_VALUE), NIL); - setvar (cintern ("SF-STRING"), flocons (SF_STRING), NIL); - setvar (cintern ("SF-FILENAME"), flocons (SF_FILENAME), NIL); - setvar (cintern ("SF-ADJUSTMENT"), flocons (SF_ADJUSTMENT), NIL); - setvar (cintern ("SF-FONT"), flocons (SF_FONT), NIL); - setvar (cintern ("SF-PATTERN"), flocons (SF_PATTERN), NIL); - setvar (cintern ("SF-BRUSH"), flocons (SF_BRUSH), NIL); - setvar (cintern ("SF-GRADIENT"), flocons (SF_GRADIENT), NIL); - setvar (cintern ("SF-OPTION"), flocons (SF_OPTION), NIL); - - /* for SF_ADJUSTMENT */ - setvar (cintern ("SF-SLIDER"), flocons (SF_SLIDER), NIL); - setvar (cintern ("SF-SPINNER"), flocons (SF_SPINNER), NIL); -} - -static void -convert_string (gchar *str) -{ - while (*str) - { - if (*str == '_') *str = '-'; - str++; - } -} - -static gboolean -sputs_fcn (gchar *st, - gpointer dest) -{ - strcpy (*((gchar**)dest), st); - *((gchar**)dest) += strlen (st); - - return TRUE; -} - -static LISP -lprin1s (LISP exp, - gchar *dest) -{ - struct gen_printio s; - - s.putc_fcn = NULL; - s.puts_fcn = sputs_fcn; - s.cb_argument = &dest; - - lprin1g (exp, &s); - - return (NIL); -} - - -static LISP -marshall_proc_db_call (LISP a) -{ - GimpParam *args; - GimpParam *values = NULL; - gint nvalues; - gchar *proc_name; - gchar *proc_blurb; - gchar *proc_help; - gchar *proc_author; - gchar *proc_copyright; - gchar *proc_date; - GimpPDBProcType proc_type; - gint nparams; - gint nreturn_vals; - GimpParamDef *params; - GimpParamDef *return_vals; - gchar error_str[256]; - gint i; - gint success = TRUE; - LISP color_list; - LISP intermediate_val; - LISP return_val = NIL; - gchar *string; - gint string_len; - LISP a_saved; - - /* Save a in case it is needed for an error message. */ - a_saved = a; - - /* Make sure there are arguments */ - if (a == NIL) - return my_err ("Procedure database argument marshaller was called with no arguments. " - "The procedure to be executed and the arguments it requires " - "(possibly none) must be specified.", NIL); - - /* Derive the pdb procedure name from the argument - or first argument of a list */ - if (TYPEP (a, tc_cons)) - proc_name = get_c_string (car (a)); - else - proc_name = get_c_string (a); - - /* report the current command */ - script_fu_report_cc (proc_name); - - /* Attempt to fetch the procedure from the database */ - if (! gimp_procedural_db_proc_info (proc_name, - &proc_blurb, - &proc_help, - &proc_author, - &proc_copyright, - &proc_date, - &proc_type, - &nparams, &nreturn_vals, - ¶ms, &return_vals)) - return my_err ("Invalid procedure name specified.", NIL); - - - /* Check the supplied number of arguments */ - if ((nlength (a) - 1) != nparams) - { - g_snprintf (error_str, sizeof (error_str), - "Invalid arguments supplied to %s--(# args: %ld, expecting: %d)", - proc_name, (nlength (a) - 1), nparams); - return my_err (error_str, NIL); - } - - /* Marshall the supplied arguments */ - if (nparams) - args = g_new (GimpParam, nparams); - else - args = NULL; - - a = cdr (a); - for (i = 0; i < nparams; i++) - { - switch (params[i].type) - { - case GIMP_PDB_INT32: - if (!TYPEP (car (a), tc_flonum)) - success = FALSE; - if (success) - { - args[i].type = GIMP_PDB_INT32; - args[i].data.d_int32 = get_c_long (car (a)); - } - break; - - case GIMP_PDB_INT16: - if (!TYPEP (car (a), tc_flonum)) - success = FALSE; - if (success) - { - args[i].type = GIMP_PDB_INT16; - args[i].data.d_int16 = (gint16) get_c_long (car (a)); - } - break; - - case GIMP_PDB_INT8: - if (!TYPEP (car (a), tc_flonum)) - success = FALSE; - if (success) - { - args[i].type = GIMP_PDB_INT8; - args[i].data.d_int8 = (gint8) get_c_long (car (a)); - } - break; - - case GIMP_PDB_FLOAT: - if (!TYPEP (car (a), tc_flonum)) - success = FALSE; - if (success) - { - args[i].type = GIMP_PDB_FLOAT; - args[i].data.d_float = get_c_double (car (a)); - } - break; - - case GIMP_PDB_STRING: - if (!TYPEP (car (a), tc_string)) - success = FALSE; - if (success) - { - args[i].type = GIMP_PDB_STRING; - args[i].data.d_string = get_c_string (car (a)); - } - break; - - case GIMP_PDB_INT32ARRAY: - if (!TYPEP (car (a), tc_long_array)) - success = FALSE; - if (success) - { - args[i].type = GIMP_PDB_INT32ARRAY; - args[i].data.d_int32array = - (gint32*) (car (a))->storage_as.long_array.data; - } - break; - - case GIMP_PDB_INT16ARRAY: - if (!TYPEP (car (a), tc_long_array)) - success = FALSE; - if (success) - { - args[i].type = GIMP_PDB_INT16ARRAY; - args[i].data.d_int16array = - (gint16*) (car (a))->storage_as.long_array.data; - } - break; - - case GIMP_PDB_INT8ARRAY: - if (!TYPEP (car (a), tc_byte_array)) - success = FALSE; - if (success) - { - args[i].type = GIMP_PDB_INT8ARRAY; - args[i].data.d_int8array = - (gint8*) (car (a))->storage_as.string.data; - } - break; - - case GIMP_PDB_FLOATARRAY: - if (!TYPEP (car (a), tc_double_array)) - success = FALSE; - if (success) - { - args[i].type = GIMP_PDB_FLOATARRAY; - args[i].data.d_floatarray = - (car (a))->storage_as.double_array.data; - } - break; - - case GIMP_PDB_STRINGARRAY: - if (!TYPEP (car (a), tc_cons)) - success = FALSE; - if (success) - { - args[i].type = GIMP_PDB_STRINGARRAY; - - /* Set the array */ - { - gint j; - gint num_strings; - gchar **array; - LISP list; - - list = car (a); - num_strings = args[i - 1].data.d_int32; - if (nlength (list) != num_strings) - return my_err ("String array argument has incorrectly specified length", NIL); - array = args[i].data.d_stringarray = - g_new (char *, num_strings); - - for (j = 0; j < num_strings; j++) - { - array[j] = get_c_string (car (list)); - list = cdr (list); - } - } - } - break; - - case GIMP_PDB_COLOR: - if (!TYPEP (car (a), tc_cons)) - success = FALSE; - if (success) - { - guchar color[3]; - - args[i].type = GIMP_PDB_COLOR; - color_list = car (a); - color[0] = get_c_long (car (color_list)); - color[1] = get_c_long (car (color_list)); - color[2] = get_c_long (car (color_list)); - - gimp_rgb_set_uchar (&args[i].data.d_color, - color[0], color[1], color[2]); - } - break; - - case GIMP_PDB_REGION: - return my_err ("Regions are currently unsupported as arguments", - car (a)); - break; - - case GIMP_PDB_DISPLAY: - if (!TYPEP (car (a), tc_flonum)) - success = FALSE; - if (success) - { - args[i].type = GIMP_PDB_DISPLAY; - args[i].data.d_int32 = get_c_long (car (a)); - } - break; - - case GIMP_PDB_IMAGE: - if (!TYPEP (car (a), tc_flonum)) - success = FALSE; - if (success) - { - args[i].type = GIMP_PDB_IMAGE; - args[i].data.d_int32 = get_c_long (car (a)); - } - break; - - case GIMP_PDB_LAYER: - if (!TYPEP (car (a), tc_flonum)) - success = FALSE; - if (success) - { - args[i].type = GIMP_PDB_LAYER; - args[i].data.d_int32 = get_c_long (car (a)); - } - break; - - case GIMP_PDB_CHANNEL: - if (!TYPEP (car (a), tc_flonum)) - success = FALSE; - if (success) - { - args[i].type = GIMP_PDB_CHANNEL; - args[i].data.d_int32 = get_c_long (car (a)); - } - break; - - case GIMP_PDB_DRAWABLE: - if (!TYPEP (car (a), tc_flonum)) - success = FALSE; - if (success) - { - args[i].type = GIMP_PDB_DRAWABLE; - args[i].data.d_int32 = get_c_long (car (a)); - } - break; - - case GIMP_PDB_SELECTION: - if (!TYPEP (car (a), tc_flonum)) - success = FALSE; - if (success) - { - args[i].type = GIMP_PDB_SELECTION; - args[i].data.d_int32 = get_c_long (car (a)); - } - break; - - case GIMP_PDB_BOUNDARY: - return my_err ("Boundaries are currently unsupported as arguments", - car (a)); - break; - - case GIMP_PDB_PATH: - return my_err ("Paths are currently unsupported as arguments", - car (a)); - break; - - case GIMP_PDB_PARASITE: - if (!TYPEP (car (a), tc_cons)) - success = FALSE; - if (success) - { - args[i].type = GIMP_PDB_PARASITE; - /* parasite->name */ - intermediate_val = car (a); - args[i].data.d_parasite.name = - get_c_string (car (intermediate_val)); - - /* parasite->flags */ - intermediate_val = cdr (intermediate_val); - args[i].data.d_parasite.flags = get_c_long (car(intermediate_val)); - - /* parasite->size */ - intermediate_val = cdr (intermediate_val); - args[i].data.d_parasite.size = - (car (intermediate_val))->storage_as.string.dim; - - /* parasite->data */ - args[i].data.d_parasite.data = - (void*) (car (intermediate_val))->storage_as.string.data; - } - break; - - case GIMP_PDB_STATUS: - return my_err ("Status is for return types, not arguments", car (a)); - break; - - default: - return my_err ("Unknown argument type", NIL); - } - - a = cdr (a); - } - - if (success) - values = gimp_run_procedure2 (proc_name, &nvalues, nparams, args); - else - return my_err ("Invalid types specified for arguments", NIL); - - /* Check the return status */ - if (! values) - { - strcpy (error_str, "Procedural database execution did not return a status:\n "); - lprin1s (a_saved, error_str + strlen(error_str)); - - return my_err (error_str, NIL); - } - - switch (values[0].data.d_status) - { - case GIMP_PDB_EXECUTION_ERROR: - strcpy (error_str, "Procedural database execution failed:\n "); - lprin1s (a_saved, error_str + strlen(error_str)); - return my_err (error_str, NIL); - break; - - case GIMP_PDB_CALLING_ERROR: - strcpy (error_str, "Procedural database execution failed on invalid input arguments:\n "); - lprin1s (a_saved, error_str + strlen(error_str)); - return my_err (error_str, NIL); - break; - - case GIMP_PDB_SUCCESS: - return_val = NIL; - - for (i = 0; i < nvalues - 1; i++) - { - switch (return_vals[i].type) - { - case GIMP_PDB_INT32: - return_val = cons (flocons (values[i + 1].data.d_int32), - return_val); - break; - - case GIMP_PDB_INT16: - return_val = cons (flocons (values[i + 1].data.d_int32), - return_val); - break; - - case GIMP_PDB_INT8: - return_val = cons (flocons (values[i + 1].data.d_int32), - return_val); - break; - - case GIMP_PDB_FLOAT: - return_val = cons (flocons (values[i + 1].data.d_float), - return_val); - break; - - case GIMP_PDB_STRING: - string = (gchar *) values[i + 1].data.d_string; - string_len = strlen (string); - return_val = cons (strcons (string_len, string), return_val); - break; - - case GIMP_PDB_INT32ARRAY: - { - LISP array; - gint j; - - array = arcons (tc_long_array, values[i].data.d_int32, 0); - for (j = 0; j < values[i].data.d_int32; j++) - { - array->storage_as.long_array.data[j] = - values[i + 1].data.d_int32array[j]; - } - return_val = cons (array, return_val); - } - break; - - case GIMP_PDB_INT16ARRAY: - return my_err ("Arrays are currently unsupported as return values", NIL); - break; - - case GIMP_PDB_INT8ARRAY: - { - LISP array; - gint j; - - array = arcons (tc_byte_array, values[i].data.d_int32, 0); - for (j = 0; j < values[i].data.d_int32; j++) - { - array->storage_as.string.data[j] = - values[i + 1].data.d_int8array[j]; - } - return_val = cons (array, return_val); - } - break; - - case GIMP_PDB_FLOATARRAY: - { - LISP array; - gint j; - - array = arcons (tc_double_array, values[i].data.d_int32, 0); - for (j = 0; j < values[i].data.d_int32; j++) - { - array->storage_as.double_array.data[j] = - values[i + 1].data.d_floatarray[j]; - } - return_val = cons (array, return_val); - } - break; - - case GIMP_PDB_STRINGARRAY: - /* string arrays are always implemented such that the previous - * return value contains the number of strings in the array - */ - { - gint j; - gint num_strings = values[i].data.d_int32; - LISP string_array = NIL; - gchar **array = (gchar **) values[i + 1].data.d_stringarray; - - for (j = 0; j < num_strings; j++) - { - string_len = strlen (array[j]); - string_array = cons (strcons (string_len, array[j]), - string_array); - } - - return_val = cons (nreverse (string_array), return_val); - } - break; - - case GIMP_PDB_COLOR: - { - guchar color[3]; - gimp_rgb_get_uchar (&values[i + 1].data.d_color, color, color + 1, color + 2); - intermediate_val = cons (flocons ((int) color[0]), - cons (flocons ((int) color[1]), - cons (flocons ((int) color[2]), - NIL))); - return_val = cons (intermediate_val, return_val); - break; - } - - case GIMP_PDB_REGION: - return my_err ("Regions are currently unsupported as return values", NIL); - break; - - case GIMP_PDB_DISPLAY: - return_val = cons (flocons (values[i + 1].data.d_int32), - return_val); - break; - - case GIMP_PDB_IMAGE: - return_val = cons (flocons (values[i + 1].data.d_int32), - return_val); - break; - - case GIMP_PDB_LAYER: - return_val = cons (flocons (values[i + 1].data.d_int32), - return_val); - break; - - case GIMP_PDB_CHANNEL: - return_val = cons (flocons (values[i + 1].data.d_int32), - return_val); - break; - - case GIMP_PDB_DRAWABLE: - return_val = cons (flocons (values[i + 1].data.d_int32), - return_val); - break; - - case GIMP_PDB_SELECTION: - return_val = cons (flocons (values[i + 1].data.d_int32), - return_val); - break; - - case GIMP_PDB_BOUNDARY: - return my_err ("Boundaries are currently unsupported as return values", NIL); - break; - - case GIMP_PDB_PATH: - return my_err ("Paths are currently unsupported as return values", NIL); - break; - - case GIMP_PDB_PARASITE: - { - LISP name, flags, data; - - if (values[i + 1].data.d_parasite.name == NULL) - { - return_val = my_err("Error: null parasite", NIL); - } - else - { - string_len = strlen (values[i + 1].data.d_parasite.name); - name = strcons (string_len, - values[i + 1].data.d_parasite.name); - - flags = flocons (values[i + 1].data.d_parasite.flags); - data = arcons (tc_byte_array, - values[i+1].data.d_parasite.size, 0); - memcpy(data->storage_as.string.data, - values[i+1].data.d_parasite.data, - values[i+1].data.d_parasite.size); - - intermediate_val = cons (name, - cons(flags, cons(data, NIL))); - return_val = cons (intermediate_val, return_val); - } - } - break; - - case GIMP_PDB_STATUS: - return my_err ("Procedural database execution returned multiple status values", NIL); - break; - - default: - return my_err ("Unknown return type", NIL); - } - } - break; - - case GIMP_PDB_PASS_THROUGH: - case GIMP_PDB_CANCEL: /* should we do something here? */ - break; - } - - /* free up the executed procedure return values */ - gimp_destroy_params (values, nvalues); - - /* free up arguments and values */ - g_free (args); - - /* free the query information */ - g_free (proc_blurb); - g_free (proc_help); - g_free (proc_author); - g_free (proc_copyright); - g_free (proc_date); - g_free (params); - g_free (return_vals); - - /* reverse the return values */ - return_val = nreverse (return_val); -#ifndef G_OS_WIN32 - /* if we're in server mode, listen for additional commands for 10 ms */ - if (server_mode) - script_fu_server_listen (10); -#endif - -#ifdef GDK_WINDOWING_WIN32 - /* This seems to help a lot on Windoze. */ - while (gtk_events_pending ()) - gtk_main_iteration (); -#endif - - return return_val; -} - -static LISP -script_fu_register_call (LISP a) -{ - if (script_fu_base) - return script_fu_add_script (a); - else - return NIL; -} - -static LISP -script_fu_quit_call (LISP a) -{ - script_fu_done = TRUE; - - return NIL; -} static void script_fu_auxillary_init (void) diff --git a/plug-ins/script-fu/siod-wrapper.c b/plug-ins/script-fu/siod-wrapper.c new file mode 100644 index 0000000000..fa6fbd62e6 --- /dev/null +++ b/plug-ins/script-fu/siod-wrapper.c @@ -0,0 +1,946 @@ +#include "config.h" + +#include "siod.h" +#include "siod-wrapper.h" +#include +#include "libgimp/gimp.h" +#include "script-fu-constants.h" +#include "script-fu-enums.h" +#include "script-fu-scripts.h" +#include "script-fu-server.h" + +/* global variables declared by the scheme interpreter */ +extern FILE* siod_output; +extern int siod_verbose_level; +extern char siod_err_msg[]; +extern LISP repl_return_val; + + +/* defined in regex.c. not exported by regex.h */ +extern void init_regex (void); + +/* defined in siodp.h but this file cannot be imported... */ +extern long nlength (LISP obj); +extern LISP leval_define (LISP args, LISP env); + + +/* wrapper functions */ +FILE * +siod_get_output_file (void) +{ + return siod_output; +} + +void +siod_set_output_file (FILE *file) +{ + siod_output = file; +} + +int +siod_get_verbose_level (void) +{ + return siod_verbose_level; +} + + +void +siod_set_verbose_level (int verbose_level) +{ + siod_verbose_level = verbose_level; +} + + +void +siod_print_welcome (void) +{ + print_welcome (); +} + + +int +siod_interpret_string (const char *expr) +{ + return repl_c_string ((char *)expr, 0, 0, 1); +} + + +const char * +siod_get_error_msg (void) +{ + return siod_err_msg; +} + +const char * +siod_get_success_msg (void) +{ + char *response; + + if (TYPEP (repl_return_val, tc_string)) + response = get_c_string (repl_return_val); + else + response = "Success"; + + return (const char *) response; +} + + +static void init_constants (void); +static void init_procedures (void); + +static gboolean register_scripts = FALSE; + +void +siod_init (gint local_register_scripts) +{ + char *siod_argv[] = + { + "siod", + "-h100000:10", + "-g0", + "-o1000", + "-s200000", + "-n2048", + "-v0", + }; + + register_scripts = local_register_scripts; + + /* init the interpreter */ + process_cla (sizeof (siod_argv) / sizeof (char *), siod_argv, 1); + init_storage (); + init_subrs (); + init_trace (); + init_regex (); + + /* register in the interpreter the gimp functions and types. */ + init_procedures (); + init_constants (); + +} + +static void convert_string (char *str); +static gint sputs_fcn (char *st, + void *dest); +static LISP lprin1s (LISP exp, + char *dest); +static LISP marshall_proc_db_call (LISP a); +static LISP script_fu_register_call (LISP a); +static LISP script_fu_quit_call (LISP a); + + +/********* + + Below can be found the functions responsible for registering the gimp functions + and types against the scheme interpreter. + +********/ + + +static void +init_procedures (void) +{ + gchar **proc_list; + gchar *proc_name; + gchar *arg_name; + gchar *proc_blurb; + gchar *proc_help; + gchar *proc_author; + gchar *proc_copyright; + gchar *proc_date; + GimpPDBProcType proc_type; + gint nparams; + gint nreturn_vals; + GimpParamDef *params; + GimpParamDef *return_vals; + gint num_procs; + gint i; + + /* register the database execution procedure */ + init_lsubr ("gimp-proc-db-call", marshall_proc_db_call); + init_lsubr ("script-fu-register", script_fu_register_call); + init_lsubr ("script-fu-quit", script_fu_quit_call); + + gimp_procedural_db_query (".*", ".*", ".*", ".*", ".*", ".*", ".*", + &num_procs, &proc_list); + + /* Register each procedure as a scheme func */ + for (i = 0; i < num_procs; i++) + { + proc_name = g_strdup (proc_list[i]); + + /* lookup the procedure */ + if (gimp_procedural_db_proc_info (proc_name, + &proc_blurb, + &proc_help, + &proc_author, + &proc_copyright, + &proc_date, + &proc_type, + &nparams, &nreturn_vals, + ¶ms, &return_vals)) + { + LISP args = NIL; + LISP code = NIL; + gint j; + + /* convert the names to scheme-like naming conventions */ + convert_string (proc_name); + + /* create a new scheme func that calls gimp-proc-db-call */ + for (j = 0; j < nparams; j++) + { + arg_name = g_strdup (params[j].name); + convert_string (arg_name); + args = cons (cintern (arg_name), args); + code = cons (cintern (arg_name), code); + } + + /* reverse the list */ + args = nreverse (args); + code = nreverse (code); + + /* set the scheme-based procedure name */ + args = cons (cintern (proc_name), args); + + /* set the acture pdb procedure name */ + code = cons (cons (cintern ("quote"), + cons (cintern (proc_list[i]), NIL)), + code); + code = cons (cintern ("gimp-proc-db-call"), code); + + leval_define (cons (args, cons (code, NIL)), NIL); + + /* free the queried information */ + g_free (proc_blurb); + g_free (proc_help); + g_free (proc_author); + g_free (proc_copyright); + g_free (proc_date); + gimp_destroy_paramdefs (params, nparams); + gimp_destroy_paramdefs (return_vals, nreturn_vals); + } + } + + g_free (proc_list); +} + +static void +init_constants (void) +{ + gchar *gimp_plugin_dir; + + setvar (cintern ("gimp-data-dir"), + strcons (-1, (gchar *) gimp_data_directory ()), NIL); + + gimp_plugin_dir = gimp_gimprc_query ("gimp_plugin_dir"); + if (gimp_plugin_dir) + { + setvar (cintern ("gimp-plugin-dir"), + strcons (-1, gimp_plugin_dir), NIL); + g_free (gimp_plugin_dir); + } + + /* Generated constants */ + init_generated_constants (); + + /* These are for backwards compatibility; they should be removed sometime */ + setvar (cintern ("NORMAL"), flocons (GIMP_NORMAL_MODE), NIL); + setvar (cintern ("DISSOLVE"), flocons (GIMP_DISSOLVE_MODE), NIL); + setvar (cintern ("BEHIND"), flocons (GIMP_BEHIND_MODE), NIL); + setvar (cintern ("MULTIPLY"), flocons (GIMP_MULTIPLY_MODE), NIL); + setvar (cintern ("SCREEN"), flocons (GIMP_SCREEN_MODE), NIL); + setvar (cintern ("OVERLAY"), flocons (GIMP_OVERLAY_MODE), NIL); + setvar (cintern ("DIFFERENCE"), flocons (GIMP_DIFFERENCE_MODE), NIL); + setvar (cintern ("ADDITION"), flocons (GIMP_ADDITION_MODE), NIL); + setvar (cintern ("SUBTRACT"), flocons (GIMP_SUBTRACT_MODE), NIL); + setvar (cintern ("DARKEN-ONLY"), flocons (GIMP_DARKEN_ONLY_MODE), NIL); + setvar (cintern ("LIGHTEN-ONLY"), flocons (GIMP_LIGHTEN_ONLY_MODE), NIL); + setvar (cintern ("HUE"), flocons (GIMP_HUE_MODE), NIL); + setvar (cintern ("SATURATION"), flocons (GIMP_SATURATION_MODE), NIL); + setvar (cintern ("COLOR"), flocons (GIMP_COLOR_MODE), NIL); + setvar (cintern ("VALUE"), flocons (GIMP_VALUE_MODE), NIL); + setvar (cintern ("DIVIDE"), flocons (GIMP_DIVIDE_MODE), NIL); + + setvar (cintern ("BLUR"), flocons (GIMP_BLUR_CONVOLVE), NIL); + setvar (cintern ("SHARPEN"), flocons (GIMP_SHARPEN_CONVOLVE), NIL); + + setvar (cintern ("RGB_IMAGE"), flocons (GIMP_RGB_IMAGE), NIL); + setvar (cintern ("RGBA_IMAGE"), flocons (GIMP_RGBA_IMAGE), NIL); + setvar (cintern ("GRAY_IMAGE"), flocons (GIMP_GRAY_IMAGE), NIL); + setvar (cintern ("GRAYA_IMAGE"), flocons (GIMP_GRAYA_IMAGE), NIL); + setvar (cintern ("INDEXED_IMAGE"), flocons (GIMP_INDEXED_IMAGE), NIL); + setvar (cintern ("INDEXEDA_IMAGE"), flocons (GIMP_INDEXEDA_IMAGE), NIL); + + /* Useful misc stuff */ + setvar (cintern ("TRUE"), flocons (TRUE), NIL); + setvar (cintern ("FALSE"), flocons (FALSE), NIL); + + /* Script-fu types */ + setvar (cintern ("SF-IMAGE"), flocons (SF_IMAGE), NIL); + setvar (cintern ("SF-DRAWABLE"), flocons (SF_DRAWABLE), NIL); + setvar (cintern ("SF-LAYER"), flocons (SF_LAYER), NIL); + setvar (cintern ("SF-CHANNEL"), flocons (SF_CHANNEL), NIL); + setvar (cintern ("SF-COLOR"), flocons (SF_COLOR), NIL); + setvar (cintern ("SF-TOGGLE"), flocons (SF_TOGGLE), NIL); + setvar (cintern ("SF-VALUE"), flocons (SF_VALUE), NIL); + setvar (cintern ("SF-STRING"), flocons (SF_STRING), NIL); + setvar (cintern ("SF-FILENAME"), flocons (SF_FILENAME), NIL); + setvar (cintern ("SF-ADJUSTMENT"), flocons (SF_ADJUSTMENT), NIL); + setvar (cintern ("SF-FONT"), flocons (SF_FONT), NIL); + setvar (cintern ("SF-PATTERN"), flocons (SF_PATTERN), NIL); + setvar (cintern ("SF-BRUSH"), flocons (SF_BRUSH), NIL); + setvar (cintern ("SF-GRADIENT"), flocons (SF_GRADIENT), NIL); + setvar (cintern ("SF-OPTION"), flocons (SF_OPTION), NIL); + + /* for SF_ADJUSTMENT */ + setvar (cintern ("SF-SLIDER"), flocons (SF_SLIDER), NIL); + setvar (cintern ("SF-SPINNER"), flocons (SF_SPINNER), NIL); +} + +static void +convert_string (gchar *str) +{ + while (*str) + { + if (*str == '_') *str = '-'; + str++; + } +} + +static gboolean +sputs_fcn (gchar *st, + gpointer dest) +{ + strcpy (*((gchar**)dest), st); + *((gchar**)dest) += strlen (st); + + return TRUE; +} + +static LISP +lprin1s (LISP exp, + gchar *dest) +{ + struct gen_printio s; + + s.putc_fcn = NULL; + s.puts_fcn = sputs_fcn; + s.cb_argument = &dest; + + lprin1g (exp, &s); + + return (NIL); +} + + +static LISP +marshall_proc_db_call (LISP a) +{ + GimpParam *args; + GimpParam *values = NULL; + gint nvalues; + gchar *proc_name; + gchar *proc_blurb; + gchar *proc_help; + gchar *proc_author; + gchar *proc_copyright; + gchar *proc_date; + GimpPDBProcType proc_type; + gint nparams; + gint nreturn_vals; + GimpParamDef *params; + GimpParamDef *return_vals; + gchar error_str[256]; + gint i; + gint success = TRUE; + LISP color_list; + LISP intermediate_val; + LISP return_val = NIL; + gchar *string; + gint string_len; + LISP a_saved; + + /* Save a in case it is needed for an error message. */ + a_saved = a; + + /* Make sure there are arguments */ + if (a == NIL) + return my_err ("Procedure database argument marshaller was called with no arguments. " + "The procedure to be executed and the arguments it requires " + "(possibly none) must be specified.", NIL); + + /* Derive the pdb procedure name from the argument + or first argument of a list */ + if (TYPEP (a, tc_cons)) + proc_name = get_c_string (car (a)); + else + proc_name = get_c_string (a); + + /* report the current command */ + script_fu_report_cc (proc_name); + + /* Attempt to fetch the procedure from the database */ + if (! gimp_procedural_db_proc_info (proc_name, + &proc_blurb, + &proc_help, + &proc_author, + &proc_copyright, + &proc_date, + &proc_type, + &nparams, &nreturn_vals, + ¶ms, &return_vals)) + return my_err ("Invalid procedure name specified.", NIL); + + + /* Check the supplied number of arguments */ + if ((nlength (a) - 1) != nparams) + { + g_snprintf (error_str, sizeof (error_str), + "Invalid arguments supplied to %s--(# args: %ld, expecting: %d)", + proc_name, (nlength (a) - 1), nparams); + return my_err (error_str, NIL); + } + + /* Marshall the supplied arguments */ + if (nparams) + args = g_new (GimpParam, nparams); + else + args = NULL; + + a = cdr (a); + for (i = 0; i < nparams; i++) + { + switch (params[i].type) + { + case GIMP_PDB_INT32: + if (!TYPEP (car (a), tc_flonum)) + success = FALSE; + if (success) + { + args[i].type = GIMP_PDB_INT32; + args[i].data.d_int32 = get_c_long (car (a)); + } + break; + + case GIMP_PDB_INT16: + if (!TYPEP (car (a), tc_flonum)) + success = FALSE; + if (success) + { + args[i].type = GIMP_PDB_INT16; + args[i].data.d_int16 = (gint16) get_c_long (car (a)); + } + break; + + case GIMP_PDB_INT8: + if (!TYPEP (car (a), tc_flonum)) + success = FALSE; + if (success) + { + args[i].type = GIMP_PDB_INT8; + args[i].data.d_int8 = (gint8) get_c_long (car (a)); + } + break; + + case GIMP_PDB_FLOAT: + if (!TYPEP (car (a), tc_flonum)) + success = FALSE; + if (success) + { + args[i].type = GIMP_PDB_FLOAT; + args[i].data.d_float = get_c_double (car (a)); + } + break; + + case GIMP_PDB_STRING: + if (!TYPEP (car (a), tc_string)) + success = FALSE; + if (success) + { + args[i].type = GIMP_PDB_STRING; + args[i].data.d_string = get_c_string (car (a)); + } + break; + + case GIMP_PDB_INT32ARRAY: + if (!TYPEP (car (a), tc_long_array)) + success = FALSE; + if (success) + { + args[i].type = GIMP_PDB_INT32ARRAY; + args[i].data.d_int32array = + (gint32*) (car (a))->storage_as.long_array.data; + } + break; + + case GIMP_PDB_INT16ARRAY: + if (!TYPEP (car (a), tc_long_array)) + success = FALSE; + if (success) + { + args[i].type = GIMP_PDB_INT16ARRAY; + args[i].data.d_int16array = + (gint16*) (car (a))->storage_as.long_array.data; + } + break; + + case GIMP_PDB_INT8ARRAY: + if (!TYPEP (car (a), tc_byte_array)) + success = FALSE; + if (success) + { + args[i].type = GIMP_PDB_INT8ARRAY; + args[i].data.d_int8array = + (gint8*) (car (a))->storage_as.string.data; + } + break; + + case GIMP_PDB_FLOATARRAY: + if (!TYPEP (car (a), tc_double_array)) + success = FALSE; + if (success) + { + args[i].type = GIMP_PDB_FLOATARRAY; + args[i].data.d_floatarray = + (car (a))->storage_as.double_array.data; + } + break; + + case GIMP_PDB_STRINGARRAY: + if (!TYPEP (car (a), tc_cons)) + success = FALSE; + if (success) + { + args[i].type = GIMP_PDB_STRINGARRAY; + + /* Set the array */ + { + gint j; + gint num_strings; + gchar **array; + LISP list; + + list = car (a); + num_strings = args[i - 1].data.d_int32; + if (nlength (list) != num_strings) + return my_err ("String array argument has incorrectly specified length", NIL); + array = args[i].data.d_stringarray = + g_new (char *, num_strings); + + for (j = 0; j < num_strings; j++) + { + array[j] = get_c_string (car (list)); + list = cdr (list); + } + } + } + break; + + case GIMP_PDB_COLOR: + if (!TYPEP (car (a), tc_cons)) + success = FALSE; + if (success) + { + guchar color[3]; + + args[i].type = GIMP_PDB_COLOR; + color_list = car (a); + color[0] = get_c_long (car (color_list)); + color[1] = get_c_long (car (color_list)); + color[2] = get_c_long (car (color_list)); + + gimp_rgb_set_uchar (&args[i].data.d_color, + color[0], color[1], color[2]); + } + break; + + case GIMP_PDB_REGION: + return my_err ("Regions are currently unsupported as arguments", + car (a)); + break; + + case GIMP_PDB_DISPLAY: + if (!TYPEP (car (a), tc_flonum)) + success = FALSE; + if (success) + { + args[i].type = GIMP_PDB_DISPLAY; + args[i].data.d_int32 = get_c_long (car (a)); + } + break; + + case GIMP_PDB_IMAGE: + if (!TYPEP (car (a), tc_flonum)) + success = FALSE; + if (success) + { + args[i].type = GIMP_PDB_IMAGE; + args[i].data.d_int32 = get_c_long (car (a)); + } + break; + + case GIMP_PDB_LAYER: + if (!TYPEP (car (a), tc_flonum)) + success = FALSE; + if (success) + { + args[i].type = GIMP_PDB_LAYER; + args[i].data.d_int32 = get_c_long (car (a)); + } + break; + + case GIMP_PDB_CHANNEL: + if (!TYPEP (car (a), tc_flonum)) + success = FALSE; + if (success) + { + args[i].type = GIMP_PDB_CHANNEL; + args[i].data.d_int32 = get_c_long (car (a)); + } + break; + + case GIMP_PDB_DRAWABLE: + if (!TYPEP (car (a), tc_flonum)) + success = FALSE; + if (success) + { + args[i].type = GIMP_PDB_DRAWABLE; + args[i].data.d_int32 = get_c_long (car (a)); + } + break; + + case GIMP_PDB_SELECTION: + if (!TYPEP (car (a), tc_flonum)) + success = FALSE; + if (success) + { + args[i].type = GIMP_PDB_SELECTION; + args[i].data.d_int32 = get_c_long (car (a)); + } + break; + + case GIMP_PDB_BOUNDARY: + return my_err ("Boundaries are currently unsupported as arguments", + car (a)); + break; + + case GIMP_PDB_PATH: + return my_err ("Paths are currently unsupported as arguments", + car (a)); + break; + + case GIMP_PDB_PARASITE: + if (!TYPEP (car (a), tc_cons)) + success = FALSE; + if (success) + { + args[i].type = GIMP_PDB_PARASITE; + /* parasite->name */ + intermediate_val = car (a); + args[i].data.d_parasite.name = + get_c_string (car (intermediate_val)); + + /* parasite->flags */ + intermediate_val = cdr (intermediate_val); + args[i].data.d_parasite.flags = get_c_long (car(intermediate_val)); + + /* parasite->size */ + intermediate_val = cdr (intermediate_val); + args[i].data.d_parasite.size = + (car (intermediate_val))->storage_as.string.dim; + + /* parasite->data */ + args[i].data.d_parasite.data = + (void*) (car (intermediate_val))->storage_as.string.data; + } + break; + + case GIMP_PDB_STATUS: + return my_err ("Status is for return types, not arguments", car (a)); + break; + + default: + return my_err ("Unknown argument type", NIL); + } + + a = cdr (a); + } + + if (success) + values = gimp_run_procedure2 (proc_name, &nvalues, nparams, args); + else + return my_err ("Invalid types specified for arguments", NIL); + + /* Check the return status */ + if (! values) + { + strcpy (error_str, "Procedural database execution did not return a status:\n "); + lprin1s (a_saved, error_str + strlen(error_str)); + + return my_err (error_str, NIL); + } + + switch (values[0].data.d_status) + { + case GIMP_PDB_EXECUTION_ERROR: + strcpy (error_str, "Procedural database execution failed:\n "); + lprin1s (a_saved, error_str + strlen(error_str)); + return my_err (error_str, NIL); + break; + + case GIMP_PDB_CALLING_ERROR: + strcpy (error_str, "Procedural database execution failed on invalid input arguments:\n "); + lprin1s (a_saved, error_str + strlen(error_str)); + return my_err (error_str, NIL); + break; + + case GIMP_PDB_SUCCESS: + return_val = NIL; + + for (i = 0; i < nvalues - 1; i++) + { + switch (return_vals[i].type) + { + case GIMP_PDB_INT32: + return_val = cons (flocons (values[i + 1].data.d_int32), + return_val); + break; + + case GIMP_PDB_INT16: + return_val = cons (flocons (values[i + 1].data.d_int32), + return_val); + break; + + case GIMP_PDB_INT8: + return_val = cons (flocons (values[i + 1].data.d_int32), + return_val); + break; + + case GIMP_PDB_FLOAT: + return_val = cons (flocons (values[i + 1].data.d_float), + return_val); + break; + + case GIMP_PDB_STRING: + string = (gchar *) values[i + 1].data.d_string; + string_len = strlen (string); + return_val = cons (strcons (string_len, string), return_val); + break; + + case GIMP_PDB_INT32ARRAY: + { + LISP array; + gint j; + + array = arcons (tc_long_array, values[i].data.d_int32, 0); + for (j = 0; j < values[i].data.d_int32; j++) + { + array->storage_as.long_array.data[j] = + values[i + 1].data.d_int32array[j]; + } + return_val = cons (array, return_val); + } + break; + + case GIMP_PDB_INT16ARRAY: + return my_err ("Arrays are currently unsupported as return values", NIL); + break; + + case GIMP_PDB_INT8ARRAY: + { + LISP array; + gint j; + + array = arcons (tc_byte_array, values[i].data.d_int32, 0); + for (j = 0; j < values[i].data.d_int32; j++) + { + array->storage_as.string.data[j] = + values[i + 1].data.d_int8array[j]; + } + return_val = cons (array, return_val); + } + break; + + case GIMP_PDB_FLOATARRAY: + { + LISP array; + gint j; + + array = arcons (tc_double_array, values[i].data.d_int32, 0); + for (j = 0; j < values[i].data.d_int32; j++) + { + array->storage_as.double_array.data[j] = + values[i + 1].data.d_floatarray[j]; + } + return_val = cons (array, return_val); + } + break; + + case GIMP_PDB_STRINGARRAY: + /* string arrays are always implemented such that the previous + * return value contains the number of strings in the array + */ + { + gint j; + gint num_strings = values[i].data.d_int32; + LISP string_array = NIL; + gchar **array = (gchar **) values[i + 1].data.d_stringarray; + + for (j = 0; j < num_strings; j++) + { + string_len = strlen (array[j]); + string_array = cons (strcons (string_len, array[j]), + string_array); + } + + return_val = cons (nreverse (string_array), return_val); + } + break; + + case GIMP_PDB_COLOR: + { + guchar color[3]; + gimp_rgb_get_uchar (&values[i + 1].data.d_color, color, color + 1, color + 2); + intermediate_val = cons (flocons ((int) color[0]), + cons (flocons ((int) color[1]), + cons (flocons ((int) color[2]), + NIL))); + return_val = cons (intermediate_val, return_val); + break; + } + + case GIMP_PDB_REGION: + return my_err ("Regions are currently unsupported as return values", NIL); + break; + + case GIMP_PDB_DISPLAY: + return_val = cons (flocons (values[i + 1].data.d_int32), + return_val); + break; + + case GIMP_PDB_IMAGE: + return_val = cons (flocons (values[i + 1].data.d_int32), + return_val); + break; + + case GIMP_PDB_LAYER: + return_val = cons (flocons (values[i + 1].data.d_int32), + return_val); + break; + + case GIMP_PDB_CHANNEL: + return_val = cons (flocons (values[i + 1].data.d_int32), + return_val); + break; + + case GIMP_PDB_DRAWABLE: + return_val = cons (flocons (values[i + 1].data.d_int32), + return_val); + break; + + case GIMP_PDB_SELECTION: + return_val = cons (flocons (values[i + 1].data.d_int32), + return_val); + break; + + case GIMP_PDB_BOUNDARY: + return my_err ("Boundaries are currently unsupported as return values", NIL); + break; + + case GIMP_PDB_PATH: + return my_err ("Paths are currently unsupported as return values", NIL); + break; + + case GIMP_PDB_PARASITE: + { + LISP name, flags, data; + + if (values[i + 1].data.d_parasite.name == NULL) + { + return_val = my_err("Error: null parasite", NIL); + } + else + { + string_len = strlen (values[i + 1].data.d_parasite.name); + name = strcons (string_len, + values[i + 1].data.d_parasite.name); + + flags = flocons (values[i + 1].data.d_parasite.flags); + data = arcons (tc_byte_array, + values[i+1].data.d_parasite.size, 0); + memcpy(data->storage_as.string.data, + values[i+1].data.d_parasite.data, + values[i+1].data.d_parasite.size); + + intermediate_val = cons (name, + cons(flags, cons(data, NIL))); + return_val = cons (intermediate_val, return_val); + } + } + break; + + case GIMP_PDB_STATUS: + return my_err ("Procedural database execution returned multiple status values", NIL); + break; + + default: + return my_err ("Unknown return type", NIL); + } + } + break; + + case GIMP_PDB_PASS_THROUGH: + case GIMP_PDB_CANCEL: /* should we do something here? */ + break; + } + + /* free up the executed procedure return values */ + gimp_destroy_params (values, nvalues); + + /* free up arguments and values */ + g_free (args); + + /* free the query information */ + g_free (proc_blurb); + g_free (proc_help); + g_free (proc_author); + g_free (proc_copyright); + g_free (proc_date); + g_free (params); + g_free (return_vals); + + /* reverse the return values */ + return_val = nreverse (return_val); +#ifndef G_OS_WIN32 + /* if we're in server mode, listen for additional commands for 10 ms */ + if (script_fu_server_get_mode ()) + script_fu_server_listen (10); +#endif + +#ifdef GDK_WINDOWING_WIN32 + /* This seems to help a lot on Windoze. */ + while (gtk_events_pending ()) + gtk_main_iteration (); +#endif + + return return_val; +} + +static LISP +script_fu_register_call (LISP a) +{ + if (register_scripts) + return script_fu_add_script (a); + else + return NIL; +} + +static LISP +script_fu_quit_call (LISP a) +{ + script_fu_server_quit (); + + return NIL; +} + diff --git a/plug-ins/script-fu/siod-wrapper.h b/plug-ins/script-fu/siod-wrapper.h new file mode 100644 index 0000000000..4948a6c372 --- /dev/null +++ b/plug-ins/script-fu/siod-wrapper.h @@ -0,0 +1,25 @@ + +#ifndef SIOD_WRAPPER_H +#define SIOD_WRAPPER_H + +#include +#include + +void siod_init (gboolean register_scripts); + +FILE *siod_get_output_file (void); +void siod_set_output_file (FILE *file); + +int siod_get_verbose_level (void); +void siod_set_verbose_level (int verbose_level); + +void siod_print_welcome (void); + +const char *siod_get_error_msg (void); +const char *siod_get_success_msg (void); + +/* if the return value is 0, success. error otherwise. */ +int siod_interpret_string (const char *expr); + + +#endif /* SIOD_WRAPPER_H */