mirror of https://github.com/GNOME/gimp.git
1187 lines
27 KiB
C
1187 lines
27 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>
|
|
#include "parasiteP.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_PARASITE:
|
|
(void) va_arg (args, Parasite*);
|
|
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_PARASITE:
|
|
{
|
|
Parasite *p = va_arg (args, Parasite*);
|
|
if (p == NULL)
|
|
p = parasite_error();
|
|
proc_run.params[i].data.d_parasite.name = p->name;
|
|
proc_run.params[i].data.d_parasite.flags = p->flags;
|
|
proc_run.params[i].data.d_parasite.size = p->size;
|
|
proc_run.params[i].data.d_parasite.data = p->data;
|
|
} 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 (); */
|
|
}
|
|
}
|