export the tattoo functions to the plug-ins

1998-11-07  Jay Cox  <jaycox@earthlink.net>

	* libgimp/{gimp.h, gimpchannel.c, gimpdrawable.c, gimplayer.c}:
	export the tattoo functions to the plug-ins

	* libimp/gserialize.c, libimp/gserialize.h: new files for
	serializing structures

	* main.c: test the gserialize functions

	* gimpsignal.h: declare gimp_sigtype_* as extern
This commit is contained in:
Jay Cox 1998-11-07 23:02:14 +00:00 committed by jaycox
parent d8e4db64de
commit de2c3f4813
13 changed files with 519 additions and 6 deletions

View file

@ -1,3 +1,15 @@
1998-11-07 Jay Cox <jaycox@earthlink.net>
* libgimp/{gimp.h, gimpchannel.c, gimpdrawable.c, gimplayer.c}:
export the tattoo functions to the plug-ins
* libimp/gserialize.c, libimp/gserialize.h: new files for
serializing structures
* main.c: test the gserialize functions
* gimpsignal.h: declare gimp_sigtype_* as extern
Thu Nov 5 16:42:21 PST 1998 Manish Singh <yosh@gimp.org>
* Makefile.am: added MAINTAINERS to EXTRA_DIST

View file

@ -10,16 +10,16 @@ typedef guint GimpSignalID;
typedef const struct _GimpSignalType GimpSignalType;
/* The arguments are encoded in the names.. */
GimpSignalType* const gimp_sigtype_void;
extern GimpSignalType* const gimp_sigtype_void;
typedef void (*GimpHandlerVoid)(GtkObject*, gpointer);
GimpSignalType* const gimp_sigtype_pointer;
extern GimpSignalType* const gimp_sigtype_pointer;
typedef void (*GimpHandlerPointer)(GtkObject*, gpointer, gpointer);
GimpSignalType* const gimp_sigtype_int;
extern GimpSignalType* const gimp_sigtype_int;
typedef void (*GimpHandlerInt)(GtkObject*, gint, gpointer);
GimpSignalType* const gimp_sigtype_int_int_int_int;
extern GimpSignalType* const gimp_sigtype_int_int_int_int;
typedef void (*GimpHandlerIntIntIntInt) (GtkObject*, gint, gint, gint, gint,
gpointer);

View file

@ -24,6 +24,7 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include "libgimp/gserialize.h"
#ifndef WAIT_ANY
#define WAIT_ANY -1
@ -41,6 +42,7 @@
static RETSIGTYPE on_signal (int);
static RETSIGTYPE on_sig_child (int);
static void init (void);
static void test_gserialize();
/* GLOBAL data */
int no_interface;
@ -151,6 +153,8 @@ main (int argc, char **argv)
show_version = FALSE;
show_help = FALSE;
test_gserialize();
for (i = 1; i < argc; i++)
{
if ((strcmp (argv[i], "--no-interface") == 0) ||
@ -384,3 +388,60 @@ on_sig_child (int sig_num)
break;
}
}
typedef struct
{
gint32 test_gint32;
float test_float;
char *test_string;
guint32 test_length;
guint16 *test_array;
} test_struct;
static void test_gserialize()
{
GSerialDescription *test_struct_descript;
test_struct *ts, *to;
char ser_1[] = {3, 4, 3, 2, 1, 4, 51, 51, 83, 64, 6, 4, 0, 0, 0, 102, 111, 111, 0, 8, 2, 0, 0, 0, 6, 5, 8, 7};
void *ser;
long len;
int i;
ts = g_malloc(sizeof(test_struct));
to = g_malloc(sizeof(test_struct));
test_struct_descript
= g_new_serial_description("test_struct",
g_serial_item(GSERIAL_INT32,
test_struct,
test_gint32),
g_serial_item(GSERIAL_FLOAT,
test_struct,
test_float),
g_serial_item(GSERIAL_STRING,
test_struct,
test_string),
g_serial_vlen_array(GSERIAL_INT16ARRAY,
test_struct,
test_array,
test_length),
NULL);
ts->test_gint32 = 0x01020304;
ts->test_float = 3.3f;
ts->test_string = "foo";
ts->test_length = 2;
ts->test_array = g_malloc(sizeof(short) *2);
ts->test_array[0] = 0x0506;
ts->test_array[1] = 0x0708;
g_deserialize(test_struct_descript, (char *)(void*)to, ser_1);
g_return_if_fail (to->test_gint32 == ts->test_gint32);
g_return_if_fail (to->test_float == ts->test_float);
g_return_if_fail (strcmp(to->test_string, ts->test_string) == 0);
g_return_if_fail (to->test_length == ts->test_length);
g_return_if_fail (to->test_array[0] == ts->test_array[0]);
g_return_if_fail (to->test_array[1] == ts->test_array[1]);
/* really should free the memory... */
g_message("Passed serialization test\n");
}

