Files
gimp/libgimp/gimp.c
BST 1998 Andy Thomas dbb801e2d6 app/blend.c app/brush_select.c app/brush_select.h app/bucket_fill.c
Sat Sep 19 01:19:18 BST 1998 Andy Thomas <alt@picnic.demon.co.uk>

	* app/blend.c app/brush_select.c app/brush_select.h app/bucket_fill.c
	app/gimpbrushlist.c app/internal_procs.c app/plug_in.c libgimp/gimp.c
	libgimp/gimp.h libgimp/gimpmenu.c libgimp/gimptile.c
	plug-ins/gfig/gfig.c

	Infrastructure to allow gimp dialogs to be controlled from plugins.
	Brush dialog can now be invoked multiple times. Dialogs invoked
	via plugins do not control the active brush (dialog only used for
	selections).
	New gimp_interactive_selection_brush() function to popup dialog
	Example of usage in the gfig plugin.
	Other dialogs should be able to use this method of invocation.
1998-09-19 00:40:27 +00:00

1173 lines
26 KiB
C

/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <errno.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/param.h>
#include <unistd.h>
#ifdef HAVE_IPC_H
#include <sys/ipc.h>
#endif
#ifdef HAVE_SHM_H
#include <sys/shm.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#include "gimp.h"
#include "gimpprotocol.h"
#include "gimpwire.h"
#define WRITE_BUFFER_SIZE 1024
void gimp_extension_process (guint timeout);
void gimp_extension_ack (void);
void gimp_read_expect_msg(WireMessage *msg, int type);
static RETSIGTYPE gimp_signal (int signum);
static int gimp_write (int fd, guint8 *buf, gulong count);
static int gimp_flush (int fd);
static void gimp_loop (void);
static void gimp_config (GPConfig *config);
static void gimp_proc_run (GPProcRun *proc_run);
static void gimp_temp_proc_run (GPProcRun *proc_run);
static void gimp_message_func (char *str);
static void gimp_process_message(WireMessage *msg);
int _readfd = 0;
int _writefd = 0;
int _shm_ID = -1;
guchar *_shm_addr = NULL;
const guint gimp_major_version = GIMP_MAJOR_VERSION;
const guint gimp_minor_version = GIMP_MINOR_VERSION;
const guint gimp_micro_version = GIMP_MICRO_VERSION;
static gdouble _gamma_val;
static gint _install_cmap;
static gint _use_xshm;
static guchar _color_cube[4];
static gint _gdisp_ID = -1;
static char *progname = NULL;
static guint8 write_buffer[WRITE_BUFFER_SIZE];
static guint write_buffer_index = 0;
static GHashTable *temp_proc_ht = NULL;
extern GPlugInInfo PLUG_IN_INFO;
int
gimp_main (int argc,
char *argv[])
{
if ((argc < 4) || (strcmp (argv[1], "-gimp") != 0))
{
g_print ("%s is a gimp plug-in and must be run by the gimp to be used\n", argv[0]);
return 1;
}
progname = argv[0];
signal (SIGHUP, gimp_signal);
signal (SIGINT, gimp_signal);
signal (SIGQUIT, gimp_signal);
signal (SIGBUS, gimp_signal);
signal (SIGSEGV, gimp_signal);
signal (SIGPIPE, gimp_signal);
signal (SIGTERM, gimp_signal);
signal (SIGFPE, gimp_signal);
_readfd = atoi (argv[2]);
_writefd = atoi (argv[3]);
gp_init ();
wire_set_writer (gimp_write);
wire_set_flusher (gimp_flush);
if ((argc == 5) && (strcmp (argv[4], "-query") == 0))
{
if (PLUG_IN_INFO.query_proc)
(* PLUG_IN_INFO.query_proc) ();
gimp_quit ();
return 0;
}
g_set_message_handler ((GPrintFunc) gimp_message_func);
temp_proc_ht = g_hash_table_new (&g_str_hash, &g_str_equal);
gimp_loop ();
return 0;
}
void
gimp_quit ()
{
if (PLUG_IN_INFO.quit_proc)
(* PLUG_IN_INFO.quit_proc) ();
#ifdef HAVE_SHM_H
if ((_shm_ID != -1) && _shm_addr)
shmdt ((char*) _shm_addr);
#endif
gp_quit_write (_writefd);
exit (0);
}
void
gimp_set_data (gchar * id,
gpointer data,
guint32 length)
{
GParam *return_vals;
int nreturn_vals;
return_vals = gimp_run_procedure ("gimp_procedural_db_set_data",
&nreturn_vals,
PARAM_STRING, id,
PARAM_INT32, length,
PARAM_INT8ARRAY, data,
PARAM_END);
gimp_destroy_params (return_vals, nreturn_vals);
}
guint32
gimp_get_data_size (gchar * id)
{
GParam *return_vals;
int nreturn_vals;
guint32 length;
return_vals = gimp_run_procedure ("gimp_procedural_db_get_data_size",
&nreturn_vals,
PARAM_STRING, id,
PARAM_END);
if (return_vals[0].data.d_status == STATUS_SUCCESS)
length= return_vals[1].data.d_int32;
else
length= 0;
gimp_destroy_params (return_vals, nreturn_vals);
return length;
}
void
gimp_get_data (gchar * id,
gpointer data)
{
GParam *return_vals;
int nreturn_vals;
int length;
gchar *returned_data;
return_vals = gimp_run_procedure ("gimp_procedural_db_get_data",
&nreturn_vals,
PARAM_STRING, id,
PARAM_END);
if (return_vals[0].data.d_status == STATUS_SUCCESS)
{
length = return_vals[1].data.d_int32;
returned_data = (gchar *) return_vals[2].data.d_int8array;
memcpy (data, returned_data, length);
}
gimp_destroy_params (return_vals, nreturn_vals);
}
void
gimp_progress_init (char *message)
{
GParam *return_vals;
int nreturn_vals;
return_vals = gimp_run_procedure ("gimp_progress_init",
&nreturn_vals,
PARAM_STRING, message,
PARAM_INT32, _gdisp_ID,
PARAM_END);
gimp_destroy_params (return_vals, nreturn_vals);
}
void
gimp_progress_update (gdouble percentage)
{
GParam *return_vals;
int nreturn_vals;
return_vals = gimp_run_procedure ("gimp_progress_update",
&nreturn_vals,
PARAM_FLOAT, percentage,
PARAM_END);
gimp_destroy_params (return_vals, nreturn_vals);
}
void
gimp_message (char *message)
{
GParam *return_vals;
int nreturn_vals;
return_vals = gimp_run_procedure ("gimp_message",
&nreturn_vals,
PARAM_STRING, message,
PARAM_END);
gimp_destroy_params (return_vals, nreturn_vals);
}
static void
gimp_message_func (char *str)
{
gimp_message (str);
}
void
gimp_query_database (char *name_regexp,
char *blurb_regexp,
char *help_regexp,
char *author_regexp,
char *copyright_regexp,
char *date_regexp,
char *proc_type_regexp,
int *nprocs,
char ***proc_names)
{
GParam *return_vals;
int nreturn_vals;
int i;
return_vals = gimp_run_procedure ("gimp_procedural_db_query",
&nreturn_vals,
PARAM_STRING, name_regexp,
PARAM_STRING, blurb_regexp,
PARAM_STRING, help_regexp,
PARAM_STRING, author_regexp,
PARAM_STRING, copyright_regexp,
PARAM_STRING, date_regexp,
PARAM_STRING, proc_type_regexp,
PARAM_END);
*nprocs = 0;
*proc_names = NULL;
if (return_vals[0].data.d_status == STATUS_SUCCESS)
{
*nprocs = return_vals[1].data.d_int32;
*proc_names = g_new (gchar*, *nprocs);
for (i = 0; i < *nprocs; i++)
(*proc_names)[i] = g_strdup (return_vals[2].data.d_stringarray[i]);
}
gimp_destroy_params (return_vals, nreturn_vals);
}
gint
gimp_query_procedure (char *proc_name,
char **proc_blurb,
char **proc_help,
char **proc_author,
char **proc_copyright,
char **proc_date,
int *proc_type,
int *nparams,
int *nreturn_vals,
GParamDef **params,
GParamDef **return_vals)
{
GParam *ret_vals;
int nret_vals;
int i;
int success = TRUE;
ret_vals = gimp_run_procedure ("gimp_procedural_db_proc_info",
&nret_vals,
PARAM_STRING, proc_name,
PARAM_END);
if (ret_vals[0].data.d_status == STATUS_SUCCESS)
{
*proc_blurb = g_strdup (ret_vals[1].data.d_string);
*proc_help = g_strdup (ret_vals[2].data.d_string);
*proc_author = g_strdup (ret_vals[3].data.d_string);
*proc_copyright = g_strdup (ret_vals[4].data.d_string);
*proc_date = g_strdup (ret_vals[5].data.d_string);
*proc_type = ret_vals[6].data.d_int32;
*nparams = ret_vals[7].data.d_int32;
*nreturn_vals = ret_vals[8].data.d_int32;
*params = g_new (GParamDef, *nparams);
*return_vals = g_new (GParamDef, *nreturn_vals);
for (i = 0; i < *nparams; i++)
{
GParam *rvals;
int nrvals;
rvals = gimp_run_procedure ("gimp_procedural_db_proc_arg",
&nrvals,
PARAM_STRING, proc_name,
PARAM_INT32, i,
PARAM_END);
if (rvals[0].data.d_status == STATUS_SUCCESS)
{
(*params)[i].type = rvals[1].data.d_int32;
(*params)[i].name = g_strdup (rvals[2].data.d_string);
(*params)[i].description = g_strdup (rvals[3].data.d_string);
}
else
{
g_free (*params);
g_free (*return_vals);
gimp_destroy_params (rvals, nrvals);
return FALSE;
}
gimp_destroy_params (rvals, nrvals);
}
for (i = 0; i < *nreturn_vals; i++)
{
GParam *rvals;
int nrvals;
rvals = gimp_run_procedure ("gimp_procedural_db_proc_val",
&nrvals,
PARAM_STRING, proc_name,
PARAM_INT32, i,
PARAM_END);
if (rvals[0].data.d_status == STATUS_SUCCESS)
{
(*return_vals)[i].type = rvals[1].data.d_int32;
(*return_vals)[i].name = g_strdup (rvals[2].data.d_string);
(*return_vals)[i].description = g_strdup (rvals[3].data.d_string);
}
else
{
g_free (*params);
g_free (*return_vals);
gimp_destroy_params (rvals, nrvals);
return FALSE;
}
gimp_destroy_params (rvals, nrvals);
}
}
else
success = FALSE;
gimp_destroy_params (ret_vals, nret_vals);
return success;
}
gint32*
gimp_query_images (int *nimages)
{
GParam *return_vals;
int nreturn_vals;
gint32 *images;
return_vals = gimp_run_procedure ("gimp_list_images",
&nreturn_vals,
PARAM_END);
images = NULL;
if (return_vals[0].data.d_status == STATUS_SUCCESS)
{
*nimages = return_vals[1].data.d_int32;
images = g_new (gint32, *nimages);
memcpy (images, return_vals[2].data.d_int32array, *nimages * 4);
}
gimp_destroy_params (return_vals, nreturn_vals);
return images;
}
void
gimp_install_procedure (char *name,
char *blurb,
char *help,
char *author,
char *copyright,
char *date,
char *menu_path,
char *image_types,
int type,
int nparams,
int nreturn_vals,
GParamDef *params,
GParamDef *return_vals)
{
GPProcInstall proc_install;
proc_install.name = name;
proc_install.blurb = blurb;
proc_install.help = help;
proc_install.author = author;
proc_install.copyright = copyright;
proc_install.date = date;
proc_install.menu_path = menu_path;
proc_install.image_types = image_types;
proc_install.type = type;
proc_install.nparams = nparams;
proc_install.nreturn_vals = nreturn_vals;
proc_install.params = (GPParamDef*) params;
proc_install.return_vals = (GPParamDef*) return_vals;
if (!gp_proc_install_write (_writefd, &proc_install))
gimp_quit ();
}
void
gimp_install_temp_proc (char *name,
char *blurb,
char *help,
char *author,
char *copyright,
char *date,
char *menu_path,
char *image_types,
int type,
int nparams,
int nreturn_vals,
GParamDef *params,
GParamDef *return_vals,
GRunProc run_proc)
{
gimp_install_procedure (name, blurb, help, author, copyright, date,
menu_path, image_types, type,
nparams, nreturn_vals, params, return_vals);
/* Insert the temp proc run function into the hash table */
g_hash_table_insert (temp_proc_ht, (gpointer) name, (gpointer) run_proc);
}
void
gimp_uninstall_temp_proc (char *name)
{
GPProcUninstall proc_uninstall;
proc_uninstall.name = name;
if (!gp_proc_uninstall_write (_writefd, &proc_uninstall))
gimp_quit ();
g_hash_table_remove (temp_proc_ht, (gpointer) name);
}
void
gimp_register_magic_load_handler (char *name,
char *extensions,
char *prefixes,
char *magics)
{
GParam *return_vals;
int nreturn_vals;
return_vals = gimp_run_procedure ("gimp_register_magic_load_handler",
&nreturn_vals,
PARAM_STRING, name,
PARAM_STRING, extensions,
PARAM_STRING, prefixes,
PARAM_STRING, magics,
PARAM_END);
gimp_destroy_params (return_vals, nreturn_vals);
}
void
gimp_register_load_handler (char *name,
char *extensions,
char *prefixes)
{
GParam *return_vals;
int nreturn_vals;
return_vals = gimp_run_procedure ("gimp_register_load_handler",
&nreturn_vals,
PARAM_STRING, name,
PARAM_STRING, extensions,
PARAM_STRING, prefixes,
PARAM_END);
gimp_destroy_params (return_vals, nreturn_vals);
}
void
gimp_register_save_handler (char *name,
char *extensions,
char *prefixes)
{
GParam *return_vals;
int nreturn_vals;
return_vals = gimp_run_procedure ("gimp_register_save_handler",
&nreturn_vals,
PARAM_STRING, name,
PARAM_STRING, extensions,
PARAM_STRING, prefixes,
PARAM_END);
gimp_destroy_params (return_vals, nreturn_vals);
}
GParam*
gimp_run_procedure (char *name,
int *nreturn_vals,
...)
{
GPProcRun proc_run;
GPProcReturn *proc_return;
WireMessage msg;
GParamType param_type;
GParam *return_vals;
va_list args;
guchar *color;
int i;
proc_run.name = name;
proc_run.nparams = 0;
proc_run.params = NULL;
va_start (args, nreturn_vals);
param_type = va_arg (args, GParamType);
while (param_type != PARAM_END)
{
switch (param_type)
{
case PARAM_INT32:
case PARAM_DISPLAY:
case PARAM_IMAGE:
case PARAM_LAYER:
case PARAM_CHANNEL:
case PARAM_DRAWABLE:
case PARAM_SELECTION:
case PARAM_BOUNDARY:
case PARAM_PATH:
case PARAM_STATUS:
(void) va_arg (args, int);
break;
case PARAM_INT16:
(void) va_arg (args, int);
break;
case PARAM_INT8:
(void) va_arg (args, int);
break;
case PARAM_FLOAT:
(void) va_arg (args, double);
break;
case PARAM_STRING:
(void) va_arg (args, gchar*);
break;
case PARAM_INT32ARRAY:
(void) va_arg (args, gint32*);
break;
case PARAM_INT16ARRAY:
(void) va_arg (args, gint16*);
break;
case PARAM_INT8ARRAY:
(void) va_arg (args, gint8*);
break;
case PARAM_FLOATARRAY:
(void) va_arg (args, gdouble*);
break;
case PARAM_STRINGARRAY:
(void) va_arg (args, gchar**);
break;
case PARAM_COLOR:
(void) va_arg (args, guchar*);
break;
case PARAM_REGION:
break;
case PARAM_END:
break;
}
proc_run.nparams += 1;
param_type = va_arg (args, GParamType);
}
va_end (args);
proc_run.params = g_new (GPParam, proc_run.nparams);
va_start (args, nreturn_vals);
for (i = 0; i < proc_run.nparams; i++)
{
proc_run.params[i].type = va_arg (args, GParamType);
switch (proc_run.params[i].type)
{
case PARAM_INT32:
proc_run.params[i].data.d_int32 = (gint32) va_arg (args, int);
break;
case PARAM_INT16:
proc_run.params[i].data.d_int16 = (gint16) va_arg (args, int);
break;
case PARAM_INT8:
proc_run.params[i].data.d_int8 = (gint8) va_arg (args, int);
break;
case PARAM_FLOAT:
proc_run.params[i].data.d_float = (gdouble) va_arg (args, double);
break;
case PARAM_STRING:
proc_run.params[i].data.d_string = va_arg (args, gchar*);
break;
case PARAM_INT32ARRAY:
proc_run.params[i].data.d_int32array = va_arg (args, gint32*);
break;
case PARAM_INT16ARRAY:
proc_run.params[i].data.d_int16array = va_arg (args, gint16*);
break;
case PARAM_INT8ARRAY:
proc_run.params[i].data.d_int8array = va_arg (args, gint8*);
break;
case PARAM_FLOATARRAY:
proc_run.params[i].data.d_floatarray = va_arg (args, gdouble*);
break;
case PARAM_STRINGARRAY:
proc_run.params[i].data.d_stringarray = va_arg (args, gchar**);
break;
case PARAM_COLOR:
color = va_arg (args, guchar*);
proc_run.params[i].data.d_color.red = color[0];
proc_run.params[i].data.d_color.green = color[1];
proc_run.params[i].data.d_color.blue = color[2];
break;
case PARAM_REGION:
break;
case PARAM_DISPLAY:
proc_run.params[i].data.d_display = va_arg (args, gint32);
break;
case PARAM_IMAGE:
proc_run.params[i].data.d_image = va_arg (args, gint32);
break;
case PARAM_LAYER:
proc_run.params[i].data.d_layer = va_arg (args, gint32);
break;
case PARAM_CHANNEL:
proc_run.params[i].data.d_channel = va_arg (args, gint32);
break;
case PARAM_DRAWABLE:
proc_run.params[i].data.d_drawable = va_arg (args, gint32);
break;
case PARAM_SELECTION:
proc_run.params[i].data.d_selection = va_arg (args, gint32);
break;
case PARAM_BOUNDARY:
proc_run.params[i].data.d_boundary = va_arg (args, gint32);
break;
case PARAM_PATH:
proc_run.params[i].data.d_path = va_arg (args, gint32);
break;
case PARAM_STATUS:
proc_run.params[i].data.d_status = va_arg (args, gint32);
break;
case PARAM_END:
break;
}
}
va_end (args);
if (!gp_proc_run_write (_writefd, &proc_run))
gimp_quit ();
gimp_read_expect_msg(&msg,GP_PROC_RETURN);
proc_return = msg.data;
*nreturn_vals = proc_return->nparams;
return_vals = (GParam*) proc_return->params;
switch (return_vals[0].data.d_status)
{
case STATUS_EXECUTION_ERROR:
/*g_warning ("an execution error occured while trying to run: \"%s\"", name);*/
break;
case STATUS_CALLING_ERROR:
g_warning ("a calling error occured while trying to run: \"%s\"", name);
break;
default:
break;
}
g_free (proc_run.params);
g_free (proc_return->name);
g_free (proc_return);
return return_vals;
}
void
gimp_read_expect_msg(WireMessage *msg, int type)
{
while(1)
{
if (!wire_read_msg (_readfd, msg))
gimp_quit ();
if (msg->type != type)
{
if(msg->type == GP_TEMP_PROC_RUN)
{
gimp_process_message(msg);
continue;
}
else
g_error ("unexpected message: %d\n", msg->type);
}
else
break;
}
}
GParam*
gimp_run_procedure2 (char *name,
int *nreturn_vals,
int nparams,
GParam *params)
{
GPProcRun proc_run;
GPProcReturn *proc_return;
WireMessage msg;
GParam *return_vals;
proc_run.name = name;
proc_run.nparams = nparams;
proc_run.params = (GPParam *) params;
if (!gp_proc_run_write (_writefd, &proc_run))
gimp_quit ();
gimp_read_expect_msg(&msg,GP_PROC_RETURN);
proc_return = msg.data;
*nreturn_vals = proc_return->nparams;
return_vals = (GParam*) proc_return->params;
switch (return_vals[0].data.d_status)
{
case STATUS_EXECUTION_ERROR:
/*g_warning ("an execution error occured while trying to run: \"%s\"", name);*/
break;
case STATUS_CALLING_ERROR:
g_warning ("a calling error occured while trying to run: \"%s\"", name);
break;
default:
break;
}
g_free (proc_return);
return return_vals;
}
void
gimp_destroy_params (GParam *params,
int nparams)
{
extern void _gp_params_destroy (GPParam *params, int nparams);
_gp_params_destroy ((GPParam*) params, nparams);
}
gdouble
gimp_gamma ()
{
return _gamma_val;
}
gint
gimp_install_cmap ()
{
return _install_cmap;
}
gint
gimp_use_xshm ()
{
return _use_xshm;
}
guchar*
gimp_color_cube ()
{
return _color_cube;
}
gchar*
gimp_gtkrc ()
{
static char filename[MAXPATHLEN];
char *home_dir;
home_dir = getenv ("HOME");
if (!home_dir)
return NULL;
sprintf (filename, "%s/%s/gtkrc", home_dir, GIMPDIR);
return filename;
}
static void
gimp_process_message(WireMessage *msg)
{
switch (msg->type)
{
case GP_QUIT:
gimp_quit ();
break;
case GP_CONFIG:
gimp_config (msg->data);
break;
case GP_TILE_REQ:
case GP_TILE_ACK:
case GP_TILE_DATA:
g_warning ("unexpected tile message received (should not happen)\n");
break;
case GP_PROC_RUN:
g_warning ("unexpected proc run message received (should not happen)\n");
break;
case GP_PROC_RETURN:
g_warning ("unexpected proc return message received (should not happen)\n");
break;
case GP_TEMP_PROC_RUN:
gimp_temp_proc_run (msg->data);
break;
case GP_TEMP_PROC_RETURN:
g_warning ("unexpected temp proc return message received (should not happen)\n");
break;
case GP_PROC_INSTALL:
g_warning ("unexpected proc install message received (should not happen)\n");
break;
}
}
static void
gimp_single_message()
{
WireMessage msg;
/* Run a temp function */
if (!wire_read_msg (_readfd, &msg))
gimp_quit ();
gimp_process_message(&msg);
wire_destroy (&msg);
}
void
gimp_extension_process (guint timeout)
{
fd_set readfds;
int select_val;
struct timeval tv;
struct timeval *tvp;
if (timeout)
{
tv.tv_sec = timeout / 1000;
tv.tv_usec = timeout % 1000;
tvp = &tv;
}
else
tvp = NULL;
FD_ZERO (&readfds);
FD_SET (_readfd, &readfds);
if ((select_val = select (FD_SETSIZE, &readfds, NULL, NULL, tvp)) > 0)
{
gimp_single_message();
}
else if (select_val == -1)
{
perror ("gimp_process");
gimp_quit ();
}
}
void
gimp_extension_ack ()
{
/* Send an extension initialization acknowledgement */
if (! gp_extension_ack_write (_writefd))
gimp_quit ();
}
void
gimp_run_temp()
{
gimp_single_message();
}
static RETSIGTYPE
gimp_signal (int signum)
{
static int caught_fatal_sig = 0;
if (caught_fatal_sig)
kill (getpid (), signum);
caught_fatal_sig = 1;
fprintf (stderr, "\n%s: %s caught\n", progname, g_strsignal (signum));
switch (signum)
{
case SIGBUS:
case SIGSEGV:
case SIGFPE:
g_on_error_query (progname);
break;
default:
break;
}
gimp_quit ();
}
static int
gimp_write (int fd, guint8 *buf, gulong count)
{
gulong bytes;
while (count > 0)
{
if ((write_buffer_index + count) >= WRITE_BUFFER_SIZE)
{
bytes = WRITE_BUFFER_SIZE - write_buffer_index;
memcpy (&write_buffer[write_buffer_index], buf, bytes);
write_buffer_index += bytes;
if (!wire_flush (fd))
return FALSE;
}
else
{
bytes = count;
memcpy (&write_buffer[write_buffer_index], buf, bytes);
write_buffer_index += bytes;
}
buf += bytes;
count -= bytes;
}
return TRUE;
}
static int
gimp_flush (int fd)
{
int count;
int bytes;
if (write_buffer_index > 0)
{
count = 0;
while (count != write_buffer_index)
{
do {
bytes = write (fd, &write_buffer[count], (write_buffer_index - count));
} while ((bytes == -1) && (errno == EAGAIN));
if (bytes == -1)
return FALSE;
count += bytes;
}
write_buffer_index = 0;
}
return TRUE;
}
static void
gimp_loop ()
{
WireMessage msg;
while (1)
{
if (!wire_read_msg (_readfd, &msg))
gimp_quit ();
switch (msg.type)
{
case GP_QUIT:
gimp_quit ();
break;
case GP_CONFIG:
gimp_config (msg.data);
break;
case GP_TILE_REQ:
case GP_TILE_ACK:
case GP_TILE_DATA:
g_warning ("unexpected tile message received (should not happen)\n");
break;
case GP_PROC_RUN:
gimp_proc_run (msg.data);
gimp_quit ();
break;
case GP_PROC_RETURN:
g_warning ("unexpected proc return message received (should not happen)\n");
break;
case GP_TEMP_PROC_RUN:
g_warning ("unexpected temp proc run message received (should not happen\n");
break;
case GP_TEMP_PROC_RETURN:
g_warning ("unexpected temp proc return message received (should not happen\n");
break;
case GP_PROC_INSTALL:
g_warning ("unexpected proc install message received (should not happen)\n");
break;
}
wire_destroy (&msg);
}
}
static void
gimp_config (GPConfig *config)
{
extern gint _gimp_tile_width;
extern gint _gimp_tile_height;
if (config->version < GP_VERSION)
{
g_message ("%s: the gimp is using an older version of the "
"plug-in protocol than this plug-in\n", progname);
gimp_quit ();
}
else if (config->version > GP_VERSION)
{
g_message ("%s: the gimp is using a newer version of the "
"plug-in protocol than this plug-in\n", progname);
gimp_quit ();
}
_gimp_tile_width = config->tile_width;
_gimp_tile_height = config->tile_height;
_shm_ID = config->shm_ID;
_gamma_val = config->gamma;
_install_cmap = config->install_cmap;
_use_xshm = config->use_xshm;
_color_cube[0] = config->color_cube[0];
_color_cube[1] = config->color_cube[1];
_color_cube[2] = config->color_cube[2];
_color_cube[3] = config->color_cube[3];
_gdisp_ID = config->gdisp_ID;
#ifdef HAVE_SHM_H
if (_shm_ID != -1)
{
_shm_addr = (guchar*) shmat (_shm_ID, 0, 0);
if (_shm_addr == (guchar*) -1)
g_error ("could not attach to gimp shared memory segment\n");
}
#endif
}
static void
gimp_proc_run (GPProcRun *proc_run)
{
GPProcReturn proc_return;
GParam *return_vals;
int nreturn_vals;
if (PLUG_IN_INFO.run_proc)
{
(* PLUG_IN_INFO.run_proc) (proc_run->name,
proc_run->nparams,
(GParam*) proc_run->params,
&nreturn_vals,
&return_vals);
proc_return.name = proc_run->name;
proc_return.nparams = nreturn_vals;
proc_return.params = (GPParam*) return_vals;
if (!gp_proc_return_write (_writefd, &proc_return))
gimp_quit ();
}
}
static void
gimp_temp_proc_run (GPProcRun *proc_run)
{
GParam *return_vals;
int nreturn_vals;
GRunProc run_proc;
run_proc = (GRunProc)g_hash_table_lookup (temp_proc_ht, (gpointer) proc_run->name);
if (run_proc)
{
(* run_proc) (proc_run->name,
proc_run->nparams,
(GParam*) proc_run->params,
&nreturn_vals,
&return_vals);
/* No longer a return message */
/* proc_return.name = proc_run->name; */
/* proc_return.nparams = nreturn_vals; */
/* proc_return.params = (GPParam*) return_vals; */
/* if (!gp_temp_proc_return_write (_writefd, &proc_return)) */
/* gimp_quit (); */
}
}