/*
*
* Print plug-in driver utility functions for the GIMP.
*
* Copyright 1997-2000 Michael Sweet (mike@easysw.com) and
* Robert Krawitz (rlk@alum.mit.edu)
*
* 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, see .
*/
/*
* This file must include only standard C header files. The core code must
* compile on generic platforms that don't support glib, gimp, gtk, etc.
*/
#ifdef HAVE_CONFIG_H
#include
#endif
#include
#ifdef HAVE_LIMITS_H
#include
#endif
#include
#include
#include "gutenprint-internal.h"
#include
#include "generic-options.h"
typedef struct
{
char *name;
stp_parameter_type_t typ;
stp_parameter_activity_t active;
union
{
int ival;
int bval;
double dval;
stp_dimension_t sval;
stp_curve_t *cval;
stp_array_t *aval;
stp_raw_t rval;
} value;
} value_t;
struct stp_compdata
{
char *name;
stp_copy_data_func_t copyfunc;
stp_free_data_func_t freefunc;
void *data;
};
struct stp_vars /* Plug-in variables */
{
char *driver; /* Name of printer "driver" */
char *color_conversion; /* Color module in use */
stp_dimension_t left; /* Offset from left-upper corner, points */
stp_dimension_t top; /* ... */
stp_dimension_t width; /* Width of the image, points */
stp_dimension_t height; /* ... */
stp_dimension_t page_width; /* Width of page in points */
stp_dimension_t page_height; /* Height of page in points */
stp_list_t *params[STP_PARAMETER_TYPE_INVALID];
stp_list_t *internal_data;
void (*outfunc)(void *data, const char *buffer, size_t bytes);
void *outdata;
void (*errfunc)(void *data, const char *buffer, size_t bytes);
void *errdata;
void (*dbgfunc)(void *data, const char *buffer, size_t bytes);
void *dbgdata;
int verified; /* Ensure that params are OK! */
};
static int standard_vars_initialized = 0;
void
stp_parameter_description_destroy(stp_parameter_t *desc)
{
switch (desc->p_type)
{
case STP_PARAMETER_TYPE_CURVE:
if (desc->bounds.curve)
stp_curve_destroy(desc->bounds.curve);
desc->bounds.curve = NULL;
break;
case STP_PARAMETER_TYPE_ARRAY:
if (desc->bounds.array)
stp_array_destroy(desc->bounds.array);
desc->bounds.array = NULL;
break;
case STP_PARAMETER_TYPE_STRING_LIST:
if (desc->bounds.str)
stp_string_list_destroy(desc->bounds.str);
desc->bounds.str = NULL;
break;
default:
break;
}
}
static stp_vars_t default_vars;
#define CHECK_VARS(v) STPI_ASSERT(v, NULL)
static const char *
value_namefunc(const void *item)
{
const value_t *v = (const value_t *) (item);
return v->name;
}
static void
value_freefunc(void *item)
{
value_t *v = (value_t *) (item);
switch (v->typ)
{
case STP_PARAMETER_TYPE_STRING_LIST:
case STP_PARAMETER_TYPE_FILE:
case STP_PARAMETER_TYPE_RAW:
stp_free(stpi_cast_safe(v->value.rval.data));
break;
case STP_PARAMETER_TYPE_CURVE:
if (v->value.cval)
stp_curve_destroy(v->value.cval);
break;
case STP_PARAMETER_TYPE_ARRAY:
stp_array_destroy(v->value.aval);
break;
default:
break;
}
stp_free(v->name);
stp_free(v);
}
static stp_list_t *
create_vars_list(void)
{
stp_list_t *ret = stp_list_create();
stp_list_set_freefunc(ret, value_freefunc);
stp_list_set_namefunc(ret, value_namefunc);
return ret;
}
static void
copy_to_raw(stp_raw_t *raw, const void *data, size_t bytes)
{
char *ndata = NULL;
if (data)
{
ndata = stp_malloc(bytes + 1);
memcpy(ndata, data, bytes);
ndata[bytes] = '\0';
}
else
bytes = 0;
raw->data = (void *) ndata;
raw->bytes = bytes;
}
static value_t *
value_copy(const void *item)
{
value_t *ret = stp_malloc(sizeof(value_t));
const value_t *v = (const value_t *) (item);
ret->name = stp_strdup(v->name);
ret->typ = v->typ;
ret->active = v->active;
switch (v->typ)
{
case STP_PARAMETER_TYPE_CURVE:
ret->value.cval = stp_curve_create_copy(v->value.cval);
break;
case STP_PARAMETER_TYPE_ARRAY:
ret->value.aval = stp_array_create_copy(v->value.aval);
break;
case STP_PARAMETER_TYPE_STRING_LIST:
case STP_PARAMETER_TYPE_FILE:
case STP_PARAMETER_TYPE_RAW:
copy_to_raw(&(ret->value.rval), v->value.rval.data, v->value.rval.bytes);
break;
case STP_PARAMETER_TYPE_DIMENSION:
ret->value.sval = v->value.sval;
break;
case STP_PARAMETER_TYPE_INT:
case STP_PARAMETER_TYPE_BOOLEAN:
ret->value.ival = v->value.ival;
break;
case STP_PARAMETER_TYPE_DOUBLE:
ret->value.dval = v->value.dval;
break;
default:
break;
}
return ret;
}
static stp_list_t *
copy_value_list(const stp_list_t *src)
{
stp_list_t *ret = create_vars_list();
const stp_list_item_t *item = stp_list_get_start((const stp_list_t *)src);
while (item)
{
stp_list_item_create(ret, NULL, value_copy(stp_list_item_get_data(item)));
item = stp_list_item_next(item);
}
return ret;
}
static const char *
compdata_namefunc(const void *item)
{
const compdata_t *cd = (const compdata_t *) (item);
return cd->name;
}
static void
compdata_freefunc(void *item)
{
compdata_t *cd = (compdata_t *) (item);
if (cd->freefunc)
(cd->freefunc)(cd->data);
stp_free(cd->name);
stp_free(cd);
}
static void *
compdata_copyfunc(const void *item)
{
const compdata_t *cd = (const compdata_t *) (item);
if (cd->copyfunc)
return (cd->copyfunc)(cd->data);
else
return cd->data;
}
void
stp_allocate_component_data(stp_vars_t *v,
const char *name,
stp_copy_data_func_t copyfunc,
stp_free_data_func_t freefunc,
void *data)
{
compdata_t *cd;
stp_list_item_t *item;
CHECK_VARS(v);
cd = stp_malloc(sizeof(compdata_t));
item = stp_list_get_item_by_name(v->internal_data, name);
if (item)
stp_list_item_destroy(v->internal_data, item);
cd->name = stp_strdup(name);
cd->copyfunc = copyfunc;
cd->freefunc = freefunc;
cd->data = data;
stp_list_item_create(v->internal_data, NULL, cd);
}
void
stp_destroy_component_data(stp_vars_t *v, const char *name)
{
stp_list_item_t *item;
CHECK_VARS(v);
item = stp_list_get_item_by_name(v->internal_data, name);
if (item)
stp_list_item_destroy(v->internal_data, item);
}
void *
stp_get_component_data(const stp_vars_t *v, const char *name)
{
stp_list_item_t *item;
CHECK_VARS(v);
item = stp_list_get_item_by_name(v->internal_data, name);
if (item)
return ((compdata_t *) stp_list_item_get_data(item))->data;
else
return NULL;
}
static stp_list_t *
create_compdata_list(void)
{
stp_list_t *ret = stp_list_create();
stp_list_set_freefunc(ret, compdata_freefunc);
stp_list_set_namefunc(ret, compdata_namefunc);
return ret;
}
static stp_list_t *
copy_compdata_list(const stp_list_t *src)
{
stp_list_t *ret = create_compdata_list();
const stp_list_item_t *item = stp_list_get_start(src);
while (item)
{
stp_list_item_create(ret, NULL, compdata_copyfunc(item));
item = stp_list_item_next(item);
}
return ret;
}
static void
initialize_standard_vars(void)
{
if (!standard_vars_initialized)
{
int i;
for (i = 0; i < STP_PARAMETER_TYPE_INVALID; i++)
default_vars.params[i] = create_vars_list();
default_vars.driver = stp_strdup("ps2");
default_vars.color_conversion = stp_strdup("traditional");
default_vars.internal_data = create_compdata_list();
standard_vars_initialized = 1;
}
}
const stp_vars_t *
stp_default_settings(void)
{
initialize_standard_vars();
return (stp_vars_t *) &default_vars;
}
stp_vars_t *
stp_vars_create(void)
{
int i;
stp_vars_t *retval = stp_zalloc(sizeof(stp_vars_t));
initialize_standard_vars();
for (i = 0; i < STP_PARAMETER_TYPE_INVALID; i++)
retval->params[i] = create_vars_list();
retval->internal_data = create_compdata_list();
stp_vars_copy(retval, (stp_vars_t *)&default_vars);
return (retval);
}
void
stp_vars_destroy(stp_vars_t *v)
{
int i;
CHECK_VARS(v);
for (i = 0; i < STP_PARAMETER_TYPE_INVALID; i++)
stp_list_destroy(v->params[i]);
stp_list_destroy(v->internal_data);
STP_SAFE_FREE(v->driver);
STP_SAFE_FREE(v->color_conversion);
stp_free(v);
}
#define DEF_STRING_FUNCS(s, pre) \
void \
pre##_set_##s(stp_vars_t *v, const char *val) \
{ \
CHECK_VARS(v); \
if (val) \
stp_dprintf(STP_DBG_VARS, v, "set %s to %s (0x%p)\n", #s, val, \
(const void *) v); \
else \
stp_dprintf(STP_DBG_VARS, v, "clear %s (0x%p)\n", #s, \
(const void *) v); \
if (v->s == val) \
return; \
STP_SAFE_FREE(v->s); \
v->s = stp_strdup(val); \
v->verified = 0; \
} \
\
void \
pre##_set_##s##_n(stp_vars_t *v, const char *val, int n) \
{ \
CHECK_VARS(v); \
if (v->s == val) \
return; \
STP_SAFE_FREE(v->s); \
v->s = stp_strndup(val, n); \
v->verified = 0; \
} \
\
const char * \
pre##_get_##s(const stp_vars_t *v) \
{ \
CHECK_VARS(v); \
return v->s; \
}
#define DEF_FUNCS(s, t, pre) \
void \
pre##_set_##s(stp_vars_t *v, t val) \
{ \
CHECK_VARS(v); \
v->verified = 0; \
v->s = val; \
} \
\
t \
pre##_get_##s(const stp_vars_t *v) \
{ \
CHECK_VARS(v); \
return v->s; \
}
DEF_STRING_FUNCS(driver, stp)
DEF_STRING_FUNCS(color_conversion, stp)
DEF_FUNCS(left, stp_dimension_t, stp)
DEF_FUNCS(top, stp_dimension_t, stp)
DEF_FUNCS(width, stp_dimension_t, stp)
DEF_FUNCS(height, stp_dimension_t, stp)
DEF_FUNCS(page_width, stp_dimension_t, stp)
DEF_FUNCS(page_height, stp_dimension_t, stp)
DEF_FUNCS(outdata, void *, stp)
DEF_FUNCS(errdata, void *, stp)
DEF_FUNCS(dbgdata, void *, stp)
DEF_FUNCS(outfunc, stp_outfunc_t, stp)
DEF_FUNCS(errfunc, stp_outfunc_t, stp)
DEF_FUNCS(dbgfunc, stp_outfunc_t, stp)
void
stp_set_verified(stp_vars_t *v, int val)
{
CHECK_VARS(v);
v->verified = val;
}
int
stp_get_verified(const stp_vars_t *v)
{
CHECK_VARS(v);
return v->verified;
}
static void
set_default_raw_parameter(stp_list_t *list, const char *parameter,
const char *value, size_t bytes, int typ)
{
stp_list_item_t *item = stp_list_get_item_by_name(list, parameter);
if (value && !item)
{
value_t *val = stp_malloc(sizeof(value_t));
val->name = stp_strdup(parameter);
val->typ = typ;
val->active = STP_PARAMETER_DEFAULTED;
stp_list_item_create(list, NULL, val);
copy_to_raw(&(val->value.rval), value, bytes);
}
}
static void
set_raw_parameter(stp_list_t *list, const char *parameter, const char *value,
size_t bytes, int typ)
{
stp_list_item_t *item = stp_list_get_item_by_name(list, parameter);
if (value)
{
value_t *val;
if (item)
{
val = (value_t *) stp_list_item_get_data(item);
if (val->active == STP_PARAMETER_DEFAULTED)
val->active = STP_PARAMETER_ACTIVE;
stp_free(stpi_cast_safe(val->value.rval.data));
}
else
{
val = stp_malloc(sizeof(value_t));
val->name = stp_strdup(parameter);
val->typ = typ;
val->active = STP_PARAMETER_ACTIVE;
stp_list_item_create(list, NULL, val);
}
copy_to_raw(&(val->value.rval), value, bytes);
}
else if (item)
stp_list_item_destroy(list, item);
}
void
stp_set_string_parameter_n(stp_vars_t *v, const char *parameter,
const char *value, size_t bytes)
{
stp_list_t *list = v->params[STP_PARAMETER_TYPE_STRING_LIST];
if (value)
stp_dprintf(STP_DBG_VARS, v, "stp_set_string_parameter(0x%p, %s, %s)\n",
(const void *) v, parameter, value);
else
stp_dprintf(STP_DBG_VARS, v, "stp_set_string_parameter(0x%p, %s)\n",
(const void *) v, parameter);
set_raw_parameter(list, parameter, value, bytes,
STP_PARAMETER_TYPE_STRING_LIST);
stp_set_verified(v, 0);
}
void
stp_set_string_parameter(stp_vars_t *v, const char *parameter,
const char *value)
{
int byte_count = 0;
if (value)
byte_count = strlen(value);
stp_dprintf(STP_DBG_VARS, v, "stp_set_string_parameter(0x%p, %s, %s)\n",
(const void *) v, parameter, value ? value : "NULL");
stp_set_string_parameter_n(v, parameter, value, byte_count);
stp_set_verified(v, 0);
}
void
stp_set_default_string_parameter_n(stp_vars_t *v, const char *parameter,
const char *value, size_t bytes)
{
stp_list_t *list = v->params[STP_PARAMETER_TYPE_STRING_LIST];
stp_dprintf(STP_DBG_VARS, v, "stp_set_default_string_parameter(0x%p, %s, %s)\n",
(const void *) v, parameter, value ? value : "NULL");
set_default_raw_parameter(list, parameter, value, bytes,
STP_PARAMETER_TYPE_STRING_LIST);
stp_set_verified(v, 0);
}
void
stp_set_default_string_parameter(stp_vars_t *v, const char *parameter,
const char *value)
{
int byte_count = 0;
if (value)
byte_count = strlen(value);
stp_set_default_string_parameter_n(v, parameter, value, byte_count);
stp_set_verified(v, 0);
}
void
stp_clear_string_parameter(stp_vars_t *v, const char *parameter)
{
stp_set_string_parameter(v, parameter, NULL);
}
const char *
stp_get_string_parameter(const stp_vars_t *v, const char *parameter)
{
stp_list_t *list = v->params[STP_PARAMETER_TYPE_STRING_LIST];
value_t *val;
stp_list_item_t *item = stp_list_get_item_by_name(list, parameter);
if (item)
{
val = (value_t *) stp_list_item_get_data(item);
return val->value.rval.data;
}
else
return NULL;
}
void
stp_set_raw_parameter(stp_vars_t *v, const char *parameter,
const void *value, size_t bytes)
{
stp_list_t *list = v->params[STP_PARAMETER_TYPE_RAW];
set_raw_parameter(list, parameter, value, bytes, STP_PARAMETER_TYPE_RAW);
stp_set_verified(v, 0);
}
void
stp_set_default_raw_parameter(stp_vars_t *v, const char *parameter,
const void *value, size_t bytes)
{
stp_list_t *list = v->params[STP_PARAMETER_TYPE_RAW];
set_default_raw_parameter(list, parameter, value, bytes,
STP_PARAMETER_TYPE_RAW);
stp_set_verified(v, 0);
}
void
stp_clear_raw_parameter(stp_vars_t *v, const char *parameter)
{
stp_set_raw_parameter(v, parameter, NULL, 0);
}
const stp_raw_t *
stp_get_raw_parameter(const stp_vars_t *v, const char *parameter)
{
const stp_list_t *list = v->params[STP_PARAMETER_TYPE_RAW];
const value_t *val;
const stp_list_item_t *item = stp_list_get_item_by_name(list, parameter);
if (item)
{
val = (const value_t *) stp_list_item_get_data(item);
return &(val->value.rval);
}
else
return NULL;
}
void
stp_set_file_parameter(stp_vars_t *v, const char *parameter,
const char *value)
{
stp_list_t *list = v->params[STP_PARAMETER_TYPE_FILE];
size_t byte_count = 0;
if (value)
byte_count = strlen(value);
stp_dprintf(STP_DBG_VARS, v, "stp_set_file_parameter(0x%p, %s, %s)\n",
(const void *) v, parameter, value ? value : "NULL");
set_raw_parameter(list, parameter, value, byte_count,
STP_PARAMETER_TYPE_FILE);
stp_set_verified(v, 0);
}
void
stp_set_file_parameter_n(stp_vars_t *v, const char *parameter,
const char *value, size_t byte_count)
{
stp_list_t *list = v->params[STP_PARAMETER_TYPE_FILE];
stp_dprintf(STP_DBG_VARS, v, "stp_set_file_parameter(0x%p, %s, %s)\n",
(const void *) v, parameter, value ? value : "NULL");
set_raw_parameter(list, parameter, value, byte_count,
STP_PARAMETER_TYPE_FILE);
stp_set_verified(v, 0);
}
void
stp_set_default_file_parameter(stp_vars_t *v, const char *parameter,
const char *value)
{
stp_list_t *list = v->params[STP_PARAMETER_TYPE_FILE];
size_t byte_count = 0;
if (value)
byte_count = strlen(value);
stp_dprintf(STP_DBG_VARS, v, "stp_set_default_file_parameter(0x%p, %s, %s)\n",
(const void *) v, parameter, value ? value : "NULL");
set_default_raw_parameter(list, parameter, value, byte_count,
STP_PARAMETER_TYPE_FILE);
stp_set_verified(v, 0);
}
void
stp_set_default_file_parameter_n(stp_vars_t *v, const char *parameter,
const char *value, size_t byte_count)
{
stp_list_t *list = v->params[STP_PARAMETER_TYPE_FILE];
stp_dprintf(STP_DBG_VARS, v, "stp_set_default_file_parameter(0x%p, %s, %s)\n",
(const void *) v, parameter, value ? value : "NULL");
set_default_raw_parameter(list, parameter, value, byte_count,
STP_PARAMETER_TYPE_FILE);
stp_set_verified(v, 0);
}
void
stp_clear_file_parameter(stp_vars_t *v, const char *parameter)
{
stp_set_file_parameter(v, parameter, NULL);
}
const char *
stp_get_file_parameter(const stp_vars_t *v, const char *parameter)
{
const stp_list_t *list = v->params[STP_PARAMETER_TYPE_FILE];
const value_t *val;
const stp_list_item_t *item = stp_list_get_item_by_name(list, parameter);
if (item)
{
val = (const value_t *) stp_list_item_get_data(item);
return val->value.rval.data;
}
else
return NULL;
}
void
stp_set_curve_parameter(stp_vars_t *v, const char *parameter,
const stp_curve_t *curve)
{
stp_list_t *list = v->params[STP_PARAMETER_TYPE_CURVE];
stp_list_item_t *item = stp_list_get_item_by_name(list, parameter);
stp_dprintf(STP_DBG_VARS, v, "stp_set_curve_parameter(0x%p, %s)\n",
(const void *) v, parameter);
if (curve)
{
value_t *val;
if (item)
{
val = (value_t *) stp_list_item_get_data(item);
if (val->active == STP_PARAMETER_DEFAULTED)
val->active = STP_PARAMETER_ACTIVE;
if (val->value.cval)
stp_curve_destroy(val->value.cval);
}
else
{
val = stp_malloc(sizeof(value_t));
val->name = stp_strdup(parameter);
val->typ = STP_PARAMETER_TYPE_CURVE;
val->active = STP_PARAMETER_ACTIVE;
stp_list_item_create(list, NULL, val);
}
val->value.cval = stp_curve_create_copy(curve);
}
else if (item)
stp_list_item_destroy(list, item);
stp_set_verified(v, 0);
}
void
stp_set_default_curve_parameter(stp_vars_t *v, const char *parameter,
const stp_curve_t *curve)
{
stp_list_t *list = v->params[STP_PARAMETER_TYPE_CURVE];
stp_list_item_t *item = stp_list_get_item_by_name(list, parameter);
stp_dprintf(STP_DBG_VARS, v, "stp_set_default_curve_parameter(0x%p, %s)\n",
(const void *) v, parameter);
if (!item)
{
if (curve)
{
value_t *val;
val = stp_malloc(sizeof(value_t));
val->name = stp_strdup(parameter);
val->typ = STP_PARAMETER_TYPE_CURVE;
val->active = STP_PARAMETER_DEFAULTED;
stp_list_item_create(list, NULL, val);
val->value.cval = stp_curve_create_copy(curve);
}
}
stp_set_verified(v, 0);
}
void
stp_clear_curve_parameter(stp_vars_t *v, const char *parameter)
{
stp_set_curve_parameter(v, parameter, NULL);
}
const stp_curve_t *
stp_get_curve_parameter(const stp_vars_t *v, const char *parameter)
{
const stp_list_t *list = v->params[STP_PARAMETER_TYPE_CURVE];
const value_t *val;
const stp_list_item_t *item = stp_list_get_item_by_name(list, parameter);
if (item)
{
val = (value_t *) stp_list_item_get_data(item);
return val->value.cval;
}
else
return NULL;
}
void
stp_set_array_parameter(stp_vars_t *v, const char *parameter,
const stp_array_t *array)
{
stp_list_t *list = v->params[STP_PARAMETER_TYPE_ARRAY];
stp_list_item_t *item = stp_list_get_item_by_name(list, parameter);
stp_dprintf(STP_DBG_VARS, v, "stp_set_array_parameter(0x%p, %s)\n",
(const void *) v, parameter);
if (array)
{
value_t *val;
if (item)
{
val = (value_t *) stp_list_item_get_data(item);
if (val->active == STP_PARAMETER_DEFAULTED)
val->active = STP_PARAMETER_ACTIVE;
stp_array_destroy(val->value.aval);
}
else
{
val = stp_malloc(sizeof(value_t));
val->name = stp_strdup(parameter);
val->typ = STP_PARAMETER_TYPE_ARRAY;
val->active = STP_PARAMETER_ACTIVE;
stp_list_item_create(list, NULL, val);
}
val->value.aval = stp_array_create_copy(array);
}
else if (item)
stp_list_item_destroy(list, item);
stp_set_verified(v, 0);
}
void
stp_set_default_array_parameter(stp_vars_t *v, const char *parameter,
const stp_array_t *array)
{
stp_list_t *list = v->params[STP_PARAMETER_TYPE_ARRAY];
stp_list_item_t *item = stp_list_get_item_by_name(list, parameter);
stp_dprintf(STP_DBG_VARS, v, "stp_set_default_array_parameter(0x%p, %s)\n",
(const void *) v, parameter);
if (!item)
{
if (array)
{
value_t *val;
val = stp_malloc(sizeof(value_t));
val->name = stp_strdup(parameter);
val->typ = STP_PARAMETER_TYPE_ARRAY;
val->active = STP_PARAMETER_DEFAULTED;
stp_list_item_create(list, NULL, val);
val->value.aval = stp_array_create_copy(array);
}
}
stp_set_verified(v, 0);
}
void
stp_clear_array_parameter(stp_vars_t *v, const char *parameter)
{
stp_set_array_parameter(v, parameter, NULL);
}
const stp_array_t *
stp_get_array_parameter(const stp_vars_t *v, const char *parameter)
{
const stp_list_t *list = v->params[STP_PARAMETER_TYPE_ARRAY];
const value_t *val;
const stp_list_item_t *item = stp_list_get_item_by_name(list, parameter);
if (item)
{
val = (const value_t *) stp_list_item_get_data(item);
return val->value.aval;
}
else
return NULL;
}
void
stp_set_int_parameter(stp_vars_t *v, const char *parameter, int ival)
{
stp_list_t *list = v->params[STP_PARAMETER_TYPE_INT];
value_t *val;
stp_list_item_t *item = stp_list_get_item_by_name(list, parameter);
stp_dprintf(STP_DBG_VARS, v, "stp_set_int_parameter(0x%p, %s, %d)\n",
(const void *) v, parameter, ival);
if (item)
{
val = (value_t *) stp_list_item_get_data(item);
if (val->active == STP_PARAMETER_DEFAULTED)
val->active = STP_PARAMETER_ACTIVE;
}
else
{
val = stp_malloc(sizeof(value_t));
val->name = stp_strdup(parameter);
val->typ = STP_PARAMETER_TYPE_INT;
val->active = STP_PARAMETER_ACTIVE;
stp_list_item_create(list, NULL, val);
}
val->value.ival = ival;
stp_set_verified(v, 0);
}
void
stp_set_default_int_parameter(stp_vars_t *v, const char *parameter, int ival)
{
stp_list_t *list = v->params[STP_PARAMETER_TYPE_INT];
value_t *val;
stp_list_item_t *item = stp_list_get_item_by_name(list, parameter);
stp_dprintf(STP_DBG_VARS, v, "stp_set_default_int_parameter(0x%p, %s, %d)\n",
(const void *) v, parameter, ival);
if (!item)
{
val = stp_malloc(sizeof(value_t));
val->name = stp_strdup(parameter);
val->typ = STP_PARAMETER_TYPE_INT;
val->active = STP_PARAMETER_DEFAULTED;
stp_list_item_create(list, NULL, val);
val->value.ival = ival;
}
stp_set_verified(v, 0);
}
void
stp_clear_int_parameter(stp_vars_t *v, const char *parameter)
{
stp_list_t *list = v->params[STP_PARAMETER_TYPE_INT];
stp_list_item_t *item = stp_list_get_item_by_name(list, parameter);
stp_dprintf(STP_DBG_VARS, v, "stp_clear_int_parameter(0x%p, %s)\n",
(const void *) v, parameter);
if (item)
stp_list_item_destroy(list, item);
stp_set_verified(v, 0);
}
int
stp_get_int_parameter(const stp_vars_t *v, const char *parameter)
{
const stp_list_t *list = v->params[STP_PARAMETER_TYPE_INT];
const stp_list_item_t *item = stp_list_get_item_by_name(list, parameter);
if (item)
{
const value_t *val = (const value_t *) stp_list_item_get_data(item);
return val->value.ival;
}
else
{
stp_parameter_t desc;
stp_describe_parameter(v, parameter, &desc);
if (desc.p_type == STP_PARAMETER_TYPE_INT)
{
int intval = desc.deflt.integer;
stp_parameter_description_destroy(&desc);
return intval;
}
else
{
stp_parameter_description_destroy(&desc);
stp_eprintf
(v, "Gutenprint: Attempt to retrieve unset integer parameter %s\n",
parameter);
return 0;
}
}
}
void
stp_set_boolean_parameter(stp_vars_t *v, const char *parameter, int ival)
{
stp_list_t *list = v->params[STP_PARAMETER_TYPE_BOOLEAN];
value_t *val;
stp_list_item_t *item = stp_list_get_item_by_name(list, parameter);
stp_dprintf(STP_DBG_VARS, v, "stp_set_boolean_parameter(0x%p, %s, %d)\n",
(const void *) v, parameter, ival);
if (item)
{
val = (value_t *) stp_list_item_get_data(item);
if (val->active == STP_PARAMETER_DEFAULTED)
val->active = STP_PARAMETER_ACTIVE;
}
else
{
val = stp_malloc(sizeof(value_t));
val->name = stp_strdup(parameter);
val->typ = STP_PARAMETER_TYPE_BOOLEAN;
val->active = STP_PARAMETER_ACTIVE;
stp_list_item_create(list, NULL, val);
}
if (ival)
val->value.ival = 1;
else
val->value.ival = 0;
stp_set_verified(v, 0);
}
void
stp_set_default_boolean_parameter(stp_vars_t *v, const char *parameter,
int ival)
{
stp_list_t *list = v->params[STP_PARAMETER_TYPE_BOOLEAN];
value_t *val;
stp_list_item_t *item = stp_list_get_item_by_name(list, parameter);
stp_dprintf(STP_DBG_VARS, v, "stp_set_default_boolean_parameter(0x%p, %s, %d)\n",
(const void *) v, parameter, ival);
if (!item)
{
val = stp_malloc(sizeof(value_t));
val->name = stp_strdup(parameter);
val->typ = STP_PARAMETER_TYPE_BOOLEAN;
val->active = STP_PARAMETER_DEFAULTED;
stp_list_item_create(list, NULL, val);
if (ival)
val->value.ival = 1;
else
val->value.ival = 0;
}
stp_set_verified(v, 0);
}
void
stp_clear_boolean_parameter(stp_vars_t *v, const char *parameter)
{
stp_list_t *list = v->params[STP_PARAMETER_TYPE_BOOLEAN];
stp_list_item_t *item = stp_list_get_item_by_name(list, parameter);
stp_dprintf(STP_DBG_VARS, v, "stp_clear_boolean_parameter(0x%p, %s)\n",
(const void *) v, parameter);
if (item)
stp_list_item_destroy(list, item);
stp_set_verified(v, 0);
}
int
stp_get_boolean_parameter(const stp_vars_t *v, const char *parameter)
{
const stp_list_t *list = v->params[STP_PARAMETER_TYPE_BOOLEAN];
const stp_list_item_t *item = stp_list_get_item_by_name(list, parameter);
if (item)
{
const value_t *val = (const value_t *) stp_list_item_get_data(item);
return val->value.ival;
}
else
{
stp_parameter_t desc;
stp_describe_parameter(v, parameter, &desc);
if (desc.p_type == STP_PARAMETER_TYPE_BOOLEAN)
{
int boolean = desc.deflt.boolean;
stp_parameter_description_destroy(&desc);
return boolean;
}
else
{
stp_parameter_description_destroy(&desc);
stp_eprintf
(v, "Gutenprint: Attempt to retrieve unset boolean parameter %s\n",
parameter);
return 0;
}
}
}
void
stp_set_dimension_parameter(stp_vars_t *v, const char *parameter, stp_dimension_t sval)
{
stp_list_t *list = v->params[STP_PARAMETER_TYPE_DIMENSION];
value_t *val;
stp_list_item_t *item = stp_list_get_item_by_name(list, parameter);
stp_dprintf(STP_DBG_VARS, v, "stp_set_dimension_parameter(0x%p, %s, %f)\n",
(const void *) v, parameter, sval);
if (item)
{
val = (value_t *) stp_list_item_get_data(item);
if (val->active == STP_PARAMETER_DEFAULTED)
val->active = STP_PARAMETER_ACTIVE;
}
else
{
val = stp_malloc(sizeof(value_t));
val->name = stp_strdup(parameter);
val->typ = STP_PARAMETER_TYPE_DIMENSION;
val->active = STP_PARAMETER_ACTIVE;
stp_list_item_create(list, NULL, val);
}
val->value.sval = sval;
stp_set_verified(v, 0);
}
void
stp_set_default_dimension_parameter(stp_vars_t *v, const char *parameter,
stp_dimension_t sval)
{
stp_list_t *list = v->params[STP_PARAMETER_TYPE_DIMENSION];
value_t *val;
stp_list_item_t *item = stp_list_get_item_by_name(list, parameter);
stp_dprintf(STP_DBG_VARS, v, "stp_set_default_dimension_parameter(0x%p, %s, %f)\n",
(const void *) v, parameter, sval);
if (!item)
{
val = stp_malloc(sizeof(value_t));
val->name = stp_strdup(parameter);
val->typ = STP_PARAMETER_TYPE_DIMENSION;
val->active = STP_PARAMETER_DEFAULTED;
stp_list_item_create(list, NULL, val);
val->value.sval = sval;
}
stp_set_verified(v, 0);
}
void
stp_clear_dimension_parameter(stp_vars_t *v, const char *parameter)
{
stp_list_t *list = v->params[STP_PARAMETER_TYPE_DIMENSION];
stp_list_item_t *item = stp_list_get_item_by_name(list, parameter);
stp_dprintf(STP_DBG_VARS, v, "stp_clear_dimension_parameter(0x%p, %s)\n",
(const void *) v, parameter);
if (item)
stp_list_item_destroy(list, item);
stp_set_verified(v, 0);
}
stp_dimension_t
stp_get_dimension_parameter(const stp_vars_t *v, const char *parameter)
{
const stp_list_t *list = v->params[STP_PARAMETER_TYPE_DIMENSION];
const stp_list_item_t *item = stp_list_get_item_by_name(list, parameter);
if (item)
{
const value_t *val = (const value_t *) stp_list_item_get_data(item);
return val->value.sval;
}
else
{
stp_parameter_t desc;
stp_describe_parameter(v, parameter, &desc);
if (desc.p_type == STP_PARAMETER_TYPE_DIMENSION)
{
stp_dimension_t intval = desc.deflt.dimension;
stp_parameter_description_destroy(&desc);
return intval;
}
else
{
stp_parameter_description_destroy(&desc);
stp_eprintf
(v, "Gutenprint: Attempt to retrieve unset dimension parameter %s\n",
parameter);
return 0;
}
}
}
void
stp_set_float_parameter(stp_vars_t *v, const char *parameter, double dval)
{
stp_list_t *list = v->params[STP_PARAMETER_TYPE_DOUBLE];
value_t *val;
stp_list_item_t *item = stp_list_get_item_by_name(list, parameter);
stp_dprintf(STP_DBG_VARS, v, "stp_set_float_parameter(0x%p, %s, %f)\n",
(const void *) v, parameter, dval);
if (item)
{
val = (value_t *) stp_list_item_get_data(item);
if (val->active == STP_PARAMETER_DEFAULTED)
val->active = STP_PARAMETER_ACTIVE;
}
else
{
val = stp_malloc(sizeof(value_t));
val->name = stp_strdup(parameter);
val->typ = STP_PARAMETER_TYPE_DOUBLE;
val->active = STP_PARAMETER_ACTIVE;
stp_list_item_create(list, NULL, val);
}
val->value.dval = dval;
stp_set_verified(v, 0);
}
void
stp_set_default_float_parameter(stp_vars_t *v, const char *parameter,
double dval)
{
stp_list_t *list = v->params[STP_PARAMETER_TYPE_DOUBLE];
value_t *val;
stp_list_item_t *item = stp_list_get_item_by_name(list, parameter);
stp_dprintf(STP_DBG_VARS, v, "stp_set_default_float_parameter(0x%p, %s, %f)\n",
(const void *) v, parameter, dval);
if (!item)
{
val = stp_malloc(sizeof(value_t));
val->name = stp_strdup(parameter);
val->typ = STP_PARAMETER_TYPE_DOUBLE;
val->active = STP_PARAMETER_DEFAULTED;
stp_list_item_create(list, NULL, val);
val->value.dval = dval;
}
stp_set_verified(v, 0);
}
void
stp_clear_float_parameter(stp_vars_t *v, const char *parameter)
{
stp_list_t *list = v->params[STP_PARAMETER_TYPE_DOUBLE];
stp_list_item_t *item = stp_list_get_item_by_name(list, parameter);
stp_dprintf(STP_DBG_VARS, v, "stp_clear_float_parameter(0x%p, %s)\n",
(const void *) v, parameter);
if (item)
stp_list_item_destroy(list, item);
stp_set_verified(v, 0);
}
double
stp_get_float_parameter(const stp_vars_t *v, const char *parameter)
{
const stp_list_t *list = v->params[STP_PARAMETER_TYPE_DOUBLE];
const stp_list_item_t *item = stp_list_get_item_by_name(list, parameter);
if (item)
{
const value_t *val = (value_t *) stp_list_item_get_data(item);
return val->value.dval;
}
else
{
stp_parameter_t desc;
stp_describe_parameter(v, parameter, &desc);
if (desc.p_type == STP_PARAMETER_TYPE_DOUBLE)
{
double dbl = desc.deflt.dbl;
stp_parameter_description_destroy(&desc);
return dbl;
}
else
{
stp_parameter_description_destroy(&desc);
stp_eprintf
(v, "Gutenprint: Attempt to retrieve unset float parameter %s\n",
parameter);
return 1.0;
}
}
}
void
stp_scale_float_parameter(stp_vars_t *v, const char *parameter,
double scale)
{
double val;
if (stp_check_float_parameter(v, parameter, STP_PARAMETER_DEFAULTED))
val = stp_get_float_parameter(v, parameter);
else
{
stp_parameter_t desc;
stp_describe_parameter(v, parameter, &desc);
if (desc.p_type != STP_PARAMETER_TYPE_DOUBLE)
{
stp_parameter_description_destroy(&desc);
return;
}
val = desc.deflt.dbl;
stp_parameter_description_destroy(&desc);
}
stp_dprintf(STP_DBG_VARS, v, "stp_scale_float_parameter(%p, %s, %f*%f)\n",
(const void *) v, parameter, val, scale);
stp_set_float_parameter(v, parameter, val * scale);
}
void
stp_clear_parameter(stp_vars_t *v, const char *parameter, stp_parameter_type_t type)
{
switch (type)
{
case STP_PARAMETER_TYPE_STRING_LIST:
stp_clear_string_parameter(v, parameter);
break;
case STP_PARAMETER_TYPE_FILE:
stp_clear_file_parameter(v, parameter);
break;
case STP_PARAMETER_TYPE_DOUBLE:
stp_clear_float_parameter(v, parameter);
break;
case STP_PARAMETER_TYPE_INT:
stp_clear_int_parameter(v, parameter);
break;
case STP_PARAMETER_TYPE_DIMENSION:
stp_clear_dimension_parameter(v, parameter);
break;
case STP_PARAMETER_TYPE_BOOLEAN:
stp_clear_boolean_parameter(v, parameter);
break;
case STP_PARAMETER_TYPE_CURVE:
stp_clear_curve_parameter(v, parameter);
break;
case STP_PARAMETER_TYPE_ARRAY:
stp_clear_array_parameter(v, parameter);
break;
case STP_PARAMETER_TYPE_RAW:
stp_clear_raw_parameter(v, parameter);
break;
default:
stp_eprintf(v, "Attempt to clear unknown type parameter!\n");
}
}
int
stp_check_parameter(const stp_vars_t *v,
const char *parameter,
stp_parameter_activity_t active,
stp_parameter_type_t p_type)
{
if (p_type >= STP_PARAMETER_TYPE_STRING_LIST &&
p_type < STP_PARAMETER_TYPE_INVALID)
{
const stp_list_t *list = v->params[p_type];
const stp_list_item_t *item = stp_list_get_item_by_name(list, parameter);
if (item &&
active <= ((const value_t *) stp_list_item_get_data(item))->active)
return 1;
else
return 0;
}
return 0;
}
#define CHECK_FUNCTION(type, index) \
int \
stp_check_##type##_parameter(const stp_vars_t *v, const char *parameter, \
stp_parameter_activity_t active) \
{ \
return stp_check_parameter(v, parameter, active, index); \
}
CHECK_FUNCTION(string, STP_PARAMETER_TYPE_STRING_LIST)
CHECK_FUNCTION(file, STP_PARAMETER_TYPE_FILE)
CHECK_FUNCTION(float, STP_PARAMETER_TYPE_DOUBLE)
CHECK_FUNCTION(int, STP_PARAMETER_TYPE_INT)
CHECK_FUNCTION(dimension, STP_PARAMETER_TYPE_DIMENSION)
CHECK_FUNCTION(boolean, STP_PARAMETER_TYPE_BOOLEAN)
CHECK_FUNCTION(curve, STP_PARAMETER_TYPE_CURVE)
CHECK_FUNCTION(array, STP_PARAMETER_TYPE_ARRAY)
CHECK_FUNCTION(raw, STP_PARAMETER_TYPE_RAW)
stp_string_list_t *
stp_list_parameters(const stp_vars_t *v, stp_parameter_type_t p_type)
{
if (p_type >= STP_PARAMETER_TYPE_STRING_LIST &&
p_type < STP_PARAMETER_TYPE_INVALID)
{
const stp_list_t *list = v->params[p_type];
stp_string_list_t *answer = stp_string_list_create();
const stp_list_item_t *li = stp_list_get_start(list);
while (li)
{
const value_t *val = (value_t *) stp_list_item_get_data(li);
stp_string_list_add_string(answer, val->name, val->name);
li = stp_list_item_next(li);
}
return answer;
}
return NULL;
}
#define LIST_FUNCTION(type, index) \
stp_string_list_t * \
stp_list_##type##_parameters(const stp_vars_t *v) \
{ \
return stp_list_parameters(v, index); \
}
LIST_FUNCTION(string, STP_PARAMETER_TYPE_STRING_LIST)
LIST_FUNCTION(file, STP_PARAMETER_TYPE_FILE)
LIST_FUNCTION(float, STP_PARAMETER_TYPE_DOUBLE)
LIST_FUNCTION(int, STP_PARAMETER_TYPE_INT)
LIST_FUNCTION(dimension, STP_PARAMETER_TYPE_DIMENSION)
LIST_FUNCTION(boolean, STP_PARAMETER_TYPE_BOOLEAN)
LIST_FUNCTION(curve, STP_PARAMETER_TYPE_CURVE)
LIST_FUNCTION(array, STP_PARAMETER_TYPE_ARRAY)
LIST_FUNCTION(raw, STP_PARAMETER_TYPE_RAW)
stp_parameter_activity_t
stp_get_parameter_active(const stp_vars_t *v, const char *parameter,
stp_parameter_type_t p_type)
{
if (p_type >= STP_PARAMETER_TYPE_STRING_LIST &&
p_type < STP_PARAMETER_TYPE_INVALID)
{
const stp_list_t *list = v->params[p_type];
const stp_list_item_t *item = stp_list_get_item_by_name(list, parameter);
if (item)
return ((const value_t *) stp_list_item_get_data(item))->active;
else
return 0;
}
return 0;
}
#define GET_PARAMETER_ACTIVE_FUNCTION(type, index) \
stp_parameter_activity_t \
stp_get_##type##_parameter_active(const stp_vars_t *v, const char *parameter) \
{ \
return stp_get_parameter_active(v, parameter, index); \
}
GET_PARAMETER_ACTIVE_FUNCTION(string, STP_PARAMETER_TYPE_STRING_LIST)
GET_PARAMETER_ACTIVE_FUNCTION(file, STP_PARAMETER_TYPE_FILE)
GET_PARAMETER_ACTIVE_FUNCTION(float, STP_PARAMETER_TYPE_DOUBLE)
GET_PARAMETER_ACTIVE_FUNCTION(int, STP_PARAMETER_TYPE_INT)
GET_PARAMETER_ACTIVE_FUNCTION(dimension, STP_PARAMETER_TYPE_DIMENSION)
GET_PARAMETER_ACTIVE_FUNCTION(boolean, STP_PARAMETER_TYPE_BOOLEAN)
GET_PARAMETER_ACTIVE_FUNCTION(curve, STP_PARAMETER_TYPE_CURVE)
GET_PARAMETER_ACTIVE_FUNCTION(array, STP_PARAMETER_TYPE_ARRAY)
GET_PARAMETER_ACTIVE_FUNCTION(raw, STP_PARAMETER_TYPE_RAW)
void
stp_set_parameter_active(stp_vars_t *v,
const char *parameter,
stp_parameter_activity_t active,
stp_parameter_type_t p_type)
{
if (p_type >= STP_PARAMETER_TYPE_STRING_LIST &&
p_type < STP_PARAMETER_TYPE_INVALID)
{
const stp_list_t *list = v->params[p_type];
const stp_list_item_t *item = stp_list_get_item_by_name(list, parameter);
if (item && (active == STP_PARAMETER_ACTIVE ||
active == STP_PARAMETER_INACTIVE))
((value_t *) stp_list_item_get_data(item))->active = active;
}
}
#define SET_PARAMETER_ACTIVE_FUNCTION(type, index) \
void \
stp_set_##type##_parameter_active(stp_vars_t *v, const char *parameter, \
stp_parameter_activity_t active) \
{ \
stp_dprintf(STP_DBG_VARS, v, \
"stp_set_%s_parameter_active(0x%p, %s, %d)\n", \
#type, (const void *) v, parameter, active); \
stp_set_parameter_active(v, parameter, active, index); \
}
SET_PARAMETER_ACTIVE_FUNCTION(string, STP_PARAMETER_TYPE_STRING_LIST)
SET_PARAMETER_ACTIVE_FUNCTION(file, STP_PARAMETER_TYPE_FILE)
SET_PARAMETER_ACTIVE_FUNCTION(float, STP_PARAMETER_TYPE_DOUBLE)
SET_PARAMETER_ACTIVE_FUNCTION(int, STP_PARAMETER_TYPE_INT)
SET_PARAMETER_ACTIVE_FUNCTION(dimension, STP_PARAMETER_TYPE_DIMENSION)
SET_PARAMETER_ACTIVE_FUNCTION(boolean, STP_PARAMETER_TYPE_BOOLEAN)
SET_PARAMETER_ACTIVE_FUNCTION(curve, STP_PARAMETER_TYPE_CURVE)
SET_PARAMETER_ACTIVE_FUNCTION(array, STP_PARAMETER_TYPE_ARRAY)
SET_PARAMETER_ACTIVE_FUNCTION(raw, STP_PARAMETER_TYPE_RAW)
void
stp_fill_parameter_settings(stp_parameter_t *desc,
const stp_parameter_t *param)
{
if (param)
{
desc->p_type = param->p_type;
desc->p_level = param->p_level;
desc->p_class = param->p_class;
desc->is_mandatory = param->is_mandatory;
desc->is_active = param->is_active;
desc->channel = param->channel;
desc->verify_this_parameter = param->verify_this_parameter;
desc->read_only = param->read_only;
desc->name = param->name;
STPI_ASSERT(param->text, NULL);
desc->text = gettext(param->text);
STPI_ASSERT(param->category, NULL);
desc->category = gettext(param->category);
desc->help = param->help ? gettext(param->help) : NULL;
return;
}
}
void
stp_vars_copy(stp_vars_t *vd, const stp_vars_t *vs)
{
int i;
if (vs == vd)
return;
stp_set_outdata(vd, stp_get_outdata(vs));
stp_set_errdata(vd, stp_get_errdata(vs));
stp_set_dbgdata(vd, stp_get_dbgdata(vs));
stp_set_outfunc(vd, stp_get_outfunc(vs));
stp_set_errfunc(vd, stp_get_errfunc(vs));
stp_set_dbgfunc(vd, stp_get_dbgfunc(vs));
stp_set_driver(vd, stp_get_driver(vs));
stp_set_color_conversion(vd, stp_get_color_conversion(vs));
stp_set_left(vd, stp_get_left(vs));
stp_set_top(vd, stp_get_top(vs));
stp_set_width(vd, stp_get_width(vs));
stp_set_height(vd, stp_get_height(vs));
stp_set_page_width(vd, stp_get_page_width(vs));
stp_set_page_height(vd, stp_get_page_height(vs));
for (i = 0; i < STP_PARAMETER_TYPE_INVALID; i++)
{
stp_list_destroy(vd->params[i]);
vd->params[i] = copy_value_list(vs->params[i]);
}
stp_list_destroy(vd->internal_data);
vd->internal_data = copy_compdata_list(vs->internal_data);
stp_set_verified(vd, stp_get_verified(vs));
}
void
stp_vars_print_error(const stp_vars_t *v, const char *prefix)
{
int i;
char *cptr;
static const char *data_types[] = {
"String",
"Int",
"Bool",
"Double",
"Curve",
"File",
"Raw",
"Array",
"Dimension",
"(Inactive)"
};
if (! prefix)
prefix = "";
stp_eprintf(v, "%s: Gutenprint: === BEGIN GUTENPRINT SETTINGS ===\n", prefix);
stp_eprintf(v, "%s: Gutenprint: Driver: %s\n", prefix, stp_get_driver(v));
stp_eprintf(v, "%s: Gutenprint: L: %f T: %f W: %f H: %f\n", prefix, stp_get_left(v),
stp_get_top(v), stp_get_width(v), stp_get_height(v));
stp_eprintf(v, "%s: Gutenprint: Page: %fx%f\n", prefix, stp_get_page_width(v),
stp_get_page_height(v));
stp_eprintf(v, "%s: Gutenprint: Conversion: %s\n", prefix, stp_get_color_conversion(v));
for (i = 0; i < STP_PARAMETER_TYPE_INVALID; i++)
{
const stp_list_item_t *item =
stp_list_get_start((const stp_list_t *) v->params[i]);
while (item)
{
char *crep;
const value_t *val = (const value_t *) stp_list_item_get_data(item);
switch (val->typ)
{
case STP_PARAMETER_TYPE_CURVE:
crep = stp_curve_write_string(val->value.cval);
cptr = crep;
while (cptr && *cptr)
{
if (*cptr == '\n')
*cptr = ' ';
cptr++;
}
stp_eprintf(v, "%s: Gutenprint: (%s) (%i) (%s) [%s]\n", prefix,
val->name, val->active, data_types[val->typ],
crep ? crep : "NULL");
if (crep)
stp_free(crep);
break;
case STP_PARAMETER_TYPE_ARRAY:
break;
case STP_PARAMETER_TYPE_STRING_LIST:
case STP_PARAMETER_TYPE_FILE:
case STP_PARAMETER_TYPE_RAW:
crep = stp_rawtoxmlstr(&(val->value.rval));
stp_eprintf(v, "%s: Gutenprint: (%s) (%i) (%s) [%s]\n", prefix,
val->name, val->active, data_types[val->typ],
crep ? crep : "NULL");
if (crep)
stp_free(crep);
break;
case STP_PARAMETER_TYPE_DIMENSION:
stp_eprintf(v, "%s: Gutenprint: (%s) (%i) (%s) [%f]\n", prefix,
val->name, val->active, data_types[val->typ],
val->value.sval);
break;
case STP_PARAMETER_TYPE_INT:
case STP_PARAMETER_TYPE_BOOLEAN:
stp_eprintf(v, "%s: Gutenprint: (%s) (%i) (%s) [%d]\n", prefix,
val->name, val->active, data_types[val->typ],
val->value.ival);
break;
case STP_PARAMETER_TYPE_DOUBLE:
stp_eprintf(v, "%s: Gutenprint: (%s) (%i) (%s) [%f]\n", prefix,
val->name, val->active, data_types[val->typ],
val->value.dval);
break;
default:
break;
}
item = stp_list_item_next(item);
}
}
stp_eprintf(v, "%s: Gutenprint: === END GUTENPRINT SETTINGS ===\n", prefix);
}
void
stp_prune_inactive_options(stp_vars_t *v)
{
stp_parameter_list_t params = stp_get_parameter_list(v);
int i;
for (i = 0; i < STP_PARAMETER_TYPE_INVALID; i++)
{
stp_list_t *list = v->params[i];
stp_list_item_t *item = stp_list_get_start(list);
while (item)
{
stp_list_item_t *next = stp_list_item_next(item);
value_t *var = (value_t *)stp_list_item_get_data(item);
if (var->active < STP_PARAMETER_DEFAULTED ||
!(stp_parameter_find(params, var->name)))
stp_list_item_destroy(list, item);
item = next;
}
}
stp_parameter_list_destroy(params);
}
stp_vars_t *
stp_vars_create_copy(const stp_vars_t *vs)
{
stp_vars_t *vd = stp_vars_create();
stp_vars_copy(vd, vs);
return (vd);
}
static const char *
param_namefunc(const void *item)
{
const stp_parameter_t *param = (const stp_parameter_t *)(item);
return param->name;
}
static const char *
param_longnamefunc(const void *item)
{
const stp_parameter_t *param = (const stp_parameter_t *) (item);
return param->text;
}
stp_parameter_list_t
stp_parameter_list_create(void)
{
stp_list_t *ret = stp_list_create();
stp_list_set_namefunc(ret, param_namefunc);
stp_list_set_long_namefunc(ret, param_longnamefunc);
return (stp_parameter_list_t) ret;
}
void
stp_parameter_list_add_param(stp_parameter_list_t list,
const stp_parameter_t *item)
{
stp_list_t *ilist = (stp_list_t *) list;
stp_list_item_create(ilist, NULL, item);
}
static void
debug_print_parameter_description(const stp_parameter_t *desc, const char *who,
const stp_vars_t *v)
{
int i;
char *curve;
if (! (stp_get_debug_level() & STP_DBG_VARS))
return;
stp_dprintf(STP_DBG_VARS, v, "Describe %s: vars 0x%p from %s type %d class %d level %d\n",
desc->name, (const void *) v, who,
desc->p_type, desc->p_class, desc->p_level);
stp_dprintf(STP_DBG_VARS, v, " driver %s mandatory %d active %d channel %d verify %d ro %d\n",
stp_get_driver(v), desc->is_mandatory, desc->is_active,
desc->channel, desc->verify_this_parameter, desc->read_only);
switch (desc->p_type)
{
case STP_PARAMETER_TYPE_STRING_LIST:
stp_dprintf(STP_DBG_VARS, v,
" String default: %s\n",
desc->deflt.str ? desc->deflt.str : "(null)");
if (desc->bounds.str)
for (i = 0; i < stp_string_list_count(desc->bounds.str); i++)
{
if (i == 0)
stp_dprintf(STP_DBG_VARS, v, " Choices: %s\n",
stp_string_list_param(desc->bounds.str, i)->name);
else
stp_dprintf(STP_DBG_VARS, v, " : %s\n",
stp_string_list_param(desc->bounds.str, i)->name);
}
break;
case STP_PARAMETER_TYPE_INT:
stp_dprintf(STP_DBG_VARS, v,
" Integer default: %d Bounds: %d %d\n",
desc->deflt.integer,
desc->bounds.integer.lower, desc->bounds.integer.upper);
break;
case STP_PARAMETER_TYPE_DIMENSION:
stp_dprintf(STP_DBG_VARS, v,
" Dimension default: %f Bounds: %f %f\n",
desc->deflt.dimension,
desc->bounds.dimension.lower, desc->bounds.dimension.upper);
break;
case STP_PARAMETER_TYPE_BOOLEAN:
stp_dprintf(STP_DBG_VARS, v,
" Boolean default: %d\n", desc->deflt.boolean);
break;
case STP_PARAMETER_TYPE_DOUBLE:
stp_dprintf(STP_DBG_VARS, v,
" Double default: %f Bounds: %f %f\n",
desc->deflt.dbl,
desc->bounds.dbl.lower, desc->bounds.dbl.upper);
break;
case STP_PARAMETER_TYPE_FILE:
stp_dprintf(STP_DBG_VARS, v, " File (no default)\n");
break;
case STP_PARAMETER_TYPE_RAW:
stp_dprintf(STP_DBG_VARS, v, " Raw (no default)\n");
break;
case STP_PARAMETER_TYPE_CURVE:
curve = stp_curve_write_string(desc->deflt.curve);
stp_dprintf(STP_DBG_VARS, v,
" Curve default: %s\n", curve);
stp_free(curve);
curve = stp_curve_write_string(desc->bounds.curve);
stp_dprintf(STP_DBG_VARS, v,
" bounds: %s\n", curve);
stp_free(curve);
break;
case STP_PARAMETER_TYPE_ARRAY:
stp_dprintf(STP_DBG_VARS, v, " Array\n");
break;
case STP_PARAMETER_TYPE_INVALID:
stp_dprintf(STP_DBG_VARS, v, " *** Invalid ***\n");
break;
default:
stp_dprintf(STP_DBG_VARS, v, " Unknown type!\n");
}
}
void
stp_describe_parameter(const stp_vars_t *v, const char *name,
stp_parameter_t *description)
{
description->p_type = STP_PARAMETER_TYPE_INVALID;
/* Set these to NULL in case stpi_*_describe_parameter() doesn't */
description->bounds.str = NULL;
description->deflt.str = NULL;
stp_printer_describe_parameter(v, name, description);
if (description->p_type != STP_PARAMETER_TYPE_INVALID)
{
debug_print_parameter_description(description, "driver", v);
return;
}
stp_color_describe_parameter(v, name, description);
if (description->p_type != STP_PARAMETER_TYPE_INVALID)
{
debug_print_parameter_description(description, "color", v);
return;
}
stp_dither_describe_parameter(v, name, description);
if (description->p_type != STP_PARAMETER_TYPE_INVALID)
{
debug_print_parameter_description(description, "dither", v);
return;
}
stpi_describe_generic_parameter(v, name, description);
if (description->p_type != STP_PARAMETER_TYPE_INVALID)
debug_print_parameter_description(description, "generic", v);
else
stp_dprintf(STP_DBG_VARS, v, "Describing invalid parameter %s\n", name);
}
stp_string_list_t *
stp_parameter_get_categories(const stp_vars_t *v, const stp_parameter_t *desc)
{
const char *dptr;
stp_string_list_t *answer;
int count = 0;
if (!v || !desc || !(desc->category))
return NULL;
answer = stp_string_list_create();
dptr = desc->category;
while (dptr)
{
const char *xptr = strchr(dptr, '=');
if (xptr)
{
char *name = stp_strndup(dptr, xptr - dptr);
char *text;
dptr = xptr + 1;
xptr = strchr(dptr, ',');
if (xptr)
{
text = stp_strndup(dptr, xptr - dptr);
dptr = xptr + 1;
}
else
{
text = stp_strdup(dptr);
dptr = NULL;
}
stp_string_list_add_string(answer, name, text);
stp_free(name);
stp_free(text);
count++;
}
else
dptr = NULL;
}
if (count == 0)
{
stp_string_list_destroy(answer);
return NULL;
}
else
return answer;
}
char *
stp_parameter_get_category(const stp_vars_t *v, const stp_parameter_t *desc,
const char *category)
{
const char *dptr;
char *cptr;
int len;
if (!v || !desc || !(desc->category) || !category)
return NULL;
dptr = desc->category;
stp_asprintf(&cptr, "%s=", category);
len = stp_strlen(cptr);
while (dptr)
{
if (strncmp(dptr, cptr, len) == 0)
{
const char *xptr;
char *answer;
dptr += len;
xptr = strchr(dptr, ',');
if (xptr)
answer = stp_strndup(dptr, xptr - dptr);
else
answer = stp_strdup(dptr);
stp_free(cptr);
return answer;
}
dptr = strchr(dptr, ',');
if (dptr)
dptr++;
}
return NULL;
}
int
stp_parameter_has_category_value(const stp_vars_t *v,
const stp_parameter_t *desc,
const char *category, const char *value)
{
char *cptr;
int answer = 0;
if (!v || !desc || !category)
return -1;
cptr = stp_parameter_get_category(v, desc, category);
if (cptr == NULL)
return 0;
if (value == NULL || strcmp(value, cptr) == 0)
answer = 1;
stp_free(cptr);
return answer;
}
const stp_parameter_t *
stp_parameter_find_in_settings(const stp_vars_t *v, const char *name)
{
stp_parameter_list_t param_list = stp_get_parameter_list(v);
const stp_parameter_t *param = stp_parameter_find(param_list, name);
stp_parameter_list_destroy(param_list);
return param;
}
size_t
stp_parameter_list_count(stp_const_parameter_list_t list)
{
const stp_list_t *ilist = (const stp_list_t *)list;
return stp_list_get_length(ilist);
}
const stp_parameter_t *
stp_parameter_find(stp_const_parameter_list_t list, const char *name)
{
const stp_list_t *ilist = (const stp_list_t *)list;
const stp_list_item_t *item = stp_list_get_item_by_name(ilist, name);
if (item)
return (const stp_parameter_t *) stp_list_item_get_data(item);
else
return NULL;
}
const stp_parameter_t *
stp_parameter_list_param(stp_const_parameter_list_t list, size_t item)
{
const stp_list_t *ilist = (const stp_list_t *)list;
stp_list_item_t *i = NULL;
if (item >= stp_list_get_length(ilist))
return NULL;
else
{
i = stp_list_get_item_by_index(ilist, item);
if (i == NULL)
return NULL;
return (const stp_parameter_t *) stp_list_item_get_data(i);
}
}
void
stp_parameter_list_destroy(stp_parameter_list_t list)
{
stp_list_destroy((stp_list_t *)list);
}
stp_parameter_list_t
stp_parameter_list_copy(stp_const_parameter_list_t list)
{
stp_list_t *ret = stp_parameter_list_create();
int i;
size_t count = stp_parameter_list_count(list);
for (i = 0; i < count; i++)
stp_list_item_create(ret, NULL, stp_parameter_list_param(list, i));
return (stp_parameter_list_t) ret;
}
void
stp_parameter_list_append(stp_parameter_list_t list,
stp_const_parameter_list_t append)
{
int i;
stp_list_t *ilist = (stp_list_t *)list;
size_t count = stp_parameter_list_count(append);
for (i = 0; i < count; i++)
{
const stp_parameter_t *param = stp_parameter_list_param(append, i);
if (!stp_list_get_item_by_name(ilist, param->name))
stp_list_item_create(ilist, NULL, param);
}
}
void
stp_copy_vars_from(stp_vars_t *to, const stp_vars_t *from)
{
int i;
if (!from || !to)
return;
for (i = 0; i < STP_PARAMETER_TYPE_INVALID; i++)
{
const stp_list_item_t *item =
stp_list_get_start((const stp_list_t *) from->params[i]);
while (item)
{
const value_t *val = (const value_t *) stp_list_item_get_data(item);
switch (val->typ)
{
case STP_PARAMETER_TYPE_CURVE:
stp_set_curve_parameter(to, val->name, val->value.cval);
break;
case STP_PARAMETER_TYPE_ARRAY:
stp_set_array_parameter(to, val->name, val->value.aval);
break;
case STP_PARAMETER_TYPE_STRING_LIST:
stp_set_string_parameter(to, val->name, val->value.rval.data);
break;
case STP_PARAMETER_TYPE_FILE:
stp_set_file_parameter(to, val->name, val->value.rval.data);
break;
case STP_PARAMETER_TYPE_RAW:
stp_set_raw_parameter(to, val->name, val->value.rval.data,
val->value.rval.bytes);
break;
case STP_PARAMETER_TYPE_INT:
stp_set_int_parameter(to, val->name, val->value.ival);
break;
case STP_PARAMETER_TYPE_DIMENSION:
stp_set_dimension_parameter(to, val->name, val->value.ival);
break;
case STP_PARAMETER_TYPE_BOOLEAN:
stp_set_boolean_parameter(to, val->name, val->value.bval);
break;
case STP_PARAMETER_TYPE_DOUBLE:
stp_set_float_parameter(to, val->name, val->value.dval);
break;
default:
break;
}
item = stp_list_item_next(item);
}
}
}
static void
fill_vars_from_xmltree(stp_mxml_node_t *prop, stp_mxml_node_t *root,
stp_vars_t *v)
{
#ifdef HAVE_LOCALE_H
char *locale = stp_strdup(setlocale(LC_ALL, NULL));
setlocale(LC_ALL, "C");
#endif
stp_dprintf(STP_DBG_XML, v, "Enter fill_vars_from_xmltree()\n");
while (prop)
{
stp_dprintf(STP_DBG_XML, v, "Property type %d (%s)\n", prop->type,
prop->type == STP_MXML_ELEMENT ? prop->value.element.name :
(prop->type == STP_MXML_TEXT ? prop->value.text.string : "(nil)"));
if (prop->type == STP_MXML_ELEMENT &&
(prop->child || stp_mxmlElementGetAttr(prop, "name")))
{
stp_mxml_node_t *child = prop->child;
const char *prop_name = prop->value.element.name;
const char *p_type = stp_mxmlElementGetAttr(prop, "type");
const char *p_name = stp_mxmlElementGetAttr(prop, "name");
if (!strcmp(prop_name, "parameter") && (!p_type || !p_name))
stp_eprintf(v, "Bad property found!\n");
else if (!strcmp(prop_name, "parameter"))
{
const char *active = stp_mxmlElementGetAttr(prop, "active");
const char *cref = stp_mxmlElementGetAttr(prop, "ref");
stp_mxml_node_t *cnode = child;
stp_parameter_type_t type = STP_PARAMETER_TYPE_INVALID;
if (cref && root)
{
cnode = stp_mxmlFindElement(root, root, "namedParam",
"name", cref,
STP_MXML_DESCEND);
STPI_ASSERT(cnode && cnode->type == STP_MXML_ELEMENT &&
cnode->child, v);
stp_dprintf(STP_DBG_XML, v, "Found parameter ref %s\n", cref);
cnode = cnode->child;
}
if (strcmp(p_type, "float") == 0)
{
if (cnode->type == STP_MXML_TEXT)
{
stp_set_float_parameter
(v, p_name, stp_xmlstrtod(cnode->value.text.string));
type = STP_PARAMETER_TYPE_DOUBLE;
if (stp_get_debug_level() & STP_DBG_XML)
stp_dprintf(STP_DBG_XML, v, " Set float '%s' to '%s' (%f)\n",
p_name, cnode->value.text.string,
stp_get_float_parameter(v, p_name));
}
}
else if (strcmp(p_type, "integer") == 0)
{
if (cnode->type == STP_MXML_TEXT)
{
stp_set_int_parameter
(v, p_name, (int) stp_xmlstrtol(cnode->value.text.string));
type = STP_PARAMETER_TYPE_DOUBLE;
if (stp_get_debug_level() & STP_DBG_XML)
stp_dprintf(STP_DBG_XML, v, " Set int '%s' to '%s' (%d)\n",
p_name, cnode->value.text.string,
stp_get_int_parameter(v, p_name));
}
}
else if (strcmp(p_type, "dimension") == 0)
{
if (cnode->type == STP_MXML_TEXT)
{
stp_set_dimension_parameter
(v, p_name, (int) stp_xmlstrtodim(cnode->value.text.string));
type = STP_PARAMETER_TYPE_DOUBLE;
if (stp_get_debug_level() & STP_DBG_XML)
stp_dprintf(STP_DBG_XML, v, " Set dimension '%s' to '%s' (%f)\n",
p_name, cnode->value.text.string,
stp_get_dimension_parameter(v, p_name));
}
}
else if (strcmp(p_type, "boolean") == 0)
{
if (cnode->type == STP_MXML_TEXT)
{
stp_set_boolean_parameter
(v, p_name, (int) stp_xmlstrtol(cnode->value.text.string));
type = STP_PARAMETER_TYPE_DOUBLE;
if (stp_get_debug_level() & STP_DBG_XML)
stp_dprintf(STP_DBG_XML, v, " Set bool '%s' to '%s' (%d)\n",
p_name, cnode->value.text.string,
stp_get_boolean_parameter(v, p_name));
}
}
else if (strcmp(p_type, "string") == 0)
{
if (cnode->type == STP_MXML_TEXT)
{
stp_set_string_parameter
(v, p_name, cnode->value.text.string);
type = STP_PARAMETER_TYPE_DOUBLE;
if (stp_get_debug_level() & STP_DBG_XML)
stp_dprintf(STP_DBG_XML, v, " Set string '%s' to '%s' (%s)\n",
p_name, cnode->value.text.string,
stp_get_string_parameter(v, p_name));
}
}
else if (strcmp(p_type, "file") == 0)
{
if (cnode->type == STP_MXML_TEXT)
{
stp_set_file_parameter
(v, p_name, cnode->value.text.string);
type = STP_PARAMETER_TYPE_DOUBLE;
if (stp_get_debug_level() & STP_DBG_XML)
stp_dprintf(STP_DBG_XML, v, " Set file '%s' to '%s' (%s)\n",
p_name, cnode->value.text.string,
stp_get_file_parameter(v, p_name));
}
}
else if (strcmp(p_type, "raw") == 0)
{
if (cnode->type == STP_MXML_TEXT)
{
stp_raw_t *raw = stp_xmlstrtoraw(cnode->value.text.string);
if (raw)
{
stp_set_raw_parameter(v, p_name, raw->data,raw->bytes);
type = STP_PARAMETER_TYPE_DOUBLE;
stp_dprintf(STP_DBG_XML, v, " Set raw '%s' to '%s'\n",
p_name, cnode->value.text.string);
stp_free(stpi_cast_safe(raw->data));
stp_free(raw);
}
}
}
else if (strcmp(p_type, "curve") == 0)
{
stp_curve_t *curve;
while (cnode->type != STP_MXML_ELEMENT && cnode->next)
cnode = cnode->next;
STPI_ASSERT(cnode, v);
curve = stp_curve_create_from_xmltree(cnode);
STPI_ASSERT(curve, v);
stp_set_curve_parameter(v, p_name, curve);
type = STP_PARAMETER_TYPE_DOUBLE;
if (stp_get_debug_level() & STP_DBG_XML)
{
char *cv = stp_curve_write_string(curve);
stp_dprintf(STP_DBG_XML, v, " Set curve '%s' (%s)\n",
p_name, cv);
stp_free(cv);
}
stp_curve_destroy(curve);
}
else if (strcmp(p_type, "array") == 0)
{
stp_array_t *array;
while (cnode->type != STP_MXML_ELEMENT && cnode->next)
cnode = cnode->next;
STPI_ASSERT(cnode, v);
array = stp_array_create_from_xmltree(cnode);
STPI_ASSERT(array, v);
type = STP_PARAMETER_TYPE_DOUBLE;
stp_set_array_parameter(v, p_name, array);
stp_dprintf(STP_DBG_XML, v, " Set array '%s'\n", p_name);
stp_array_destroy(array);
}
else
{
stp_eprintf(v, "Bad property %s type %s\n", p_name, p_type);
}
if (active && type != STP_PARAMETER_TYPE_INVALID)
{
if (strcmp(active, "active") == 0)
stp_set_parameter_active(v, p_name, STP_PARAMETER_ACTIVE, type);
else if (strcmp(active, "inactive") == 0)
stp_set_parameter_active(v, p_name, STP_PARAMETER_INACTIVE, type);
else if (strcmp(active, "default") == 0)
stp_set_parameter_active(v, p_name, STP_PARAMETER_DEFAULTED, type);
}
}
else if (child->type == STP_MXML_TEXT)
{
stp_dprintf(STP_DBG_XML, v, " Set property %s ('%s')\n",
prop_name, child->value.text.string ?
child->value.text.string : "(nil)");
if (!strcmp(prop_name, "driver"))
stp_set_driver(v, child->value.text.string);
else if (!strcmp(prop_name, "color_conversion"))
stp_set_color_conversion(v, child->value.text.string);
else if (!strcmp(prop_name, "left"))
stp_set_left(v, stp_xmlstrtol(child->value.text.string));
else if (!strcmp(prop_name, "top"))
stp_set_top(v, stp_xmlstrtol(child->value.text.string));
else if (!strcmp(prop_name, "width"))
stp_set_width(v, stp_xmlstrtol(child->value.text.string));
else if (!strcmp(prop_name, "height"))
stp_set_height(v, stp_xmlstrtol(child->value.text.string));
else if (!strcmp(prop_name, "page_width"))
stp_set_page_width(v, stp_xmlstrtol(child->value.text.string));
else if (!strcmp(prop_name, "page_height"))
stp_set_page_height(v, stp_xmlstrtol(child->value.text.string));
}
}
else
{
if (prop->type == STP_MXML_ELEMENT)
stp_dprintf(STP_DBG_XML, v, "Unexpected node type %d name %s\n",
prop->type, prop->value.element.name);
}
prop = prop->next;
}
stp_dprintf(STP_DBG_XML, v, "End fill_vars_from_xmltree()\n");
#ifdef HAVE_LOCALE_H
setlocale(LC_ALL, locale);
stp_free(locale);
#endif
}
void
stp_vars_fill_from_xmltree(stp_mxml_node_t *prop, stp_vars_t *v)
{
fill_vars_from_xmltree(prop, NULL, v);
}
stp_vars_t *
stp_vars_create_from_xmltree(stp_mxml_node_t *da)
{
stp_vars_t *v = stp_vars_create();
fill_vars_from_xmltree(da, NULL, v);
return v;
}
void
stp_vars_fill_from_xmltree_ref(stp_mxml_node_t *prop, stp_mxml_node_t *root,
stp_vars_t *v)
{
fill_vars_from_xmltree(prop, root, v);
}
stp_vars_t *
stp_vars_create_from_xmltree_ref(stp_mxml_node_t *da, stp_mxml_node_t *root)
{
stp_vars_t *v = stp_vars_create();
fill_vars_from_xmltree(da, root, v);
return v;
}
static void
add_text_node(stp_mxml_node_t *node, const char *element, const char *value)
{
if (value)
stp_mxmlNewOpaque(stp_mxmlNewElement(node, element), value);
}
stp_mxml_node_t *
stp_xmltree_create_from_vars(const stp_vars_t *v)
{
stp_mxml_node_t *varnode;
int i;
if (!v)
return NULL;
varnode = stp_mxmlNewElement(NULL, "vars");
add_text_node(varnode, "driver", stp_get_driver(v));
add_text_node(varnode, "color_conversion", stp_get_color_conversion(v));
stp_mxmlNewInteger(stp_mxmlNewElement(varnode, "left"), stp_get_left(v));
stp_mxmlNewInteger(stp_mxmlNewElement(varnode, "top"), stp_get_top(v));
stp_mxmlNewInteger(stp_mxmlNewElement(varnode, "width"), stp_get_width(v));
stp_mxmlNewInteger(stp_mxmlNewElement(varnode, "height"), stp_get_height(v));
stp_mxmlNewInteger(stp_mxmlNewElement(varnode, "page_width"), stp_get_page_width(v));
stp_mxmlNewInteger(stp_mxmlNewElement(varnode, "page_height"), stp_get_page_height(v));
for (i = STP_PARAMETER_TYPE_STRING_LIST; i < STP_PARAMETER_TYPE_INVALID; i++)
{
stp_string_list_t *list = stp_list_parameters(v, i);
if (list)
{
int j;
int count = stp_string_list_count(list);
for (j = 0; j < count; j++)
{
const stp_param_string_t *pstr = stp_string_list_param(list, j);
const char *name = pstr->name;
char *data;
stp_mxml_node_t *node = stp_mxmlNewElement(varnode, "parameter");
stp_parameter_activity_t active =
stp_get_parameter_active(v, name, i);
stp_mxmlElementSetAttr(node, "name", name);
stp_mxmlElementSetAttr(node, "active",
(active == STP_PARAMETER_INACTIVE ?
"inactive" :
(active == STP_PARAMETER_DEFAULTED ?
"default" : "active")));
switch (i)
{
case STP_PARAMETER_TYPE_STRING_LIST:
stp_mxmlElementSetAttr(node, "type", "string");
data = stp_strtoxmlstr(stp_get_string_parameter(v, name));
if (data)
{
stp_mxmlNewOpaque(node, data);
stp_free(data);
}
break;
case STP_PARAMETER_TYPE_INT:
stp_mxmlElementSetAttr(node, "type", "integer");
stp_mxmlNewInteger(node, stp_get_int_parameter(v, name));
break;
case STP_PARAMETER_TYPE_BOOLEAN:
stp_mxmlElementSetAttr(node, "type", "boolean");
stp_mxmlNewInteger(node, stp_get_boolean_parameter(v, name));
break;
case STP_PARAMETER_TYPE_DOUBLE:
stp_mxmlElementSetAttr(node, "type", "float");
stp_mxmlNewReal(node, stp_get_float_parameter(v, name));
break;
case STP_PARAMETER_TYPE_CURVE:
stp_mxmlElementSetAttr(node, "type", "curve");
stp_mxmlAdd(node, STP_MXML_ADD_AFTER, NULL,
stp_xmltree_create_from_curve(stp_get_curve_parameter(v, name)));
break;
case STP_PARAMETER_TYPE_FILE:
stp_mxmlElementSetAttr(node, "type", "file");
data = stp_strtoxmlstr(stp_get_file_parameter(v, name));
if (data)
{
stp_mxmlNewOpaque(node, data);
stp_free(data);
}
break;
case STP_PARAMETER_TYPE_RAW:
stp_mxmlElementSetAttr(node, "type", "raw");
data = stp_rawtoxmlstr(stp_get_raw_parameter(v, name));
if (data)
{
stp_mxmlNewOpaque(node, data);
stp_free(data);
}
break;
case STP_PARAMETER_TYPE_ARRAY:
stp_mxmlElementSetAttr(node, "type", "array");
stp_mxmlAdd(node, STP_MXML_ADD_AFTER, NULL,
stp_xmltree_create_from_array(stp_get_array_parameter(v, name)));
break;
case STP_PARAMETER_TYPE_DIMENSION:
stp_mxmlElementSetAttr(node, "type", "dimension");
stp_mxmlNewDimension(node, stp_get_dimension_parameter(v, name));
break;
default:
stp_mxmlElementSetAttr(node, "type", "INVALID!");
break;
}
}
stp_string_list_destroy(list);
}
}
return varnode;
}