View file

@ -16,6 +16,8 @@ libgimpi_a_SOURCES = \
gimpprotocol.h \
gimpwire.c \
gimpwire.h \
gserialize.c \
gserialize.h \
parasite.c \
parasite.h \
parasiteF.h \
@ -44,6 +46,8 @@ libgimp_la_SOURCES = \
gimptile.c \
gimpwire.c \
gimpwire.h \
gserialize.c \
gserialize.h \
parasite.c \
parasite.h \
parasiteF.h \
@ -63,6 +67,7 @@ gimpinclude_HEADERS = \
gimpmenu.h \
gimpui.h \
gimpintl.h \
gserialize.h \
parasite.h \
parasiteF.h \
parasiteP.h

View file

@ -535,6 +535,7 @@ void gimp_layer_set_show_mask (gint32 layer_ID,
gint show_mask);
void gimp_layer_set_visible (gint32 layer_ID,
gint visible);
gint32 gimp_layer_get_tattoo (gint32 layer_ID);
/****************************************
@ -573,6 +574,7 @@ void gimp_channel_set_show_masked (gint32 channel_ID,
gint show_masked);
void gimp_channel_set_visible (gint32 channel_ID,
gint visible);
gint32 gimp_channel_get_tattoo (gint32 channel_ID);
/****************************************
@ -636,6 +638,7 @@ void gimp_layer_attach_new_parasite(gint32 drawable,
void gimp_drawable_detach_parasite (gint32 drawable,
const char *name);
/****************************************
* GTiles *
****************************************/

View file

@ -302,3 +302,25 @@ gimp_channel_set_show_masked (gint32 channel_ID,
gimp_destroy_params (return_vals, nreturn_vals);
}
gint32
gimp_channel_get_tattoo (gint32 channel_ID)
{
GParam *return_vals;
int nreturn_vals;
int tattoo;
return_vals = gimp_run_procedure ("gimp_channel_get_tattoo",
&nreturn_vals,
PARAM_CHANNEL, channel_ID,
PARAM_END);
tattoo = -1;
if (return_vals[0].data.d_status == STATUS_SUCCESS)
tattoo = return_vals[1].data.d_int32;
gimp_destroy_params (return_vals, nreturn_vals);
return tattoo;
}

View file

@ -302,3 +302,25 @@ gimp_channel_set_show_masked (gint32 channel_ID,
gimp_destroy_params (return_vals, nreturn_vals);
}
gint32
gimp_channel_get_tattoo (gint32 channel_ID)
{
GParam *return_vals;
int nreturn_vals;
int tattoo;
return_vals = gimp_run_procedure ("gimp_channel_get_tattoo",
&nreturn_vals,
PARAM_CHANNEL, channel_ID,
PARAM_END);
tattoo = -1;
if (return_vals[0].data.d_status == STATUS_SUCCESS)
tattoo = return_vals[1].data.d_int32;
gimp_destroy_params (return_vals, nreturn_vals);
return tattoo;
}

View file

@ -615,7 +615,6 @@ gimp_drawable_attach_parasite (gint32 drawable_ID,
PARAM_PARASITE, p,
PARAM_END);
gimp_destroy_params (return_vals, nreturn_vals);
}

View file

@ -615,7 +615,6 @@ gimp_drawable_attach_parasite (gint32 drawable_ID,
PARAM_PARASITE, p,
PARAM_END);
gimp_destroy_params (return_vals, nreturn_vals);
}

View file

@ -569,3 +569,25 @@ gimp_layer_set_visible (gint32 layer_ID,
gimp_destroy_params (return_vals, nreturn_vals);
}
gint32
gimp_layer_get_tattoo (gint32 layer_ID)
{
GParam *return_vals;
int nreturn_vals;
int tattoo;
return_vals = gimp_run_procedure ("gimp_layer_get_tattoo",
&nreturn_vals,
PARAM_LAYER, layer_ID,
PARAM_END);
tattoo = -1;
if (return_vals[0].data.d_status == STATUS_SUCCESS)
tattoo = return_vals[1].data.d_int32;
gimp_destroy_params (return_vals, nreturn_vals);
return tattoo;
}

View file

@ -569,3 +569,25 @@ gimp_layer_set_visible (gint32 layer_ID,
gimp_destroy_params (return_vals, nreturn_vals);
}
gint32
gimp_layer_get_tattoo (gint32 layer_ID)
{
GParam *return_vals;
int nreturn_vals;
int tattoo;
return_vals = gimp_run_procedure ("gimp_layer_get_tattoo",
&nreturn_vals,
PARAM_LAYER, layer_ID,
PARAM_END);
tattoo = -1;
if (return_vals[0].data.d_status == STATUS_SUCCESS)
tattoo = return_vals[1].data.d_int32;
gimp_destroy_params (return_vals, nreturn_vals);
return tattoo;
}

265
libgimp/gserialize.c Normal file
View file

@ -0,0 +1,265 @@
/* gserialize.h
* Copyright (C) 1998 Jay Cox <jaycox@earthlink.net>
*
* 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 "gserialize.h"
struct _GSerialDescription
{
char *struct_name;
GSList *list;
};
struct _GSerialItem
{
GSerialType type; /* the type of this data member */
gulong offset; /* the offset into the struct of this item */
glong length; /* the number of elements (if this is an array) */
/* or -1 if this is a variable length array */
gulong length_offset; /* offset to the length of the array */
};
#define g_serial_copy_from_n g_serial_copy_to_n
long g_serial_copy_to_n(char *dest, char *source, long data_size, long n_items)
{
int i;
int length = n_items*data_size;
#ifdef WORDS_BIGENDIAN
memcpy(dest, source, length);
#else
switch (data_size)
{
case 1: memcpy(dest, source, n_items);
break;
case 2:
for (i = 0; i < length; i+=2)
{
dest[i] = source[i + 1];
dest[i+1] = source[i];
} break;
case 4:
for (i = 0; i < length; i+=4)
{
dest[i] = source[i + 3];
dest[i+1] = source[i + 2];
dest[i+2] = source[i + 1];
dest[i+3] = source[i];
} break;
case 8:
for (i = 0; i < length; i+=8)
{
dest[i] = source[i+7];
dest[i+1] = source[i+6];
dest[i+2] = source[i+5];
dest[i+3] = source[i+4];
dest[i+4] = source[i+3];
dest[i+5] = source[i+2];
dest[i+6] = source[i+1];
dest[i+7] = source[i];
} break;
default:
g_assert_not_reached();
}
#endif /* !WORDS_BIGENDIAN */
return length;
}
GSerialItem *g_new_serial_item(GSerialType type, gulong offset,
gint32 length, gulong length_offset)
{
GSerialItem *item = g_new(GSerialItem, 1);
item->type = type;
item->offset = offset;
item->length = length;
item->length_offset = length_offset;
return item;
}
GSerialDescription *g_new_serial_description(char *name, ...)
{
va_list argp;
void *tmp;
GSerialDescription *d = g_new(GSerialDescription, 1);
d->struct_name = g_strdup(name);
d->list = 0;
va_start(argp, name);
while ((tmp = va_arg (argp, void*)))
d->list = g_slist_append(d->list, tmp);
va_end(argp);
return d;
}
void g_free_serial_description(GSerialDescription *d)
{
g_free (d->struct_name);
while (d->list)
{
g_free(d->list->data);
d->list = g_slist_remove_link(d->list, d->list);
}
}
static int g_serial_item_is_array(GSerialItem *item)
{
if (item->type < GSERIAL_STRING)
return 0;
return 1;
}
static long g_serial_item_data_size(GSerialItem *item)
{
static long sizes[] = {0, 1, 2, 4, 4, 8, 1, 1, 2, 4, 4, 8};
return sizes[item->type];
}
static long g_serial_item_n_items(GSerialItem *item, void *struct_data)
{
if (item->type < GSERIAL_STRING)
return 1;
if (item->type == GSERIAL_STRING)
return (strlen(G_STRUCT_MEMBER(char*, struct_data, item->offset)) + 1);
if (item->length >= 0)
return item->length;
return (G_STRUCT_MEMBER(gint32, struct_data, item->length_offset));
}
static long g_serial_item_compute_length(GSerialItem *item, void *struct_data)
{
int length;
length = g_serial_item_n_items(item, struct_data) * g_serial_item_data_size(item);
length += g_serial_item_is_array(item) * 4;
return length + 1;
}
static long g_serial_description_compute_length(GSerialDescription *d,
void *struct_data)
{
long length = 0;
GSList *list;
list = d->list;
while (list)
{
length += g_serial_item_compute_length((GSerialItem *) list->data, struct_data);
list = list->next;
}
return length;
}
static long g_serial_item_serialize(GSerialItem *item, char *buffer,
void *struct_data)
{
char *buf = buffer;
gint32 tmp;
if (item->type >= GSERIAL_LAST_TYPE)
{
g_warning("Error serializing: Unknown serial item type.\n");
return 0;
}
*buf++ = item->type;
if (g_serial_item_is_array(item))
{
tmp = g_serial_item_n_items(item, struct_data);
buf += g_serial_copy_to_n(buf, (char *)&tmp, 4, 1);
buf += g_serial_copy_to_n(buf,
G_STRUCT_MEMBER(char*, struct_data,item->offset),
g_serial_item_data_size(item),
tmp);
}
else
{
buf += g_serial_copy_to_n(buf,
G_STRUCT_MEMBER_P(struct_data, item->offset),
g_serial_item_data_size(item), 1);
}
return (buf - buffer);
}
static long g_serial_item_deserialize(GSerialItem *item, void *struct_data,
char *buffer)
{
char *buf = buffer;
gint32 n_items;
if (*buf != item->type)
{
g_warning("Error deserializing: item types do not match: %d vs %d.\n",
*buf, item->type);
return 0;
}
buf++;
if (g_serial_item_is_array(item))
{
buf += g_serial_copy_from_n((char *)&n_items, buf, 4, 1);
if (item->length < 0)
G_STRUCT_MEMBER(gint32, struct_data, item->length_offset) = n_items;
G_STRUCT_MEMBER(void*, struct_data, item->offset)
= g_malloc(n_items*g_serial_item_data_size(item));
buf += g_serial_copy_from_n(G_STRUCT_MEMBER(void *, struct_data,
item->offset),
buf,
g_serial_item_data_size(item),
n_items);
}
else
{
buf += g_serial_copy_from_n(G_STRUCT_MEMBER_P(struct_data, item->offset),
buf,
g_serial_item_data_size(item),
1);
}
return (buf - buffer);
}
long g_serialize(GSerialDescription *d, void **output, void *struct_data)
{
int length = g_serial_description_compute_length(d, struct_data);
char *outbuf;
GSList *list;
long item_length;
outbuf = (char *)g_malloc(length);
*output = outbuf;
list = d->list;
while (list)
{
item_length = g_serial_item_serialize((GSerialItem *)list->data, outbuf,
struct_data);
if (item_length == 0)
g_error("Error serializing %s\n", d->struct_name);
outbuf += item_length;
list = list->next;
}
return length;
}
void g_deserialize(GSerialDescription *d, void *struct_data, void *serial)
{
GSList *list;
char *in_buf = serial;
char *out_buf = struct_data;
list = d->list;
while (list)
{
in_buf += g_serial_item_deserialize((GSerialItem *)list->data,
out_buf, in_buf);
list = list->next;
}
}

81
libgimp/gserialize.h Normal file
View file

@ -0,0 +1,81 @@
/* gserialize.h
* Copyright (C) 1998 Jay Cox <jaycox@earthlink.net>
*
* 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.
*/
#ifndef __GSERIALIZE_H__
#define __GSERIALIZE_H__
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include <glib.h>
#include <stdarg.h>
typedef enum {
GSERIAL_END, /* for internal use only */
GSERIAL_INT8,
GSERIAL_INT16,
GSERIAL_INT32,
GSERIAL_FLOAT, /* 32 bit IEEE fp value */
GSERIAL_DOUBLE, /* 64 bit IEEE fp value */
GSERIAL_STRING,
GSERIAL_INT8ARRAY,
GSERIAL_INT16ARRAY,
GSERIAL_INT32ARRAY,
GSERIAL_FLOATARRAY,
GSERIAL_DOUBLEARRAY,
GSERIAL_LAST_TYPE
} GSerialType;
typedef struct _GSerialItem GSerialItem;
typedef struct _GSerialDescription GSerialDescription;
GSerialItem *g_new_serial_item(GSerialType type, gulong offset,
gint32 length, gulong length_offset);
#define g_serial_item(type, struct_, member) \
g_new_serial_item(type, G_STRUCT_OFFSET(struct_, member), 0, 0)
#define g_serial_array(type, struct_, member, length) \
g_new_serial_item(type, G_STRUCT_OFFSET(struct_, member), length, 0)
#define g_serial_vlen_array(type, struct_, member, length_member) \
g_new_serial_item(type, G_STRUCT_OFFSET(struct_, member), -1, \
G_STRUCT_OFFSET(struct_, length_member))
GSerialDescription *g_new_serial_description(char *name, ...);
/* pass it g_serial_s. null terminated */
void g_free_serial_description(GSerialDescription *);
long g_serialize(GSerialDescription *d, void **output, void *struct_data);
/* returns the length of the serialized data.
g_mallocs space for the data and stores a pointer to it in output */
void g_deserialize(GSerialDescription *d, void *output, void *serial);
/* output must be a preallocated area large enough to hold the
deserialized struct. */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GSERIALIZE_H__*/